Display Status Bubble
Jump to navigation
Jump to search
# ROUTINE: DISPLAY STATUS BUBBLE # Parameters: # r4 = [Unit misc data pointer] 0007eec0: 27bdff98 addiu r29,r29,-0x0068 0007eec4: afb1005c sw r17,0x005c(r29) 0007eec8: 00808821 addu r17,r4,r0 0007eecc: afbf0064 sw r31,0x0064(r29) 0007eed0: afb20060 sw r18,0x0060(r29) 0007eed4: afb00058 sw r16,0x0058(r29) 0007eed8: 3c058006 lui r5,0x8006 0007eedc: 24a57830 addiu r5,r5,0x7830 # 0x80067830 // Screw formatting. comments behind double slash. 0007eee0: 88a20003 lwl r2,0x0003(r5) # RAM_WORD[0x80067830] 0007eee4: 98a20000 lwr r2,0x0000(r5) # Load it again. 0007eee8: 88a30007 lwl r3,0x0007(r5) # RAM_WORD[0x80067834] 0007eeec: 98a30004 lwr r3,0x0004(r5) # Load it again! 0007eef0: aba2002b swl r2,0x002b(r29) # STACK[0x28] = RAM_WORD[0x80067830] 0007eef4: bba20028 swr r2,0x0028(r29) # Store it again. 0007eef8: aba3002f swl r3,0x002f(r29) # STACK[0x2c] = RAM_WORD[0x80067834] 0007eefc: bba3002c swr r3,0x002c(r29) # Store it again! 0007ef00: 34020015 ori r2,r0,0x0015 0007ef04: 922302dd lbu r3,0x02dd(r17) # [Status bubble to display] // is this like a unit-state thing? if active turn 15, if dead 0, etc.? 0007ef08: 8e3002e4 lw r16,0x02e4(r17) # Pointer to status bubble display data for parameter unit 0007ef0c: 1462000a bne r3,r2,0x0007ef38 0007ef10: 34020072 ori r2,r0,0x0072 # if ([Status bubble to display] == 0x15) { // AT graphic 0007ef14: a2020012 sb r2,0x0012(r16) # [X Load Location] = 114 // hardcoding is just depressing. 0007ef18: 340200b0 ori r2,r0,0x00b0 0007ef1c: a2020013 sb r2,0x0013(r16) # [Y Load Location] = 208 (176 + 32) // (Top AT graphic - First frame) 0007ef20: 962202e2 lhu r2,0x02e2(r17) # MiscUnitData.0x2e2 // load AT frame 0007ef24: 00000000 nop 0007ef28: 10400057 beq r2,r0,0x0007f088 # if (MiscUnitData.0x2e2 != 0) { //branch if AT frame is initial (0) 0007ef2c: 340200bc ori r2,r0,0x00bc 0007ef30: 0801fc22 j 0x0007f088 0007ef34: a2020013 sb r2,0x0013(r16) # [Y Load Location] = 220 (188 + 32) // (Bottom AT graphic - Second frame) # } # } 0007ef38: 14600031 bne r3,r0,0x0007f000 # else if ([Status bubble to display] == 0) { // branch if status bubble is not 0 (any other status?) 0007ef3c: 34020014 ori r2,r0,0x0014 0007ef40: 8e220134 lw r2,0x0134(r17) # [In-battle unit data pointer] 0007ef44: 00000000 nop 0007ef48: 90440007 lbu r4,0x0007(r2) # Treasure/Crystal Countdown Timer 0007ef4c: 8e220140 lw r2,0x0140(r17) # Status Flags 1-4 (misc data) 0007ef50: 3c031000 lui r3,0x1000 0007ef54: 00431024 and r2,r2,r3 0007ef58: 1040000f beq r2,r0,0x0007ef98 # if (Unit has Reraise status) { // branch if doesn't have reraise, seems fair... and, also hardcoded as fuck 0007ef5c: 340200ff ori r2,r0,0x00ff 0007ef60: 3c028009 lui r2,0x8009 0007ef64: 904249e6 lbu r2,0x49e6(r2) # [Reraise Icon X Load Location] // that's good to know 0007ef68: 00000000 nop 0007ef6c: a2020012 sb r2,0x0012(r16) # [X Load Location] = [Reraise Icon X Load Location] 0007ef70: 3c038009 lui r3,0x8009 0007ef74: 906349fe lbu r3,0x49fe(r3) # [Reraise Icon Y Load Location] 0007ef78: 00000000 nop 0007ef7c: a2030013 sb r3,0x0013(r16) # [Y Load Location] = [Reraise Icon Y Load Location] // store first frame load location 0007ef80: 962202e2 lhu r2,0x02e2(r17) # MiscUnitData.0x2e2 0007ef84: 00000000 nop 0007ef88: 1040003f beq r2,r0,0x0007f088 # if (MiscUnitData.0x2e2 != 0) { //branch if frame is 0 0007ef8c: 2462000c addiu r2,r3,0x000c 0007ef90: 0801fc22 j 0x0007f088 0007ef94: a2020013 sb r2,0x0013(r16) # [Y Load Location] = [Reraise Icon Y Load Location] + 12 // if frame is 1, store second frame's load location # } # } 0007ef98: 1082000b beq r4,r2,0x0007efc8 # else if (Treasure/Crystal Countdown Timer != 0xFF) { // branch if dead counter is -1 (target is immortal) 0007ef9c: 00000000 nop 0007efa0: 3c018009 lui r1,0x8009 0007efa4: 00240821 addu r1,r1,r4 0007efa8: 90224a0c lbu r2,0x4a0c(r1) # [X Load Location for Number: Countdown Timer] // 0x80094a0c would be the start of a set of 4 timer x load locations. wild. 0007efac: 00000000 nop 0007efb0: a2020012 sb r2,0x0012(r16) # [X Load Location] = [X Load Location for Number: Countdown Timer] 0007efb4: 3c018009 lui r1,0x8009 0007efb8: 00240821 addu r1,r1,r4 0007efbc: 90224a24 lbu r2,0x4a24(r1) # [Y Load Location for Number: Countdown Timer] // comment comment Y location. 0007efc0: 0801fc22 j 0x0007f088 0007efc4: a2020013 sb r2,0x0013(r16) # [Y Load Location] = [Y Load Location for Number: Countdown Timer] # } else { 0007efc8: 3c028009 lui r2,0x8009 0007efcc: 904249dc lbu r2,0x49dc(r2) # [KO Stars X Load Location] // KO stars at 0x800949dc 0007efd0: 00000000 nop 0007efd4: a2020012 sb r2,0x0012(r16) # [X Load Location] = [KO Stars X Load Location] 0007efd8: 3c038009 lui r3,0x8009 0007efdc: 906349f4 lbu r3,0x49f4(r3) # [KO Stars Y Load Location] 0007efe0: 00000000 nop 0007efe4: a2030013 sb r3,0x0013(r16) # [Y Load Location] = [KO Stars Y Load Location] // (First frame) 0007efe8: 962202e2 lhu r2,0x02e2(r17) # MiscUnitData.0x2e2 0007efec: 00000000 nop 0007eff0: 10400025 beq r2,r0,0x0007f088 # if (MiscUnitData.0x2e2 != 0) { // branch if KO stars frame is 0 0007eff4: 2462000c addiu r2,r3,0x000c 0007eff8: 0801fc22 j 0x0007f088 0007effc: a2020013 sb r2,0x0013(r16) # [Y Load Location] = [KO Stars Y Load Location] + 12 // (Second frame) # } # } # } 0007f000: 14620010 bne r3,r2,0x0007f044 # else if ([Status bubble to display] == 0x14) { // doom? 0007f004: 00000000 nop 0007f008: 8e220134 lw r2,0x0134(r17) # [In-battle unit data pointer] 0007f00c: 00000000 nop 0007f010: 9042006c lbu r2,0x006c(r2) # [Death Sentence CT] 0007f014: 00000000 nop 0007f018: 30440003 andi r4,r2,0x0003 # [Death Sentence CT] mod 4 // (Should already be between 0 - 3?) (Might be for immortal units? hypothesis requires verification) 0007f01c: 3c018009 lui r1,0x8009 0007f020: 00240821 addu r1,r1,r4 0007f024: 90224a0c lbu r2,0x4a0c(r1) # [X Load Location for Number: Death Sentence CT] 0007f028: 00000000 nop 0007f02c: a2020012 sb r2,0x0012(r16) # [X Load Location] = [X Load Location for Number: Death Sentence CT] 0007f030: 3c018009 lui r1,0x8009 0007f034: 00240821 addu r1,r1,r4 0007f038: 90224a24 lbu r2,0x4a24(r1) # [Y Load Location for Number: Death Sentence CT] 0007f03c: 0801fc22 j 0x0007f088 0007f040: a2020013 sb r2,0x0013(r16) # [Y Load Location] = [Y Load Location for Number: Death Sentence CT] # } else { 0007f044: 3c018009 lui r1,0x8009 0007f048: 00230821 addu r1,r1,r3 0007f04c: 902249dc lbu r2,0x49dc(r1) # [Status Bubble X Load Location] // if status bubble to display is anything other than countdown, reraise, or doom 0007f050: 00000000 nop 0007f054: a2020012 sb r2,0x0012(r16) # [X Load Location] = [Status Bubble X Load Location] 0007f058: 2462fff7 addiu r2,r3,-0x0009 0007f05c: 3c018009 lui r1,0x8009 0007f060: 00230821 addu r1,r1,r3 0007f064: 902449f4 lbu r4,0x49f4(r1) # [Status Bubble Y Load Location] 0007f068: 2c420002 sltiu r2,r2,0x0002 # Check (Status Bubble - 9) < 2 0007f06c: 10400006 beq r2,r0,0x0007f088 0007f070: a2040013 sb r4,0x0013(r16) # [Y Load Location] = [Status Bubble Y Load Location] // (First frame) # if ((Status Bubble - 9) < 2) { 0007f074: 962202e2 lhu r2,0x02e2(r17) # MiscUnitData.0x2e2 0007f078: 00000000 nop 0007f07c: 10400002 beq r2,r0,0x0007f088 # if (MiscUnitData.0x2e2 != 0) { // these status bubbles have the potential to have 2 frames. they don't, but they can. 0007f080: 2482000c addiu r2,r4,0x000c 0007f084: a2020013 sb r2,0x0013(r16) # [Y Load Location] = [Status Bubble Y Load Location] + 12 // (Second frame) # } # } # } 0007f088: 3c10800a lui r16,0x800a 0007f08c: 26108a24 addiu r16,r16,-0x75dc # 0x80098a24 0007f090: 0c00742a jal 0x0001d0a8 # ROUTINE: Store Rotation matrix elements to GTE 0007f094: 02002021 addu r4,r16,r0 # Parameter: 0x80098a24 // Camera rotation matrix in RAM 0007f098: 0c00744e jal 0x0001d138 # ROUTINE: Store Translation Vectors to GTE 0007f09c: 02002021 addu r4,r16,r0 # Parameter: 0x80098a24 // Camera Translation Matrix in RAM 0007f0a0: 27b00040 addiu r16,r29,0x0040 # [Stack pointer] + 0x40 0007f0a4: 02002021 addu r4,r16,r0 # Parameter 1 for next call: [Stack pointer] + 0x40 0007f0a8: 86230040 lh r3,0x0040(r17) # X Location on Screen 0007f0ac: 86250060 lh r5,0x0060(r17) # X Offset? 0007f0b0: 86260042 lh r6,0x0042(r17) # Z Location on Screen 0007f0b4: 86220062 lh r2,0x0062(r17) # Height Offset? 0007f0b8: 86270064 lh r7,0x0064(r17) # Y Offset? 0007f0bc: 00652821 addu r5,r3,r5 # Parameter 2 for next call: X Location + X Offset 0007f0c0: 00c23021 addu r6,r6,r2 # Z Location + Height Offset? 0007f0c4: 822202df lb r2,0x02df(r17) # Y Location of Status Bubble 0007f0c8: 86230044 lh r3,0x0044(r17) # Y Location on Screen 0007f0cc: 00c23021 addu r6,r6,r2 # Parameter 3 for next call: Z Location + Height Offset? + Y Location of Status Bubble 0007f0d0: 0c010ac7 jal 0x00042b1c # ROUTINE: Store Three Consecutive Halfwords 0007f0d4: 00673821 addu r7,r3,r7 # Parameter 4: Y Location on Screen + Y Offset 0007f0d8: 02002021 addu r4,r16,r0 # Parameter 1: [Stack pointer] + 0x40 0007f0dc: 27b20030 addiu r18,r29,0x0030 # [Stack pointer] + 0x30 0007f0e0: 02402821 addu r5,r18,r0 # Parameter 2: (Output parameter): [Stack pointer] + 0x30 // stores result of vector multiplication to stack 0007f0e4: 0c00755e jal 0x0001d578 # Get vector*matrix from GTE // Finds true X, Y, Z coordinates of graphic on screen (rotation by camera, shifted by camera + unit + graphic offsets) 0007f0e8: 2626012c addiu r6,r17,0x012c # Parameter 3: (Output parameter): MiscUnitData + 0x12c // stores 0 or 1 here. could this be important for negative vectors? 0007f0ec: 922202de lbu r2,0x02de(r17) # X Location of Status Bubble 0007f0f0: 97a30030 lhu r3,0x0030(r29) # X value of status' vector 0007f0f4: 96240058 lhu r4,0x0058(r17) # MiscUnitData.0x58 //in similar manner to above, this could be an indicator of a negative vector or offset 0007f0f8: 00021600 sll r2,r2,0x18 0007f0fc: 00021603 sra r2,r2,0x18 # X Location (but the compiler is bein dumb) 0007f100: 00641821 addu r3,r3,r4 # X Vector + MiscUnitData.0x58 0007f104: 00431021 addu r2,r2,r3 # X Location + X Vector + MiscUnitData.0x58 (final X location?) 0007f108: 97a30034 lhu r3,0x0034(r29) # Height value of status' vector 0007f10c: a7a20020 sh r2,0x0020(r29) # STACK[0x20] = Final X location 0007f110: 9622005a lhu r2,0x005a(r17) # MiscUnitData.0x5a // negative indicator? 0007f114: 00000000 nop 0007f118: 00621821 addu r3,r3,r2 # Height Vector + MiscUnitData.0x5a 0007f11c: a7a30022 sh r3,0x0022(r29) # STACK[0x22] = Height Vector + MiscUnitData.0x5a 0007f120: 962202e0 lhu r2,0x02e0(r17) # Timer? 0007f124: 00000000 nop 0007f128: 30420010 andi r2,r2,0x0010 # Timer? & 0x10 //perform a function every 0x10 frames? 0007f12c: 10400003 beq r2,r0,0x0007f13c 0007f130: 02002021 addu r4,r16,r0 # Parameter 1 for next call: [Stack pointer] + 0x40 # if ((Timer? & 0x10) != 0) { 0007f134: 2462ffff addiu r2,r3,-0x0001 0007f138: a7a20022 sh r2,0x0022(r29) # STACK[0x22] = STACK[0x34] + MiscUnitData.0x5a - 1 // round negative down only once every 10 frames? # } 0007f13c: 27b00048 addiu r16,r29,0x0048 # [Stack pointer] + 0x48 0007f140: 0c01ee4b jal 0x0007b92c # ROUTINE: ? (0x7b92c) 0007f144: 02002821 addu r5,r16,r0 # Parameter 2: (Output parameter) [Stack pointer] + 0x48 0007f148: 02002021 addu r4,r16,r0 # Parameter 1: [Stack pointer] + 0x48 0007f14c: 02402821 addu r5,r18,r0 # Parameter 2: [Stack pointer] + 0x30 0007f150: 97a2004a lhu r2,0x004a(r29) # STACK[0x4a] 0007f154: 27a60050 addiu r6,r29,0x0050 # Parameter 3: (Output parameter) [Stack pointer] + 0x50 0007f158: 2442000c addiu r2,r2,0x000c # STACK[0x4a] + 12 0007f15c: 0c00755e jal 0x0001d578 # Get_vector_from_GTE (use r4 0x00 0x04) returns vector value at r5 0x00,0x04 and 0x08 0007f160: a7a2004a sh r2,0x004a(r29) # STACK[0x4a] = STACK[0x4a] + 12 0007f164: 8e3002e4 lw r16,0x02e4(r17) # Pointer to status bubble display data for parameter unit 0007f168: 0c011298 jal 0x00044a60 # ROUTINE: ? (0x44a60) 0007f16c: 00000000 nop 0007f170: 8fa30038 lw r3,0x0038(r29) # STACK[0x38] 0007f174: 00000000 nop 0007f178: 04610002 bgez r3,0x0007f184 0007f17c: 00404021 addu r8,r2,r0 # STACK[0x4a] # if (STACK[0x38] < 0) { 0007f180: 24630003 addiu r3,r3,0x0003 # STACK[0x38] = STACK[0x38] + 3 # } 0007f184: 02002021 addu r4,r16,r0 # Parameter 1 for next routine call: Pointer to status bubble display data for parameter unit 0007f188: 00003021 addu r6,r0,r0 # Parameter 3 for next routine call: 0 0007f18c: 27a70020 addiu r7,r29,0x0020 # Parameter 4 for next routine call: [Stack pointer] + 0x20 0007f190: 90850003 lbu r5,0x0003(r4) # Parameter 2 for next routine call: Sprite Type 0007f194: 27a20028 addiu r2,r29,0x0028 0007f198: afa20018 sw r2,0x0018(r29) # STACK[0x18] = (Stack pointer) + 0x28 0007f19c: 00031083 sra r2,r3,0x02 0007f1a0: 00021080 sll r2,r2,0x02 # ((Stack pointer) + 0x28) 0007f1a4: 01021021 addu r2,r8,r2 # STACK[0x4a] + (Stack pointer) + 0x28 0007f1a8: afa00010 sw r0,0x0010(r29) # STACK[0x10] = 0 0007f1ac: afa00014 sw r0,0x0014(r29) # STACK[0x14] = 0 0007f1b0: 0c01ebd1 jal 0x0007af44 # ROUTINE: ? Related to GTE (0x7af44) 0007f1b4: afa2001c sw r2,0x001c(r29) # STACK[0x1c] = STACK[0x4a] + (Stack pointer) + 0x28 0007f1b8: 8fbf0064 lw r31,0x0064(r29) 0007f1bc: 8fb20060 lw r18,0x0060(r29) 0007f1c0: 8fb1005c lw r17,0x005c(r29) 0007f1c4: 8fb00058 lw r16,0x0058(r29) 0007f1c8: 27bd0068 addiu r29,r29,0x0068 0007f1cc: 03e00008 jr r31 0007f1d0: 00000000 nop
Notes on Display bubbles <3 AT Graphic: hardcoded into the routine. XX load location = 114, YY load location = 208 (if first frame), 220 (if second frame) Reraise Graphics: 0x800949e6 = XX Location of graphic, 0x800949fe = YY location of graphic (if second frame, + 0xc) Countdown graphics: 0x80094a0c = XX locations of graphics (+1 per No. turns remaining), 0x80094a24 = YY locations of graphics (+1 per No. turns remaining). applies to dead and doomed units Immortal stars: 0x800949dc = XX location of graphics, 0x800949f4 = YY location of graphics (if second frame, + 0xc) other statuses: 0x800949dc + status bubble = XX locations of graphics, 0x800949f4 + status bubble = YY location of graphics (if second frame, and status bubble is 0x9 or 0xa, + 0xc)