Super Mario Galaxy 2 Multi-Teleporter/Levitation v2 details

Started by dcx2, July 24, 2010, 11:13:45 PM

Previous topic - Next topic

Deathwolf

ähm yea thanks.

which link is the right and which should I download?
lolz

dcx2

This is the first teleporter that I wrote.  It has only one slot, but it's a much less complex code, so it might be easier to understand.  It uses cmpwi, so you must press C and up but no other buttons.  If you press C and up and left, it won't work.


Hook 803880A8 = lwz r0,52(r1)
r3 has coordinates to read/write
r0,r30,r31 safe
buttons at 80750A02
c+up to store, c+down to restore

Everything below this line can be converted using PyiiASMH

--

# put the address of DATA_POINTER_BASE into the LR
bl 0x04

DATA_POINTER_BASE:
# move the LR into r31, so that r31 can be a data pointer
mflr r31      

# add the offset from DATA_POINTER_BASE to DATA_POINTER_OFFSET to r31
addi r31,r31,DATA_POINTER_OFFSET-DATA_POINTER_BASE

# load r30 with the pointer to the button values
lis r30,0x8075
ori r30,r30,0x0A02

# load r30 with the button values
lhz r30,0(r30)

# compare the button values to 0x4001 = C and up and nothing else
cmpwi r30,0x4001   

# if the button values are not equal to C and up, branch to the next compare
bne- TEST_RESTORE

# if we get here, r30 = 0x4001
# store the current coordinates (from r3 pointer)
# into the data area (to r31 pointer)
lwz r0,0(r3)      # store
stw r0,0(r31)
lwz r0,4(r3)      
stw r0,4(r31)
lwz r0,8(r3)      
stw r0,8(r31)

# we're done now
b THE_END


# if we get here, then the C and up test failed
# so now we'll test C and down = 0x4008
TEST_RESTORE:
cmpwi r30,0x4008

# if it is not C and down either, then we're done
bne- THE_END

# otherwise, C and down are pressed,
# so let's restore the coordinates from the data area (from r31 pointer)
# to Mario's coordinates (to r3 pointer)
lwz r0,0(r31)      # restore
stw r0,0(r3)
lwz r0,4(r31)      
stw r0,4(r3)
lwz r0,8(r31)      
stw r0,8(r3)

# skip over the data area
b THE_END

# this is the data area, where the coordinates are stored when you press C and up
DATA_POINTER_OFFSET:
.long 0,0,0

# this is the instruction that is being replaced by my hook
THE_END:
lwz r0,52(r1)

Deathwolf

aha okay.

so that's your button activator:
lis r12,-32651
ori r12,r12,2560
lhz r30,2(r12)
andi. r0,r30,1024
beq- 0x78

and this your code:
rlwinm. r0,r30,19,9,12
beq- 0x70
cntlzw r0,r0
mulli r0,r0,12
bl 0x04
mflr r31
andi. r30,r30,8192
add r30,r31,r0
beq- 0x0C
mr r12,r3
b 0x3C
lfs f0,104(r31)
lfs f1,100(r12)
fmuls f0,f0,f1
li r0,3
mtctr r0
addi r31,r12,8
subi r12,r30,4
lfsu f1,4(r31)
lfsu f2,4(r12)
fnmsubs f1,f0,f1,f2
stfs f1,0(r12)
bdnz+ 0xFFFFFFF0
mr r12,r30
mr r30,r3
psq_l f0,0(r12),0,0
psq_l f1,8(r12),1,0
psq_st f0,0(r30),0,0
psq_st f1,8(r30),1,0
lwz r0,52(r1)
b 0x38
bdnz- 0x00
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
lolz

dcx2

That is one of the three button activators in the multi-teleporter.  But...why do you keep converting the code to get rid of all the notes and stuff?  You're making it more difficult.  I posted the disassembly with comments and variables for a reason.

I'm trying to show others that there is a way to write ASM codes that makes them easier to read and modify.  You can use variables like BUTTON_OFFSET and B_MASK instead of hard numbers.  You can add comments so you know what registers have what values.  You can use branch labels like THE_END instead of calculating branch offsets.

What's easier to read and understand?

# r12 is controller pointer
# r30 is button values
lis r12,0x8075
ori r12,r12,0x0A00
lhz r30,BUTTON_OFFSET(r12)
andi. r0,r30,B_MASK
beq- THE_END   # no b means do nothing

or

lis r12,-32651
ori r12,r12,2560
lhz r30,2(r12)
andi. r0,r30,1024
beq- 0x78

---

Besides.  If you're having trouble with button activators, the multi-teleporter is not what you want to learn from.  Look at the single teleporter that I posted.  It's a lot simpler.

dragonboy269

When you do the branch and link, and it stores the return in the LR, is that the address of the very first coordinate data?
If not, how far away from that would it be? I try reading your stuff but, you're using count leading zeros and multiplying by 12 (I guess cause theres 12 bytes per line, and so checking which line to get the data from?)  to get how much to add.
If you have any requests for AC:WW/AC:CF codes, send me a message. :D

dcx2

"return" is an awkward word to use, especially because this bl has no matching blr.  bl will put PC + 4 into LR.  It just so happens that my data is aligned with this PC + 4.  I also use bl to branch over the data and prevent it from being executed as if it were code.

If you put the data anywhere besides immediately after bl, you can use labels to automatically generate offsets to the data.  However, you'll need to branch over the data somehow.

Also, in my case, I want the data to be 12-byte aligned with the data pointer from the LR.  This way, my index gets multiplied by 12 and I'm done; otherwise I have to add an offset to account for the alignment.

Another example would be reading the max speed. 

lfs f0,FLOAT_OFFSET(r31)

After putting the data pointer into r31, I load the float from the data area into f0.  FLOAT_OFFSET is a number that was calculated by the assembler based on labels; you can see that it's .set at the top.  It's probably 48 or something like that, but that's the beauty of labels and variables...I don't know/care what it is.

dragonboy269

I keep trying to access data in the code, but it doesn't seem to be working, or at least how i want it to...Can you tell me why this won't work?
(this is just a test)

.set Offset, Saved_Data - Next_Instruction

mflr r0
bl Next_Instruction
Next_Instruction:
mflr r5
mtlr r0
lwz r14, Offset(r5)
cmpwi r14, 0x3
bne Exit
#code should run if its reading correctly...
#next part of code here#
Exit:
blr

Saved_Data:
.long 0x3

If you have any requests for AC:WW/AC:CF codes, send me a message. :D

dcx2

You're using blr...is this a C0 code?

I wouldn't trust r14.  Try r12 instead.

I also generally prefer putting the data after the bl.  The bl then skips over the data.  In the case of a C0 code, your blr is skipping over the data.  However, for a C2 code, you will need an extra branch to jump over the data.

EDIT: putting the data after the bl also has the convenient side effect of making the LR point directly at the first piece of data, meaning at least one of the offsets will be 0.