News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: TMNT of Rage - The Final Shell Shock (A Streets of Rage 2 Hacking Progress Blog)  (Read 17179 times)

kmilloz

  • Newbie
  • *
  • Posts: 2
    • View Profile
Hey, kmilloz.  Dha Lau Hoo actually already created that tutorial, which you'll find here.  That's how I was able to get my turtle portraits into the game.

You might find one or two of these useful, too, though:
1) sor2palette.bin
2) sor2portraits.bin
3) sor2tilespritemap.bin

These are .bin files I created while working through the tutorial, but it's been a good year or so since I've done anything with them, so use at your own risk.



-----Epilogue – After the Release-----
A Brief History Lesson…


Romhacking has been a fun process.  With each iteration I’ve developed, I’ve realized that there’s a few more things I can likely figure out and do.  And so, just like my NBA Jam TE series, one TMNT mod became another, and another, and another, each one improving more over the last, till I finally made it through The Final Shell Shock.

Hopefully, you’ve some of these mods enjoyable too.  In the meantime, let’s get back to a little unfinished business…



Adding an Intro Screen

I’m not the biggest fan of intro screens added to romhacks.  Unless they blend with the original spirit and style of the game, my thoughts are to leave them out.  I tried to keep that in mind when creating my NBA Jam TE mods by incorporating logos and fonts that clearly synched up with the game.  With TMNT Final, given I was looking for the arcade Ninja Turtles feel, I couldn’t help but slip in an old-school “Winners Don’t Do Drugs!” logo.



Other than TLP not being terribly friendly with the colors (TileMolester was again worse!), the screen itself was fairly easy to drop in using AddIntroGen.  But… buyer beware… this utility is a general Genesis / Mega Drive tool not optimized for any specific game.  In using it, I found myself with two problems.

Of lesser concern, the intro only added code that exited the intro screen when pressing Start.  My preference was that it should also simply fade out to the next screen after a certain period of time, much like the SNES tutorials allow for that system.  A minor inconvenience, which I actually solved via writing some ASM (which ultimately conflicted; we’ll get to that in a bit).

Of much greater concern, something in the AddIntroGen code that the utility added reset the difficulty, lives, and stage select to values of 1 upon exiting to attract mode.  At the same time, it cleared all the values in RAM that created the high score table.  While none of that is detrimental to gameplay (settings can be changed in options), it doesn’t exactly make the game look polished at issuance.

My goal was to fix both issues.  Starting with trace logs to find where the Start button press occurred and next with research and chats on a Sega development Discord, I finally learned the value of ASM versus hex and grabbed an assembler.   I also learned a bit about the DBF function and how much time it could potentially save writing that versus commands to push 60+ bytes of data into RAM one byte at a time via the same MOVE command over and over again.  The end result was a fix to the high score table plus the default lives and difficulty values… but when incorporating those fixes with my additional code to move from the intro screen after a delay, those value were again lost in RAM.

(Oddly enough, the DBF function worked in one emulator and not another, so I ended up going the byte-by-byte route…)

I never did revise the Start button bit, as the integrity of the high score table was the more mission critical item.  For those who are curious, here is my code and some of the trace log (I ended up going with my option 3 to favor fixing the high score table over adding the intro screen delay):

Code: [Select]
;BTST is the Start button.
;BNE causes the jump to $000208, the initialization.
32:F8CC  08 00  BTST    #7,D0                   
32:F8D0  66 0C  BNE     #$0C [32:F8DE]           
;…
;Initialize the game
00:0208  4A B9  TST.L   ($00A10008)             
00:020E  66 06  BNE     #$06 [00:0216]           
00:0216  66 7C  BNE     #$7C [00:0294]           
00:0294  60 6C  BRA     #$6C [00:0302]           
00:0302  4A 79  TST.W   ($00C00004)             
00:0308  30 39  MOVE.W  ($00C00004),D0           
00:030E  08 00  BTST    #1,D0                   
00:0312  66 F4  BNE     #$F4 [00:0308]           
00:0314  4E B9  JSR     ($000015F4)             

;HIJACKS TO ADD--
;OPTION 1 - hijack start button press and add delay (does not recover hi score table)
org $32F8CC
4E F9 00 33 87 80 JMP ($00338780) - putting this at end of rom will cause the hi score table to revert to broken
org $338780
0C 42 00 60 CMPI.W #$0060,D2
66 06 BNE #$06
4E F9 00 00 02 08 JMP ($00000208)
52 42 ADDQ.W #1,D2
08 00 00 07 BTST #7,D0
67 06 BEQ #$06
4E F9 00 00 02 08 JMP ($00000208)
4E F9 00 32 F8 D2 JMP ($0032F8D2)

;OPTION 2 - remove start button press and go with delay only (does not recover hi score table)
org $32F8CC
4E F9 00 33 87 80 JMP ($00338780)
0C 42 00 60 CMPI.W #$0060,D2
66 06 BNE #$06
4E F9 00 00 02 08 JMP ($00000208)
52 42 ADDQ.W #1,D2
4E F9 00 32 F8 D2 JMP ($0032F8D2)

;DELAY ADD AT END OF INTRO SCREEN / BEFORE SEGA SCREEN
;RIGHT BEFORE SEGA LOGO
org $005924
4E F9 00 33 87 A0 JMP ($003387A0)
4E 71
;39 79 00 03 A4 A8 FF FC 39 79  MOVE.W  ($0003A4A8),$FFFC(A4)

org $3387A0
0C 42 7F FF CMPI.W #$7FFF,D2
66 0E BNE #$0E
39 79 00 03 A4 A8 FF FC 39 79  MOVE.W  ($0003A4A8),$FFFC(A4)  ; the hijacked code
4E F9 00 00 59 2C JMP ($0000592C)
52 42 ADDQ.W #1,D2
4E F9 00 33 87 A0 JMP ($003387A0); JMP to start of this code to loop

;OPTION 3 - USED
;RECOVER THE OVERWRITTEN RAM FROM THE INTRO SCREEN INSERT
org $32F8DE
4E F9 00 33 87 80 JMP ($00338780)

org $338780
31 FC 00 08 FD 06 MOVE.W #$0008,$FD06 ;lives
31 FC 00 06 FD 04 MOVE.W #$0006,$FD04 ;difficulty
20 7C 00 00 03 60 MOVE.L #$00000360,A0 ;the top high score table in rom
22 7C FF FF FD 30 MOVE.L #$FFFFFD30,A1 ; where the table is supposed to go in ram
20 3C 00 00 00 9F MOVE.L #$A0-1,D0 ;the decrement for the loop
E4 48 LSR.W #2,D0 ;a division by 4 to account for the long address
@RECOVERTABLE:
22 D8 MOVE.L (A0)+,(A1)+ ;160 bytes from $360 to $3FF need to go to $FFFFFD30 to $FFFFFDCF
51 C8 FF FC DBF D0, @RECOVERTABLE ;loop back to the label
4E F9 00 00 02 28 JMP ($00000208) ;the jump to the sega screen

;DELAY ADD AT END OF INTRO SCREEN / BEFORE SEGA SCREEN
;RIGHT BEFORE SEGA LOGO
org $005924
4E F9 00 33 87 AC JMP ($003387C0)
4E 71
;39 79 00 03 A4 A8 FF FC MOVE.W  ($0003A4A8),$FFFC(A4)

org $3387AC
0C 42 7F FF CMPI.W #$7FFF,D2
66 0E BNE #$0E
39 79 00 03 A4 A8 FF FC  MOVE.W  ($0003A4A8),$FFFC(A4)  ; the hijacked code
4E F9 00 00 59 2C JMP ($0000592C)
52 42 ADDQ.W #1,D2
4E F9 00 33 87 AC JMP ($003387AC); JMP to start of this code to loop



Thanks for reading this blog!  I may have other things I’ve learned while making these hacks and may look to slip them in from time to time as I recall them.  Otherwise, please feel free as well to keep the conversations going on this thread!  And… please be sure to try out my TMNT Final hack and give it a review!

thanks I'll try

eskayelle

  • Full Member
  • ***
  • Posts: 183
  • NBA Jam 2KTE / TMNT of Rage / Pong de las TMNT Dev
    • View Profile
Clarification
Quote
NOTE: The .zip file for this hack contains two .ips files: the  Final Shell Shock patch being playable on all hardware and in all emulators, with the Re-Shelled add-on allowing players a better sound experience when using the Terraonion MegaSD cartridge. Be sure to first patch a copy of your SoR2 rom with the Final Shell Shock patch to begin your TMNT experience.

I've gotten a few messages or seen a few notes this past couple weeks about some folks not being able to hear music when playing the game.  Let's fix that...

Are you playing the game in a Windows or Android-based emulator, including a Raspberry Pi?  If yes, do not apply the Re-Shelled patch.  Only apply the Final Shell Shock patch.

Are you playing the game using Terraonion's MegaSD cartridge?  The Re-Shelled patch is designed to allow you to hook the music tracks to new music, which you have to download and put on the same memory card that holds the .md Re-Shelled ROM.

First, apply the Final Shell Shock patch to a clean SoR2 ROM.  Then, apply the Re-Shelled patch to the same ROM.

You also need a .cue sheet and new music.  Download the .zip file with the music from MEGA.  Use this link: https://mega.nz/#!nB0z0SRC!2dJ9bYE3fo58F4ZkptIPSsOp_5tF2f0i9pXemTw4vqc

For more instructions on how to get MD+ functionality on your MegaSD cartridge, please visit the Terraonion website or Zeldix.

MD+ functionality does not work on another current emulator in the wild... yet.  In the meantime, please be sure to try out that solo Final Shell Shock patch!


Shameless Plugs
Not sure you want to try out the game?  Why not take a look at a few gameplay videos?

https://www.youtube.com/watch?v=YXavDYoYGQ8

https://www.youtube.com/watch?v=cIj0wLJWlhM

This dude had some fun with the music... perhaps they made their own .cue sheet for the MegaSD?
https://www.youtube.com/watch?v=m0jxhNBrVTg

Looks like there might be a live stream of gameplay June 18th?
https://www.youtube.com/watch?v=YN9yc8NbAfg


Love them turtles and think the two worlds mesh together pretty well?  Hate the game with a passion and think I ruined your childhood?  Why not put up a review on RHDN?

Thanks again for reading... and playing!
I once wrote a blog.  Maybe you'll find something in it useful?  https://www.romhacking.net/forum/index.php?topic=30593.0

kaine23

  • Jr. Member
  • **
  • Posts: 31
    • View Profile
I love this! Recently finished doing runs with all 4 turtles on streams. i wrote a review of this hack here:
https://kainetertainment.home.blog/2020/06/01/tmnt-of-rage-the-final-shell-shock-streets-of-rage-2-hack/

eskayelle

  • Full Member
  • ***
  • Posts: 183
  • NBA Jam 2KTE / TMNT of Rage / Pong de las TMNT Dev
    • View Profile
Aftermath
Having finalized and issued my NBA Jam 2K21 TE hack, I decided to take one more look at my TMNT Final mod, since it had been a while since I'd done a playthrough.  To be honest, I didn't think the reviews on the RHDN project page did the game as much justice to all the improvements as I'd hoped, as some of the items were more reviewer preference versus consideration/contemplation of artistic choice, but I did want to have a go at rectifying a couple items that had bothered me since the release.

For starters, I re-did the Re-Shelled patch, such that you no longer need to apply it to the TMNT Final one.  Now it's much clearer as to the purpose of each patch: If you want to use MD+ functionality with the Terraonion MegaSD, use the Re-Shelled patch.  If you don't have a MegaSD, go with TMNT Final.  One SoR2 rom, one patch. 

My next nit was with those moves that just didn't work, particularly in Raph's move set.  (Man, being a Mike fan, I did not realize how many Raph fans are out there!!!)  There had been an issue with Pancake 2 that I just couldn't resolve, in major part because I didn't have enough experience with or understanding of resizing animations and the resizer template.

With some brute force trial and error, and some guidance from savok, I recreated a resizer template for Raph based on what was currently in Pancake 2, but the goal being to force the application to open up hit box selection for those moves where either a weapon was held or a charge was performed. 

Based on a couple hours of trial and error, I landed on this:

Code: [Select]
4 0
4 0
6 0
5 0
1 0
-5 0
1 0
-7 0
4 0
4 0
1 0
1 0
4 0
2 0
1 0
1 0
-16 0
1 0
5 0
5 0
4 0
3 0
2 0
-11 0
7 0 1
8 0 1
5 0 1
1 0 1
1 0 1
4 0 1
7 0 1
7 0 1
-32 0 1
1 0 1
2 0 1
9 0 1
11 0 1
10 0 1
4 0 1
-25 0 0
4 0 0
2 0 0
3 0 1
3 0 1
4 0 0
-44 0 1
-44 0 1
-44 0 0
-44 0 0
-32 0 1

The problem then became that the resizer crashed Pancake 2 v1.6 every time I tried to load it.  Thankfully, after pushing the resizer into a test rom several times using v1.5, I finally caught a break... and Raph could now use his charge moves, as well as attack after confiscating a weapon.

(Note: The weapon confiscation is an artistic choice.  Why do the TMNT need to use weapons when they have their own?  So instead, they clean up the streets of these weapons, sheathing them upon pickup, with the option to still throw them at enemies as well.)

The updated patches are currently in the submission queue, so please be sure to check the project page over the next number of days to pick up those updates.  Feel free to continue to provide your thoughts as well, and thanks to all of you who've read this, tried out the game, and otherwise showed some love by letting others know it's out there! :beer:
I once wrote a blog.  Maybe you'll find something in it useful?  https://www.romhacking.net/forum/index.php?topic=30593.0

M2_Game_Developer

  • Newbie
  • *
  • Posts: 2
    • View Profile
Hey, kmilloz.  Dha Lau Hoo actually already created that tutorial, which you'll find here.  That's how I was able to get my turtle portraits into the game.

You might find one or two of these useful, too, though:
1) sor2palette.bin
2) sor2portraits.bin
3) sor2tilespritemap.bin

These are .bin files I created while working through the tutorial, but it's been a good year or so since I've done anything with them, so use at your own risk.



-----Epilogue – After the Release-----
A Brief History Lesson…


Romhacking has been a fun process.  With each iteration I’ve developed, I’ve realized that there’s a few more things I can likely figure out and do.  And so, just like my NBA Jam TE series, one TMNT mod became another, and another, and another, each one improving more over the last, till I finally made it through The Final Shell Shock.

Hopefully, you’ve some of these mods enjoyable too.  In the meantime, let’s get back to a little unfinished business…



Adding an Intro Screen

I’m not the biggest fan of intro screens added to romhacks.  Unless they blend with the original spirit and style of the game, my thoughts are to leave them out.  I tried to keep that in mind when creating my NBA Jam TE mods by incorporating logos and fonts that clearly synched up with the game.  With TMNT Final, given I was looking for the arcade Ninja Turtles feel, I couldn’t help but slip in an old-school “Winners Don’t Do Drugs!” logo.



Other than TLP not being terribly friendly with the colors (TileMolester was again worse!), the screen itself was fairly easy to drop in using AddIntroGen.  But… buyer beware… this utility is a general Genesis / Mega Drive tool not optimized for any specific game.  In using it, I found myself with two problems.

Of lesser concern, the intro only added code that exited the intro screen when pressing Start.  My preference was that it should also simply fade out to the next screen after a certain period of time, much like the SNES tutorials allow for that system.  A minor inconvenience, which I actually solved via writing some ASM (which ultimately conflicted; we’ll get to that in a bit).

Of much greater concern, something in the AddIntroGen code that the utility added reset the difficulty, lives, and stage select to values of 1 upon exiting to attract mode.  At the same time, it cleared all the values in RAM that created the high score table.  While none of that is detrimental to gameplay (settings can be changed in options), it doesn’t exactly make the game look polished at issuance.

My goal was to fix both issues.  Starting with trace logs to find where the Start button press occurred and next with research and chats on a Sega development Discord, I finally learned the value of ASM versus hex and grabbed an assembler.   I also learned a bit about the DBF function and how much time it could potentially save writing that versus commands to push 60+ bytes of data into RAM one byte at a time via the same MOVE command over and over again.  The end result was a fix to the high score table plus the default lives and difficulty values… but when incorporating those fixes with my additional code to move from the intro screen after a delay, those value were again lost in RAM.

(Oddly enough, the DBF function worked in one emulator and not another, so I ended up going the byte-by-byte route…)

I never did revise the Start button bit, as the integrity of the high score table was the more mission critical item.  For those who are curious, here is my code and some of the trace log (I ended up going with my option 3 to favor fixing the high score table over adding the intro screen delay):

Code: [Select]
;BTST is the Start button.
;BNE causes the jump to $000208, the initialization.
32:F8CC  08 00  BTST    #7,D0                   
32:F8D0  66 0C  BNE     #$0C [32:F8DE]           
;…
;Initialize the game
00:0208  4A B9  TST.L   ($00A10008)             
00:020E  66 06  BNE     #$06 [00:0216]           
00:0216  66 7C  BNE     #$7C [00:0294]           
00:0294  60 6C  BRA     #$6C [00:0302]           
00:0302  4A 79  TST.W   ($00C00004)             
00:0308  30 39  MOVE.W  ($00C00004),D0           
00:030E  08 00  BTST    #1,D0                   
00:0312  66 F4  BNE     #$F4 [00:0308]           
00:0314  4E B9  JSR     ($000015F4)             

;HIJACKS TO ADD--
;OPTION 1 - hijack start button press and add delay (does not recover hi score table)
org $32F8CC
4E F9 00 33 87 80 JMP ($00338780) - putting this at end of rom will cause the hi score table to revert to broken
org $338780
0C 42 00 60 CMPI.W #$0060,D2
66 06 BNE #$06
4E F9 00 00 02 08 JMP ($00000208)
52 42 ADDQ.W #1,D2
08 00 00 07 BTST #7,D0
67 06 BEQ #$06
4E F9 00 00 02 08 JMP ($00000208)
4E F9 00 32 F8 D2 JMP ($0032F8D2)

;OPTION 2 - remove start button press and go with delay only (does not recover hi score table)
org $32F8CC
4E F9 00 33 87 80 JMP ($00338780)
0C 42 00 60 CMPI.W #$0060,D2
66 06 BNE #$06
4E F9 00 00 02 08 JMP ($00000208)
52 42 ADDQ.W #1,D2
4E F9 00 32 F8 D2 JMP ($0032F8D2)

;DELAY ADD AT END OF INTRO SCREEN / BEFORE SEGA SCREEN
;RIGHT BEFORE SEGA LOGO
org $005924
4E F9 00 33 87 A0 JMP ($003387A0)
4E 71
;39 79 00 03 A4 A8 FF FC 39 79  MOVE.W  ($0003A4A8),$FFFC(A4)

org $3387A0
0C 42 7F FF CMPI.W #$7FFF,D2
66 0E BNE #$0E
39 79 00 03 A4 A8 FF FC 39 79  MOVE.W  ($0003A4A8),$FFFC(A4)  ; the hijacked code
4E F9 00 00 59 2C JMP ($0000592C)
52 42 ADDQ.W #1,D2
4E F9 00 33 87 A0 JMP ($003387A0); JMP to start of this code to loop

;OPTION 3 - USED
;RECOVER THE OVERWRITTEN RAM FROM THE INTRO SCREEN INSERT
org $32F8DE
4E F9 00 33 87 80 JMP ($00338780)

org $338780
31 FC 00 08 FD 06 MOVE.W #$0008,$FD06 ;lives
31 FC 00 06 FD 04 MOVE.W #$0006,$FD04 ;difficulty
20 7C 00 00 03 60 MOVE.L #$00000360,A0 ;the top high score table in rom
22 7C FF FF FD 30 MOVE.L #$FFFFFD30,A1 ; where the table is supposed to go in ram
20 3C 00 00 00 9F MOVE.L #$A0-1,D0 ;the decrement for the loop
E4 48 LSR.W #2,D0 ;a division by 4 to account for the long address
@RECOVERTABLE:
22 D8 MOVE.L (A0)+,(A1)+ ;160 bytes from $360 to $3FF need to go to $FFFFFD30 to $FFFFFDCF
51 C8 FF FC DBF D0, @RECOVERTABLE ;loop back to the label
4E F9 00 00 02 28 JMP ($00000208) ;the jump to the sega screen

;DELAY ADD AT END OF INTRO SCREEN / BEFORE SEGA SCREEN
;RIGHT BEFORE SEGA LOGO
org $005924
4E F9 00 33 87 AC JMP ($003387C0)
4E 71
;39 79 00 03 A4 A8 FF FC MOVE.W  ($0003A4A8),$FFFC(A4)

org $3387AC
0C 42 7F FF CMPI.W #$7FFF,D2
66 0E BNE #$0E
39 79 00 03 A4 A8 FF FC  MOVE.W  ($0003A4A8),$FFFC(A4)  ; the hijacked code
4E F9 00 00 59 2C JMP ($0000592C)
52 42 ADDQ.W #1,D2
4E F9 00 33 87 AC JMP ($003387AC); JMP to start of this code to loop



Thanks for reading this blog!  I may have other things I’ve learned while making these hacks and may look to slip them in from time to time as I recall them.  Otherwise, please feel free as well to keep the conversations going on this thread!  And… please be sure to try out my TMNT Final hack and give it a review!

I'm friends with Ayano Koshiro, program lead of the original Streets of Rage 2, and we enjoy some of these hacks!

I was hoping to ask some questions and we play around with some creative romhacking of our own. Please let us know if you are interested in inquiries we have. Thank you!

eskayelle

  • Full Member
  • ***
  • Posts: 183
  • NBA Jam 2KTE / TMNT of Rage / Pong de las TMNT Dev
    • View Profile
Unfinished Business
Quote
Even though you put in a whole new title screen, 6 new ending images, pizza icon, Bebop and Rocksteady, the Shredder, new sounds... you don't have foot soldiers, and you refuse to do it... so no, I don't recommend your game.  It’s just a beta, nothing interesting...

OK, so that quote's a bit of an exaggeration for fun on my part, but c'mon... foot soldiers?  That makes or breaks the immersive feel of a game???


PROTIP: When reading reviews, always consider what you know about your reviewers based on their profiles.  Check your reviewers' contributions.  If they haven't evidenced they've done a reasonable amount of romhacking, and they're giving you negative reviews, assume they may not understand the level of effort necessary to turn a game into your vision and go back to enjoying making your visions come true... with thicker skin...


Putting that and the spam bots / fake accounts aside, I have seen the question about feasibility of foot soldiers come up every now and then, so let's dig into what it takes to change out enemies in Streets of Rage 2.

Why do romhackers tend not to do it?  My personal opinion?  Because it's a lot of work and not a lot of payoff.  You see, Pancake 2 generously allows modders to take the original rom and edit the four protagonists plus a handful of the bosses.  But… all other enemies are compressed within the rom, and Pancake 2 does not provide for the decompression, alteration, re-compression, and insertion of new enemy sprites.  It allows you to work with uncompressed sprites.  And that’s a lot to be permitted to do!

Meanwhile, your basic enemies (Galsia/Donovan, the Signals, etc.) are compressed.  You could get your hands on that awesome Syndicate Wars hack and use it with Pancake 2 to modify those enemies, but what if your vision isn't to have all enemies be playable, or you don't want to introduce some of the softlocking bugs that modified rom has?

That brings us back to the original rom and Pancake 2.  You could get your hands on the compression and decompression routines by debugging the game (one such sequence is at $30C0), but 1) that's a lot of work to put into generating a new basic enemy, and 2) not everyone knows how to read and reverse compression routines (nor might they be motivated to do so just for a foot solider).  I myself fall into the category of not having a clue.

This next part is all theory, so feel free to try it, add theory to this blog, show your progress, share your newfound knowledge, etc., but here's one process by which you can probably get foot soldiers or some other enemy type in the rom.

1) Obtain and decrypt the enemy sprite tiles.  If you know the location of those sprites, you can use Pancake 2 and decompress and output the sprite tiles to a .bin file.  You can very likely find the location of the enemy you want using that archived SOR Online site.

2) With Galsia, if you open the .bin Pancake 2 gave you in Tile Layer Pro, and if you use the typical player palette, you'll get something like this.



This is where I throw my hands up and say "pass".  No can do, buckaroo!  If you're a good pixel artist and good with puzzles or the tile arranger in Tile Layer Pro, your next step is to

3) Find or make some good foot soldier sprites that use similar positions and animations as Galsia, and paste 8x8 tiles of them in the proper spots over the Galsia tiles above.

Here's a possible setback... Galsia and Donovan share the same bottom halves of their bodies.  The minute you change one, you're changing both.  Maybe you go with Y. Signal instead?  Up to you, but Galsia requires the least amount of edits, as he has the least amount of sprites.

One more challenge.  What will you do about palettes?  They follow the same ones as your protagonists, so you may not be guaranteeing yourself a purple foot soldier.  You'll need to dig out the palettes and perhaps how the code switches them and determine what can be done there. 

4) Let's say you now have your .bin with all foot solider tiles.  Kudos to you!  Let's get it into the game!

...
...
...

How???

Recall that Pancake 2 does not allow you to re-insert this tile set.  You need another way.

Enter Sharpnull's compressor.


PROTIP: Always re-read blogs and forum posts that you find interesting.  You'll find some stuff in there, even if you're not working on that specific project... yet.


Remember in my previous posts that I needed a way to get my ending sequence images into TMNT Remix and TMNT Final?  I used that compressor, but for a different purpose than it was originally designed for, knowing that the compression routine for enemies, title screen, and ending images are the same.  That compressor's original purpose was to compress and re-insert enemies.  So go do that!

Quick caveat: Months ago, as a test, I took that Decompressed Galsia.bin above, and - as a proof in concept - used the compressor to insert those tiles back into the game.  The idea was to see that all the pixels landed in the same place, such that the compressor works.  And indeed... it does work.  (To prove it actually inserted the images, I put beards on all the Galsia faces to verify the file insertion.)  But... on at least one animation, part of Galsia's head (I think mostly the hair, maybe 3-4 vertically aligned pixels) end up 3-4 pixels to the left or right of where they're supposed to be.

What does this mean?  It means you'll be able to fit Galsia (or your foot soldier) back into the game, but you're going to need to edit at least one tile such that you only use transparent colors on part of the head, just so the pixels can't be seen as out of place.  You may have a lopsided lookin’ footsolider if you don’t then correct his head!

After all that… I think you’re done.  You now have a foot soldier in your game.

So… after reading all of the above, don't you want to go out there and make some new minions for your Streets of Rage 2 hacks???

[INSERT CRICKET SOUNDS]
I once wrote a blog.  Maybe you'll find something in it useful?  https://www.romhacking.net/forum/index.php?topic=30593.0

kaine23

  • Jr. Member
  • **
  • Posts: 31
    • View Profile
between this and tmnt sor project this is my fav of the 2. i would love to see some foot around if it was possible.

eskayelle

  • Full Member
  • ***
  • Posts: 183
  • NBA Jam 2KTE / TMNT of Rage / Pong de las TMNT Dev
    • View Profile
Definitely appreciate that!  I'm obviously partial to TMNT Final as well, given all the time I put in to get it to fruition, but savok did a helluva job on the TMNT Streets animations, and it was fun to lend a hand with the title screen, end credits, other programming bits, and working title.  I always enjoy a good collab!

I'd like to create a foot soldier enemy eventually, but you can see the hurdles we're all up against there.  There's such a thing as diminishing returns, and it's evident for this one.



More Unfinished Business
Remember that TMNT Kaizo custom code I was trying to develop to create an opening puzzle in the game?  Sometimes, you just need to get back to fundamentals, i.e., debugging and running breakpoints to give yourself a fresh look at what the code is actually doing versus what you expected it to do (thanks to Tony H. for providing that reminder over on the Help Wanted forum).

So... it turns out the increment that I created in the code tends to double, so my comparison value for player 2 was off by at least 50%.  The other tidbit I needed to rethink is that these increments to player 1 and 2 happen regardless of whether a 1-player or 2-player game is running.  By fixing the player 2 dilemma, and getting it to set itself to one health point only on the first life, I ended up breaking the player 1 code because it was trying to use increments not meant for it. 

I jumped into the disassembly to search for a RAM value that flagged when two players were present versus one.  While there's no flag that consistently does this, I was able to use the RAM offset $FFFC18 & 19, which denotes when a 2-player game is selected.  If a turtle jumps into a one-player game, that flag isn't set, but I was able to work around that just enough to have my original puzzle in place.

Grab the v1.666 Kaizo patch here.  In the meantime, here's the code:
Code: [Select]
;=========================================
;Streets of Rage 2
;Initial Health Code Modifications v9
;by eskayelle, 2/27/2021
;=========================================

;-----------------------------------------
;Purpose: Hijack the code before the 1st
;stage starts and send it to another area
;in ROM to add functionality to two more
;RAM bytes.
;-----------------------------------------
org $00005CBE ;offset to hijack
; lea ($00005D74),A6 ;4D F9 00 00 5D 74 ;original (hijacked) $5CBE code
jsr $00024E00 ;4E B9 00 02 4E 00 ;jump to new code location

;-----------------------------------------
;Purpose: Set two unused RAM bytes to zero
;before a game (stage 1) starts. 
;These bytes will be changed so the health
;value increases to 0x68 whenever a player
;dies, but the very first life should have
;a health value much less than the default
;0x68.
;-----------------------------------------
org $00024E00 ;offset to hijack
move.b #$00,$F0BE ;11 FC 00 00 F0 BE ;create a player 1 parameter (1 byte)
move.b #$00,$F0BF ;11 FC 00 00 F0 BF ;create a player 2 parameter (1 byte)
lea ($00005D74),A6 ;4D F9 00 00 5D 74 ;original (hijacked) $5CBE code
rts ;4E 75 ;return to hijacked location and continue code

;-----------------------------------------
;Purpose: The byte with the initial health
;value is at offset $7EC8.
;Need to modify this code to split the
;commands such that the initial value is
;reduced, but all lives after receive a
;larger health value (the old 0x68).
;-----------------------------------------
org $00007EC8 ;offset to hijack
; move.w #$0068,$0080(A2) ;35 7C 00 68 00 80 ;this is the original code at $7EC8
jsr $00024E50 ;4E B9 00 02 4E 50 ;jump to new code location

org $00024E50 ;new code to split out 0x68 health per player after death
addq.b,#1,$F0BE ;52 38 F0 BE ;increment new player 1 byte
cmpi.b,#$01,$FC18 ;0C 38 00 01 FC 19 ;$FFFC18 is the 2 player game flag
bne.s no2p ;66 04 ;if that flag is not set, ignore incrementing player 2 byte
addq.b,#1,$F0BF ;52 38 F0 BF ;increment new player 2 byte
no2p:
cmpi.b #$01,$F0BE ;0C 38 00 01 F0 BE ;P1 RAM byte should be #$01 the first stage, first life
beq.s splithealth ;67 18 ;if equals #$01, give #$01 in health; else, give health of #$68
;it'll always increment up, so you'd need more than 256 deaths to roll this

cmpi.b #$01,$FC18 ;0C 38 00 01 FC 19 ;$FFFC18 is the 2 player game flag
bne.s stillno2p ;66 08 ;if that flag is not set, ignore doing any comparison work

cmpi.b #$02,$F0BF ;0C 38 00 02 F0 BF ;P2 RAM byte should be #$02 the first stage, first life
beq.s splithealth ;67 08 ;if equals #$02, give #$01 in health; else, give health of #$68
;in a two player game, starting value will be #$02
;in a two player game, where player 2 joined into one one player game,
;starting value will be #$00, and it'll never increment;
;rather, both players will share $F0BE
;in a one player game, starting value will be #$00, and it'll never increment

stillno2p:
move.w #$0068,$0080(A2) ;35 7C 00 68 00 80 ;this is the original code at $7EC8
rts ;4E 75 ;looking to jump back to $7ECE -- clr.w $00A8(A2)

splithealth:
; move.b #$68,$EF81 ;11 FC 00 68 EF 81 ;$EF81 appears to be where the default health value comes from; but $F081 is for player 2
; move.w #$0068,$0080(A2) ;35 7C 00 68 00 80 ;this is the original code at $7EC8; seems to do almost the same thing my code above would have
move.w #$0001,$0080(A2) ;35 7C 00 01 00 80 ;change #$68 to a lower number, so when $F0BE or $F0BF = #$01, that player starts game with less life
rts ;4E 75 ;looking to jump back to $7ECE -- clr.w $00A8(A2)

;-----------------NOTES--------------------
;FFEFA9 and FFF0A9 are the life counters
;FFEF80 is the total health value (max).
;$7ECB is the offset for how high health can go.
;FFFC18 (a two-byte value, so really FFFC19) determines 1P game or 2P.
;But... that FFFC19 flag won't set if P2 joins in on a 1P game!
;
;Try FFFFF0BE and FFFFF0BF as unused RAM...
;
;...
;
;7EC8 move.w #$0068,$0080(A2) ;this is the original code for the default life points
;7ECE clr.w $00A8(A2) ;this is where I want the hijack to come back to
;7ED2 bra $00C6 [00:7F9A]
;
;...
;-------------------------------------------

« Last Edit: February 27, 2021, 04:42:42 pm by eskayelle »
I once wrote a blog.  Maybe you'll find something in it useful?  https://www.romhacking.net/forum/index.php?topic=30593.0