User Tools

Site Tools


mario_golf:hole_components

Overview

Each hole in the game is made up of seven different components that each define their own subset of the hole layout:

  • geometry 1 (.vtx)
  • geometry 2 (.dtx)
  • trees (.tre)
  • initial hole conditions (.hol)
  • pins and tees (.pnt)
  • triangles and rings (.tri)
  • ground type map (.att)

Where the file extensions listed above are taken from leftover debug text within the ROM. A description of each component and its file format will be provided below.

The function to load the majority of these components is:

void loadHoleComponent(int holeNumber, int courseNumber, int componentNumber) // 0x80251DFC (US version)

Where componentNumber takes values:

1 - geometry 1
2 - geometry 2
3 - trees
4 - triangles and rings
5 - ground type map

Where coordinates are listed as shorts (geometry), the bounds of the hole are 0x1000x, 0x2000z. Where coordinates are listed as ints (pins, tees), the bounds of the hole are 0x400000x, 0x800000z. To scale between the systems, shift left or right by 10 bits as appropriate.

Geometry

Both geometry files follow the same format, and consist of a file containing a number of encoded vertices. The expected number of vertices is 0x231 for .vtx files and 0x800 for .dtx files, and the files will be read either until these counts are reached or a terminator is encountered.

Encoding

The vertex encoding works on the basis of having implicit x- and z-coordinates which may be overridden, while a y-coordinate is always specified. The format is a command byte followed by up to three variable-length data values:

cc [xx[xx]] [yy[yy]] [zz[zz]]

The command byte's bits are split as follows:

1 1 11 11 11
z x zs ys xs

Where:

z = implicit z flag
x = implicit x flag
zs = z shift type
ys = y shift type
xs = x shift type

The shift types determine whether the coordinate being stored should be stored as a short or a byte, and what amount of right shifting has been applied to the original value. When decoded, these values would then be left shifted by the appropriate amount. Their possible behaviours are:

Value x, z behaviour y behaviour
0 » 0, store short » 0, store short
1 » 8, store byte » 0, store byte
2 » 5, store byte » 1, store byte
3 » 6, store byte » 2, store byte

Note that a command byte of 0x09 is interpreted as a terminator when decoding the data, and processing of the file will stop if this value is encountered.

Implicit coordinates

The x- and z-coordinates take their implicit values when no value is otherwise specified. The pattern is different for the .vtx and .dtx files.

.vtx:

x    z   
0000 0000
0200 0000
0400 0000
0600 0000
0800 0000
0a00 0000
0c00 0000
0e00 0000
1000 0000
0100 0000
0300 0000
0500 0000
0700 0000
0900 0000
0b00 0000
0d00 0000
0f00 0000
+0100z until 0f00x, 2000z

.dtx:

x    z    pattern
0080 0000
0180 0000
0000 0080
0200 0080
0000 0180
0200 0180
0080 0200
0180 0200
0080 0080
0100 0080
0180 0080
0080 0100
0180 0100
0080 0180
0100 0180
0180 0180
+0200x until 0f80x
then
+0200z
repeat until  0f80x, 1f80z

For an example, see here.

Trees

The file begins with a single byte giving the number of tree entries contained within the file. The tree data follows immediately after, in the format:

struct treeEntry
{
  short x;
  short y;
  short z;
  byte treeType;
  byte unused;
  short width;
  short height;
}

Tree types here.

Note that data in this file is not aligned.

Initial hole conditions

This file contains various hole data to initialise with. However, this is all (?) overwritten later. The file format is:

struct initHoleConditions
{
  int pinX;
  int pinY;
  int pinZ;
  int teeX;
  int teeY;
  int teeZ;
  int windSpeed;
  int windDirection;
  int weather;
  int time;
  short sunPosition1;
  short sunPosition2;
  byte par;
  byte pinIndex;
  byte unknown1;
  byte unknown2;
  int unknown3; //0x04000000
}

Pins and tees

This file defines the four possible pin and tee locations for the hole. Although four tees can be listed, only the first is ever used. Additionally, further vectors are listed that affect where different characters will aim their shots by default. The format is:

pin positions (int x, int y, int z) * 4
tee positions (int x, int y, int z) * 4
aim positions (int x, int y, int z) * 16
total length: 0x120 bytes

Triangles and rings

This file contains triangle definitions for drawing water and/or the walls used in mini-golf, as well as definitions for the rings present in ring shot mode. The file begins with a single byte giving the number of definitions, followed by data in the format:

struct triangleDef
{
  byte triType;
  short x1;
  short y1;
  short z1;
  short x2;
  short y2;
  short z2;
  short x3;
  short y3;
  short z3;
}

Where triType is:

0 water
1 ring
2 water
3 wall

For rings, rather than the data corresponding to three vertices, x2/y2/z2 will be the rotation, x3 the scale, and y3/z3 unused.

Note that data in this file is not aligned.

Ground type map

The ground type map is a 256*512 array that defines the ground type at each point in space. This file is compressed in ROM and will be decompressed upon transfer to RAM. The types normally in use are:

0 Fairway
1 Rough
2 Bunker
3 Bare ground
4 Cart way
5 Deep rough
6 Green
7 OB
8 Tee ground
9 Rock

Note the absence of semi-rough and green edge; these types are not included in the ground maps themselves, but are added dynamically during processing. Additionally, deep rough will be swapped out with waste area on the Shy Guy Desert course, and green is swapped with cart way and fairway in the fast and slow mini-golf courses respectively.

The ground colours and patterns are generated during processing of the ground type maps. Unfortunately, these are normally all hardcoded and difficult to modify, though the functions have been rewritten (see here and here).

mario_golf/hole_components.txt · Last modified: 2020/08/18 22:45 by DeathBasket