User Tools


Levels

Levels are contained in two gzip blocks. e.g.: chimp.raw: level data for Simian Acres chimp_dl.raw: display lists for Simian Acres

The level data begins with a header that contains the offsets in the file for all of the level information (RDUs, buildings, vehicles, etc.). The level data file also contains vertices and other data used by the display list that are loaded into segment 08.

The display list contains mostly raw F3D commands. The exception is 0xFD G_SETTIMG command which contain indexes to a texture table. At run-time, after the display list is copied to RAM, the texture indexes in the G_SETTIMG are replaced with texture offsets in segment 0x00.

List of Levels

The function at 0x8025615C is used to lookup and copy the level data files from level ID and is implemented as a switch statement with the following lookup:

ID JmpTable Start End Name gzip Level Name
0 802561B8 4ACC10 4B8960 chimp.raw Simian Acres
1 80256194 4A5660 4ACC10 lagp.raw Angel City
2 802561DC 4B8960 4BFD60 valley.raw Outland Farm
3 80256200 4BFD60 4C3AC0 fact.raw Blackridge Works
4 80256224 4C3AC0 4D5F90 dip.raw Glory Crossing
5 80256248 4D5F90 4E2F70 beetle.raw Shuttle Gully
6 8025626C 4E2F70 4E4E80 bonus1.raw Salvage Wharf
7 80256290 4E4E80 4E7C00 bonus2.raw Skyfall
8 802562B4 4E7C00 4E8F70 bonus3.raw Twilight Foundry
9 802562D8 4E8F70 4F5C10 level9.raw Crystal Rift
10 802562FC 4F5C10 500520 level10.raw Argent Towers
11 80256320 500520 507E80 level11.raw Skerries
12 80256344 507E80 511340 level12.raw Diamond Sands
13 80256368 511340 523080 level13.raw Ebony Coast
14 8025638C 523080 52CD00 level14.raw Oyster Harbor
15 802563B0 52CD00 532700 level15.raw Carrick Point
16 802563D4 532700 53E9B0 level16.raw Havoc District
17 802563F8 53E9B0 54A820 level17.raw Ironstone Mine
18 8025641C 54A820 552DE0 level18.raw Beeton Tracks
19 80256440 552DE0 555000 level19.raw J-Bomb
20 80256464 555000 560E90 level20.raw Jade Plateau
21 80256488 560E90 5652D0 level21.raw Marine Quarter
22 802564AC 5652D0 56F3F0 level22.raw Cooter Creek
23 802564D0 56F3F0 5721E0 level23.raw Gibbon's Gate
24 802564F4 5721E0 5736E0 level24.raw Baboon Catacomb
25 80256518 5736E0 57A2C0 level25.raw Sleek Streets
26 8025653C 57A2C0 580B60 level26.raw Obsidian Mile
27 80256560 580B60 588CE0 level27.raw Corvine Bluff
28 80256584 588CE0 58BE80 level28.raw Sideswipe
29 802565A8 58BE80 597B80 level29.raw Echo Marches
30 802565CC 597B80 59B7D0 level30.raw Kipling Plant
31 802565F0 59B7D0 5A5840 level31.raw Falchion Field
32 80256614 5A5840 5B0B10 level32.raw Morgan Hall
33 80256638 5B0B10 5B5A30 level33.raw Tempest City
34 8025665C 5B5A30 5B8BB0 level34.raw Orion Plaza
35 80256680 5B8BB0 5C4C80 level35.raw Glander's Ranch
36 802566A4 5C4C80 5CA9C0 level36.raw Dagger Pass
37 802566C8 5CA9C0 5CCF50 level37.raw Geode Square
38 802566EC 5CCF50 5D1060 level38.raw Shuttle Island
39 80256710 5D1060 5DC830 level39.raw Mica Park
40 80256734 5DC830 5E6EE0 level40.raw Moon
41 80256758 5E6EE0 5EC800 level41.raw Cobalt Quarry
42 8025677C 5EC800 5F3A80 level42.raw Moraine Chase
43 802567A0 5F3A80 6014B0 level43.raw Mercury
44 802567C4 6014B0 60A710 level44.raw Venus
45 802567E8 60A710 613AA0 level45.raw Mars
46 8025680C 613AA0 61DD70 level46.raw Neptune
47 80256830 61DD70 621AF0 level47.raw CMO Intro
48 80256854 621AF0 6269E0 level48.raw Silver Junction
49 80256878 6269E0 630C30 level49.raw End Sequence
50 8025689C 630C30 635700 level50.raw Shuttle Clear
51 802568C0 635700 63CA10 level51.raw Dark Heartland
52 802568E4 63CA10 641F30 level52.raw Magma Peak
53 80256908 641F30 644810 level53.raw Thunderfist
54 8025692C 644810 646080 level54.raw Saline Watch
55 80256950 646080 647550 level55.raw Backlash
56 80256974 647550 654FC0 level56.raw Bison Ridge
57 80256998 654FC0 660950 level57.raw Ember Hamlet
58 802569BC 660950 665F80 level58.raw Cromlech Court
59 802569E0 665F80 66C900 level59.raw Lizard Island

Level Header

The level header is 0xC8 bytes long. Immediately following the level header at offset 0xC8 is the display data loaded into segment 8. A pointer to this display list is also stored at 0x80364458.

Offset Size Type Description
0x00 2 unsigned TODO stored to 0x803BE714, stored to (*0x803C2B88)→h4, passed through s4
0x02 2 unsigned TODO stored to 0x803BE716, stored to (*0x803C2B88)→h6
0x04 2 unsigned TODO « 5, stored to word 0x803BE70C, passed through s7
0x06 2 unsigned TODO « 5, stored to word 0x803BE710, passed through t8
0x08 2 unsigned TODO stored to 0x803BE720
0x0A 2 unsigned TODO stored to 0x803BE722, handled in proc_802A4464
0x0C 2 unsigned TODO « 5, stored to word 0x803BE718
0x0E 2 unsigned TODO « 5, stored to word 0x803BE71C
0x10 2 unsigned TODO stored to 0x803BE72C, handled in proc_802A3D54, proc_802A3DF8
0x12 2 unsigned TODO stored to 0x803BE72E, handled in proc_802A3D54, proc_802A3DF8
0x14 2 unsigned TODO « 5, stored to word 0x803BE724
0x16 2 unsigned TODO « 5, stored to word 0x803BE728
0x18 4 signed gravity related (-4 normal, -2 planets), converted to float stored in 0x803EBBF0
0x1C 4 unsigned (1: normal, 0: dip, level18, level20, level34, level43, level9), stored to byte 0x803BE739
0x20 4 unsigned Ammo boxes (Ballista and Sideswipe)
0x24 4 unsigned Y Collision
0x28 4 unsigned Communication Point
0x2C 4 unsigned Animated textures (water, lava, barricades)
0x30 4 unsigned Terrain
0x34 4 unsigned RDUs
0x38 4 unsigned TNT crates
0x3C 4 unsigned Square blocks and holes
0x40 4 unsigned Bounding boxes?
0x44 4 unsigned Bounding boxes?
0x48 4 unsigned TODO
0x4C 4 unsigned Level bounds?
0x50 4 unsigned Vehicles
0x54 4 unsigned Missile carrier settings
0x58 4 unsigned Unused? (only in lagp and level26)
0x5C 4 unsigned Buildings
0x60 4 unsigned Unused (only in chimp and lagp)
0x64 4 unsigned X/Z Collision (prevent walking over ledge)
0x68 4 unsigned Train platform and stopping zones
0x6C 4 unsigned X/Z Collision (level perimeter, trees, walls)
0x70 4 unsigned X/Z Player collision
0x74 4 unsigned TODO
0x78 4 unsigned TODO
0x7C 4 TODO TODO
0x80 4 TODO TODO
0x84 4 TODO TODO
0x88 4 TODO TODO
0x8C 4 TODO TODO
0x90 4 unsigned handled in proc_802A1C88 offset to F3D DL
0x94 4 unsigned handled in proc_802A1C88 offset to F3D DL
0x98 4 unsigned handled in proc_802A1C88 offset to F3D DL
0x9C 4 unsigned handled in proc_802A1C88 offset to F3D DL
0xA0 4 TODO TODO
0xA4 4 TODO TODO
0xA8 4 TODO TODO
0xAC 4 TODO TODO
0xB0 4 TODO TODO
0xB4 4 TODO TODO
0xB8 4 TODO TODO
0xBC 4 TODO TODO
0xC0 4 TODO TODO

Level Data

0x20: Ammo

Ballista missile and Sideswipe hydraulic boxes

[XX XX] [YY YY] [ZZ ZZ] [TT TT]
X,Y,Z position of box
T type of box (0 = Ballista missile, 1 = Sideswipe hydraulic)

Example: Argent Towers / level10:

0AD8 002C 13AB 0000 
0AD8 002C 1379 0000 
0AA6 002C 1379 0000

0x24: Y Collision

These are additional collision triangles set up to prevent J-Bomb from clipping through structures from above. In levels that contain the J-Bomb, triangles are drawn around the semi, tunnels, and other things it probably shouldn't mess with from above. Also, the large gray area surrounding the crane in Ironstone Mine is defined with these.

[X1 X1] [Y1 Y1] [Z1 Z1] [X2 X2] [Y2 Y2] [Z2 Z2] [X3 X3] [Y3 Y3] [Z3 Z3] [?? ??]
X1,Y1,Z1
X2,Y2,Z2
X3,Y3,Z3
three 3D coordinates that define a triangle
? TODO padding? always 0

Example Argent Towers / level10: 010420-010470

03EF 0109 119D 0395 0109 119D 0395 0108 12AB 0000
03EF 0109 119D 0395 0108 12AB 03EF 0108 12AB 0000 
0675 00DA 12A9 0701 00DA 12FE 06ED 00DA 131F 0000 
0675 00DA 12A9 0661 00DA 12CB 06ED 00DA 131F 0000

0x28: Communication Point

[XX XX] [YY YY] [ZZ ZZ] [AA AA]
X,Y,Z position of communication point
A Always 0, if 1 animates spinning dish before touched

Example Argent Towers / level10: 010470-010480

067F 00BA 0C23 0000 
0813 00A5 08A0 0000

0x2C: Animated Textures

{[W0 W0 W0 W0] [CC] [B5] [B6] [??] [??] [??] [??] [??] {[TT TT TT TT]}}
W0 Texture ID used in lookup
C count of records to follow (+1)
B5 *0x803C3240 = B5 ? *(B5*4+V0+8) : 0x0
B6 stored to 0x803C324A, if not 0, compares 'C' with 'A5'
? TODO
T texture index, overwritten with address

further handled by proc_802A1C20() proc_802A0CFC(T6) - some lookup and DMA

W0 read by proc_802A50DC at 802A510C proc_802A4E4C → proc_802A50DC

Levels containing 0x2C:

  • Angel City lagp
  • Blackridge Works fact
  • Salvage Warf bonus1
  • Argent Towers level10
  • Skerries level11
  • Ebony Coast level13
  • Oyster Harbor level14
  • Carrick Point level15
  • Havoc District level16
  • Marine Quarter level21
  • Cooter Creek level22
  • Sleek Streets level25
  • Obsidian Mile level26
  • Corvine Bluff level27
  • Sideswipe level28
  • Echo Marches level29
  • Glander's Ranch level35
  • Dagger Pass level36
  • Magma Peak level52
  • Lizard Island level59

Example Argent Towers / level10: 010480-0104D0

{0000002F 03 00 00 00 00 0A 00 00 {00000614 00000614}}  --> converted to 000965C0 000965C0
{00000032 03 00 00 00 00 0A 00 00 {00000615 00000615}}  --> converted to 000975C0 000975C0
{00000033 03 00 00 00 00 0A 00 00 {00000616 00000616}}  --> converted to 000945C0 000945C0
{00000043 03 00 00 00 00 0A 00 00 {00000617 00000617}}  --> converted to 000955C0 000955C0

614,615,616,617 are texture IDs for flashing road barricade

Example Magma Peak / level52: 005800-005838

{00000205 03 00 01 00 00 0F 00 00 {00000A82 00000A83}}
{00000202 02 00 01 00 00 0E 00 00 {00000A84}}
{00000200 03 00 01 00 00 0F 00 00 {00000633 00000634}}

A82,A83,A84 is animated magma 633,634 is water animated waves

Example Lizard Island / level59: 0092A0-0092C4

{00000201 03 00 01 00 00 0F 00 00 {00000A82 00000A83}}
{00000202 02 00 01 00 00 0E 00 00 {00000A85}}

A82,A83 is animated magma A85 is glowing rock

0x30: Terrain

Two halfwords from 0x08 and 0x0A in the level header are multiplied to get the count of the number of groups in this list. Each group contains multiple triangles and is stored to an array at 0x803BDB10. Triangles are overlapped between groups.

[EE EE EE EE] {[X1 X1] [Y1 Y1] [Z1 Z1] [X2 X2] [Y2 Y2] [Z2 Z2] [X3 X3] [Y3 Y3] [Z3 Z3] [AA] [BB]}
E end offset of this group of triangles
X1,Y1,Z1
X2,Y2,Z2
X3,Y3,Z3
triangle vertices for terrain data
A Terrain type
01: low traction / dirt
02: high traction, high speed / roads, rails
03: high traction, medium speed / grass
05: slow speed / ponds
67: high traction, high speed / gravel lots (similar to roads?)
B TODO byte at offset 0x13 flag?

proc_802A4464()

Example Simian Acres / chimp: 010258-01B6B4

000: 000000F4    
004: 03FA 00B6 031E  0328 00B2 0332  0332 00C1 064A  03 00
018: 03FA 008C 031E  03FA 008C 0596  052E 008C 058B  03 00
02C: 03FA 00B6 031E  0332 00C1 064A  03FA 00B6 0596  03 00 
040: 03FA 008C 031E  03FA 00B6 031E  03FA 008C 0596  02 00
054: 03FA 00B6 031E  03FA 00B6 0596  03FA 008C 0596  02 00
068: 03FA 00B6 031E  0332 00C1 064A  03FA 00B6 0596  03 00 
07C: 03FA 008C 031E  03FA 00B6 031E  03FA 008C 0596  02 00 
090: 03FA 00B6 031E  03FA 00B6 0596  03FA 008C 0596  02 00 
0A4: 0359 008C 01DC  035A 008C 01E1  073F 008C 0579  03 00  
0B8: 035A 008C 01E1  052E 008C 058B  073F 008C 0579  03 00 
0CC: 053B 0078 014D  0332 008C 018E  073F 008C 0579  03 00 
0E0: 0332 008C 018E  0359 008C 01DC  073F 008C 0579  03 00 
0F4: 0000029C
0F8: 03FA 008C 031E  03FA 008C 0596  052E 008C 058B  03 00 
10C: 0359 008C 01DC  035A 008C 01E1  073F 008C 0579  03 00 
120: 035A 008C 01E1  052E 008C 058B  073F 008C 0579  03 00 
134: 073F 008C 0579  0723 008C 0237  06DA 008C 014D  03 01  
148: 06DA 008C 014D  053B 0078 014D  073F 008C 0579  03 01 
15C: 053B 0078 014D  0332 008C 018E  073F 008C 0579  03 00
...

0x34: RDUs

[XX XX] [YY YY] [ZZ ZZ]
X,Y,Z position of RDU

proc_802A1674() → proc_8026FBB0(A0, A1)

six halfwords copied out to struct array at 801DC508 *0x8036bed8 + (halfword at 0x8036eb90 * 0x88)

Example Simian Acres / chimp: 01B6B4-01B90C

07E2 0013 0AC8 
07A6 0013 0AC8 
07DD 0016 0A4B 
07A1 0016 0A4B 
079B 0017 09DA 
...

0x38: TNT crates

[XX XX] [YY YY] [ZZ ZZ] [EE] [TT] [H8 H8] [PP PP]
X,Y,Z position of TNT crate
E texture
T explosion timer (~2-2.5s * this value)
(T * 60) stored to halfword (T9 + 0x8039B080)
H8 TODO halfword stored to (T1 + 0x8039B08A)
P power of TNT (also affects blast radius)

proc_8028D4C0(A0, A1)

Example Simian Acres / chimp: 01B90C-01B924

08B3 0012 0B78 00 05 0001 0834 
097D 0012 0D82 00 05 0001 0834

0x3C: Square Blocks

[NN NN] {[XX XX] [YY YY] [ZZ ZZ] [T1] [T2] (HH HH) {[X1 X1] [Y1 Y1] [Z1 Z1]... [AA] [BB] [CC] [DD]}}
N number of square blocks in group, stored as word to 0x8039C710
X « 5 stored to 0x8039C550 + 56*SP[1C]
Y « 5 stored to 0x8039C554 + 56*SP[1C]
Z « 5 stored to 0x8039C558 + 56*SP[1C]
T1 if 'T2' is 8, this is type of block, stored to 0x8039C7F8
T2 block = 0/1/2, hole = 8
H TODO if 'T2' is 8, this flag is present (either 1 or 0)
X1,Y1,Z1
X2,Y2,Z2
X3,Y3,Z3
if 'T2' is 8, then eight triangles follow
A,B,C,D TODO flags? normals?

proc_8028FDA0()

Example Argent Towers / level10: 01C41C-01C4E2

[0001] 
  0A16 00A4 0BB0 00 00
[0001] 
  0985 00A4 17BF 00 08 0000
  09AB 0095 179B 
  095D 0095 179B 
  095D 00B3 179B 
  07 FD 01 00 
  09AB 00B3 179B 
  09AB 0095 179B 
  095D 00B3 179B 
  07 FD 01 00 
  09AB 0095 17E9 
  09AB 0095 179B 
  09AB 00B3 179B 
  0B FF 00 00 
  09AB 00B3 17E9 
  09AB 0095 17E9 
  09AB 00B3 179B 
  0B FF 00 00 
  095D 0095 179B 
  095D 0095 17E9 
  095D 00B3 17E9 
  0B FE 01 00 
  095D 00B3 179B 
  095D 0095 179B 
  095D 00B3 17E9 
  0B FE 01 00 
  095D 0095 17E9 
  09AB 0095 17E9 
  09AB 00B3 17E9 
  07 FD 00 00 
  095D 00B3 17E9 
  095D 0095 17E9 
  09AB 00B3 17E9 
  07 FD 00 00

0x40: Bounding Boxes

some bounding boxes

[X1 X1] [Z1 Z1] [X2 X2] [Z2 Z2] [?? ??]
X1,Z1 lower X,Z of box
X2,Z2 upper X,Z of box
? TODO Y? type?
proc_802A5510() {
   t2 = *0x803643E0;
   t3 = *0x803643E8;
   t1 = a0 + *(a0 + 0x40);
   t5 = a0 + *(a0 + 0x44);
   t6 = -1;
   t2 >>= 5;
   t3 >>= 5;
   while (t1 != t5) {
      t4 = *(u16*)(0 + t1);
      if (t2 >= t4) {
         t4 = *(u16*)(2 + t1);
         if (t3 >= t4) {
            t4 = *(u16*)(4 + t1);
            if (t4 >= t2) {
               t4 = *(u16*)(6 + t1);
               if (t4 >= t3) {
                  v0 = *(u16*)(8 + t1);
                  if (v0 >= t6) {
                     t6 = v0;
                  }
               }
            }
         }
      }
      t1 += 10;
   }
   if (at == 0xBB8) {
      *(u8*)0x80364411 = 1;
   } else {
      t1 = *(u16*)(0x80364450);
      t6 <<= 5;
      t6 += t1;
      *(u16*)0x8036444E = t6;
      *(u8*)0x80364411 = 0;
   }
}

Example Simian Acres / chimp: 01B924-01BA14

00D2 041A 1072 1B8A 00A9 
07DA 0ABE 096A 0B86 00F9 
064A 0ABE 0776 0C4E 00F9 
0456 0ABE 051E 0BEA 00F9 
07DA 0C4E 083E 0D16 00F9 
064A 0CB2 0712 0E42 00F9 
0712 0DDE 096A 0EA6 00F9 
0776 0D16 083E 0DDE 00F9 
07DA 0C4E 08A2 0D16 00F9 
05E6 0EA6 06AE 1036 00F9 
051E 1036 064A 10FE 00F9 
0712 0F6E 08A2 0FD2 00F9 
096A 0E42 0A32 0F0A 00F9 
09CE 0F6E 0A96 109A 00F9 
0906 109A 09CE 1162 00F9 
083E 10FE 0906 122A 00F9 
0712 1162 07DA 12F2 00F9 
08A2 0F6E 096A 1036 00F9 
0A32 0DDE 0AFA 0EA6 00F9 
0712 109A 083E 10FE 00F9 
0712 0FD2 0776 109A 00F9 
09CE 0CB2 0A96 0DDE 00F9 
0C8A 041A 1072 1B8A 012F 
0AFA 041A 0C8A 0C4E 012F

0x44: Bounding Boxes

some bounding boxes

[X1 X1] [Z1 Z1] [X2 X2] [Z2 Z2] [?? ??]
X1,Z1 lower X,Z of box
X2,Z2 upper X,Z of box
? TODO Y? type?

proc_802A5604()

Example Simian Acres / chimp: 01BA14-01BA46

00D2 0AD5 1072 1B8A 0059 
01FE 0B22 051E 18CE 0099 
051E 128E 0776 18CE 0067 
08A2 0CB2 0E1A 18CE 007B 
00D2 0305 1072 0AD5 0121

0x48: TODO

some u32s?

Example Simian Acres / chimp: 01BA46-01BA8E

000000B6 000000B6 000000D5 000000D5 
000000D2 000000EC 000000F2 00000073 
00000101 000000F2 000000B6 000000E9 
000000B6 000000B6 000000E9 00000000 
00000062 00000062

0x4C: TODO

level bounds? two points X1,Z1 and X2,Z2

[X1 X1] [Z1 Z1] [X2 X2] [Z2 Z2]
// set in
proc_802A2D68() {
   ...
   *0x803BE730 = *(0 + t1);
   *0x803BE734 = *(2 + t1);
   *0x803BE732 = *(4 + t1);
   *0x803BE736 = *(6 + t1);
   ...
}
 
// compared in
proc_802A8CCC() {
  if ((t2 >= *0x803BE730 && t2 <= *0x803BE732) &&
      (t3 >= *0x803BE734 && t3 <= *0x803BE736)) {
      ...
   }
}

Example Simian Acres / chimp: 01BA8E

009E 011B 10B9 1FA8

0x50: Vehicles

records 9 bytes each

[TT] [XX XX] [YY YY] [ZZ ZZ] [HH HH]
T vehicle type (see vehicles)
X,Y,Z position of vehicle
H heading
N/+Z: 0x0
W/+X: 0x400
S/-Z: 0x800
E/-X: 0xC00

proc_802A350C() → proc_802A396C(T3=id)

Example Simian Acres / chimp: 01BA96-01BABA

00 08C0 008C 0801 0000 // player, north
04 08C0 008C 0801 002D // bulldozer, slightly west of north
07 073C 0014 0B01 0400 // train, west
08 0685 0014 0AFC 0400 // hotrod, west

0x54: Missile Carrier

Missile carrier settings. proc_802A303C()

[SS] [XX XX] [ZZ ZZ] [HH HH] [DD DD] [??]
S speed
X,Z X,Z start position
H heading
N/+Z: 0x0
W/+X: 0x400
S/-Z: 0x800
E/-X: 0xC00
D distance carrier travel to complete level
? unused?

Example Simian Acres / chimp: 01BABA

1C 07BC 07E2 0000 0BB8 00

0x58: Unused?

8 bytes of data, only used in two levels, both with same data

Angel City / lagp: 0144CC Obsidian Mile / level26: 01201E

0B3F 0101 0581 0000

if read as X,Y,Z coordinates, lower left corner, up high

0x5C: Buildings

proc_802A1D54()

[XX XX] [YY YY] [ZZ ZZ] [TT TT] [CC] [B9] [BB BB] [SS SS]
X,Y,Z position of object
T type
C if 1, increase 'destroyed buildings' counter
B9 TODO stored to t4→b6
B behavior
1: vertical
2: circle
3: horizontal
4: follow player
5: rotation 90
S speed (for moving objects)

Simian Acres / chimp: 01BAC4-01BCD8

07E0 0014 0AEA 001E 00 00 0000 0000 
07E0 0014 0B1C 001E 00 00 0000 0000 
07A7 0014 0AEA 001E 00 00 0000 0000 
07A7 0014 0B1C 001E 00 00 0000 0000 
06D3 0012 0B8E 0020 00 04 0000 0000 
0777 0012 0B1F 0021 00 00 0000 0000 
07E1 0012 0CA2 0023 01 03 0000 0000 
080D 0012 0C99 0024 00 00 0000 0000 
0814 0012 0C78 0025 00 00 0000 0000 
0873 0012 0D77 0026 00 00 0000 0000 
087B 0012 0C8E 0027 00 00 0000 0000 
07A4 0012 0DB5 002A 01 00 0000 0000 
0798 0012 0D39 002B 00 00 0000 0000 
078F 0012 0E8A 002C 01 04 0000 0000 
0724 0014 0ECD 002D 00 00 0000 0000 
067B 0013 0E4F 0030 00 00 0000 0000 
...

0x60: Unused?

Probably unused. Data in chimp shows 5 points under bridge. Data in lagp looks like zig-zag lamp post pattern. first byte stored to 0x80364a6e, variable length records after that

[H0 H0] [H2 H2] [H4 H4] [H6 H6] [B8] [B9] {**} [GG] [HH]
H0 TODO u16 « 5, stored as word to (0 + t3)
H2 TODO u16 « 5, stored as word to (4 + t3)
H4 TODO u16 « 5, stored as word to (8 + t3)
H6 TODO u16 « 5, stored as word to (C + t3)
B8 TODO stored to (0x10 + t3)
B9 TODO stored to (0x13 + t3), used as count for next bytes
* TODO 'B9' number of bytes, stored to t5
G TODO stored to (0x11 + t3)
H TODO stored to (0x14 + t3)
1 stored to (0x12 + t3)

proc_802A2C54() t3 = 0x803BDFD8 t5 = t3 + 0x15

Example Simian Acres / chimp: 01BCD8-01BD24

FF
07B9 003A 083A 002D 01 03 {04 08 FF} 00 96 
07D5 0046 083A 002D 01 03 {04 08 FF} 00 96 
07F3 0053 083A 002D 01 03 {04 08 FF} 00 96 
079B 0046 083A 002D 01 03 {04 08 FF} 00 96 
077D 0053 083A 002D 01 03 {04 08 FF} 00 96

0x64: X/Z Collision Walls

Walls to restrict player movement off edges.

[B0] [CC] {BN*} [TT] {[X1 X1] [Y1 Y1] [Z1 Z1] [X1 X1] [Y1 Y1] [Z1 Z1] [X1 X1] [Y1 Y1] [Z1 Z1] [HH HH]}
B0 stored to offset 0xF9 of 0x803BD310
C count of bytes to follow, stored to offset 0x00 of 0x803BD310
BN CC number of bytes
T count of triangles to follow
XYZ,123 triangle coordinates
H TODO: halfword for each triangle

proc_802A3E9C

Example Crystal Rift / level9: 01CE87-01CEE1

00 01 C8 
02 
1271 010E 06D9 
11D9 010E 0606 
11E5 00C8 0616 0D 95 
1271 010E 06D9 
11E5 00C8 0616 
125B 00C8 06BA 0D 95 
00 03 03 04 0E 
02 
143D 0370 0C3C 
146E 0370 0C3C 
146E 03D4 0C3C 07 FF 
143D 0370 0C3C 
146E 03D4 0C3C 
143D 03D4 0C3C 07 FF

0x68: Train Platform

Train and barge platform and stopping zone.

[B0] [B1]
[B2] {[X1 X1] [Z1 Z1] [X2 X2] [Z2 Z2] [X3 X3] [Z3 Z3]}
[WW WW WW WW]
[AA] {[H0 H0] [H2 H2] [H4 H4] [H6 H6] [H8 H8] [HA HA] [HC HC] [HE HE] [HG HG] [HI HI] [BK]}
[CC] {[BZ]}
B0 TODO stored to T3→bC4
B1 if non-zero, skip B2 (TODO: does something else)
B2 count of 6 int16s to follow, stored to T3→bC6
X1,Z1
X2,Z2
X3,Z3
valid stopping zone (smiley face): constructed by 'B2' # triangles
W TODO stored to T6
A count of records to follow, stored to T3→bC7, handled by proc_802A41B0()
H0-HI struct of 10 halfwords and 1 byte (0x15 bytes) ('A' count of these)
BK TODO stored to s0, passed through v0 to proc_802A4168
C count of bytes to follow
BZ 'C' number of bytes

proc_802A3F80()

Example Simian Acres / chimp: 01BD24-01BD9D

07 00
02 
{097B 0B0A 09B7 0B0A 09B7 0AF6}
{09B7 0AF6 097B 0AF6 097B 0B0A}
0000B5F4
04
{0889 002B 0B1A 0948 002B 0B1A 0948 0011 0B1A 07FE 01}
{0889 002B 0B1A 0948 0011 0B1A 0889 0011 0B1A 07FE 02} 
{0889 0012 0AE8 0948 0012 0AE8 0948 002C 0AE8 07FF 03}
{0889 0012 0AE8 0948 002C 0AE8 0889 002C 0AE8 07FF 04}
04
{01} {02} {03} {04}

Example Ebony Coast / level13: 026DB7-026EA8

07 00 
02 
{11CB 1F42 11B7 1F8F 11CA 1F94}
{11CA 1F94 11DF 1F47 11CB 1F42}
0000B5F4
04
{11FB 0164 1E65 11CA 0164 1F1D 11CA 0149 1F1D 0B54 01}
{11FB 0164 1E65 11CA 0149 1F1D 11FB 0149 1E65 0B54 02}
{122B 014A 1E72 11FA 014A 1F2A 11FA 0164 1F2A 0B54 03}
{122B 014A 1E72 11FA 0164 1F2A 122B 0164 1E72 0B54 04}
04 
{01} {02} {03} {04}
07 00 
02 
{1692 0D80 1683 0DBA 1696 0DBF}
{1696 0DBF 16A6 0D85 1692 0D80}
0000B5F4
04
{16BE 0164 0CA2 168D 0164 0D5A 168D 0149 0D5A 0B54 05}
{16BE 0164 0CA2 168D 0149 0D5A 16BE 0149 0CA2 0B54 06}
{16EE 014A 0CAF 16BD 014A 0D67 16BD 0164 0D67 0B54 07}
{16EE 014A 0CAF 16BD 0164 0D67 16EE 0164 0CAF 0B54 08}
04 
{01} {02} {03} {04}

0x6C: X/Z Collision

X/Z Collision (level perimeter, trees, walls)

Number of entries = t0→h10 * t0→h12

{[EE EE EE EE] {[X1 X1] [Y1 Y1] [Z1 Z1] [X2 X2] [Y2 Y2] [Z2 Z2] [X3 X3] [Y3 Y3] [Z3 Z3] [AA AA] [BB] [CC]}}
E end offset current collision group
X1,Y1,Z1
X2,Y2,Z2
X3,Y3,Z3
triangle vertices for collision data
A TODO: stored to 0x4c(T4) in proc_802A41B0
B TODO: passed through T7 to proc_802A41B0
C TODO: stored to T4

Two halfwords h10 and h12 from level header are multiplied to get the count of the number of groups in this list. Each group contains multiple triangles that consist of three X,Y,Z points a halfword and two bytes.

proc_802A3D54() → proc_802A41B0()

Example Simian Acres / chimp: 01BD9D-01E6E3

0000010C
03FA 008C 0596 03FA 00B6 0596 03FA 00B6 07EE 0BFF 00 00 
03FA 008C 0596 03FA 00B6 07EE 03FA 008C 07EE 0BFF 00 00 
03FA 00F0 0596 03FA 008C 0596 0494 008C 0590 0816 00 00 
03FA 00F0 0596 0494 008C 0590 0494 00BE 0590 0816 00 00 
0494 008C 0590 052E 008C 058B 0494 00BE 0590 0816 00 00 
03FA 00F0 0596 0494 00BE 0590 0494 00F0 0590 0816 00 00 
0494 00BE 0590 052E 008C 058B 052E 00F0 058B 0816 00 00 
0494 00BE 0590 052E 00F0 058B 0494 00F0 0590 0816 00 00 
052E 00F0 058B 052E 008C 058B 05B3 008C 0586 0815 00 00 
052E 00F0 058B 05B3 008C 0586 05BB 00F0 0585 0819 00 00 
0637 008C 0582 0647 00F0 0580 05BB 00F0 0585 0819 00 00 
05B3 008C 0586 0637 008C 0582 05BB 00F0 0585 0815 00 00
000003BA 
0B66 0000 0852 0B66 015B 0852 0B66 015B 0596 0BFE 01 00 
0B66 0000 0852 0B66 015B 0596 0B66 0000 0596 0BFE 01 00 
07D8 003E 0586 0839 008C 056E 0813 00F0 056E 0879 00 00 
0813 00F0 056E 0839 008C 056E 08BD 008C 056E 07FF 00 00 
0813 00F0 056E 08BD 008C 056E 08B3 00F0 056D 0801 00 00 
...

0x70: Player Collision

Number of entries = t0→h10 * t0→h12

{[EE EE EE EE] {[X1 X1] [Y1 Y1] [Z1 Z1] [X2 X2] [Y2 Y2] [Z2 Z2] [X3 X3] [Y3 Y3] [Z3 Z3] [AA AA] [BB] [CC]}}
E end offset current, added to T1, compared with T5 inner loop
X1,Y1,Z1
X2,Y2,Z2
X3,Y3,Z3
triangle vertices for collision data
A TODO: stored to 0x4c(T4) in proc_802A41B0
B passed through T7 to proc_802A41B0
C stored to T4

proc_802A3DF8()

Example Argent Towers / level10: 0211B1, count = 3*5 = 15

00000004 
00000008
0000000C 
00000010 
00000098
062F 00CD 0C83 062F 00BB 0C83 062F 00BA 0BD3 0BFF 00 00
062F 00CD 0C83 062F 00BA 0BD3 062F 00CD 0BD3 0BFE 00 00 
06DA 00CD 0BD3 06DA 00BA 0BD3 06DA 00BA 0C83 0BFE 01 00 
06DA 00CD 0BD3 06DA 00BA 0C83 06DA 00CD 0C83 0BFE 01 00 
062F 00CD 0BD3 062F 00BA 0BD3 06DA 00BA 0BD3 07FF 00 00 
062F 00CD 0BD3 06DA 00BA 0BD3 06DA 00CD 0BD3 07FF 00 00 
0000009C 
00000124 
0395 0131 119D 0395 0109 119D 03EF 0108 119D 07FF 00 00 
0395 0131 119D 03EF 0108 119D 03EF 0131 119D 07FF 00 00 
0395 0131 12AB 0395 0109 12AB 0395 0109 119D 0BFF 00 00 
0395 0131 12AB 0395 0109 119D 0395 0131 119D 0BFF 00 00 
03EF 0131 119D 03EF 0108 119D 03EF 0108 12AB 0BFE 01 00 
03EF 0131 119D 03EF 0108 12AB 03EF 0131 12AB 0BFE 01 00 
0000030C 
062F 00CD 0C83 062F 00BB 0C83 062F 00BA 0BD3 0BFF 00 00 
062F 00CD 0C83 062F 00BA 0BD3 062F 00CD 0BD3 0BFE 00 00 
06DA 00CD 0C83 06DA 00BA 0C83 062F 00BB 0C83 07FE 01 00 
...

0x74: TODO

0x74 starts at word boundary, so between 0 and 3 bytes of padding may be inserted

[NN NN NN NN] {[EE EE] ... [CC CC CC CC] {[H0 H0] [H2 H2] [H4 H4] [H6 H6] [H8 H8] [HA HA] [HC HC] [HE HE] [HG HG] [BI] ...}}
N number of structs to allocate
E if -1, last set
TODO
C number of 0x44 byte structs in this set
H0-HG int16 stored in allocated structs through T3
BI u8 stored in allocated struct through T3
TODO

proc_802A1A9C() initializes 'N' structs each of length 0x40

Example Simian Acres / chimp: 01E72C-01F420

000001C0
FFFF 
08 32 08 5C 07 2B 08 5C 07 2B 08 10 08 32 08 10 00 07 00 00 00 40 00 80 00 C0 01 00 01 40 01 80 FF FF FF FF FF FF 
00000030 
072B 00BD 0814 072B 00BD 0860 074C 00BA 0814 02 00 F5 FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 F5 FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
072B 00BD 0860 074C 00BA 0860 074C 00BA 0814 02 00 F5 FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
074C 00BA 0860 076C 00B6 0814 074C 00BA 0814 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
074C 00BA 0860 076C 00B6 0860 076C 00B6 0814 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 
076C 00B6 0860 078D 00B4 0814 076C 00B6 0814 02 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 
...

0x78: TODO

looking at F3D DL for 0xFD G_SETTIMG commands to dynamically load textures

Added to offset of start of level, passed as s0/s1 to proc_802A08E4

proc_802A08E4() - records 8 bytes, used as 2 words
s3 = *(0x803B8D40);
s5 = *(0x803B8D44);
do {
  w0 = read_u32_be(s0);
  s0 += 8;
} while (((w0 & 0xFF000000) >> 24) == 0xFD);
w1 = read_u32_be(s0-4);
s4 = 0x803B8570;
while (w1 != *s4 && s3 != s4) {
   s4 += 8;
}

0x88: TODO

Display list stuff, related to 0x2C animated textures calls proc_802A50DC with T4 = ID of W0 to change