Complex Height Data from unit misc data and coordinates

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search

Instructions and notes

Parameters : r4 = Unit misc data pointer
             r5 = Previous routine stack pointer
                      - 0x00 (X coord.)*28 + Value
                      - 0x02 (Unit tile elevation)					   
                      - 0x04 (Y coord.)*28 + Value
Returns : r2 = Complex height data as negative number depending of
                  - Tile data height/depth/slope
                  - Unit sprite height/riding/float/dead/movement skill (on water)
                  - Unit effect (misc data 0x06)
                  - Unit sprite animation (misc data 0x1dc)
-----------------------------------------------------------------
0007d0d4: 27bdffd8 addiu r29,r29,-0x0028    |
0007d0d8: afb20020 sw r18,0x0020(r29)       |
0007d0dc: 00809021 addu r18,r4,r0           |r18 = Unit's Misc Data Pointer
0007d0e0: afb1001c sw r17,0x001c(r29)       |
0007d0e4: 00a08821 addu r17,r5,r0           |r17 = PR Stack Pointer
0007d0e8: afbf0024 sw r31,0x0024(r29)       |
0007d0ec: afb00018 sw r16,0x0018(r29)       |
0007d0f0: 9245011e lbu r5,0x011e(r18)       |r5 = unit ID +1 (?)
0007d0f4: 00000000 nop                      |
0007d0f8: 10a00012 beq r5,r0,0x0007d144     #If unit ID +1 <> 0x00 #Branch if ? Unit ID = 0
0007d0fc: 27a40010 addiu r4,r29,0x0010           |r4 = Stack Pointer + 0x10
0007d100: 0c05f056 jal 0x0017c158                |-->Calculate_Height_Data Return ID + flag + Coord + Height data on stack (stack is r2 = r29 0x10 here)
0007d104: 24a5ffff addiu r5,r5,-0x0001           |r5 = Unit ID
0007d108: 93a20013 lbu r2,0x0013(r29)            |r2 = Unit ID (from jal)
0007d10c: 00000000 nop                           |
0007d110: 30420080 andi r2,r2,0x0080             |r2 = 0x80 if Unit is invalid/dead/crystal/treasure 
0007d114: 1440000b bne r2,r0,0x0007d144          #If Unit ID is valid/alive
0007d118: 00000000 nop                               | 
0007d11c: 93a20016 lbu r2,0x0016(r29)                |r2 = Total height (tile height + unit height)
0007d120: 00000000 nop                               |
0007d124: 00021023 subu r2,r0,r2                     |r2 = -Total height
0007d128: 00021fc2 srl r3,r2,0x1f                    |r3 = 0x01 if r2 is < 0x00
0007d12c: 00431021 addu r2,r2,r3                     |r2 = - total height + 1
0007d130: 00021043 sra r2,r2,0x01                    |(- Total Height + 1) / 2
0007d134: 00021840 sll r3,r2,0x01                    |(-Total Height + 1) even number (down rounded)
0007d138: 00621821 addu r3,r3,r2                     |(- Total Height + 1) / 2 * 3
0007d13c: 0801f455 j 0x0007d154                      |jump after slope calculation
0007d140: 00038080 sll r16,r3,0x02                   |r16 = (-Total Height + 1) *6 (default is Tile height * 12 + halves*6 + unit height*6)
0007d144: 92250002 lbu r5,0x0002(r17)            |r5 = unit elevation (from PR stack pointer)
0007d148: 0c01f203 jal 0x0007c80c                |-->Slope Calculations returns r2 =  -(Tile height * 12 + halves*Value/28)   (Value is set in previous routine, may be 14 so halves*6)
0007d14c: 02202021 addu r4,r17,r0                |r4 = PR Stack Pointer
0007d150: 00408021 addu r16,r2,r0                |r16 = Zmod (from height and slope)
0007d154: 8e420134 lw r2,0x0134(r18)             |r2 = Unit Data pointer
0007d158: 00000000 nop                           |
0007d15c: 10400052 beq r2,r0,0x0007d2a8          #If Unit data pointer is valid /Else branch to near end (no depht calculation)
0007d160: 3c079249 lui r7,0x9249                     | 
0007d164: 96220000 lhu r2,0x0000(r17)                |r2 = unit X mod (X coord *28)+14
0007d168: 34e72493 ori r7,r7,0x2493                  |r7 = (-3/7)*2^32
0007d16c: 00021400 sll r2,r2,0x10                    |
0007d170: 00022c03 sra r5,r2,0x10                    |r5 = Unit X mod (upper register cleared)
0007d174: 00a70018 mult r5,r7                        |Unit X mod * (-3/7)*2^32
0007d178: 96230004 lhu r3,0x0004(r17)                |r3 =  Unit Y mod (Y coord *28)+14
0007d17c: 00002010 mfhi r4                           |r4 = Unit X mod * -3/7
0007d180: 00031c00 sll r3,r3,0x10                    |
0007d184: 00033403 sra r6,r3,0x10                    |r6 = Unit Y mod (upper register cleared)
0007d188: 00c70018 mult r6,r7                        |Unit Y mod * (-3/7)*2^32
0007d18c: 000217c3 sra r2,r2,0x1f                    |r2 = 0x00 (technically 0x01 if X mod > 2^31)
0007d190: 00031fc3 sra r3,r3,0x1f                    |r3 = 0x00
0007d194: 00852021 addu r4,r4,r5                     |r4 = Unit X mod * 4/7
0007d198: 00042103 sra r4,r4,0x04                    |r4 = Unit X mod / 28 ( = Unit X coord)
0007d19c: 00822023 subu r4,r4,r2                     |r4 = r4 -0x00
0007d1a0: 00042400 sll r4,r4,0x10                    |
0007d1a4: 00042403 sra r4,r4,0x10                    |r4 = Unit X coord (rounded and upper register cleared)
0007d1a8: 00002810 mfhi r5                           |r5= Unit Y mod * -3/7
0007d1ac: 00a62821 addu r5,r5,r6                     |r5= Unit Y mod * 4/7
0007d1b0: 00052903 sra r5,r5,0x04                    |r5 = Unit Y mod / 28 ( = Unit Y coord)
0007d1b4: 00a32823 subu r5,r5,r3                     |
0007d1b8: 00052c00 sll r5,r5,0x10                    |
0007d1bc: 86260002 lh r6,0x0002(r17)                 |r6 = Unit Elevation
0007d1c0: 0c060fed jal 0x00183fb4                    |-->Get_Tile_Data_Pointer return r2 = Tile data pointer
0007d1c4: 00052c03 sra r5,r5,0x10                    |r5 = Unit Y coord (rounded and upper register cleared)
0007d1c8: 00408821 addu r17,r2,r0                    |r17 = Unit tile data pointer
0007d1cc: 92220003 lbu r2,0x0003(r17)                |r2 = Unit Tile Hieght + depht
0007d1d0: 00000000 nop                               |
0007d1d4: 304200e0 andi r2,r2,0x00e0                 |r2 = Unit Tile depht
0007d1d8: 10400033 beq r2,r0,0x0007d2a8              #If depht <> 0x00 /Else branch near end (no depht modification)
0007d1dc: 00000000 nop                                   | 
0007d1e0: 8e440134 lw r4,0x0134(r18)                     |r4 = Unit data pointer
0007d1e4: 0c05fc08 jal 0x0017f020                        |-->Float/Float/Fly movements Returns r2 holding flags depending on movement skills
0007d1e8: 00000000 nop                                   |
0007d1ec: 00402021 addu r4,r2,r0                         |r4 = Movements flags
0007d1f0: 30820040 andi r2,r4,0x0040                     |r2 = 0x40 if unit uses/have float
0007d1f4: 964301dc lhu r3,0x01dc(r18)                    |r3 = Unit current animation
0007d1f8: 92450006 lbu r5,0x0006(r18)                    |r5 = Unit spritesheet ID
0007d1fc: 14400020 bne r2,r0,0x0007d280                  #If unit don't use float /Else branch (will add depht to height)
0007d200: 00031842 srl r3,r3,0x01                        |r3 = Unit current animation/2 (?)
0007d204: 30820020 andi r2,r4,0x0020                         |r2 = 0x20 if unit uses move on water
0007d208: 1440001d bne r2,r0,0x0007d280                      #If unit doesn't uses move on water /Else branch (will add depht to height)
0007d20c: 24a2ff64 addiu r2,r5,-0x009c                           |r2 = Unit spritesheet ID - 0x9c
0007d210: 2c420002 sltiu r2,r2,0x0002                            |r2 = 0x01 if unit sprite ID was 0x9c or 0x9d (EFF1 and EFF2 ?)
0007d214: 1040000b beq r2,r0,0x0007d244                          #If EFF spritesheet
0007d218: 30820010 andi r2,r4,0x0010                             |r2 = 0x10 if unit uses walk in water
0007d21c: 92230003 lbu r3,0x0003(r17)                                |r3 = Unit tile halves + depht
0007d220: 26040004 addiu r4,r16,0x0004                               |r4 = -(Height data) + 0x04 (minoring height)
0007d224: 00031942 srl r3,r3,0x05                                    |r3 = Unit tile effective depht  (Unit tile halves + depht)/32   (only keep depht data : 0x80 = 0x04)
0007d228: 00031040 sll r2,r3,0x01                                    |r2 = Unit Tile effective depht * 2
0007d22c: 00431021 addu r2,r2,r3                                     |r2 = Unit Tile effective depht * 3
0007d230: 96430074 lhu r3,0x0074(r18)                                |r3 = ?? From misc unit data (height related)
0007d234: 00021080 sll r2,r2,0x02                                    |r2 = Unit tile effective depht * 12
0007d238: 00431021 addu r2,r2,r3                                     |r2 = Unit tile depht * 12 + Unit Height related value
0007d23c: 0801f4ae j 0x0007d2b8                                      >>Jump
0007d240: 00828023 subu r16,r4,r2                                    |r16 = (Final Height data)  =  -(Total Height data) -( Tile Depht * 12 + Unit height related value)
0007d244: 14400004 bne r2,r0,0x0007d258                          # Else if unit don't use move in water #(Spritesheet is not WEP1 nor WEP2)
0007d248: 00000000 nop                                               | 
0007d24c: 3402001a ori r2,r0,0x001a                                  | r2 = 0x1a
0007d250: 14620006 bne r3,r2,0x0007d26c                              #If unit animation/2 = 0x1a  (animation 0x34 = dying, 0x35 been raised)
0007d254: 00000000 nop                                                   | 
0007d258: 92220003 lbu r2,0x0003(r17)                            #E      |r2 = Unit tile halves + depht (or Unit move in water)
0007d25c: 00000000 nop                                                   | 
0007d260: 00021142 srl r2,r2,0x05                                        |r2 = Unit tile effective depht  (Unit tile halves + depht)/32   (only keep depht data : 0x80 = 0x04)
0007d264: 0801f4a3 j 0x0007d28c                                          >>jump to *12 section (depht is downed by 1)
0007d268: 2442ffff addiu r2,r2,-0x0001                                   |r2 = Unit tile effective depht - 1 
0007d26c: 3402009e ori r2,r0,0x009e                                  #Else (animation/2 <> 0x1a) r2 = 0x9e
0007d270: 10a20003 beq r5,r2,0x0007d280                              #If spritesheet ID <> 0x9e (not trap ?)
0007d274: 3402009b ori r2,r0,0x009b                                      |r2 = 0x009b
0007d278: 14a2000b bne r5,r2,0x0007d2a8                                  #If spritesheet ID = 0x9b (WEP2 ?)
0007d27c: 00000000 nop                                                   |    
0007d280: 92220003 lbu r2,0x0003(r17)                    #E #E #E            |r2 = Unit tile halves + depht (Unit floating, moving on water,trap, WEP2)
0007d284: 00000000 nop                                                       | 
0007d288: 00021142 srl r2,r2,0x05                                            |r2 = Effective depht
0007d28c: 00021840 sll r3,r2,0x01                                            |r3 = Effective depht * 2 (dying, raised landing location)
0007d290: 00621821 addu r3,r3,r2                                             |r3 = Effective depht * 3
0007d294: 96420074 lhu r2,0x0074(r18)                                        |2 = ?? From misc unit data (height related)
0007d298: 00031880 sll r3,r3,0x02                                            |r3 = Effective depht * 12
0007d29c: 00621821 addu r3,r3,r2                                             |r3 = Effective depht * 12 + Unit height related value
0007d2a0: 0801f4ae j 0x0007d2b8                                              >>Jump to end
0007d2a4: 02038023 subu r16,r16,r3                                           |r16 = Final Height data = -(Total height data + depht *12 + unit height related value)
0007d2a8: 96420074 lhu r2,0x0074(r18)            #E #E                   #Else r2 = ?? From misc unit data (Invalid Unit data pointer, no depht, spritesheet <> 0x9b)
0007d2ac: 00000000 nop                           |   
0007d2b0: 02021023 subu r2,r16,r2                |r2 = -(Total height data + unit height related value)
0007d2b4: 00408021 addu r16,r2,r0                |r16 =  -(Total height data + unit height related value)
0007d2b8: 00101400 sll r2,r16,0x10               |r2 = -(Final Height data)*1024 (landing site of depht managing)
0007d2bc: 00021403 sra r2,r2,0x10                |r2 = -(Final Height data)  (register cleanup)
0007d2c0: 8fbf0024 lw r31,0x0024(r29)            |
0007d2c4: 8fb20020 lw r18,0x0020(r29)            |
0007d2c8: 8fb1001c lw r17,0x001c(r29)            |
0007d2cc: 8fb00018 lw r16,0x0018(r29)            |
0007d2d0: 27bd0028 addiu r29,r29,0x0028          |
0007d2d4: 03e00008 jr r31                        END
0007d2d8: 00000000 nop

Details

Data is returned as a negative number 

Basic Height Data
- Default : -(Tile height * 12 + Halves * 6 + unit height*6) (if floating effective height + 1 )
- Unit Dead/treasure/crystal or invalid : slope calc (if preset is 14 = -(Height*12 + Halves*6))

Final height data (order matters)
- Float/ Move on water 
    = Height data + Depht *12 + Unit misc 0x74
- If Unit Unit spritesheet (misc 0x06) = EFF1 or EFF2
    = (Height data -4) + Depht *12 + Unit misc 0x74 
- Move in water or Unit animation = dying or raised [(misc 0x1dc)/2 = 0x1a]
    = Height data + (Depht-1)*12 + Unit misc 0x74 
- Unit spritesheet (misc 0x06) if WEP2 or Trap
    = Height data + Depht *12 + Unit misc 0x74
- Else or unit invalid (not floating, not on/in water, not EFF1, EFF2, WEP2, Trap , not dying or raised)
    = Height data
  
Rq unit misc 0x74 might be related to depht (if not, depht will be added twice as it is already count in Default height data)

Return locations

0007d30c: 0007d2dc_-_0007d34c
0007d3b4: 0007d350_-_0007d3f0
0007d438: 0007d3f4_-_0007d474
0007d4dc: 0007d478_-_0007d518
0007d590: Get_Final_Height_data_from_unit_misc_data  X and Y preset values = 14