Language…
13 users online: Blizzard Buffalo, Daniel_mi_bb_fiu_fiu, Dark Prince, DashGamer, Garlude, Masso1996, mizounimax, MorrieTheMagpie,  Nanako, Oskise, RetroSamBam, Sokobansolver, thatwaterblockrk - Guests: 108 - Bots: 90
Users: 68,930 (2,354 active)
Latest user: Masso1996

Star Fox Disassembly Thread!

  • Pages:
  • 1
  • 2

I've been working on a Star Fox disassembly for the past while now, and I figured I'd share what I have, though it's not much right now.

GitHub link


PROGRESS (approximate):
Bank 00: 100%
Bank 01: 25% (most of the SuperFX code is here)
Bank 02: 25% (the beginning bits of code here get copied to WRAM)
Bank 03: 80%
Bank 04: 2%
Bank 05: 100%
Bank 06: 2% (the rest of the SuperFX code is at the end of this bank)
Bank 07: 2%
Bank 08: 2%
Bank 09: 2%
Bank 0A: 2%
Bank 0B: 2%
Bank 0C: 100%
Bank 0D: 100%
Bank 0E: 100%
Bank 0F: 100%
Bank 10: 25%
Bank 11: 2%
Bank 12: 100%
Bank 13: 100%
Bank 14: 50%
Bank 15: 100%
Bank 16: 100%
Bank 17: 100%
Bank 18: 75% (SPC700 code here, along with some samples)
Bank 19: 100%
Bank 1A: 100%
Bank 1B: 100%
Bank 1C: 100%
Bank 1D: 100%
Bank 1E: 100%
Bank 1F: 90% (A bunch of important object management code is here)
I have also been working on reading the StarFox ROM data for about a year now. I've extracted the models, the textures, the audio clips, the character portraits, and most of the level events. I ended up writing my own decompiler in order to step through and document a bunch of the code, so maybe I can help speed things up a bit. Most of the stuff I've found, I've documented over on datacrystal.romhacking.net.

Which tools are you using to compile/decompile the code, and have you started looking at the SPC or the SuperFX code, yet?

I tracked down one of the original guys that wrote a model viewer and documented the level data over 10 years ago. He is still active on Twitter. He just posted this video 2 months ago. https://twitter.com/vl_tone/status/1204599297020481539

My github has all of my projects, including the StarFox ROM Browser and SNES decompiler. https://github.com/SpyderTL

I'll go through my notes and send you a pull request if I find anything useful.

"Good Luck"

Originally posted by SpyderTL
I have also been working on reading the StarFox ROM data for about a year now. I've extracted the models, the textures, the audio clips, the character portraits, and most of the level events. I ended up writing my own decompiler in order to step through and document a bunch of the code, so maybe I can help speed things up a bit. Most of the stuff I've found, I've documented over on datacrystal.romhacking.net.

Which tools are you using to compile/decompile the code, and have you started looking at the SPC or the SuperFX code, yet?

I tracked down one of the original guys that wrote a model viewer and documented the level data over 10 years ago. He is still active on Twitter. He just posted this video 2 months ago. https://twitter.com/vl_tone/status/1204599297020481539

My github has all of my projects, including the StarFox ROM Browser and SNES decompiler. https://github.com/SpyderTL

I'll go through my notes and send you a pull request if I find anything useful.

"Good Luck"


That'd be super useful! The main hurdle I'm facing is just typing up a base disassembly (that is, no comments or function/variable names). I've tried a bunch of different methods, but none seems to work all that well. If you could help with that, that'd be awesome!

I've also gotten a good chunk of the SuperFX code disassembled, but I still need to add it to the repo. I made a quick tool to generate the code, but it doesn't create labels for branches or anything like that, so I have to insert those myself currently. It also doesn't handle the move/moves instruction combo (instead just outputing the with/from/to instructions that make it up).
It looks like you already have most of the disassembly written out with labels and function names. Can you be more specific?

Is there a particular bank or address that you would like me to focus on?

I'm trying out radare with Cutter, and it's not what I would call easy, but it may be sufficient for getting the output that we need.

Originally posted by SpyderTL
It looks like you already have most of the disassembly written out with labels and function names. Can you be more specific?

Is there a particular bank or address that you would like me to focus on?

I'm trying out radare with Cutter, and it's not what I would call easy, but it may be sufficient for getting the output that we need.


Well I mean, I am able to type some stuff out. I'm mainly using IDA to go through the code, and bsnes/emuhawk to analyze memory and breakpoints during gameplay.

Banks 00-0B (with the exception of bank 05) are the ones that contain code (though bank 01's code is all SuperFX, and bank 06 has SuperFX code starting at FB5D). Bank 1F also contains some code towards the end.

As for which ones I could use help on, I think I can handle banks 00-03 and bank 1F just fine (those seem to be the most important, and hold a lot of the core game engine code).

Bank 0B seems to be where the player control code is (among a bunch of other things). Really, most of the stuff in bank 04 and beyond is just behavior routines and related functions. It'd probably be best to wait until the other important banks I mentioned above are finished somewhat, before trying to disassemble these banks.
Alright, I forked the project on GitHub, and started filling in missing code in 1F. Once that is done, I'll start on 00 and just go from there.

Just let me know if there is anything specific you want me to focus on.

When I finish a bank, I'll send you a pull request. Or you can probably just merge the changes directly, if you don't want to wait.
First pull request created on GitHub. Let me know if this is what you are looking for, or if there are any issues or changes you'd like me to make.

Thanks.

Originally posted by SpyderTL
First pull request created on GitHub. Let me know if this is what you are looking for, or if there are any issues or changes you'd like me to make.

Thanks.

Thanks, I'll check it out!
I added some more code from bank 02 to the pull request. I actually thought that it would create a new pull request, but it just added the changes to the existing pull request. Let me know if you want me to create separate branches so that I can create separate pull requests, or if I should just keep adding changes to the same pull request.

Out of curiosity, do you happen to know how the compressed graphics, like the title screen images are stored and decompressed? I found the SuperFX code that is responsible for decompressing the data, but I'm not familiar enough with the SuperFX assembly to be able to follow the logic, yet.

If you understand this logic, can you add a wiki page to the GitHub project that explains how it works?

If not, I'll see if I can figure it out and document it myself.

Thanks.
Hey, this is actually very interesting and I hope to see the project eventually complete!

One thing I plan to do with this when it's finished is actually to raise the FPS cap from 20 to 30 and retime things so the speed is 1:1 with what it is when the game is running at its full 20FPS cap.

However, that may be a dilemma in of itself, as the game rarely ever runs at its 20FPS cap, or anything above 15FPS most of the time for that matter, and various ingame moments, namely cutscenes, is thus accordingly timed so that for example, the music in the intro has time to finish playing in its entirety.

Of course this kind of hack would probably only be playable at full speed in BSNES with the CPU and SuperFX overclocking turned up, but I also wouldn't know what to do with the game speed. Any ideas?

(This is all really just an idea for a hack I want to make when this is finished.)
That's similar to my plan. I've created a new rendering engine in C# and SharpDX, and I want to import the level events and models and play the original game in 4K @ 60 FPS (or 120+FPS), and eventually even in VR.

Actually, the only thing I'm really missing now is the object behavior code, and some of that has already been documented on the GitHub project, so it shouldn't be much longer now.
Originally posted by SpyderTL
That's similar to my plan. I've created a new rendering engine in C# and SharpDX, and I want to import the level events and models and play the original game in 4K @ 60 FPS (or 120+FPS), and eventually even in VR.

Actually, the only thing I'm really missing now is the object behavior code, and some of that has already been documented on the GitHub project, so it shouldn't be much longer now.

Oh, in this case I meant actually getting the original ROM running at a 30FPS cap... But then it came to my attention that the SNES is actually incapable of displaying the game at 30FPS, unfortunately.

So, I guess I have one question regarding your own plan then:
Will there be a 'game speed toggle' of any sort? One where the game's speed is the same as when the original game is running at 20FPS (Faster) and one where the game is slower like on real hardware?

I actually find Star Fox much more enjoyable to play with the faster game speed.
Tweaking or adjusting the game speed and the refresh rate is fairly simple, once everything is working properly. So, letting the user pick their own preferences shouldn't be a problem.

Personally, I've played most of the StarFox games, including StarLink on the Switch, and there is something about the original SNES SuperFX StarFox and it's "terrible" frame rate that somehow adds to the experience. I think it is the most fun out of all of the SF games, to be honest. The only one that I haven't ever played is the StarFox Zero for the WII U, so it's possible that I would prefer it to the original, but I've heard that the WII U controls in that game are pretty terrible.

In any case, if increasing the frame rate to 60+ FPS somehow "loses" the feel of the original game, then I will probably artificially limit it. But initially I'm going to shoot for the highest FPS and resolution that I can achieve. Given the simplicity of the models, I wouldn't be surprised if I can get 1000 FPS on a modern GPU with VSYNC disabled.

I've spent a little time tweaking the controls and Arwing flight mechanics in my engine side by side with the original game in an emulator trying to get it as close to the original "feel" as possible, but it will probably need some more work once I have the levels imported, and I can run an entire level side-by-side.

Sorry I haven't been active in this thread much, but I assure you that I've been busy working away at this.

Also @SpyderTL, I appreciate your help and work, but I think I can take it from here in terms of the disassembly.

I'll try to keep you updated as best I can, but progress has been a bit slow. I wanna be thorough, in terms of labeling and comments, and make sure I get it right.
No problem.. Just let me know if you need help with anything.

I'll keep an eye on this thread, and the github.

I have been working on rewriting my disassembler to speed things up a bit. But if you have the disassembly under control, then I can go back to working on my game engine.
Quick question.

I'm looking at the decompression algorithm in Bank 01 for the SuperFX chip, and maybe I'm crazy, but it looks like the data is being read backwards. The ROM data pointer is decremented instead of incremented.

Is it possible that the addresses used to point to the compressed data is actually the address of the last byte, and the actual data ends at that address, and is in reverse order?

Or am I missing something?

Also, the compression algorithm seems to be using bitwise compression, rather than byte patterns, similar to this type of algorithm. Does anyone know if this is what is being used?

https://en.wikipedia.org/wiki/Universal_code_(data_compression)

Thanks.

Originally posted by SpyderTL
Quick question.

I'm looking at the decompression algorithm in Bank 01 for the SuperFX chip, and maybe I'm crazy, but it looks like the data is being read backwards. The ROM data pointer is decremented instead of incremented.

Is it possible that the addresses used to point to the compressed data is actually the address of the last byte, and the actual data ends at that address, and is in reverse order?

Or am I missing something?

Also, the compression algorithm seems to be using bitwise compression, rather than byte patterns, similar to this type of algorithm. Does anyone know if this is what is being used?

https://en.wikipedia.org/wiki/Universal_code_(data_compression)

Thanks.

I do recall hearing that the decompression is backwards, yes. Not sure on the exact algorithm though.
So, if the addresses used by the code are actually the end address, or more specifically, the start of the next block of compressed data, then it’s likely that all of the bin files in the “compressed” folder are named incorrectly. We probably also need some labels in the bank files that can be used in the disassembly correctly.

Just wanted to mention it so I don’t forget about it.
I found some minor issues with the wiki pages in GitHub for the level format page, so I created an issue, since I can't those pages directly.

Just FYI.
Alright, I've decided to start a new project from scratch, as my existing project was using static models with custom code for the animations. The new project generates dynamic models every frame at run time, which is quite a bit slower, but I believe that is the only way to correctly render the animated models and textures.

In any case, I've got the level objects rendering in the correct sequence, but I wanted to see if anyone could help me figure out why some of the models are oriented toward the screen (+Z) and some models are oriented away from the screen (-Z).

For instance, on the first Corneria stage, the big blue archway is facing away from the camera, but the gray buildings on the side are facing toward the camera.

If I multiply the vertex data Z coordinates by -1, I can get the blue archway to face the camera, but the gray buildings will be facing away from the camera. (Both the gray buildings and the blue archway are hollow when viewed from the back.)

Since the actual game does not have this issue, I assume that either the archway or the buildings are placed in the level and then rotated by 180 degrees. However, I don't see any rotation information in either the model data or the level data. The only other option that I can think of is that the rotation is handled by the behavior code, but that seems unlikely.

Anyway, if anyone knows how objects are rotated in the level to face the camera, that would be helpful.

Thanks.

EDIT: I found one way that models are rotated. A few of the buildings in Corneria are immediately followed by a “set property” event that sets address 0x13 to 0x64. I added support for rotating models based on this value, and now almost all of the buildings exactly match the actual game on that level.

However, there are only a few buildings that use this approach, and the blue archway does not have any “set property” events attached to it, so there still has to be another mechanism for rotating these models, I think.

EDIT2: Well, I found the answer, and it's definitely the behavior code that is responsible for rotating the models. Even the static models that never move... Yeah. No wonder the game runs at 12 FPS. LOL :)
  • Pages:
  • 1
  • 2