From CloudModding MM Wiki
See also: Category:Actors

Actors are the various interactive pieces in the Zelda 64 engine, from enemies to static scenery.

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

For a list of the data within this table, see Actor List.
code (File)
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; //Actor Id. 
    /* 0x02 */ u8       type; //Actor Type. See Below
    /* 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; //flags used for drawing stuff?
    // & 0x0040 0000 = Affects actor lighting
    // & 0x0000 1000 = ?
    // & 0x0000 0040 = ?
    /* 0x08 */ Coord_f  pos1; //Related to collision detection routine
    /* 0x14 */ Rotation initRot; //Initial Rotation when spawned
    /* 0x1A */ u16      unk_0x01A;
    /* 0x1C */ u16      variable; //Configurable variable set by an actor's spawn data
    /* 0x1E */ s8       objTableIndex; //index to the Object Table at Game Play + ????
    /* 0x1F */ u8       unk_0x01F;
    /* 0x20 */ u16      soundEffect; //Plays sound effect relative to actor's location (if within range of camera?)
    /* 0x22 */ u16      unk_0x022;
    /* 0x24 */ Coord_f  position; //Current coordinates
    /* 0x30 */ Rotation speedRot; //0x32 sets what direction the 0x68 speedXZ variable is moving the actor
    /* 0x36 */ u16      unk; //same as 0x1A
    /* 0x38 */ int8     unk;                   
    /* 0x39 */ uint8    unk;       
    /* 0x3A */ u16      unk;              
    /* 0x3C */ Coord_f  pos3; //Related to camera
    /* 0x48 */ Rotation rot1; //0x30 rotation copied into here
    /* 0x4E */ u16      unk;
    /* 0x50 */ int32    unk;
    /* 0x54 */ float    unk; /* I know this is a float from breakpointing it */
    /* 0x58 */ Coord_f  scale; //sets x,y,z scaling factor. Typically, a factor of 0.01 is used for each axis
    /* 0x64 */ Coord_f  velocity;
    /* 0x70 */ float    speedXZ; //Always positive, stores how fast the actor is traveling along the XZ plane
    /* 0x74 */ float    gravity; //acceleration due to gravity; value is added to Y velocity every frame
    /* 0x78 */ float    minVelocityY; //sets the lower bounds cap on velocity along the Y axis
	//struct, collision related
    /* 0x7C */ int*     wallPoly; //Wall polygon an actor is touching
    /* 0x80 */ int*     floorPoly; //Floor polygon an actor is over/touching
    /* 0x84 */ u8       wallPolySource; //Complex Poly Surface Source. 0x32 = Scene
    /* 0x85 */ u8       floorPolySource; //Complex Poly Surface Source. 0x32 = Scene
    /* 0x86 */ u16      wallrot;
    /* 0x88 */ float    unk; //floor poly height?
    /* 0x8C */ float    water_surface_dist;
    /* 0x90 */ u16      bgcheck_flags; //unknown
    /* 0x92 */ s16      unk_roty; //rotation y (give item, possibly next facing dir?/face toward link?)
    /* 0x94 */ float    unk;
    /* 0x98 */ float    xzDistanceFromLink; 
    /* 0x9C */ float    yDistanceFromLink; // relative distance
    

    /* 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).

At Game Play + 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