Display Status Bubble

From Final Fantasy Hacktics Wiki
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)