How to make a roller in ASM?

Started by Bully@Wiiplaza, June 19, 2011, 06:45:24 PM

Previous topic - Next topic

Bully@Wiiplaza

How would someone write the assembly to toggle through the written values, each time the same button is pressed?

Like this WiiRd codestype code:

[spoiler]Super Wetter Modifier (Change Weather with Z Button) [Bully@Wiiplaza]
043B4530 38000005
285356D2 DFFF2000 -> BA
C23BFB40 00000003
3D800000 618C0000
91830180 80030180
60000000 00000000
02478554 00000000
02478630 00000000
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800000 618C0002
91830180 80030180
60000000 00000000
02478554 00000002
02478630 00000002
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800000 618C0004
91830180 80030180
60000000 00000000
02478554 00000004
02478630 00000004
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800000 618C0010
91830180 80030180
60000000 00000000
02478554 0000000A
02478630 0000000A
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800000 618C0040
91830180 80030180
60000000 00000000
02478554 00000028
02478630 00000028
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800000 618C5000
91830180 80030180
60000000 00000000
02478554 00001388
02478630 00001388
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800000 618C8000
91830180 80030180
60000000 00000000
02478554 00001F40
02478630 00001F40
CC000000 00000000 -> Switch
C23BFB40 00000003
3D800005 618C0000
91830180 80030180
60000000 00000000
02478554 0000C350
02478630 0000C350
E0000000 80008000[/spoiler]

Default assembly code:

[spoiler]Transformation V.6 [Thomas83Lin]
C2140F58 00000013
899F0007 2C0C0000
41820020 2C0C0001
4182002C 2C0C0002
41820038 2C0C0003
41820044 4082006C
3D80803A A18C1ACE
2C0C1000 41820040
40820058 3D80803A
A18C2046 2C0C1000
4182002C 40820044
3D80803A A18C25BE
2C0C1000 41820018
40820030 3D80803A
A18C2B36 2C0C1000
40820020 39800000
7D8C0214 398C0001
2C0C0006 40810008
39800000 919F14E0
808314E0 00000000

lbz r12,7(r31)
cmpwi r12,0
beq- 0x0020
cmpwi r12,1
beq- 0x0020
cmpwi r12,2
beq- 0x0020
cmpwi r12,3
beq- 0x0020
bne- 0x0020
lis r12,-32710
lhz r12,6862(r12)
cmpwi r12,4096
beq- 0x0020
bne- 0x0020
lis r12,-32710
lhz r12,8262(r12)
cmpwi r12,4096
beq- 0x0020
bne- 0x0020
lis r12,-32710
lhz r12,9662(r12)
cmpwi r12,4096
beq- 0x0020
bne- 0x0020
lis r12,-32710
lhz r12,11062(r12)
cmpwi r12,4096
bne- 0x0020
li r12,0
add r12,r12,r0
addi r12,r12,1
cmpwi r12,6
ble- 0x0020
li r12,0
stw r12,5344(r31)
lwz r4,5344(r3)[/spoiler]

I´ll provide a random example for which it should be made:

lis r12, 0x803f
ori r12, r12, 0x12e2
lhz r12, 0 (r12) # load button value into r12
cmpwi r12, 0x8000 # if home is pressed...
bne- _END
li r0, 0xYY # load value into r0
... # how do I toggle the li according to how many times my cmpwi was true, like the CC codestype? (= button pressed)
_END:
stw r0, 0 (r3) # store it

thx!
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

Thomas83lin's code didn't disassemble right.  The branches are all wrong.  Which app did you use to generate that?

---

I think you mean "how do you make a roller".  The feature of the CC code that you want is that it only does something once each time the combination is pressed, instead of doing it for the duration of the combination being held down.

Assuming 805356D2 is your button activator address, then 805356D6 probably holds a "delta activator".  delta is a science term for "changed".  You can use that for a button activator that only happens once per button press.  It's usually used to "roll" something from one value to the next.

Bully@Wiiplaza

#2
Quote from: dcx2 on June 19, 2011, 06:59:50 PM
Thomas83lin's code didn't disassemble right.  The branches are all wrong.  Which app did you use to generate that?
I used PyiiASMH.
ASMWiiRd is probably not that error prone.
Yet I also noticed that PyiiASMH calculated some braches wrong, so that my game froze.... (while ASMWiiRd did it right with the offsets) :rolleyes:

Quote from: dcx2 on June 19, 2011, 06:59:50 PM
I think you mean "how do you make a roller".  
Yes, that´s what I mean.

Quote from: dcx2 on June 19, 2011, 06:59:50 PM
You can use that for a button activator that only happens once per button press.
Which address do I need to pick, if I search for the button values to get the "one shot" button activator (if I calculate +4 then)?
There are always like 20 results left that act like this. Finding one legit button activator is an ease for me, however...
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

Pick the first address, go to Memory Viewer, hit Pause, then hold a button in, then press Next Frame a couple times.  You should see the delta activator appear for one frame.  If you don't see it, try the next address.

Bully@Wiiplaza

#4
Quote from: dcx2 on June 19, 2011, 08:35:27 PM
Pick the first address, go to Memory Viewer, hit Pause, then hold a button in, then press Next Frame a couple times.  You should see the delta activator appear for one frame.  If you don't see it, try the next address.
thx, and how would you build a roller then? :-[

Default code:
[spoiler]
Party Roller [dcx2]
C205C88C 0000000C
3D80804D 618C755A
A14C0004 714A000C
41820048 A1431B62
2C0A000B 4181003C
A18C0000 2C0C2008
40820010 2C0A000B
40800008 394A0001
2C0C2004 40820010
2C0A0001 40810008
394AFFFF B1431B62
394AFFFF B1431B60
A0631B62 00000000
Hold Z. Press down and up to change the character (non-monsters only).[/spoiler]
It seems like you´re adding/subing a value if the button is pressed...
Very cool rollers you made, I couldn´t even find a simple one that only uses one button to roll :o
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

Just one button to roll is bad.  You could roll accidentally.

First, pick a good hook.  There are usually a lot of read breakpoints; pick one that looks like it only executes at a specific place in the game, usually which can provide feedback.  For instance, the Party Roller hooks a read which only executes during the Status menu.  When you roll the value, you see the character change immediately to another party member.  But if you aren't in the Status menu, the hook won't work, so you can't accidentally change who you are.

The next step is to pick a good "roll enable" button.  Some button that doesn't do anything in the area of interest.  At the Status menu, the Z button does nothing, so there is no reason for you to press it normally.  It acts as another level of protection against accidentally activating the roller.  Holding this button down enables the roller, so this step checks the "regular" button address.

The next step is to pick increment and/or decrement buttons.  This does the act of rolling.  These will check the delta activators and make sure that we inc or dec only once.

Then, you must protect against roll-over and roll-under.  Usually if you roll too far the game will crash.  A good idea to do for roll-over is to jump to the first value, and for roll-under jump to the last value.  This way it wraps around.

Finally, if there are a lot of values to roll through, it helps to make "scrollers".  These are "regular" button activators so that it keeps rolling while the button is held down.  You can use the scroll to get close to the value you want quickly, and then roll the rest of the way with the one-shot delta activators.

---

A good example is the Skit Roller, which does all of these things.  In this game, Skits were short cut-scenes.  There were 304 of them.  The hook I chose was      8006F5B4:  836373A8   lwz   r27,29608(r3)   and it would check for skits on the world map (so it wouldn't activate during a battle, or on the menu, etc).  The skit number was put into r27.  The min value was -1, which meant "no skit", and the last skit was 303.  The enable button was Z, which made you stand still on the world map.  This was convenient, because otherwise the arrow keys would cause you to move, heh.  Left or right would roll one value, up or down would scroll.  Everything within the spoiler can be copied and pasted into PyiiASMH or ASMWiiRD (you may have to resize the window with ASMWiiRD for it to work)

[spoiler]
.set BTN_ADDR,0x804D755A

.set BTN_Z,0x2000
.set BTN_UP,0x0008
.set BTN_DOWN,0x0004
.set BTN_RIGHT,0x0002
.set BTN_LEFT,0x0001

.set BTN_ENABLE,BTN_Z


lwz r27,29608(r3)   # original instruction


lis r12,BTN_ADDR@h
ori r12,r12,BTN_ADDR@l
lhz r9,0(r12)      # get buttons
lhz r10,4(r12)      # get button deltas hword

andi. r0,r9,BTN_DOWN|BTN_UP   # if up or down held, skip the delta check
bne- _DO_CODE

andi. r0,r10,BTN_LEFT|BTN_RIGHT
beq- _END


_DO_CODE:

cmpwi r9,BTN_ENABLE|BTN_UP      # if z up
beq- _ROLL_INC

cmpwi r9,BTN_ENABLE|BTN_RIGHT   # or z right, inc skit
bne- _TEST_ROLL_DEC

_ROLL_INC:
addi r27,r27,1


_TEST_ROLL_DEC:
cmpwi r9,BTN_ENABLE|BTN_DOWN      # if z down
beq- _ROLL_DEC

cmpwi r9,BTN_ENABLE|BTN_LEFT      # or z left, dec skit
bne- _WRAP_TEST

_ROLL_DEC:
subi r27,r27,1


_WRAP_TEST:
cmpwi r27,303         # 303 is the last skit
ble- 0f
li r27,-1

0:

cmpwi r27,-1         # -1 is no skit
bge- 0f
li r27,303

0:

_END:
stw r27,29608(r3)   # update skit value
[/spoiler]

Bully@Wiiplaza

#6
Normal Button Activator: 803A1AC8
One Shot Button Activator: 803A1ACC
Best Hook: 80140F58  lwz   r4,5344(r3)
Button for the roller: Minus (Value 1000)
Possible distance: 00 - 06 (other values freeze the game)

Function:
[spoiler]80140F40:  9421FFF0   stwu   r1,-16(r1)
80140F44:  7C0802A6   mflr   r0
80140F48:  90010014   stw   r0,20(r1)
80140F4C:  93E1000C   stw   r31,12(r1)
80140F50:  7C7F1B78   mr   r31,r3
80140F54:  80031090   lwz   r0,4240(r3)
80140F58:  808314E0   lwz   r4,5344(r3)
80140F5C:  7C002000   cmpw   r0,r4
80140F60:  4082000C   bne-   0x80140f6c
80140F64:  38600000   li   r3,0
80140F68:  4800006C   b   0x80140fd4
80140F6C:  81830060   lwz   r12,96(r3)
80140F70:  38A00000   li   r5,0
80140F74:  818C00E4   lwz   r12,228(r12)
80140F78:  7D8903A6   mtctr   r12
80140F7C:  4E800421   bctrl   
80140F80:  7FE3FB78   mr   r3,r31
80140F84:  4BF0D0CD   bl   0x8004e050
80140F88:  887F038D   lbz   r3,909(r31)
80140F8C:  7C630774   extsb   r3,r3
80140F90:  4BF29841   bl   0x8006a7d0
80140F94:  7FE3FB78   mr   r3,r31
80140F98:  38800001   li   r4,1
80140F9C:  480004C5   bl   0x80141460
80140FA0:  801F1090   lwz   r0,4240(r31)
80140FA4:  2C000003   cmpwi   r0,3
80140FA8:  40820024   bne-   0x80140fcc
80140FAC:  7FE3FB78   mr   r3,r31
80140FB0:  4BFE64C1   bl   0x80127470
80140FB4:  C01F00EC   lfs   f0,236(r31)
80140FB8:  FC000840   fcmpo   cr0,f0,f1
80140FBC:  40810008   ble-   0x80140fc4
80140FC0:  D03F00EC   stfs   f1,236(r31)
80140FC4:  7FE3FB78   mr   r3,r31
80140FC8:  4BFED5D9   bl   0x8012e5a0
80140FCC:  7FE3FB78   mr   r3,r31
80140FD0:  4BF0D071   bl   0x8004e040
80140FD4:  80010014   lwz   r0,20(r1)
80140FD8:  83E1000C   lwz   r31,12(r1)
80140FDC:  7C0803A6   mtlr   r0
80140FE0:  38210010   addi   r1,r1,16
80140FE4:  4E800020   blr   
[/spoiler]
Disassembly:
[spoiler]  CR:88000488  XER:00000000  CTR:80140F40 DSIS:00400000
DAR:8154CCE4 SRR0:80140F58 SRR1:0000B032   LR:80141528
 r0:00000000   r1:8043FAB8   r2:80433080   r3:8154B804
 r4:80325248   r5:00000001   r6:00000000   r7:00000003
 r8:00000000   r9:40C00000  r10:41F80000  r11:FFFFFFFF
r12:80140F40  r13:8042F680  r14:00000000  r15:00000000
r16:00000000  r17:00000000  r18:00000000  r19:00000000
r20:00000000  r21:00000000  r22:00000000  r23:00000000
r24:00000000  r25:00000000  r26:00000000  r27:00000000
r28:8154B804  r29:8043FB88  r30:8043FB70  r31:8154B804[/spoiler]

It should roll from 01 to 06 continuing with 01 again if 06 was reached. I still need some help there... :(
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

If you want help, ask specific questions.  if you don't know what to ask, re-read the previous post.  Try to make something - anything at all - and then when you don't know what something means, or why one instruction was chosen instead of another, ask that question.  I'm not going to write the code for you.

Deathwolf

is it something like mdmwii's stalking hack?
lolz

Bully@Wiiplaza

#9
Quote from: Deathwolf on June 21, 2011, 06:30:23 PM
is it something like mdmwii's stalking hack?
it should change character suit.

Quote from: dcx2 on June 21, 2011, 01:27:04 AM
If you want help, ask specific questions.
good, I´ll provide my attempts but don´t think that they will be fine.

Hook: 80140F58
[spoiler]
lwz r4,5344(r3) # load value of interest into r4
lis r12, 0x803A
ori r12, r12, 0x1ACC # load one shot BA
lhz r12, 0 (r12) # load value into r12
andi. r12, r12, 0x1000 # do we press minus?
beq- _NOTPRESSED # if we don´t press minus, branch (I´m not quite sure why you need to use beq- with an andi.)
addi r4, r4, 1 # add 1 to the value
stw   r4,5344(r3) # update new value
_NOTPRESSED:
lwz   r4,5344(r3) # original instruction
[/spoiler]
Question:
How do I roll the value from 01 to 06, continuing at 01 again, when it reached 06? (to avoid crashes + to only use one button)

Possibly like this?
[spoiler]
lwz r4,5344(r3) # load value of interest into r4
lis r12, 0x803A
ori r12, r12, 0x1ACC # load one shot BA
lhz r12, 0 (r12) # load value into r12
andi. r12, r12, 0x1000 # do we press minus?
beq- _NOTPRESSED # if we don´t press minus, branch (I´m not quite sure why you need to use beq- with an andi.)
addi r4, r4, 1 # add 1 to the value
cmpwi r4, 0x7 # did we reach 7?
bne- _NORESET # branch, if value is not 7
li r4, 0x1 # back to 01
_NORESET:
stw   r4,5344(r3) # update new value
_NOTPRESSED:
lwz   r4,5344(r3) # original instruction[/spoiler]
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

That's a good start.  Here's a tip - do you see all the extra blank lines in my ASM template above?  They are there to help "group" instructions together.  They are like paragraphs.  Imagine reading a book which had no paragraphs - it would be terribly hard to read!

---

lis r12, 0x803A
ori r12, r12, 0x1ACC # load one shot BA
lhz r12, 0 (r12) # load value into r12

lhz = Load Half-word and Zero.  You'll load the half-word at address 803A1ACC.  This will probably be zero.  I think you want 803A1ACE instead.

---

andi. r12, r12, 0x1000 # do we press minus?
beq- _NOTPRESSED # if we don´t press minus, branch (I´m not quite sure why you need to use beq- with an andi.)

Recall that the . at the end of an instruction means you get a free cmpwi rD, 0.  In this case, if we andi. the button we want and it is NOT pressed, the result will be 0, which is equal to 0 so the branch will be taken.  If we andi. with minus and IT IS pressed, the result will be 0x1000,  which is not equal to 0, so the branch is not taken.

---

cmpwi r4, 0x6 # did we reach 6?
bgt- _END # if greater than 6, branch ("avoid crash")

You shouldn't just branch to the end (although it seems like you figured this out already, good job).  Instead, you need to roll-over.  This is the "_WRAP_TEST:" in my code above, it helps you "wrap around" to 1 again.  Instead, you should do this.

cmpwi r4,6
ble- 0f
li r4,1
0:

Bully@Wiiplaza

#11
would it look like this then?

lwz   r4,5344(r3)
lis r12, 0x803A
ori r12, r12, 0x1ACE
lhz r12, 0 (r12)
andi. r12, r12, 0x1000
beq- _NOTPRESSED
addi r4, r4, 1
cmpwi r4,6
ble- 0f
li r4,1
0:
stw   r4,5344(r3)
_NOTPRESSED:

C2140F58 00000007
808314E0 3D80803A
618C1ACE A18C0000
718C1000 41820018
38840001 2C040006
40810008 38800001
908314E0 808314E0
60000000 00000000

Thanks for your help :smileyface:
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

You forgot to lwz r4 at the beginning.

You also forgot the addi r4, r4, 1 in the middle.

I highly suggest having an "enable button" in your final code.  If someone has to press minus for any reason when your hook is executed, it will accidentally roll.

Bully@Wiiplaza

#13
Quote from: dcx2 on June 22, 2011, 03:50:15 PM
You forgot to lwz r4 at the beginning.

You also forgot the addi r4, r4, 1 in the middle.

I highly suggest having an "enable button" in your final code.  If someone has to press minus for any reason when your hook is executed, it will accidentally roll.

it´s not needed for this code since the player does never need the minus button.
If it was pressed accidentally, one can reverse it with a few more presses.
Thanks for the tip, though.
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

You can't say you know that for sure.  What if someone else wants to use - as part of a button activator?  It will conflict with your code.