#@8006b84c: lbz r0, 0x221F (r3) (beginning of playerThink function; executes every frame for every player)
#r0, r4-r12, r26-r27, r29-r30, f30-f31, cr0, ctr, lr == all safe to use
#r28 == saved external player data pointer
#r3 == internal player data pointer
#--assigning bone dimension overwrites every frame. Testing the 3 known bone data tables accessible with player data 0x5E8
b codeStart
getOverwriteData:
blrl #data table is parsed for information put into registers if character/costume matches
#0x0 = CHID, 0x1 = costume flags (5bits,) 0x2 = dimension flags, 0x3 = transformation flags,
#0x4 = table flags, 0x5 = bone ID, 0x6 = 16-bit truncated float
.long 0x00010707 #Mario, costume4, ZYX, rotation/scale/offset, 1st table, bone 0x1B, 4.0
.long 0x011B4080 #--testing table 1 writes with mario4 (rotation, scale, offsets)
#--makes a stupid looking nose modification. Notice how the transformation breaks differently between costumes
.long 0x00020707 #Mario, costume3, ZYX, rotation/scale/offset, 2nd table, bone 0x1B, 4.0
.long 0x021B4080 #--testing table 2 writes with mario3
.long 0x00040707 #Mario, costume2, ZYX, rotation/scale/offset, 3rd table, bone 0x1B, 4.0
.long 0x041B4080 #--testing table 3 writes with mario2
.long 0x151F0706 #Doc, all costumes, ZYX, scale/offset, 1st/3rd table, bone 0x1B, 4.0
.long 0x051B4080 #--A version of the above that doesn't break transformations between animations
#--rotation transformations seem to be sensitive no matter what tables are used
.long 0x091f0502 #Peach, all costumes, ZY, scale, 1st/3rd table, bone 0x58, 0.5
.long 0x05583f00
.long 0x091f0702 #Peach, all costumes, ZXY, scale, 1st/3rd table, bone 0x59, 0.0
.long 0x05590000 #--short-hair Peach
.long 0x021f0702 #Cfalcon, all costumes, ZYX, scale only, 1st/3rd table, bone 0x11, 0.0 scale
.long 0x05120000 #--Falcon butt (artificially truncate skeleton by killing WaistN scale) (bones still have origins for hitboxes)
.long 0x071f0702 #Sheik, all costumes, ZYX, scale only, 1st/3rd table, bone 0x12, 0.0 scale
.long 0x05110000 #--Sheik butt (kill WaistN scale)
.long 0x131f0702 #Zelda, all costumes, ZYX, scale, 1st/3rd table, bone 0x5D, 0.5 scale
.long 0x055C3F00
.long 0x131f0404 #Zelda, all costumes, X, offset, 1st/3rd table, bone 0x5B, 3.0
.long 0x055B4080
.long 0x131f0404 #Zelda, all costumes, X, offset, 1st/3rd table, bone 0x5C, 4.0
.long 0x055C40C0 #--Rapunzel Zelda
.long 0x11100702 #Luigi, costume0, ZYX, scale, 1st/3rd table, bone 0x05, 2.5 scale
.long 0x05054020
.long 0x11100702 #Luigi, costume0, ZYX, scale, 1st/3rd table, bone 0x16, 0.5 scale
.long 0x05163F00 #GREEN GOLIATH
.long 0x11080702 #Luigi, costume1, ZYX, scale, 1st/3rd table, bone 0x2F, 3.0 scale
.long 0x052F4040
.long 0x11080702 #Luigi, costume1, ZYX, scale, 1st/3rd table, bone 0x35, 3.0 scale
.long 0x05354040
.long 0x11080204 #Luigi, costume1, Y, offset, 1st/3rd table, bone 0x04, 5.5
.long 0x050440B0 #LEGWEEGI -- interesting topN offset problem with ground
.long 0xffffffff #termination code
codeStart:
bl getOverwriteData
mflr r30 #r30 = pointer to parse data
lbz r5, 0x619(r3) #r5 = costume ID
lwz r6, 4(r3) #r6 = character ID
loop:
#first make sure this character/costume has any entries in our in-line data array
lbz r4, 0(r30)
cmplwi r4, 0xFF #if character ID is FF, this is a termination code
beq- exitLoop
cmplw r4, r6
bne+ nextEntry #if character ID doesn't match, parse next entry
lbz r4, 1(r30)
rlwnm. r4, r4, r5, 27, 27 #if costume ID isn't == to the placement of one of the costume bits, parse next entry
beq+ nextEntry
#if character/costume matches, then load the rest of the data
lwz r29, 0x5E8(r3) #r29 = bone lookup table
lbz r7, 2(r30) #r7 = dimension flags (Z, X, Y)
lbz r8, 3(r30) #r8 = transformation flags (rotation, scale, offset)
lbz r9, 4(r30) #r9 = bone table flags (interpolation-frame, interpolation-state, interpolation-default)
lbz r10, 5(r30) #r10 = bone ID
lhz r11, 6(r30)
slwi r11, r11, 16 #r11 = float value
slwi r10, r10, 4
add r10, r10, r29 #r10 = pointer to bone data entry
#and now for some complicated bit conditions
checkT1: #write floats to tables that are flagged in r9, through transformations flagged in r8, of dimensions in r7
andi. r0, r9, 1 #checking for table 1 flag
beq+ checkT2
lwz r4, 0(r10)
writeT2:
addi r4, r4, 0x1C #start of table1/2 rotation
andi. r0, r8, 1
beq+ 0x8 #(skip if unflagged)
bl writeFloat
addi r4, r4, 0x10 #start of table1/2 scale
writeT3:
andi. r0, r8, 2
beq+ 0x8
bl writeFloat
addi r4, r4, 0xC #start of table1/2/3 offset
andi. r0, r8, 4
beq+ 0x8
bl writeFloat
checkT2:
andi. r0, r9, 2
lwz r4, 4(r10)
beq+ checkT3
andi. r9, r9, 0xFD #mask out T2 condition so it doesn't loop forever
b writeT2 #table 1 and 2 offsets are identical
checkT3:
andi. r0, r9, 4
beq+ nextEntry #start parsing next entry if T3 isn't flagged
andi. r9, r9, 0xFB #mask out T3 condition so it doesn't loop forever
lwz r4, 0x84(r4)
addi r4, r4, 0x14 #start of table 3 rotation
andi. r0, r8, 1
beq+ 0x8 #(skip if unflagged)
bl writeFloat
addi r4, r4, 0xC #start of table 3 scale
b writeT3 #table 3 has different offsets than tables 1 and 2
writeFloat: #writes the float to each dimension flagged in r7
checkZ:
andi. r0, r7, 1
beq+ checkX
stw r11, 0(r4)
checkX:
andi. r0, r7, 2
beq+ checkY
stw r11, 4(r4)
checkY:
andi. r0, r7, 4
beq+ finishWriteFloat
stw r11, 8(r4)
finishWriteFloat:
blr
nextEntry: #move pointer and restart loop to parse next entry
addi r30, r30, 0x8
b loop
exitLoop: #when termination code is found, return
return:
lbz r0, 0x221F (r3)