Skip to content

Pilotwings 64 Research & Development

roto edited this page Nov 3, 2019 · 29 revisions

Keyword Glossary

Some of these are confirmed based on strings in the main application. Some are guesses based on the character grouping and logic.

Magic Description Notes
BIRD Birdman
CB Cannon Ball
HG Hang Glider
HM Jumble Hopper
GC Gyro Copter
RP Rocket Pack
SD Sky Diver
UV UltraVision Engine Codename
ADAT ASCII (?) Data See: https://github.com/queueRAM/pilotwings_64/pull/3
APTS Audio Switch Points
BALS Balloons / Balls
BNUS Bonus Secret Birdman stars in the levels
BTGT Ball Target Missions where you push a ball into destination cylinder with the RP
CNTG Cannon Target
COMM Command/Common
DATA Text Data Strings throughout the game, see: https://github.com/queueRAM/pilotwings_64/pull/3
HPAD Hover Pad Rocket Pack hovering landing pads
HOPD Hopper Destination
JPTX Japan TeXt String character lookup table?
LPAD Landing Pad
LSTP Landing Strip
PDAT Path Data
PHDR Path Header
PHTS Photos Objects to photograph while in missions with Hang Glider
PPOS Path Pose Line ?
QUAT Quaternion
RNGS Rings
SPTH SOMETHING Path Interpreted as 3 (x,y,z) or 6 (x,y,z, heading, pitch, roll) Hermite splines with different tangent logic. Possibly related to SkyDiver missions and player placement in task.
STRG String
TABL FS Table File lookup table/map in the ROM and housing FORM sizes for each chunk. MIO0 compressed.
THER Thermals Hang Glider lift points
TPAD Takeoff Pad
TPTS Terra Switch Points for warping the player and switching terras on/off (for caves)
TOYS Toys Seems to refer to animated models (like ferris wheel)
UPWL PilotWings Level Pre-mission "stage setup", 4 levels: Holiday Island, Ever-Frost Island, Crescent Island, Little States, has info about sounds, level transitions, and some special models
UPWT PilotWings Task Missions: target/ring/balloon X/Y/Z coordinates, landing pad/strip locations, etc
UVAN Animation
UVBT Blit
UVCT Contour Main terrain geometry
UVFT Font Texture Template? Near STRG marker
UVEN Environment maybe skybox?
UVLV UltraVision Level lists other UVTR,UVMD,UVTX to load
UVMD Model
UVSQ UltraVision Sequence Guess
UVSX UltraVision Sound ArXive Standard N64 .CTL/.TBL audio data(wavetables and ADPCM compressed audio)
UVSY UltraVison System Guess
UVTR Terra Grid of UVCT contours
UVTX Texture
WOBJ Wind Objects Wind socks and wind turbines, which rotate based on the wind

Memory Addresses (ROM/RAM)

This is for things like X/Z/Y coordinates of objects/vehicles/etc and other things I've found to be of interest while dumping memory in the PJ64 debugger. Some of these mem locations can be modified in-game ("Live) but some must be modified during or right after DMA ROM read.

I'm fairly confident I have X/Z/Y coordinates correct but please double check and correct me if I reversed X/Z somehow.

Feel free to correct my findings and update/add/remove things as needed. - roto

Memory Address Data Type Name Description/Notes
80126C64 data UVTR First hit After DMA ROM read
8018fad8 data snow data pointer to itself, then snow coords (?), then snow pixel indices
80263780 data Dynamic objects array of dobjs, stride is 0x40, first short is the model ID, followed by indices into the dobj matrix array
80265080 data Dobj matrices array of floating point 4x4 joint matrices (so stride 0x40) used by dobjs
80265294 float Ball Width JetPack Level 1
802652A8 float Ball Height JetPack Level 1
802652B0 float Ball / Model X Live Change position of "current target" live, after ROM read
802652B4 float Ball / Model Z Live Seems to affect models in Character Select screen too
802652B8 float Ball / Model Y Live
80362758 float Jetpack Rotation Angle
80362788 float Vehicle X Live
8036278C float Vehicle Z Live
80362790 float Vehicle Y Live
8036AAC4 data Ring X-Rotate Angle ROM read, on UPWT load, can't seem to find this in memory after
8036C6E0 float Minimap Target X
8036C6E4 float Minimap Target Z
8036C6E8 float Minimap Target Y
8036DA79 data Ring/Object "Model" Weird one, change to '01' for a glitched out Hang Glider
8036DAAC float Ring X Live
8036DAB0 float Ring Z Live
8036DAB4 float Ring Y Live
8036DC0C data Ring rotation speed Change to 41
8036DC18 data Ring Rotation (Flip) Change to 78
80373ef0 data pointer to snow data
8037A600 data COMM Gyro Level 1 Temp marker
8037AA21 data Number of Rings? Gyro 1st Level
8037AA22 data Number of Balloons (objectives/goals?) JetPack Level 1

Function names/signatures

function names starting uv are taken directly from debug text

RAM address Name/Signature Notes
205814 uvSortAdd(int category, float dist, modelPlacement* obj) appends the given S/Dobj (based on category) to the appropriate list for rendering
206058 double uvClkGetSec(int index) returns the elapsed seconds since a start time indicated by index
216f70 uvDobjModel(int index, int modelID) loads a dynamic object
221398 uvGfxStateDraw(uint32 state) prepares rsp geo mode and rdp other mode for drawing a set of triangles. the lower bytes of state are the texture ID, if any, while the upper bytes get translated into the mode flags
229270 axisRotation(transform* mat, float angle, uint8 axis) rotates mat (excluding the translation part), axis is 78,79,7a corresponding to x,y,z
22cef8 modelPlacement* uvSobj(uint32 sobjID) retrieves the sobj struct for a given ID. ID format is (terraID << 24) | (contourID << 12) | placementID
22cfc4 uvSobjPosm(uint32 sobjID, int part, transform* mat) sets the transform for the given part of the sobj to mat (storing in fixed-point format)
22f7e8 computeLineEndpoints(uint16* entrance, *exit, float xmin, xmax, ymax, ymin, intercept, slope, inverseSlope, bool handedness, float widthScale, heightScale) stores the endpoints of a line through the given rectangle, using a coordinate that increases ccw around the rectangle, increasing widthScale or heightScale across each side
2315ec float rand() random number generator, seemingly uniform on [0,1), but haven't analyzed it too much
30b868 loadLevelDobjs load several Dobjs depending on level ID (1,3,5,a)
23031c uvTxtDraw(int texID) appends the texture's display list, including additional commands for scrolling
33fe40 randomSnow calls RNG a few times, maybe for new snowflakes
33ff30 drawSnow draws snow pixels into frame buffer
33ffb4 computeSnow computes snow pixel positions
347e9c animateToy(toy* toy) animates the given toy. The toy structure has an Sobj ID (see above) at 0x04 and a toy type byte (0-4) at 0x08

Demo Flight Path Data

The PDAT container at 0x384E64 has (among other yet unknown structures such as "RPKT") various X/Z/Y coordinates in the "PPOS" sets for the first demo flight of the game when left idle at the Title Screen. The demo is of the first Gyro Copter level where you are shown how to fly through rings and then loop around the airport.

If we take the PPOS data and convert the it to floats, we can graph the demo flight path as such:

The example code to do this (made by roto) is terrible and I apologize for it but it works:

import struct
import numpy as np

# 3D stuff
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import style

x_list = []
z_list = []
y_list = []

with open("ppos2_clean", "r") as f:
    data = f.read().splitlines()

    for line in data:
        pos_x = bytearray.fromhex(line[0:8])
        pos_z = bytearray.fromhex(line[8:16])
        pos_y = bytearray.fromhex(line[16:24])

        x_list.append(round(struct.unpack('>f', pos_x)[0],6))
        z_list.append(round(struct.unpack('>f', pos_z)[0],6))
        y_list.append(round(struct.unpack('>f', pos_y)[0],6))

        print "%s %s %s" % (round(struct.unpack('>f', pos_x)[0],6),
                            round(struct.unpack('>f', pos_z)[0],6),
                            round(struct.unpack('>f', pos_y)[0],6))

fig = plt.figure()
ax1 = fig.add_subplot(111, projection='3d')
x = np.array(x_list)
z = np.array(z_list)
y = np.array(y_list)

ax1.plot(x,z,y)
ax1.set_xlabel('x axis')
ax1.set_ylabel('z axis')
ax1.set_zlabel('y axis')

plt.show()

To feed this code with the data points ("ppos2_clean") I just ripped the PPOS data from the PW64 FS dump python script made by queueRAM (Found Here)

UPWT (COMM) Data

You can find a tool to help parse the UPWT blocks here: https://github.com/roto-n64/pw64/blob/master/pw64_upwt_parser.py

The COMM chunk in UPWT is typically 0x430 bytes in size. This table contains the Mission/Test setups. These were enumerated by pfedak/roto via MIPS function RE (pfedak), manual bit-fuzzing and UPWT comparisons (roto).

Some of the mission details (such as Target designations) were verified by debug_print output after modifying data with unexpected inputs.

Debug output sample (Setting BALS to 0xFF): balls : too many balls defined in level [%d]

The offsets in this table are from the start of the COMM data chunk (after COMM Marker+Length).

Offset Attribute Name Known Types/Options Notes
0x0 Test Class '00': 'Beginner', '01': 'Class A', '02': 'Class B', '03': 'Pilot Class'
0x1 Vehicle '00': 'Hang Glider', '01': 'Rocket Pack', '02': 'Gyro Copter', '03': 'Cannon', '06': 'Birdman'
0x2 Test Number 00 = Test 1, 01 = Test 2, etc
0x3 Level '00': 'Holiday Island', '01': 'Crescent Island', '02': 'Little States', '03': 'Ever-Frost Island'
0x8 Weather / Time of Day '00': 'Sunny', '01': 'Sunny Part 2', '02': 'Cloudy', '03': 'Snowing?', '04': 'Evening', '05': 'Starry Night'
0x41D Hang Glider Thermals
0x41E Local Winds
0x41F Takeoff Pads/Strips
0x420 Landing Pads
0x421 Landing Strips
0x422 Rings
0x423 Balloons
0x424 Rocket Targets
0x425 Floating Pads
0x426 Ball Targets Cylindrical areas to push a ball into.
0x427 Photo Targets Objects to photograph in Hang Glider tests.
0x428 "Falcos Domains" B_GC_3/P_GC_3: Meca Hawk boss. Probably coordinates for him to run to.
0x429 Unknown
0x42A Canon Targets
0x42B Jumble Hopper Goals