Actors
Cross-link to the Ocarina of Time wiki: Actors |
Actors are the various interactive pieces in the Zelda 64 engine, from enemies to static scenery.
Contents
There are three major components to an actor:
- The actor's overlay, a file that contains the code for an actor
- Actor instances, or an in memory representation of our actor.
- Object files, one or more files that contain pre-generated microcode, animations, and graphical assets for an actor. These can be shared by multiple actors.
Actor Overlay Table
Version | VRom | VRam | Size | ||
---|---|---|---|---|---|
Debug | DD5A50 | ? | ? | ? | 5640 |
US 1.0 | C45510 | ? | 801AEFD0 | ? | 5640 |
USA GC | C52280 | C578A0 | ? | ? | 5640 |
The actor table manages the actor files (overlays). It defines an actor's number, maps the actor to a virtual address, and during gameplay is used to find the overlay in ram.
Format
xxxxxxxx yyyyyyyy aaaaaaaa bbbbbbbb
pppppppp iiiiiiii nnnnnnnn ????cc??
This breaks down into-
x y: Start/End Virtual Rom addresses of the actor file
a b: Start/End Virtual Ram addresses of the actor file
p: Ram address of actor file (00000000 if overlay isn't loaded, or if in ROM)
i: Virtual Ram address of the start of the actor instance initialization variables, located within the file
n: Address of actor filename (Debug ROM only, value is 0 in commercial roms)
c: Number of actor instances of this type currently loaded (ram only)
Note: The record for Link's actor in rom (the first record in the table) only sets the vram address that points to the start of the variable info for Link's actor, and the actor file name pointer if it's the Debug Rom.
Overlay File
See Overlays for more information on the overlay format.
Initialization Variables
The actor's initialization variables are pointed to via the 6th word in the Actor Overlay Table.
/*0x00*/ short ActorNumber //value does not always match the instance's real actor number
/*0x02*/ byte ActorType //See Below
/*0x03*/ byte RoomNumber //Room instance was spawned in. If value set to FF in rom, instance does not despawn when swapping rooms
//0x04 is unknown
/*0x08*/ short ObjectNumber //possibly it's primary object dependency
//0x0A Padding
/*0x0C*/ int InstanceSize
/*0x10*/ int* ?
/*0x14*/ int* Deconstructor
/*0x18*/ int* ?
/*0x1C*/ int* ?
Common Data Structures
Actor Instances
typedef struct {
f32 x, y, z;
} Coord;
typedef struct {
u16 x, y, z;
} rotation;
typedef struct
{
struct
{
char Damage : 4;
char Effect : 4;
} Attack[0x20];
} z2_ActorDamageTable;
typedef struct
{
/* 0x00 */ u16 id;
/* 0x02 */ u8 type;
/* 0x03 */ u8 room; //Room number the actor is part of. FF denotes that the actor won't despawn on a room change
/* 0x04 */ s32 flags;
/* 0x08 */ Coord Pos1; //Related to collision detection routine
/* 0x14 */ rotation initRot;
/* 0x1A */ u16 unk_0x01A;
/* 0x1C */ u16 variable;
/* 0x1E */ u16 unk_0x01E;
/* 0x20 */ u16 soundEffect; //Plays sound effect (relative to actor's location, if within range of camera?)
/* 0x22 */ u16 unk_0x022;
/* 0x24 */ Coord Pos2; //Current coordinate
/* 0x30 */ u16 unk_0x030;
/* 0x32 */ u16 unk_0x032;
/* 0x34 */ char buff[4];
/* 0x38 */ Coord Pos3;
/* 0x44 */ rotation rot_1;
/* 0x4A */ u16 unk_0x04A;
/* 0x4C */ f32 unk_0x04C; /* I know this is a float from breakpointing it */
/* 0x50 */ Coord Scale;
/* 0x5C */ char buff2[0x54];
/* 8-10-2012 : Addition made by Jason777 */
/* For actors which contain a damage chart (example: Stalfos)... */
typedef struct
{
/* 0xA0 */ z2_ActorDamageTable* DamageChart; /* Pointer to the actor's Damage Chart in RAM. */
/* 0xA4 */ Coord_f displacement; //amount to correct velocity (0x5C) by when colliding into a body
/* 0xB0 */ s16 unk_0x0B0;
/* 0xB2 */ s16 unk_0x0B2;
/* 0xB4 */ u16 unk_0x0B4; //unk
/* 0xB6 */ u8 mass; // Used to compute displacement, 50 is common value, 0xFF for infinite mass/unmoveable
/* 0xB7 */ u8 health;
/* 0xB8 */ u8 damage;
/* 0xB9 */ u8 damageEffect; //Stores what effect should occur when hit by a weapon
/* 0xBA */ u8 impactEffect;
/* 0xBB */ u8 unk_0x0BB;
};
/* 0xBC */ rotation rot_2; //Setting this immediately changes actor's rotation
/* ? */ char buff3[0x66];
/* 0x115 */ u8 runActor; // Determines if actor instance should be processed. 01 for yes, 00 for no.
/* 0x128 */ struct z2_Actor* actor_prev; /* Previous z_ram_actor of this type */
/* 0x12C */ struct z2_Actor* actor_next; /* Next z_ram_actor of this type */
/* 0x130 */ void* Init; //Actor Constructor?
/* 0x134 */ void* Dest; //Actor Deconstructor?
/* 0x138 */ void* Main;
/* 0x13C */ void* Draw;
/* 0x140 */ void* CodeEntry; //Address to source overlay file's reference in code (file)
/* ? */
/* From here on, the structure and size varies for each actor */
} z2_Actor;
Categories
Actor instances are added into a doubly-linked list based on a category id. Ids can be set in the overlay file, but can also be pro grammatically modified (ex. Skulltula/Gold Skulltula actor). There are 12 categories total. Majora's Mask may use 16 different categories.
char * actor_types[12] = { "Switch", "Prop (1)", "Player", "Bomb", "NPC", "Enemy", "Prop (2)", "Item/Action", "Misc", "Boss", "Door", "Chests" };
Id | Description | Usage |
---|---|---|
0 | Switches | Step-on switches, Anubis enemy, Death Mountain Crater Smoke Cone |
1 | Prop (1) | Typically larger, more complex set pieces |
2 | Player | |
3 | Bomb | Bombs, Bombchus |
4 | NPC | |
5 | Enemy | Used for triggering room clear state. |
6 | Prop | |
7 | Item/Action | |
8 | Misc | |
9 | Boss | |
10 | Door | |
11 | Chests |
Loading Actors
What is currently known about the loading and execution of code from actors in Zelda 64 is that:
- The first time an actor is loaded (spawned), its overlay file is transferred to RAM
- The transferred file has its offsets relocated to a real address space in RAM
- The actor file remains allocated in ram until all instances of that actor have despawned
- The game begins to create an instance of the actor
- For each actor instance, actors are given a certain amount of memory as defined in the actor file. However, the minimum space required by the game's engine is 0x128 bytes in OoT (MM may vary).
- Within this given memory is information such as
- Location
- Rotation
- Scale
- Pointer to damage chart (if the actor has one)
- Pointers to actor functions
- Initialization - run when actor instance is loaded.
- Main - always run during gameplay.
- Drawing - to be run when actor is close enough to the camera.
- Pointer to Next/Previous actor(s) of this actor's category
- Whatever else that actor needs (ex. instanced variables).
- Within this given memory is information such as
At Global Context + 0x1CB0 is a list of actor categories (see above), each element structured as follows:
int numOfActors; ptr firstActor; int unknown;
The pointer points to the first allocated entry for an actor. The integer is the number of actors of that category, the first entry being type 0, and the last last being type 11 (chests). Actors after the first actor are pointed to through the next/previous pointers within each allocated actor.
Custom Actors
A number of custom actors have been created. For more information, see Overlays.
Examples
Every actor in Debug MQ disassembled
Credits
Cendamos - Actor table information, misc stuff that got the ball rolling
Euler - Actor file structure
JayTheHam - His early work with Cendamos on actor information
ZZT32 - Explained some actor table stuff to me
spinout - Writing this article