Jolmberg / fn22snesticle

A script to extract SNESticle from Fight Night Round 2
MIT License
59 stars 1 forks source link

Reinsertion into source #3

Open chmcarro opened 2 years ago

chmcarro commented 2 years ago

Given today's published news regarding 2-player support in Super Punch-Out, would it be possible to have your multi-player support additions to be reinserted into the source ROM?

Jolmberg commented 2 years ago

You mean patching the Fight Night ISO to allow two controllers in Super Punch-Out? Technically, yes, it would be pretty simple, and it could be distributed in the form of an ips patch or similar, but what's the benefit? You can already use fn22snesticle to play Super Punch-Out with two controllers, and without having to load up Fight Night first.

chmcarro commented 2 years ago

Yes! Exactly! Thank you for your reply. As for the question around the benefit, I will refer to your FAQ:

Why would I use this when Snes9x is already ported to the Gamecube?

What a silly question. This is SNESticle!

But really, there is no practical benefit other than to showcase the new 2-player discovery in Super Punch-Out on a released platform.

Jolmberg commented 2 years ago

I still don't get it. It's SNESticle either way. Why would you want it on a 1.5 GB ISO where you have to wade through the Fight Night menus rather than a 5 MB ISO which boots directly into Super Punch-Out?

chmcarro commented 2 years ago

I agree its more practical to run the emulator as you have already provided directly from Swiss. This request as more of a feature enhancement and correction to Fight Night Round 2. The purpose would be to showcase the new 2-player discovery in Super Punch-Out, accessed in a way that has been made commercially available.

Jolmberg commented 2 years ago

Ok, I see, and while I do appreciate efforts to bugfix and improve old games, I guess I just don't care enough in this instance. I've never played a Fight Night game in my life and I would much rather just have SNESticle. But feel free to take a stab at it. Like I said, it should not be difficult. The controller patches are in the p_main dictionary. The target offset might be different on a real Fight Night ISO, though. And the patch will remap the buttons unless you also apply the patches for literal button mapping (located further down in the script).

chmcarro commented 2 years ago

Thanks, again - and also thank you for your work on making SNESticle available on GameCube, and the excellent devlog you created for this.

I do have a fondness for Fight Night Round 2 and decided to take a stab at it this. My thought was to use your python script and only keep the p_main dictionary keys and values that would be necessary for additional controller inputs and the literal joypad mappings. I could then take the created SNESticle ISO and use Dolphin to extract the main.dol as a replacement for Fight Night's main.dol.

With this approach, Fight Night was able to load Super Punch-Out, but no joypad input worked for Player 1 other than 'z' which exited SNESticle. I suspect I may have a misunderstanding on some of the dictionary keys or I removed some necessary binary data. I tried again by only adding player 2 instead of 4 players, but had the same results. I have attached the python script changes I used.

fn22snesticle.py --p1 literal --p2 literal Fight Night Round 2.iso superpunchout.iso

If this approach might be feasible, do you think you could point me to an appropriate modification of p_main or any other suggestions that might point me in the right direction?

fn22snesticle-p_main_changes.zip

Jolmberg commented 2 years ago

That sounds like a reasonable approach! I think one problem you are having is that you have deleted the NOPs at the end of p_main. While the comment says "for good measure" they are actually important (sorry!) as they are overwriting original Fight Night code that could otherwise interfere with the patch. And likewise, if you want to remove controllers three and four (which could make sense, some games will actually fail to run if they are connected) you need to replace those instructions with NOPs rather than delete them (or you could jump to a known good location).

chmcarro commented 2 years ago

Adding the NOPs at the end worked!!! Thank you! I was able to get 2-player Super Punch-Out to work in Fight Night in Dolphin...

fn22snesticle.py --p1 literal --p2 literal --p3 off --p4 off Fight Night Round 2.iso superpunchout.iso

However, 'Z' is not quitting SNESticle.

Can you think of any NOP I would need to add/remove from the dictionary to add the 'z' as quit option back in? Is there any button mapping option that retains the original double mapping of 'y' as both 'y' and 'select'?

p_main = {0xdee44: [0x39200000], # li r9, 0 0x28b560: [0x60000000, # Placeholder for exit check 0x54093C2E, # rlwinm r9, r0, 7, 16, 23 0x50094CAC, # rlwimi 9, 0, 9, 18, 22 0x5009452A, # rlwimi 9, 0, 8, 20, 21 0x500904E6, # rlwimi 9, 0, 0, 19, 19 0x5009fEB6, # rlwimi 9, 0, 31, 26, 27 0x50092C62, # rlwimi 9, 0, 5, 17, 17 0x5009EE30, # rlwimi 9, 0, 29, 24, 24 0x5009DE72, # rlwimi 9, 0, 27, 25, 25

                 0x5529801E,   # rlwinm r9, r9, 16, 0, 15 ; Shift up
                 0x80030094,   # lwz r0, 0x94(r3) ; Load P2

                 0x50093C2E,   # Same as above except rlwimi
                 0x50094CAC,
                 0x5009452A,
                 0x500904E6,
                 0x5009fEB6,
                 0x50092C62,
                 0x5009EE30,
                 0x5009DE72,

                 0x91210008,   # stw r9, 8(r1) ; Store P1, P2
                 0x80030120,   # lwz r0, 0x120(r3) ; Load P3

                 0x54093C2E,
                 0x50094CAC,
                 0x5009452A,
                 0x500904E6,
                 0x5009fEB6,
                 0x50092C62,
                 0x5009EE30,
                 0x5009DE72,

                 0x5529801E,   # rlwinm r9, r9, 16, 0, 15 ; Shift up
                 0x800301ac,   # lwz r0, 0x1ac(r3) ; Load P4

                 0x50093C2E,
                 0x50094CAC,
                 0x5009452A,
                 0x500904E6,
                 0x5009fEB6,
                 0x50092C62,
                 0x5009EE30,
                 0x5009DE72,

                 0x9121000C,   # stw r9, 12(r1) ; Store P3, P4
                 0x60000000,   # Some nops for good measure
                 0x60000000,
                 0x60000000,
                 0x60000000,
                 0x60000000,
                 0x60000000,
                 0x60000000]}
Jolmberg commented 2 years ago

Cool! The exit check should be easy to add, just replace the placeholder NOP at the top with 0x701f1000 (from the p_multirom patch dictionary). To get Y to double as Select again you'll need to add an rlwimi instruction. Gamecube Y is 0x800 and SNES Select is 0x2000 so you want to shift it left twice and then bring in only bit 13 which when counting in the opposite direction in a 32 bit word becomes 18 (uh, I think), so rlwimi r9, r0, 2, 18, 18 probably, which is opcode 0x500914A4 (I may have messed this up completely though, let me know how it goes). You can insert it right after the first seven rlwimis (just before the "Shift up" comment. And if you want it for player 2 just insert it again before the "Store P1, P2" comment. Don't forget to remove a NOP at the end any time you add an instruction. The list length needs to stay the same.

Jolmberg commented 2 years ago

Oh, and you only need the entry with key 0x28b560 from p_main. The li r9, 0 patch is only needed when you are bypassing Fight Night. In fact it could mess things up for you now.

chmcarro commented 2 years ago

Thanks again for your help, especially since you said this was out of scope.

I made your suggestions: replaced the placeholder NOP at the top with 0x701f1000, added the rlwimi r9, r0, 2, 18, 18 opcode 0x500914a4 before the "Shift up" and again for player 2 before the "Store P1, P2" comment, removed 2 NOP values at the end of the dictionary, and removed the li r9, 0 0xdee44 key.

I observed odd button press behavior in Super Punch-Out so I replaced the embedded SNES ROM for Super Punch-Out with a controller test ROM. Pressing 'start' acts as 'Z' and exits back to Fight Night. Pressing 'y' activates 3 buttons at once - 'y', 'x', and 'select'. All other buttons are mapped appropriately.

Is this a miscalculation for the rlwimi or do I need to modify the p_literal dictionaries since I am setting the mapping as literal?

`p_main = {0x28b560: [0x701f1000, # Placeholder for exit check 0x54093C2E, # rlwinm r9, r0, 7, 16, 23 0x50094CAC, # rlwimi 9, 0, 9, 18, 22 0x5009452A, # rlwimi 9, 0, 8, 20, 21 0x500904E6, # rlwimi 9, 0, 0, 19, 19 0x5009fEB6, # rlwimi 9, 0, 31, 26, 27 0x50092C62, # rlwimi 9, 0, 5, 17, 17 0x5009EE30, # rlwimi 9, 0, 29, 24, 24 0x5009DE72, # rlwimi 9, 0, 27, 25, 25 0x500914A4, #custom rlwimi r9, r0, 2, 18, 18 for y as select 0x5529801E, # rlwinm r9, r9, 16, 0, 15 ; Shift up 0x80030094, # lwz r0, 0x94(r3) ; Load P2

                 0x50093C2E,   # Same as above except rlwimi
                 0x50094CAC,
                 0x5009452A,
                 0x500904E6,
                 0x5009fEB6,
                 0x50092C62,
                 0x5009EE30,
                 0x5009DE72,
                 0x500914A4,   #custom rlwimi r9, r0, 2, 18, 18 for y as select
                 0x91210008,   # stw r9, 8(r1) ; Store P1, P2
                 0x80030120,   # lwz r0, 0x120(r3) ; Load P3

                 0x54093C2E,
                 0x50094CAC,
                 0x5009452A,
                 0x500904E6,
                 0x5009fEB6,
                 0x50092C62,
                 0x5009EE30,
                 0x5009DE72,

                 0x5529801E,   # rlwinm r9, r9, 16, 0, 15 ; Shift up
                 0x800301ac,   # lwz r0, 0x1ac(r3) ; Load P4

                 0x50093C2E,
                 0x50094CAC,
                 0x5009452A,
                 0x500904E6,
                 0x5009fEB6,
                 0x50092C62,
                 0x5009EE30,
                 0x5009DE72,

                 0x9121000C,   # stw r9, 12(r1) ; Store P3, P4
                 0x60000000,   # Some nops for good measure
                 0x60000000,
                 0x60000000,
                 0x60000000,
                 0x60000000]}`
Jolmberg commented 2 years ago

Sorry, I missed some details. I use Start to exit SNESticle in the ROM menu. To get Z instead you want 0x701f0010 (Z has bitmask 0x10) at the top. Then, since you have inserted instructions, the offsets in the pliteral* dictionaries need to be adjusted:

p_literal_2 = {0x28b590: [0x50094CAC] + literal}
p_literal_3 = {0x28b5bc: [0x54094CAC] + literal}
p_literal_4 = {0x28b5e4: [0x50094CAC] + literal}

And same thing with the poff* dictionaries:

p_off_3 = {0x28b5d8: [0x6129ffff]}
p_off_4 = {0x28b600: [0x6129ffff]}

I'm not sure this explains why Y acts as three different buttons, though. Perhaps it's a bug in my original patch. If the problem remains, would you mind running your test rom with my unmodified script to see if it has the same problem?

chmcarro commented 2 years ago

OK, I have a lot of info to try and explain, some you might find interesting and some may not be as relevant.

Your last comment worked as expected - Changing the placeholder bitmask as you provided did change the exit function from 'start' to 'z"

Also changing the offsets in pliteral* worked as expected. Now P1 and P2 have the original "y" button double mapping as "Y" and "select". The changes you recommended above were accurate for what was proposed.

However, this had an unintended consequence in Super Punch-Out. The newly discovered 2-player mode requires P2 to press Y+R while P1 press Start to enter the hidden player selection menu. But when 'y' is double mapped, this P2(Y+R) and P1(Start) combo does not work. The game does not recognize P2(Y+Select+R) and P1(Start) as a trigger for this hidden menu.

Therefore, I proceeded to modify your python script dictionary again with keeping P1 with double mapped Y as Y+Select and removing the P2 double mapping by removing the rlwinm inserted instruction before the Store P1, P2 commented line.

Then, since I removed an instruction, I added an additional NOP back to the end of p_main, and also needed to make offset accommodations to p_literal and p_off dictionaries. I think I comprehend how that is done (by subtracting 4 bits from the Hex keys on p_literal_3, p_literal_4, p_off_3, and p_off_4. If you want to check my revisions, its attached.

So with those change, we now have the ability to enter the hidden menu and use the P2 controls with the "literal" button mappings, which is how Fight Night Round 2 + Super Punch-Out was originally mapped.

With all that said... there is a bit of a twist to this tale... I'll close out this comment since its getting wordy and gather thoughts for a reply. fn22snesticle - p1 double mapped y, p2 y to y.zip

chmcarro commented 2 years ago

My goal when I raised this issue was to integrate the 2 player enhancements into Fight Night Round 2's implementation of Super Punch-Out!!. However, it seems there was a ROM hack applied to Super Punch-Out for the default controller scheme, which does not apply in the 2 player mode. I want to think about how to proceed with the controller scheme.

Jolmberg commented 2 years ago

Right, I remember noticing that. I just figured they had SRAM on the Fight Night disc, but you are right, the ROM itself has been modified. Looks like it's just two bytes that have been changed so it would be easy to undo, but the patched control scheme makes more sense for the GC controller... I see your predicament! Anyway, fiddling with the script yesterday I found two disastrous (but trivial) bugs in the menu system, so thanks for getting me to take another look at this stuff! :)