[Release] Pokemon Pinball Ruby & Sapphire EZ Flash Omega DE Rumble Patch

djedditt

Member
Newcomer
Joined
Jan 15, 2021
Messages
22
Trophies
0
Age
34
XP
292
Country
Netherlands
This is great!!! Can you make one more improvement to it?

Can you fix the options menu in the hack to add a working 'off-on' option to make work correctly? Someone did that for the Mario & Luigi hack and it really makes things feel more 'complete'.
Yes. I played a few rounds just to make sure I'm not missing anything since I just got this cart. It's really strange. I've also test Drill Dozer, Mario & Luigi and Mario Advanced 4. Those are all working fine.

I'm the author of the Mario & Luigi and Super Mario Advance 4 rumble patches, and released my Pokémon Pinball: Ruby and Sapphire rumble patch yesterday. Maybe that one works for you? It has a functional rumble options menu, as well as more accurate rumble events. Let me know!

Thanks for making this! I've always wanted to try Pokemon Pinball R/S with rumble. I noticed some issues while playing and wanted to see if anyone can confirm them on their patched ROM.

1. There are minor graphical glitches on the bumpers when the ball makes contact and on the flippers in bonus games when hitting the ball.

2. In Kyogre's bonus game on the Sapphire table the ball does not interact with whirlpools. Instead of being trapped when entering a whirlpool the ball continues through it.

I just confirmed those bugs using Phrankles patch. If you don't want to wait for him to fix it, check out my patch above.
 
  • Like
Reactions: ThatBassoonist

djedditt

Member
Newcomer
Joined
Jan 15, 2021
Messages
22
Trophies
0
Age
34
XP
292
Country
Netherlands
Phrankles, in your other post you wrote;

[...] I now have a ROM that is working, however I had to replace some of the original assembly code in order to prevent an infinite loop within what I believe to be the rumble subroutine. I believe the code is related to rumble anyway so it probably doesn't matter, [...]

I checked and it does matter - it all comes down to your subroutine not being nested correctly and that messes up your link register, resulting in the infinite loop. The approach you took to circumvent that is not the right one, and essential instructions got lost. From there things cascade into the issues that ThatBassoonist reported.

If you want I can give you some pointers on how to fix it properly :)
 

ThatBassoonist

Member
Newcomer
Joined
Aug 5, 2021
Messages
6
Trophies
0
Age
33
XP
85
Country
United States
I'm the author of the Mario & Luigi and Super Mario Advance 4 rumble patches, and released my Pokémon Pinball: Ruby and Sapphire rumble patch yesterday. Maybe that one works for you? It has a functional rumble options menu, as well as more accurate rumble events. Let me know!



I just confirmed those bugs using Phrankles patch. If you don't want to wait for him to fix it, check out my patch above.
Just tested your patch and it seems to work great! I did run into a game freeze on the Sapphire table as Latias saved the ball after it dropped, but I wasn't able to recreate the freeze on either table after relaunching. Thanks for the patch!
 
  • Like
Reactions: djedditt

shenhan

New Member
Newbie
Joined
Sep 30, 2021
Messages
4
Trophies
0
Age
36
XP
80
Country
United States
I'm the author of the Mario & Luigi and Super Mario Advance 4 rumble patches, and released my Pokémon Pinball: Ruby and Sapphire rumble patch yesterday. Maybe works for you? It has a functional rumble options menu, as well as more accurate rumble events. Let me know!



I just confirmed those bugs using Phrankles patch. If you don't want to wait for him to fix it, check out my patch above.

Oh wow! I just tested your patch, it works perfectly! Thank you!
 
  • Like
Reactions: djedditt

Phrankles

Active Member
OP
Newcomer
Joined
Sep 22, 2021
Messages
26
Trophies
0
Age
31
XP
94
Country
United States
Phrankles, in your other post you wrote;



I checked and it does matter - it all comes down to your subroutine not being nested correctly and that messes up your link register, resulting in the infinite loop. The approach you took to circumvent that is not the right one, and essential instructions got lost. From there things cascade into the issues that ThatBassoonist reported.

If you want I can give you some pointers on how to fix it properly :)
Interesting, I recently suspected the whirlpools behavior was strange since the boss seemed really easy, but I hadn't played the game enough without my patch to know the difference. Super happy to see you were able to make a better patch. I would love to hear the proper way to hook the function as I am aware that my approach of replacing assembly in order to save the return register was desperate, and praying that it is only relevant to the original rumble function is not exactly great practice.
 

djedditt

Member
Newcomer
Joined
Jan 15, 2021
Messages
22
Trophies
0
Age
34
XP
292
Country
Netherlands
Interesting, I recently suspected the whirlpools behavior was strange since the boss seemed really easy, but I hadn't played the game enough without my patch to know the difference. Super happy to see you were able to make a better patch. I would love to hear the proper way to hook the function as I am aware that my approach of replacing assembly in order to save the return register was desperate, and praying that it is only relevant to the original rumble function is not exactly great practice.

A proper way to do it in this context would be to push the link register onto the stack at the start of the function, immediately execute your subroutine, and then at the end of the function pop the link register off the stack and put it in the program counter. You can use push {lr} and pop {pc} for that. This way the return address is not lost, and restored properly without meddling with other registers. Here's a made-up example:

Code:
Original:               Change to:

mov r0, #0xA     ---    push {lr}
mov r1, #0xB     \__    bl 0xC0DE /* pun intended */
add r0, r0, r1   /
...                     ...
bx lr            ---    pop {pc}

Instructions that have been overwritten should be executed first thing in your subroutine (not per se, but unless you know exactly what you're doing just assume that is true). For GBA games those instructions will most likely be THUMB code like the example above, so one 16-bit instruction that has been overwritten with the push instruction and then two more that had to make room for the single 32-bit branch and link instruction.

In your subroutine at 0xC0DE:
Code:
mov r0, #0xA
mov r1, #0xB
add r0, r0, r1
# Injection code here, but don't forget to push/pop registers you want to use!
bx lr

I've fixed your patch locally to test, and verified this approach will solve your issues. Good luck!
 
Last edited by djedditt,

Phrankles

Active Member
OP
Newcomer
Joined
Sep 22, 2021
Messages
26
Trophies
0
Age
31
XP
94
Country
United States
A proper way to do it in this context would be to push the link register onto the stack at the start of the function, immediately execute your subroutine, and then at the end of the function pop the link register off the stack and put it in the program counter. You can use push {lr} and pop {pc} for that. This way the return address is not lost, and restored properly without meddling with other registers. Here's a made-up example:

Code:
Original:               Change to:

mov r0, #0xA     ---    push {lr}
mov r1, #0xB     \__    bl 0xC0DE /* pun intended */
add r0, r0, r1   /
...                     ...
bx lr            ---    pop {pc}

Instructions that have been overwritten should be executed first thing in your subroutine (not per se, but unless you know exactly what you're doing just assume that is true). For GBA games those instructions will most likely be THUMB code, so one 16-bit instruction that has been overwritten with the push instruction and then two more that had to make room for the single 32-bit branch and link instruction.

In your subroutine at 0xC0DE:
Code:
mov r0, #0xA
mov r1, #0xB
add r0, r0, r1
# Injection code here, but don't forget to push/pop registers you want to use!
bx lr

I've fixed your patch locally to test, and verified this approach will solve your issues. Good luck!
Thanks so much! It is amazing how much faster I can get to the root of the problem picking the brain of someone with experience than trying to read technical docs for hours. Your tips are super helpful.
 
  • Like
Reactions: djedditt

Archolm

Active Member
Newcomer
Joined
Apr 11, 2021
Messages
42
Trophies
0
Age
43
XP
741
Country
Netherlands
Hello all, thanks for the awesome work making these hacks, I was wondering, as an owner of a RG351MP, id LOVE to be able to enjoy this game with rumble, which the MP supports. However using the Catridge Rumble Patch (and enabling Gameboy Player rumble in mGBA) does not work on my device. Is there any chance of adding support for Chinese stuff like this or is it really a per use case hack? The firmware is 351elec by the way, so most likely a standard linux port of RetroArch is used.

Thanks again for doing stuff like this!

edit: Nevermind, got it working somehow. Definitely going to give your other patches a try!
 
Last edited by Archolm,

xxNathanxx

Well-Known Member
Member
Joined
Oct 28, 2011
Messages
403
Trophies
1
XP
533
Country
New Caledonia
Hey, I just wanted to say a heartfelt thanks to both of you for making this patch. I keep coming back to this game every couple of years on different consoles, and the rumble patch elevates it to near perfection. If only the Ruby table wasn't ten times as difficult as the Sapphire one...
 
  • Like
Reactions: cearp

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Sonic Angel Knight @ Sonic Angel Knight: :ninja: