After a lot of work and very little sleep, the insertion of the new mugshots is 100% complete.
I managed to set both mugshots' animation and tile assembly data independently, so forget my last post: there's no restriction on how they're assembled. They're both working together exactly as they are.
Here's some general takeaways:Identifiers:
- There's 4 "half byte" IDs recognized by the game: 0 = Player, 1 = Alia, 2 = Enemy, 3 = Unused. Other values (4/5/6/7, 8/9/A/B, C/D/E/F) cycle back to 0/1/2/3 and can't be used as unique IDs.
- These IDs are linked to a byte in dialogues. This tells the game both which character is talking (which animation data to load) and the color used in the name of the person talking in the text box (Blue/Red/Yellow/Green).
- Interestingly, the 3/Unused value matches the text byte used for both the Hunter and Dr. Light (green names). This probably means they were meant to be implemented in a similar way I did, or maybe it's just a coincidence. Either way, this made my work a lot easier.
- IDs are used as RAM offsets to locate the right tileset/animation data in an index of more addresses. In the case of 0/Player and 2/Enemy, they're adjusted through a separate subroutine depending on character/armor in use and stage selected (and in the case of hidden stages, which enemy you're suposed to face). As for the 3/Unused, although they have unique slots assigned in this data address list, these addresses link to other mugshot's data (Commander Yammark's).File loading:
- Alia's mugshot and palette are loaded straight from the stage data and stay in VRAM and RAM (respectively) throughout gameplay
- Player's mugshot is likewise always loaded in VRAM and RAM respectively, but are loaded from their own files instead of stage data.
- Bosses mugshots and palettes are both loaded to RAM (during "Loading" screen), graphics are loaded from RAM to VRAM on the fly when needed.
- As there isn't enough room in VRAM to have an additional mugshot loaded all the time, I had to figure out how to use the same mechanism the Bosses mugshots have (have my new files always available on RAM, and loaded to VRAM only when needed). This means I can't have Dr. Light facing a Boss (as they'll use the same VRAM slot). Thankfully this never happens so I didn't worry about it.Animation/Tile assembly data:
- Tile assembly data (a single file for all mugshots) is located in all the stage's files, right next to Alia's mugshot and palette. Thanks to notes by DarkSamus933, I already had a pretty good grasp on how the games assembles tiles. I already used this information to edit the title screen's "PRESS START" text and reassembling the pause menus' text using the new font.
- Animation data (a single table for all mugshots) is located in the main executable file. This was the first time I worked on animation data, but fortunately it was fairly easy to figure out.
- Although easy to assemble, storing all this took an extra 2 KB that had to be inserted somewhere, and made accessible.Loading new files in the disc (and have them be accessible):
- Five new files needed to be added: two tilesets, two palettes, and one big fat assembly/animation data file containing data for both mugshots.
- Putting new files in the disc is easy, you just have to append them to the DAT file and list them in its header in the same way the others files are. The problem is accessing them ingame.
- The game generates a list of disc files' offsets/sizes on the fly during startup based on the header of the DAT file. However, the number of files it writes an entry for is hardcoded to the original number of files. It can be expanded, but then you'd have to deal with a lot of important data being shifted around.
- Instead of doing that, I generate offsets/sizes data for my new files whenever I update my .DAT (I wrote a script for that) and store them somewhere else in the game's data. This way, instead of having to deal with all the important stuff being done on initial startup, I simply made a modification to the subroutine reading files: "if trying to access a file with an index number bigger than the original number of files, look for them in my new table instead of the original one."
- These files are then loaded to RAM at the "Loading" screen at start of a stage (with a few checks and jumps to load either the Hunter or Dr. Light depending on the stage). The next problem was to find the right place in RAM to put them in. There's plenty of empty space in RAM at all times, but not always in the same place. Some of these places would get rewritten by other data in some stages, but not others. Figuring out a (big enough) place that's always available took some serious trial and error. At the end, the answer was pretty obvious: right after where the game loads the Boss mugshots. This is one place the game already know it has to keep safe and, fortunately, it leaves plenty of "safe" room after this one file. (There's a chance I'll run into some stage/situation where this address isn't usable and I'll need to think of a solution, but so far so good.)Loading the new data in-game:
- This is where I finally saw the light at the end of the tunnel; still lots of work to do, but within a relatively known territory: hijacking the mugshot loading code in various places to replace the addresses the game natively assigns to the 3/Unused ID.
- I made my own table of indexes at the start of my tileset/animation file, and made sure to have it work as similarly as possible to the native ones (which in turn, meant changing as little code as possible).
After all was done and working, you can bet there was lots of bugs to fix, stuff that broke for no apparent reason (until the reason became apparent). I wish it was as linear as I describe it. There was lots of back and forth.
Anyway, thanks everyone for your interest and following along the process, and specially thanks to DarkSamus93 for guiding me whenever I'm stuck, and Metalwario for providing art that's so good it made this work a top priority (this was very low on my wishlist of stuff before you showed up).
Although I'm proud, I'm so so glad it's over and I'm finally free to work on other stuff (man, has it been what, three weeks now?)
Here's my current v16 to-do list:
- Completing/polishing stuff I've already talked about (including inserting other mugshot's improvements).
- Inserting stage text (I've had the custom tools I need ready for some time, and most of the text set up for the process... I just got distracted doing more and more stuff.)
- Putting everything in the (new) Patcher tool.
That's it. Everything else I set out to do for this next release has been done. I don't think I'll work or even think of any other new idea until I'm done with this release.
March 26, 2019, 12:56:34 am - (Auto Merged - Double Posts are not allowed before 7 days.)
Well awesome, then I don't have to worry about the palette changes I made to the menus either, if/when that can happen later on. Gives me some motivation to work on that stuff again once I get some time.
While the conversion tool I'm using is not exactly 1:1 (colors tend to lose a bit of saturation), it's a good starting point. Easier to modify the few colors you're not happy with on top of it than having to change all colors manually.
I'm still pretty new to editing graphics for hacks and I still haven't figured out a straight-forward and reliable workflow to edit palettes manually... So until I get more experience, I'll settle with what I get with this conversion. Being able to convert "graphic.bmp + palette.act" directly into something the game can read is a huge timesaver.
I have a few questions:
1. Does Nightmare Zero have unique dialogue when you fight him as Zero or is it still the same as High Max's dialogue?
2. Were the few voice clips that were cut from the English version of the game have already been re-implemented?
March 26, 2019, 10:22:22 am - (Auto Merged - Double Posts are not allowed before 7 days.)
Can this tool be used with the PC version of the game?https://steamcommunity.com/app/743900/discussions/0/1746720717353940501/
I always hated the auto scroll phase in metal shark level. It kills the speedrun.
the ceiling in Metal Shark Player's level is a huge pain in the ass when going through the level several times to get all the loot, any way to make it stop after he's been beaten?
I'm not planning on doing either of those things, but there is one little improvement I'd like to try for that stage. Probably after the next release though.