Missed this post. OOPS. No worries, I found it. Debug mode is working, kinda sorta but hmm... something's still not quite right... Sky Eye will work for sure, but I want Parts Test to work!
Whoops. I should have checked back sooner. I had just finished uploading it too. Oh well. I'm not sure what Parts Test really does. Does Parts Test open at all for you? If you open certain menus, and then open another one of a different type after that, it'll sort of glitch out. Only way around that I know is you need to restart the whole emulator.
We have definately found a way to get debug mode working, but I am not sure all flags are being properly set. However, this gives me a good stepping stone to figure out in the game's code how debug mode may have originally been accessed. Also it was the POLYGON TEST I am most excited about. It will allow clean screenshots of unused objects for the Wiki.
Because of the Pokemon Gold leak, it's inspired me to clean up some of my code to make debug mode public in a script with a function to handle debug functions and can integrate into anyone else's cheat script if they've made one. For those new to this, copy the code into a blank text file using a text editor of your choice (such as notepad), and save as "sfight.lua", and place it in the "scripts" folder where the emulator is located. Voila! Spoiler Code (Text): -- script by ElSemi, Link, Biggestsonicfan, and SteveBlockhead -- Debug Usage: Press "O" key to enable debug, and Player 2 start to access it. -- While in Debug mode, pressing "Q" will advance the game without disabling Debug. -- The "L" key can be used to quit Debug Mode while it is active. require("model2"); -- Import model2 machine globals function Frame(val) dbgFrame(I960_ReadByte(RAMBASE+0x19EB9))--Sends debug flag to debug routine if not val then return else -- end end function dbgFrame(val) if val == 1 then if Input_IsKeyPressed(0x10) == 1 --Q key then I960_WriteByte(RAMBASE+0x8000, 0) -- Unfreeze Debug Mode by a single frame end if Input_IsKeyPressed(0x26) == 1 --L key then I960_WriteByte(RAMBASE+0x19EB9, 0) -- Turn off Debug Mode... I960_WriteByte(RAMBASE+0x8000, 0) -- And unfreeze time again end else if Input_IsKeyPressed(0x18) == 1 --O key then I960_WriteByte(RAMBASE+0x19EB9, 1) -- Set Debug Mode end end end function PostDraw() --Bonus function which lets you know if Debug mode is enabled or not! Video_DrawText(5,3,"Debug Mode:",0xFFFFFF); if I960_ReadByte(RAMBASE+0x19EB9) == 1 then Video_DrawText(105,3,"ENABLED",0x008000); else Video_DrawText(105,3,"DISABLED",0xFF0000); end end Happy Debugging! :specialed:
Thank you. I feel I should say something after crying "DEBUG MODE IS NEIGH!" since Honey was first found like, 11 years ago, but in 11 years the people who wanted the models moved on. The community moved on and now I feel like my biggest contribution to this was never giving up really. I knew it was there, but this interesting situation with Steve seemed to accelerate this baby to 88 and we saw some serious shit all the way back to 1996. I'd like to share some of my research leading to this point that has currently gone unpublished. In my quest to search for debug mode, I finally brought out the big guns and began disassembling Sonic the Fighters from scratch using every piece of research I had gathered to that time. After successfully dumping the entire memory contents and loading both the program and memory with correct mapping into IDA Pro, I began labeling everything I knew in the data and the memory. One particular address I saw associated with Debug was checking an address of memory at 0x508000 and branching to debug-like subroutines if true. One of these routines happened to call one of my documented routines: Code (Text): ROMBASE:00000C94 000 ld dword_508000, r15 ROMBASE:00000C9C 000 bbs 0x0D, r15, loc_CB8 ROMBASE:00000CA0 000 call health_gyr If translated to psudocode, it would look something like this: Load register r15 in the processor with the value of address 0x508000 If the value in bit 0x0D in r15 is set, branch to subroutine CB8 Else, call the subroutine to initialize the health bars health_gyr is a subroutine I documented which handles the HUD's palette data for the health bars. Their colors values are as follows: Green: Code (Text): 0x836082C08220818083E0834082A08200 Yellow: Code (Text): 0xA3FF837F82DF827FB3FF83FF835F82FF Red: Code (Text): 0x801B801880158011801F801C80198015 This subroutine is referenced in every frame of emulation. If we can change the data in the ROM, it will reflect in every frame of the emulated result! The hex for calling the health routine is 14 DC 02 09, but if we change it to 10 00 00 09, the routine looks a little different: Code (Text): ROMBASE:00000C94 000 ld dword_508000, r15 ROMBASE:00000C9C 000 bbs 0x0D, r15, loc_CB8 ROMBASE:00000CA0 000 call loc_CA4 We now call routine CA4 instead of the health bar routine and guess what, the health bars are assigned default palette values (the location of those colors as of writing I do not know) which happen to be the same ones as seen in very early prototype screenshots of the game! Et volia! An unused beta routine restored! The function for this to be used in a script is as follows: PHP: function patchdbg(value) --set health bars if value == 1 then Romset_PatchByte(0,0xCA0, 0x04) Romset_PatchWord(0,0xCA1, 0x0000) -- restore health bars elseif value == 0 then Romset_PatchByte(0,0xCA0, 0x14) Romset_PatchWord(0,0xCA1, 0x2DC) end end You can either call patchdbg(1) in Init() or in a cheat menu option. Either way, you will need to read model2lua.txt to implement it correctly into the script above. A more playful script will be released as more things are explored and documented in debug mode. Also, for some reason, it affects menu item selection in debug mode, which is incredibly bizarre.
Hey, can you provide videos of Fang, Bean, & Bark running repeatedly with the view on the side? I'd like to see how they look while running...
This can be seen in normal gameplay?The instructional VHS also has footage of every dash and move in the game. Anyway, here's Pengo and his ice blocks. I could not correctly screenshot these a decade ago. Also, a build date, which as of yet has no relevance to the game's code as far as I can tell: Code (Text): ROMBASE:000BDE1B aRYPOC: .ascii "RYPOC"<0> ROMBASE:000BDE21 aTHGI: .ascii " THGI"<0> ROMBASE:000BDE27 aAGES: .ascii " AGES"<0> ROMBASE:000BDE2D aRETNE: .ascii "RETNE"<0> ROMBASE:000BDE33 aESIRP: .ascii "ESIRP"<0> ROMBASE:000BDE39 aMILS: .ascii "MIL S"<0> ROMBASE:000BDE3F aDETI: .ascii " DETI"<0> ROMBASE:000BDE45 a5991: .ascii " 5991"<0> ROMBASE:000BDE4B .ascii " "<0> ROMBASE:000BDE51 a7211: .ascii " 7211"<0> ROMBASE:000BDE57 .ascii " "<0> ROMBASE:000BDE5D aAHMA: .ascii "AH MA"<0> ROMBASE:000BDE63 aRAWDR: .ascii "RAWDR"<0> ROMBASE:000BDE69 aDRE: .ascii "D&R E"<0> ROMBASE:000BDE6F aTPED: .ascii "TPED "<0> ROMBASE:000BDE75 .ascii " ."<0> ROMBASE:000BDE7B aCOPYR: .ascii "COPYR"<0> ROMBASE:000BDE81 aIGHT: .ascii "IGHT "<0> ROMBASE:000BDE87 aSEGA: .ascii "SEGA "<0> ROMBASE:000BDE8D aENTER: .ascii "ENTER"<0> ROMBASE:000BDE93 aPRISE: .ascii "PRISE"<0> ROMBASE:000BDE99 aSLIM: .ascii "S LIM"<0> ROMBASE:000BDE9F aITED: .ascii "ITED "<0> ROMBASE:000BDEA5 a1995: .ascii "1995 "<0> ROMBASE:000BDEAB .ascii " "<0> ROMBASE:000BDEB1 a1127: .ascii "1127 "<0> ROMBASE:000BDEB7 .ascii " "<0> ROMBASE:000BDEBD aAMHA: .ascii "AM HA"<0> ROMBASE:000BDEC3 aRDWAR: .ascii "RDWAR"<0> ROMBASE:000BDEC9 aERD: .ascii "E R&D"<0> ROMBASE:000BDECF aDEPT: .ascii " DEPT"<0> ROMBASE:000BDED5 .ascii ". " COPYRIGHT SEGA ENTERPRISE LIMITED 19951127 AM HARDWARE R&D DEPT.
^ I checked the video. It doesn't show any of the characters I named running toward the opponent, nor any polygonal demonstrations of them running. You lied to me!
Unfortunate I wasted your time, but you could find a copy of the game now you know how to play! This is the hacking forum, not a help thread. You also did not tell me what you would do with the information. The video, however, shows you a Sky Eye that we do not have access to. Debug mode only allows for single-frame observation. As of yet, the camera cannot be locked to another object or coordinate yet. Requesting such information now would be like requesting the models a decade ago, the information does not exist nor am I interested in capturing it for you. I will tell you that if you use the debug mode and set the stage to the dummy stage while in wireframe mode you will be able to see the polygons fully.
I found the the address that controls that. If you just scan in Cheat Engine for a decrease when frozen, and an increase when playing, you should be able to find it, and set it as the same value as it was when the game wasn't frozen. I also do have the animation address too, but sadly my cheat table doesn't work with others, only me.
Hah, of course someone beat me to it. I was doing a disassembly VF2, which Fighting Vipers and of course Sonic FIghters is based on, and came across the debug myself. It's activated quite easily: set bit 2 of the dword value at 0x508000. This works in all three games I mentioned. I'm actually in the middle of doing a writeup on the menu as it appears in all three games. https://twitter.com/suddendesu/status/1068296744570507264 Edit: As I explained in that twitter thread, my goal isn't to belittle anyone's work. I'm just amused (and slightly jealous!) that people beat me to finding it first. Edit again: it's the *third bit*, which is bit 2. Zero based index and all that. I'm sure I'd get called out on that eventually.
As I said before: At least now I have with 100% certainty that we are now going to be setting the flag correctly. I want to write a new method to activate and deactivate debug based on this new information. I guess a script will follow shortly. I just checked all the old, archive.org CulT threads too and can't believe you never posted in any of them Ryoga. It all seems so obvious now, but I was way too late to publish any of it.
The easiest way I found to toggle debug mode with this new information is as follows: Code (Text): function Frame() local debugAdd = RAMBASE+0x8000 local gameDebug = I960_ReadDWord(debugAdd) local q_button = Input_IsKeyPressed(0x10) if q_button == 1 then I960_WriteDWord(debugAdd,XOR(gameDebug,0x24)) end end This "Frame" function can be used in StF, Virtua Fighter 2, and Fighting Vipers in ElSemi's emulator. Be sure to save each script as the "rom.lua" ex "sfight.lua", or maybe you can put it in "common.lua" if you want, I'm not entirely sure. Have fun! EDIT: To explain it's use, as it has changed slightly since the last release, the 'Q' key is now the debug toggle. The reason I have assigned this toggle to a key instead of adding it as a cheat menu option is that there is an issue with how the emulator handles cheat toggling through the menu. Half the time, the first toggle will not work, and you need to have multiple cheats in order for other cheats to work. They also do not update dynamically, so if you exit the debug menu in-game, the emulator will not be able to tell the difference and can not dynamically change the toggle from 'On" to 'Off'.
Coming back to this thread with a new objective: Disassembly While we have debug and values we can now look at, this should apply to the code within the game as well. Hopefully enough to reverse engineer a bit of it, for say, the models? The first step is to identify large chunks of code with already labeled code from Sonic Gems Collection. A lot of codes for commands and hopefully object data still exist in Sonic Gems Collection in their raw labeled formats, but that code needs to be identified within the binary dumps of the arcade roms to help indicate what routines relate to commands and what routines relate to model objects. This is the awful sudocode I have written of the ".CMP" structure of the files: Code (Text): struct cpk { @0x00: 16 bytes header data as follows: "CRICMP..2.10...." @0x10 : 4 byte code 32 [20000000] @0x14: 4 Byte value of decompressed file size in hex in reverse order. @0x18: 4 byte code 32 [20000000] @0x1C:4 byte code 0 [00000000] @0x20 4 byte code 16 [10000000] @0x24: 4 bytes unknown data @0x28++: Compressed Data }
Replying to this thread to give a general bump and update about the disassembly: It may not be impossible to disassemble (IDA Pro and labeling), however, reassembling with an assembler and linker may prove impossible. The tools used to make i960 binaries, things such as gnu960 and CTOOLS, are long since wiped from the internet. A college has some source code of CTOOLS 5.0 available on their site as part of a "Nectar" project, but it's hard to tell whether or not this code could be taken, modified, and rebuild a disassembly of Sonic the Fighters to be bootable by an emulator or an actual Model2b board itself. The disassembly process can be accelerated by all the documentation that debug mode now gives us, EG change a value, search for that value in a memory editor and so-on and so-forth until a memory pointer is identified, which can be used to label significant parts of the programming within the game. However, it's hard to tell what the payoff of doing this would be. Better understanding the engine has always been something I wanted, but with such old tech, it can't be easily reproduced in other languages, even if I fully understood what the engine fully does. tl;dr: I'm wondering if it's all worth it to document all this. I've been an army of one for this game for a long time, with people contributing in and out sometimes such as providing the x360 files and Steve's finding of the odd debug pointer, but I'm unsure if I should continue research, as I really haven't accomplished much in terms of what would be useful for anyone to attempt to hack the game. The goals I once had are no longer clear, so it's hard to say wether or not I should continue. EDIT: It looks like people have discovered that the StF rips that did exist were riddled with errors and modifications, and I'd very much like to make proper model conversions, but I have zero motivation to do so.
I have made a stunning realization today.... I always wondered about these Flickys... I didn't really understand why they were in the game's data... until I saw this... AM1 game Bloxeed.