Closed BtEtta closed 3 years ago
Hi!
I might be wrong but since eax
is not set to 0 in this function, it might end up being something else than 0 if mods call the RingDrop function themselves? You could nop the AddRings function call and hack the condition (jle loc_6C1C7B
) to directly jump to the sound stuff.
This is why I posted my working to see if there was obvious stuff I missed.
It's been a little while since I dug into this but I believe eax
was potentially non-zero at the start of ringDrop()
and it was some unrelated function calls (that I admittedly didn't dive all the way in to) in ringDrop()
before the neg edx
instruction that reset eax
to 0. If that's the case then even a mod calling ringDrop()
would be unaffected.
I feel like I might have tried nop
ing out the addRings()
call but that caused some other side effect, or maybe I just didn't consider patching the jump too.
I don't currently have the game installed but I'm due to be getting a new PC some time in the next few days so I should be able to take a second look once that's up-and-running.
Another thing I didn't consider was whether this is for player one only. (Although I'm not sure why you'd want to have a code like this on for the multiplayer mode.)
Another thing I didn't consider was whether this is for player one only. (Although I'm not sure why you'd want to have a code like this on for the multiplayer mode.)
No this is for both players, the player id of the player that was hurt is passed to the function.
In fact eax seems to be the playerID so my previous concern was wrong:
mov eax, ebx (ebx is the player ID) and eax, 1
Forcing eax to 0 with and eax, 0
would make it not work in 2p so yeah hacking the condition would probably be better, I guess.
Edit: this will work:
Patch "Don't Lose Rings When Hit" write8 006C1B3A 0x90 x5 write16 006C1B41 0xE990
I added it to the Mod Loader, please tell me if there's any issue with it.
Can't see any issue with it.
Clearly it didn't occur to me to patch out the call to addRings() as if I'd just done that (even without patching the jump too) I'd have ended up with the same result as my original patch. ¯\_(ツ)_/¯
I was also wondering about the difference between code
and patch
in codes.lst but I'm now realising it's probably just matter of apply constantly vs. apply once.
Thanks.
it's probably just matter of apply constantly vs. apply once.
Yes, it's exactly that.
Well here it is then, thanks for the suggestion & sorry for the delay ^^
Sonic Adventure DX's mod loader comes with a code to prevent the ring total going down after being hit. I made one for Sonic Adventure 2.
For what it's worth since this is the first time I've made a code for any game that's actually patching executable code (and first time where I've analysed the code myself to follow what's happening) I thought I'd quickly run down my working to make sure I haven't missed anything obvious or non-obvious.
There's a function at
0x0044CE10
that could be calledaddRings()
. It loads the current ring count intoeax
, then adds the value fromedx
to it. In the case of losing ringsedx
is set to the two's complement of the current ring count.When hit the ring count is copied into
edx
at0x006C1B0D
. From there it's copied intoebp
and one of two things happen: Ifebp
is greater than 20ebp
is set to 20 (presumably this is used to determine how many rings fall out)edx
is then converted to its two's complement andaddRings()
is called. Ifebp
is less than or equal to 20 the code diverts to check ifebp
is 0 and if it is it jumps to the "lose a life" code, otherwise it returns to whereedx
is negated andaddRings()
is called.Ideally I'd have been able to prevent loading the ring count into
edx
withnop
s but that just causes you to always lose a life. In the end I figured out I was able to replace theneg edx
instruction withmov edx,eax
aseax
is set to 0 at that point in the code anyway.