Difference between revisions of "Zone"

From Crash Bandicoot Hacking Wiki
Jump to navigation Jump to search
(Created page with "== Format == === Item 1: Header === {| class="article-table" !Offset !Field !Size !Value |- |0x0 |World Count |4 bytes |w |- |0x4 |Reserved for World Models |8 x 0x40 bytes |...")
 
(Zone Dimensions/Octree)
Line 807: Line 807:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Zone Dimensions/Octree ==
+
== Zone Dimensions/Collision Octree ==
=== Octree ===
+
=== Collision Octree ===
 
Each node in the zone's collision octree, except for the root node, is the child of a parent node. Each parent node has either 8, 4, or 2 children nodes.  
 
Each node in the zone's collision octree, except for the root node, is the child of a parent node. Each parent node has either 8, 4, or 2 children nodes.  
  

Revision as of 09:13, 9 August 2015

Format

Item 1: Header

Offset Field Size Value
0x0 World Count 4 bytes w
0x4 Reserved for World Models 8 x 0x40 bytes *
0x204 Index of First Camera Path Item 4 bytes h
0x208 Camera Path Count 4 bytes c
0x20C Entity Count 4 bytes e
0x210 Neighbor Zone Count 4 bytes n
0x214 Neighbor Zone EIDs 8 x 4 bytes *
0x234 Texture Page Entry Count 4 bytes p
0x238 Texture Chunk CID Count 4 bytes t
0x23C Texture Page Entry EIDs 8 x 4 bytes *
0x25C Texture Chunk CIDs 32 x 4 bytes *
0x2DC Zone Spawn Flags 4 bytes *
0x2E0 VRAM Fill Height for clearing draw buffer 4 bytes *
0x2E4 unknown 4 bytes *
0x2E8 Zone Visibility Depth? 4 bytes *
0x2EC unknown 4 bytes *
0x2F0 unknown 4 bytes *
0x2F4 unknown 4 bytes *
0x2F8 unknown 4 bytes *
0x2FC Zone Flags 4 bytes *
0x300 Max Death Height? Max Water Height? 4 bytes *
0x304 unknown 4 bytes *
0x308 unknown 4 bytes *
0x30C unknown; see sub_260AC 4 bytes *
0x310 VRAM Clear Color R 1 byte *
0x311 VRAM Clear Color G 1 byte *
0x312 VRAM Clear Color B 1 byte *
0x313 unused 1 byte *
0x314 Far Color R 1 byte *
0x315 Far Color G 1 byte *
0x316 Far Color B 1 byte *
0x317 unused 1 byte *
0x318 Object Light Source Matrix L11 2 bytes *
0x31A Object Light Source Matrix L12 2 bytes *
0x31C Object Light Source Matrix L13 2 bytes *
0x31E Object Light Source Matrix L21 2 bytes *
0x320 Object Light Source Matrix L22 2 bytes *
0x322 Object Light Source Matrix L23 2 bytes *
0x324 Object Light Source Matrix L31 2 bytes *
0x326 Object Light Source Matrix L32 2 bytes *
0x328 Object Light Source Matrix L33 2 bytes *
0x32A Object Background Color R 2 bytes *
0x32C Object Background Color G 2 bytes *
0x32E Object Background Color B 2 bytes *
0x330 Object Light Color Matrix LR1 2 bytes *
0x332 Object Light Color Matrix LR2 2 bytes *
0x334 Object Light Color Matrix LR3 2 bytes *
0x336 Object Light Color Matrix LG1 2 bytes *
0x338 Object Light Color Matrix LG2 2 bytes *
0x33A Object Light Color Matrix LG3 2 bytes *
0x33C Object Light Color Matrix LB1 2 bytes *
0x33E Object Light Color Matrix LB2 2 bytes *
0x340 Object Light Color Matrix LB3 2 bytes *
0x342 Object Background Color Intensity R 2 bytes *
0x344 Object Background Color Intensity G 2 bytes *
0x346 Object Background Color Intensity B 2 bytes *
0x348 Player Light Source Matrix L11 2 bytes *
0x34A Player Light Source Matrix L12 2 bytes *
0x34C Player Light Source Matrix L13 2 bytes *
0x34E Player Light Source Matrix L21 2 bytes *
0x350 Player Light Source Matrix L22 2 bytes *
0x352 Player Light Source Matrix L23 2 bytes *
0x354 Player Light Source Matrix L31 2 bytes *
0x356 Player Light Source Matrix L32 2 bytes *
0x358 Player Light Source Matrix L33 2 bytes *
0x35A Player Background Color R 2 bytes *
0x35C Player Background Color G 2 bytes *
0x35E Player Background Color B 2 bytes *
0x360 Player Light Color Matrix LR1 2 bytes *
0x362 Player Light Color Matrix LR2 2 bytes *
0x364 Player Light Color Matrix LR3 2 bytes *
0x366 Player Light Color Matrix LG1 2 bytes *
0x368 Player Light Color Matrix LG2 2 bytes *
0x36A Player Light Color Matrix LG3 2 bytes *
0x36C Player Light Color Matrix LB1 2 bytes *
0x36E Player Light Color Matrix LB2 2 bytes *
0x370 Player Light Color Matrix LB3 2 bytes *
0x372 Player Background Color Intensity R 2 bytes *
0x374 Player Background Color Intensity G 2 bytes *
0x376 Player Background Color Intensity B 2 bytes *

Item 2: Dimensions/Collision Octree

Offset Field Size Value
0x0 Zone Location X 4 bytes *
0x4 Zone Location Y 4 bytes *
0x8 Zone Location Z 4 bytes *
0xC Zone Width 4 bytes *
0x10 Zone Height 4 bytes *
0x14 Zone Depth 4 bytes *
0x18 unknown 4 bytes *
Collision Octree
0x1C Root Node Index 2 bytes *
0x1E Maximum Depth X 2 bytes *
0x20 Maximum Depth Y 2 bytes *
0x22 Maximum Depth Z 2 bytes *
0x24 Octree Nodes * x 2 bytes *

Item 3+n: Camera Path

Offset Field Size Value
0x0 [Polygon] Sort List EID 4 bytes *
0x4 Reserved for pointer to parent zone (entry) 4 bytes garbage?
0x8 Neighboring Path Count 4 bytes *
0xC Neighboring Paths 4 x 4 x 1 byte *
Neighbor Path Structure d
0xC + (d x 4) +0x0 Relation [to this path] 1 byte *
0xC + (d x 4) +0x1 Parent Zone Index [in neighbor zone list] 1 byte *
0xC + (d x 4) +0x2 Path Item Index 1 byte *
0xC + (d x 4) +0x3 Relation to Goal/Misc Flag 1 byte *
end
0x1C Rel. Index of Entry Point [furthest from goal] 1 byte *
0x1D Rel. Index of Exit Point [closest to goal] 1 byte *
0x1E Path Length/Point Count 2 bytes L
0x20 Camera Mode 2 bytes *
0x22 Average Distance b/t Consecutive Path Points 2 bytes *
0x24 Camera Z Zoom/Y Pan Factor 2 bytes *
0x26 unknown 2 bytes *
0x28 unknown 2 bytes *
0x2A unknown 2 bytes *
0x2C Path Direction X 2 bytes *
0x2E Path Direction Y 2 bytes *
0x30 Path Direction Z 2 bytes *
0x32 Camera Path Points L x 12 bytes *
Camera Path Point Structure p (*point/trans location relative to parent zone location)
0x32 + (p x 12) + 0x0 Point X/Camera Trans X 2 bytes *
0x32 + (p x 12) + 0x2 Point Y/Camera Trans Y 2 bytes *
0x32 + (p x 12) + 0x4 Point Z/Camera Trans Z 2 bytes *
0x32 + (p x 12) + 0x6 Camera Rotation X 2 bytes *
0x32 + (p x 12) + 0x8 Camera Rotation Y 2 bytes *
0x32 + (p x 12) + 0xA Camera Rotation Z 2 bytes *

Item 3+c+n: Entity

Offset Field Size Value
0x0 Reserved for pointer to parent zone (entry) 4 bytes garbage?
0x4 Spawn Configuration Flags 2 bytes *
0x6 Object Process Type 2 bytes *
0x8 ID 2 bytes *
0xA Path Point Count 2 bytes L
0xC Mode Flags A (or initial Y rot) 2 bytes *
0xE Mode Flags B (or initial X rot) 2 bytes *
0x10 Mode Flags C (or initial Z rot) 2 bytes *
0x12 Object Type 1 byte *
0x13 Object Subtype 1 byte *
0x14 Object Path Points L x 6 bytes *
Object Path Point Structure p
0x14 + (p x 6) + 0x0 Point X 2 bytes *
0x14 + (p x 6) + 0x2 Point Y 2 bytes *
0x14 + (p x 6) + 0x4 Point Z 2 bytes *
end
0x14 + (L x 6) + 0x0 unknown? ? bytes ?

Structure

TBD: zonecollisions, entity

struct zoneheader
{
  unsigned long worldcount;
  wgeomodel world[8];
  unsigned long headercount;
  unsigned long campathcount;
  unsigned long entitycount;
  unsigned long neighborcount;
  union
  {
    entry *neighbor[8];
    unsigned long neighboreid[8];
  };
  unsigned long tpagecount;
  unsigned long tchunkcount;
  unsigned long tpage[8];
  unsigned long tchunk[32];
  unsigned long loadflags;
  unsigned long vramfillh;
  unsigned long unknownA;
  unsigned long visibilitydepth;
  unsigned long unknownB;
  unsigned long unknownC;
  unsigned long unknownD;
  unsigned long unknownE;
  unsigned long flags;
  unsigned long deathy;
  unsigned long unknownF;
  unsigned long unknownG;
  unsigned long unknownH;
  unsigned char vramfillr;
  unsigned char vramfillg;
  unsigned char vramfillb;
  unsigned char unused_a;
  unsigned char farcolorr;
  unsigned char farcolorg;
  unsigned char farcolorb;
  unsigned char unused_b;
  struct slightmatrix objectlightmatrix;
  struct scolor objectcolor;
  struct scolormatrix objectcolormatrix;
  struct scolor objectlightintensity;
  struct slightmatrix playerlightmatrix;
  struct scolor playercolor;
  struct scolormatrix playercolormatrix;
  struct scolor playerlightintensity;
};

struct zonepathdescriptor
{
  unsigned char relation;
  unsigned char neighborzoneindex;
  unsigned char campathindex;
  unsigned char goal;
};

struct zonecampathpoint
{
  signed short x;
  signed short y;
  signed short z;
  signed short rotx;
  signed short roty;
  signed short rotz;
};

struct zonecampath
{
  unsigned long slsteid;
  union
  {
    entry *parentzone;
    unsigned long parentzoneeid;
  }
  unsigned long neighborpathcount;
  struct zonepathdescriptor neighborpathdescriptor[4];
  unsigned char entranceindex;
  unsigned char exitindex;
  unsigned short length;
  unsigned short cammode;
  signed short avgptdist;
  signed short camzoom;
  unsigned short unknownA;
  unsigned short unknownB;
  unsigned short unknownC;
  struct svector direction;
  struct zonecampathpoint point[];
};

Zone Dimensions/Collision Octree

Collision Octree

Each node in the zone's collision octree, except for the root node, is the child of a parent node. Each parent node has either 8, 4, or 2 children nodes.

Each node corresponds to a portion of 3-dimensional space occupied by the zone. The root node corresponds to the entire region of space occupied by the zone (specified at offsets 0x0 to 0x14). Each child node corresponds to a separate subdivision of the space occupied by its parent. The location and dimensions of a subdivision respectively vary based on the corresponding node's index among its siblings and its depth within the tree.

In relation to its corresponding node's parent's associated region of space, a subdivision can be any region resulting from an even partitioning by any combination of 1 to 3 coordinate axis-aligned hyperplanes:

  • Upper left front, upper left back, lower left front, lower left back, upper right front, upper right back, lower right front, or lower right back octant
  • Upper left, Lower left, Upper right, Lower right, Front left, Back left, Front right, Back right, Upper front, Upper back, Lower front, or Lower back quadrant
  • Left, right, top, bottom, front, or back half

Thus, if a node's parent's associated region of space were split in half along a line parallel to either the x, y, or z axis, then optionally split in half along a line parallel to either one of the remaining axes, and then optionally split in half along a line parallel to the remaining axis, the node's associated region of space could be any of either the resulting halves, quadrants, or octants. In these terms, 3 factors determine the location and dimensions of a subdivision: the number of split lines (1 to 3), the respective axes/axis parallel to those/that split line(s) (x and/or y and/or z), and the number/index of the resulting half, quadrant, or octant that encompasses its space.

For any parent node with depth less than the minimum of the respective maximum x, y, and z depths (specified at offsets 0x1E,0x20,0x22), 3 split lines-each respectively parallel to the x, y, and z axes-determine the 8 octants that, respectively, encompass its children's corresponding subdivisions of space. For the children of parent nodes with a depth greater than or equal to the minimum, the split line(s) parallel to the axis/axes for which is/are specified that minimum are eliminated when determining the corresponding subdivisions. For the children of parent nodes with a depth greater than or equal to the second minimum, i.e. the minimum of the remaining 2 maximums (if any), the respective split lines parallel to the axes for which are specified the minimum and second minimum are eliminated when determining the corresponding subdivisions. The maximum of the 3 maximum depths determines the height of the tree.

For example, suppose maximum depth x were the minimum of the maximum depths-3, for example. Suppose also that maximum depth z were the second minimum-7, for example. For any parent node with depth less than 3, each of its children's corresponding subdivisions is a separate octant of its (the parent's) associated region of space. For any parent node with depth greater than or equal to 3 but less than 7, the x split line is eliminated in determining the subdivisions of its associated region-thus, it is only split in half y-wise and z-wise; equivalently, it is only split into 4 quadrants-an upper front, lower front, upper back, and lower back quadrant. Such a parent node could then have only 4 children, each respectively corresponding to a separate one of the 4 subdivisions/quadrants. For any parent node with depth greater than or equal to 7, the x and z split lines are eliminated in determining the subdivisions of its associated region-thus, it is only split in half y-wise; equivalently, it is only split into 2 halves-a left half and a right half. Such a parent node could then have only 2 children, each respectively corresponding to a separate one of the 2 subdivisions/halves.

  • Parent nodes with depth less than the minimum have 8 children-but only if the minimum is nonzero.
    • If a unique minimum [max] depth of 0 is specified for only one of the 3 axes, parent nodes with depth less than the second minimum have 4 children.
    • If a minimum depth of 0 is specified for 2 of the 3 axes, all parent nodes have 2 children.
    • If a minimum depth of 0 is specified for all axes, the tree is empty.
  • Parent nodes with depth greater than or equal to the minimum and less than the second minimum(if it exists) have 4 children-but only if the minimum is unique.
    • If the same minimum depth is specified for 2 of the 3 axes, parent nodes with depth greater than or equal to the minimum have 2 children.
    • If the same nonzero minimum/maximum depth is specified for all axes-that is, there does not exist a second minimum-then all parent nodes have 8 children.
  • Parent nodes with depth greater than or equal to the second minimum have 2 children-but only if the [first] minimum or second minimum is unique.
  • Height of the tree is given by the maximum [of the max] depth(s).

Octree Node Format

Each node in the octree is specified as an unsigned short (2 bytes). The relative offset of the root node within the item is specified at offset 0x1C.

Internal/parent nodes

Internal/parent nodes are indicated by a cleared LSB (least significant bit); consequently, their [nonzero] value refers to the relative offset of [the first of] their children in the item. Child nodes are stored contiguously as groups of 8, 4, or 2. The cardinality and arrangement of a parent's group of child nodes depends on its depth in relation to the axis associated maximum depths:

Parent Depth Condition Children Group [format/arrangement] A B C D E F G H
(d < min) && max AA AA BB BB CC CC DD DD EE EE FF FF GG GG HH HH ULF ULB DLF DLB URF URB DRF DRB
cond = (d >= min && d < min2 && min != min2)
cond && min == maxx && (maxx != maxy && maxx != maxz) AA AA BB BB CC CC DD DD UL UR DL DR n/a n/a n/a n/a
cond && min == maxy && (maxy != maxx && maxy != maxz) AA AA BB BB CC CC DD DD LF LB RF RB n/a n/a n/a n/a
cond && min == maxz && (maxz != maxx && maxz != maxy) AA AA BB BB CC CC DD DD UF UB DF DB n/a n/a n/a n/a
cond = (d >= min2 && (min != min2 || min2 != max)) [|| (d >= min && (min == min2 || min2 == max)) ]
cond && min2 == maxx AA AA BB BB L R n/a n/a n/a n/a n/a n/a
cond && min2 == maxy AA AA BB BB U D n/a n/a n/a n/a n/a n/a
cond && min2 == maxz AA AA BB BB F B n/a n/a n/a n/a n/a n/a
  • The Parent Depth Condition column lists conditions under which a parent node's contiguous group of children have the associated formats. Only the bolded conditions are relevant if max depths are unique. The following symbols are used for brevity:
    • d = parent node depth
    • max* = max depth *
    • M = {max*} (for *=x,y,z)
    • min = min(M)
    • min2 = min(M - {min})
    • max = max(M)
  • The Children Group column lists the arrangement or byte format of the parent's group of child nodes; depending on conditions, there are either 8 children [A-H], 4 children [A-D], or 2 children [A-B] in the group.
  • Each of the A-H columns identifies that child's corresponding subdivision with an abbreviation:
    • L = left, R = right, U = upper, D = lower, F = front, B = back

Non-existent nodes

Non-existent nodes are indicated with a value of 0. A non-existent node refers to empty space; there is nothing particularly interesting about its corresponding subdivision, since the player will never interact/collide with it.

Leaf nodes

Leaf nodes are indicated by a set LSB; the remaining 15 bits describe collision attributes for the node's corresponding subdivision:

UUUUUUSSSSSSTTT1

  • T = Node type
  • S = Node subtype
  • U = Unknown/unused?

Node type and subtype refer to type and subtype of the node's corresponding collidable subdivision of 3 space.

Node Type

Node type determines the primary type of corresponding collidable space:

Type Description
0 Solid and Interactive
1 Solid Floor/Ground
2 Level Boundary Wall
3 Pit Area
4 Trigger Misc Death on Collision
Node Subtype

Solid and Interactive, Pit Area, and Trigger Misc Death on Collision type nodes (types 0, 3, and 4) may optionally specify a node subtype. This subtype determines a specific event sent to the player upon collision with the node:

Subtype Description Event
0 ? ?
1 ? ?
2 Spin, Fall Over, and Die (death sequence) 0x700
3 ? 0xC00
4 Drown 0x2100
5 Burn to Ash 0x1F00
6 Explode 0x1E00
7 ? 0xD00
8 ? 0x1200
9 ? 0x1200
10 ? 0x1200
11 ? 0x1200
12 Fall in a Hole and Die 0x900
13 ? 0x2300

It is yet to be determined whether there are additional subtypes with other purposes.