Using CST6 switch code types with ASM hacks

Started by dcx2, February 13, 2010, 08:53:09 PM

Previous topic - Next topic

dcx2

Sometimes you want to turn hacks on and off.  For instance, I just made a Ghost Squad hack that kills every enemy instantly.

040BCAC4 38A00001   # replace instruction 0x800BCAC4 with li r5,1

But let's say you only wanted to use instant kills for a little bit.  There's a CST6 "switch" code type, CC000000 00000000.  Let's use it with a button activator, in this case button 1 because Ghost Squad doesn't use this button.

284DCFDA 00000200   # 16-bit if button 1 is pressed
CC000000 00000000   # switch

040BCAC4 38A00001   # if switch is on, replace instruction 0x800BCAC4 with li r5,1
E0000000 80008000   #end if

Switch starts on by default.  When you press 1, the switch turns off.  Press 1 again and the switch turns back on.  If the switch is on, it will patch instruction 0x800BCAC4.

But if you test this code, you'll find that pressing 1 doesn't turn it off.  Once the switch is off, it stops patching the instruction, but nothing "unpatches" the instruction.

To get around this, let's always patch the old instruction first, and only patch the new instruction if the switch is on.

040BCAC4 7C651B78   # pre-patch with the original instruction mr r5,r3
284DCFDA 00000200   # 16-bit if button 1 is pressed
CC000000 00000000   # switch
040BCAC4 38A00001   # if switch is on, replace instruction 0x800BCAC4 with li r5,1
E0000000 80008000   #end if

Now, every time the code handler runs this code, it always puts the original instruction back, and it will only apply the hack if the switch is in the on state.

Thomas83Lin

#1
I've always done something like this myself when turning codes on and off, but i like your way also, yours should work only if the button is held down right? which is good but wouldn't it be trying to activate both codes at once?? when the button is held, may not be best for alot of codes , also on the CST4 28 codetype you might to include the Not FFFF-0200 which would be FDFF

just a example
284DCFDA FDFF0200   # 16-bit if button 1 is pressed
040BCAC4 7C651B78   # original instruction mr r5,r3
CC000000 00000001   # switches between the two codes
040BCAC4 38A00001   # if switch is on, replace instruction 0x800BCAC4 with li r5,1
E0000000 80008000   #end if

dcx2

yours should work only if the button is held down right?

Do you mean, it only activates if you press 1 and only 1, without pressing any other buttons?  I think that's what you mean.  Using the mask bits would allow the code to work while other buttons were being pressed.  This is actually a bad thing, because I have another code for Ghost Squad that uses C + 1 to activate.  If I used FDFF, then every time I used C + 1, I would also toggle the insta-kill code.  By purposely leaving it 0000, I prevent it from mis-firing.

wouldn't it be trying to activate both codes at once??

Not quite...more like one after the other.  Yes, the first code is always executed every time the code handler runs, so by default it over-writes the instruction with a copy of the original unhacked instruction, every frame.  This keeps things "normal".

After it writes the old instruction, depending on whether the switch is on or off, the next code may immediately over-write with the new hacked instruction.  Off writes only the old instruction and is then done.  On writes old instruction then immediately after writes new instruction.  The game doesn't see the instruction changing back and forth, so when the switch is on, it looks like the hack is on, even though the hack is actually repeatedly turning off very briefly.

The interesting thing about the switch is that it makes the if before it edge sensitive, and the switch itself remembers the state for you.  By edge sensitive, I mean that the switch will only change state once the button is going up-to-down, but not while it is held down, down-to-up, or up.  If it wasn't edge sensitive, then the switch would constantly be turning on and off and on and off while the button was held down.

The switch is always evaluated even when the if is false.  The buttons only change the state of the switch, but don't affect execution of the code.  Execution is determined by switch state.

---

What does the second word of the switch do?  There's nothing in the codetype docs that say what the second byte is.  It just lists CC000000 00000000, but you have a 1 in yours.

I was thinking today that this same technique would work with C2 code types.  That is, pre-patch with the instruction that will be replaced with the branch.  This way when you turn the code off, the C2 branch is undone.

Are you allowed to put a code between the switch and the if?

I was under the impression that the switch must come immediately after the if.

Thomas83Lin

#3
Ok sounds interesting, i may try that sometime then.

Quote from: dcx2 on February 14, 2010, 08:32:02 PM
What does the second word of the switch do?  There's nothing in the codetype docs that say what the second byte is.  It just lists CC000000 00000000, but you have a 1 in yours.
The codetype docs doesn't really say anything about it, but putting the 1 at the end, it will switch between which code to activate. when the button mod is pressed, in this case doing that would turn your code on and off

dcx2

Quote from: thomas83lin on February 14, 2010, 09:57:42 PM
Quote from: dcx2 on February 14, 2010, 08:32:02 PM
What does the second word of the switch do?  There's nothing in the codetype docs that say what the second byte is.  It just lists CC000000 00000000, but you have a 1 in yours.
The codetype docs doesn't really say anything about it, but putting the 1 at the end, it will switch between which code to activate. when the button mod is pressed, in this case doing that would turn your code on and off
According to this post by wiiztec that word is where the current switch state is.  In the case of Ghost Squad, CC000000 00000000 and the switch starts on, and CC000000 00000001 and the switch starts off.

http://wiird.l0nk.org/forum/index.php/topic,4561.msg41616.html#msg41616

I also like how wiiztec calls the normal instruction an "anticode".  I decided to do some tests, and I confirmed that the CC codetype does not need to come immediately after the if.

I set a write breakpoint on the instruction and watched how often it was being written to.  If the anticode comes after the 28 codetype, then the anticode is only written while the button is held down.  If the switch is on, the code gets written every frame.  Once the button is released, the anticode isn't written anymore, but the switch keeps writing the code.

When you press the button again, the anticode gets written while it's held down, and the switch gets turned off, so it no longer writes the code.  Once the button is released, nothing writes to the instruction anymore.

In contrast, If the anticode comes before the 28 if codetype, then the anticode is written every frame, regardless of whether the 28 codetype is true.  If the switch is on, the anticode and code get written every frame.  If the switch is off, only the anticode gets written every frame.

Thomas83Lin

Well i guess that sums it up, I never really knew exactly how it worked, now it makes alot more sense.

wiiztec

For ASM codes it doesn't matter but if you have a RAM address that changes back but not immediately it's better to have the anticode after the button activator, take brawl's gravity for example, it usually resets when you start a new match but sometimes it can change in the middle of a match like the wind blowing up on pokemon stadium 2 or on pirate ship when the ship is rising or falling, if you had put the anticode above the button activator it would constantly be writing the normal gravity value to the address meaning the gravity wouldn't change in the aforementioned instances like it is supposed to.
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen