Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,531 changes: 769 additions & 762 deletions ASM/build/asm_symbols.txt

Large diffs are not rendered by default.

Binary file modified ASM/build/bundle.o
Binary file not shown.
1,453 changes: 731 additions & 722 deletions ASM/build/c_symbols.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ASM/c/chests.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef void (*EnBoxActionFunc)(struct EnBox*, z64_game_t*);
typedef struct EnBox
{
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0154 */ uint8_t skelanime[0x44];
/* 0x0154 */ SkelAnime skelAnime;
/* 0x0198 */ int32_t unk_198; // related to animation delays for types 3 and 8
/* 0x019C */ int32_t sub_cam_id;
/* 0x01A0 */ float unk_1A0; // 0-1, rotation-related, apparently unused (in z_en_box.c at least)
Expand Down
4 changes: 2 additions & 2 deletions ASM/c/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ void draw_debug_menu(z64_disp_buf_t* db) {
}
if (current_menu_indexes.sub_menu_index == 2) {
uint8_t nbActors = 0;
z64_actor_t* actor = z64_game.actor_list[current_menu_indexes.actor_index].first;
z64_actor_t* actor = z64_game.actorLists[current_menu_indexes.actor_index].head;
while (actor != NULL) {
nbActors++;
actor = actor->next;
Expand Down Expand Up @@ -992,7 +992,7 @@ void draw_debug_menu(z64_disp_buf_t* db) {
}
else {
uint8_t nbActors = 0;
z64_actor_t* actor = z64_game.actor_list[current_menu_indexes.actor_index].first;
z64_actor_t* actor = z64_game.actorLists[current_menu_indexes.actor_index].head;
uint8_t currentActorPage = current_menu_indexes.specific_actor_index / 10;
// Display actor list in 10 by 10 pages.
while (actor != NULL) {
Expand Down
31 changes: 31 additions & 0 deletions ASM/c/en_box.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "z64.h"
#include "chests.h"
#include "object.h"
#include "get_items.h"
#include "debug.h"

// Macro for original get item id + if opened or not
#define ENBOX_GET_GET_ITEM_ID(thisx) ((thisx).variable >> 5) & ((1 << 7) - 1)
#define ENBOX_GET_TREASURE_FLAG(thisx) ((thisx).variable >> 0) & ((1 << 5) - 1)

#define OBJECT_FZ 0x114

// Get this chest's new randomized GI id
int16_t EnBox_GetNewGetItemId(EnBox* this, z64_game_t* play) {
int16_t oldId = ENBOX_GET_GET_ITEM_ID(this->dyna.actor);
override_t override = lookup_override(&this->dyna.actor, z64_game.scene_index, ABS(oldId));

return override.value.base.item_id;
}

// Load the necessary extra object if new GI id is a trap
void EnBox_LoadObject(EnBox* this, z64_game_t* play) {
int16_t giId = EnBox_GetNewGetItemId(this, play);
bool opened = Flags_GetTreasure(play, ENBOX_GET_TREASURE_FLAG(this->dyna.actor));

if(!opened) {
if (giId == GI_ICE_TRAP) {
Object_LoadExtra(play, OBJECT_FZ, 0); // Freezard object
}
}
}
2 changes: 1 addition & 1 deletion ASM/c/item_effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void open_gate_and_mask_shop(z64_file_t* save, int16_t arg1, int16_t arg2) {
// Check if we're in kak and actually open the gate
if (z64_game.scene_index == 82) {
// Loop through the actors looking for the gate
z64_actor_t* curr = z64_game.actor_list[7].first;
z64_actor_t* curr = z64_game.actorLists[7].head;
while (curr != NULL) {
if (curr->actor_id == 0x100) { // Check for BG_GATE_SHUTTER
// Set the openingState so it starts to open
Expand Down
2 changes: 1 addition & 1 deletion ASM/c/misc_colors.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void update_bombchu_trail_colors()
colorRGB8_t rainbow_color_outer_start = get_rainbow_color(frames, BOMBCHU_CYCLE_FRAMES_OUTER);
colorRGB8_t rainbow_color_outer_end = get_rainbow_color(frames + 2 * BOMBCHU_CYCLE_FRAMES_OUTER, BOMBCHU_CYCLE_FRAMES_OUTER);

z64_actor_t* explosive = z64_game.actor_list[ACTORTYPE_EXPLOSIVES].first;
z64_actor_t* explosive = z64_game.actorLists[ACTORTYPE_EXPLOSIVES].head;
while (explosive != NULL)
{
if (explosive->main_proc != NULL && explosive->actor_id == 0xDA) // En_Bom_Chu
Expand Down
74 changes: 74 additions & 0 deletions ASM/c/object.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "z64.h"
#include "object.h"

// Function that adds an object to an object slot and sets up data for the object
// to be loaded by Object_UpdateEntries() (which is run every frame).
extern void* func_800982FC(z64_obj_ctxt_t* objectCtx, int32_t slot, int16_t objectId);
extern int32_t DmaMgr_RequestSync(void* ram, uintptr_t vrom, size_t size);

/**
* Loads an extra object that no previously loaded actor has a dependency on.
* Will get deloaded upon room/scene change, as it is not part of the room object list.
* @param syncDma true if the object should be synchronously DMA transferred this frame.
* Otherwise, it is loaded asynchronously on next frame by Object_UpdateEntries.
* @return: Slot number (if already loaded, or loaded into a new slot), else -1
* NOTE:
* - Crash risk if trying to sync DMA during En_Holl room transition, if an actor
* in the previous room depends on object data that will be overwritten by the DMA
* before the actor is properly deleted (see: GTG Lava room to Chest maze with SoT block).
* Async DMA is OK because of the extra frame delay.
* - Objects are otherwise not unloaded/loaded on demand, so extra loading is OK.
* - If crashing, if async DMA ensure that the object is loaded before the actor
* is trying to draw (try sync DMA). Ensure that there is actually object slot and space
* available for new object before drawing or doing anything else that requires object.
*
*/
int16_t Object_LoadExtra(z64_game_t* play, int16_t objectId, uint8_t syncDma) {
uint8_t i;
int16_t slot = -1;

// Check if object is already loaded, and for first available slot
for (i = 0; i < ARRAY_COUNT(play->obj_ctxt.objects); i++) {

// Already loaded (abs is needed - negative id if object not yet DMA:ed)
if (ABS((play->obj_ctxt.objects[i].id)) == objectId) {
return i;

} else if (slot == -1 && play->obj_ctxt.objects[i].id == 0) {
slot = i;
break;
}
}

if (slot != -1) {
// Take the found slot
z64_mem_obj_t* newEntry = &play->obj_ctxt.objects[slot]; // The new object
z64_mem_obj_t* lastEntry = &play->obj_ctxt.objects[play->obj_ctxt.n_objects-1]; // Previous last added object
RomFile* lastObjectFile = &gObjectTable[ABS(lastEntry->id)]; // Get previous object start pointer and size
uint32_t lastSize = lastObjectFile->vromEnd - lastObjectFile->vromStart;
newEntry->data = (void*)ALIGN16((uintptr_t)lastEntry->data + lastSize); // Gives pointer to start for the new object data

// Set up data for adding the object to the slot on next update or now
if (func_800982FC(&play->obj_ctxt, slot, objectId) != NULL) {
play->obj_ctxt.n_objects++;

if (syncDma) {
play->obj_ctxt.objects[slot].id = objectId; // Uninvert the id because it will get loaded now
RomFile* objectFile = &gObjectTable[objectId]; // Get object start pointer and size
uint32_t size = objectFile->vromEnd - objectFile->vromStart;
DmaMgr_RequestSync(newEntry->data, objectFile->vromStart, size);
}

} else { // Loading new object would exceed object space
#ifdef DEBUG_MODE
char msg[256];
sprintf(msg, "Obj %d slot %d", objectId, slot);
Fault_AddHungupAndCrashImpl("Object_LoadExtra: No memory", msg);
#endif

return -1; // Don't crash non-debug mode for now but this should not happen!
}
}

return slot;
}
16 changes: 16 additions & 0 deletions ASM/c/object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef OBJECT_H
#define OBJECT_H

#define ALIGN16(x) (((x) + 0xF) & ~0xF)
#define ARRAY_COUNT(arr) (int32_t)(sizeof(arr) / sizeof(arr[0]))

typedef struct RomFile {
/* 0x00 */ uintptr_t vromStart;
/* 0x04 */ uintptr_t vromEnd;
} RomFile; // size = 0x8

extern RomFile gObjectTable[];

int16_t Object_LoadExtra(z64_game_t* play, int16_t objectId, uint8_t syncDma);

#endif
26 changes: 19 additions & 7 deletions ASM/c/z64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,11 @@ typedef enum {
/* 0x15 */ CAM_MODE_MAX,
} CameraModeType;

typedef struct ActorListEntry {
/* 0x00 */ int32_t length; // number of actors loaded of this category
/* 0x04 */ z64_actor_t* head; // pointer to head of the linked list of this category (most recent actor added)
} ActorListEntry; // size = 0x08

/* game context */
typedef struct {
z64_ctxt_t common; /* 0x00000 */
Expand Down Expand Up @@ -1399,10 +1404,7 @@ typedef struct {
z64_actor_ctxt_t actor_ctxt; /* 0x01C24 */
uint8_t n_actors_loaded; /* 0x01C2C */
char unk_0A_[0x0003]; /* 0x01C2D */
struct {
uint32_t length;
z64_actor_t *first;
} actor_list[12]; /* 0x01C30 */
ActorListEntry actorLists[12]; /* 0x01C30 */ // index is actor category
char unk_0B_[0x0038]; /* 0x01C90 */
z64_actor_t *arrow_actor; /* 0x01CC8 */
z64_actor_t *target_actor; /* 0x01CCC */
Expand Down Expand Up @@ -1489,8 +1491,10 @@ typedef struct {
uint8_t shootingGalleryStatus; /* 0x11E5C */
uint8_t bombchuBowlingStatus; /* 0x11E5D */
uint8_t fadeout_transition; /* 0x11E5E */
/* 0x11E5F */
} z64_game_t;
char unk_25_[0x05BC]; /* 0x11E5F */
uint8_t transitionMode; /* 0x1241B */
char unk_26_[0x00FC]; /* 0x1241C */
} z64_game_t; // 0x12518


typedef struct {
Expand Down Expand Up @@ -1917,7 +1921,15 @@ typedef enum {
/* 4 */ PAUSE_BG_PRERENDER_MAX,
} PauseBgPreRenderState;


typedef struct SkelAnime {
/* 0x00 */ char known_1_[0x08];
/* 0x08 */ void* animation; // Can be an AnimationHeader or LinkAnimationHeader.
/* 0x0C */ float startFrame; // In mode ANIMMODE_LOOP_PARTIAL*, start of partial loop.
/* 0x10 */ float endFrame; // In mode ANIMMODE_ONCE*, Update returns true when curFrame is equal to this. In mode ANIMMODE_LOOP_PARTIAL*, end of partial loop.
/* 0x14 */ float animLength; // Total number of frames in the current animation.
/* 0x18 */ float curFrame; // Current frame in the animation
/* 0x1C */ char known_2_[0x28];
} SkelAnime; // size = 0x44

/* helper macros */
#define LINK_IS_ADULT (z64_file.link_age == 0)
Expand Down
5 changes: 4 additions & 1 deletion ASM/ootSymbols.ld
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Addresses should be listed in order */
z64_EquippedItemOutlineTex = 0x2000E00;
DmaMgr_RequestSync = 0x80000df0;
Flags_GetSwitch = 0x8002049C;
Flags_SetSwitch = 0x800204D0;
Flags_UnsetSwitch = 0x80020510;
Expand All @@ -19,11 +20,13 @@ Flags_SetCollectible = 0x8002071C;
Actor_SetColorFilter = 0x80027090;
CutsceneFlags_Get = 0x8005991C;
z64_Gfx_SetupDL_42Opa = 0x8007E868;
func_800982FC = 0x80081740;
Audio_StopCurrentMusic = 0x800C7684;
sprintf = 0x800CE7b4;
Message_OpenText = 0x800DC838;
Fault_AddHungupAndCrashImpl = 0x800AF564;
z64_ItemIcons = 0x800F8D2C;
gObjectTable = 0x800f8ff8;
z64_SfxDefaultPos = 0x80104394;
z64_SfxDefaultFreqAndVolScale = 0x801043A0;
z64_SfxDefaultReverb = 0x801043A8;
Expand All @@ -42,4 +45,4 @@ gActorOverlayTable = 0x800E8530;
Message_CloseTextbox = 0x800d6218;
sSetupDL = 0x800f7d50;
OVL_EnOkarinaTag_Action2 = 0x80a872d0;
OVL_EnOkarinaTag_Action1 = 0x80a87088;
OVL_EnOkarinaTag_Action1 = 0x80a87088;
2 changes: 2 additions & 0 deletions ASM/src/build.asm
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ RANDO_CONTEXT:
.include "bg_gate_shutter.asm"
.include "big_poe.asm"
.include "player_ladder_cutscene.asm"
.include "enbox_callloadobject.asm"
.include "object_checkmaxobjectspace.asm"

.align 0x10
.importobj "../build/bundle.o"
Expand Down
9 changes: 9 additions & 0 deletions ASM/src/enbox_callloadobject.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
EnBox_CallLoadObject:
addiu sp,sp,-24
sw ra,16(sp)
jal EnBox_LoadObject ; a0 EnBox*, a1 play*
move s1,a1 ; displaced
lw ra,16(sp)
move a1,s1 ; might not be needed but for safety
jr ra
addiu sp,sp,24
2 changes: 2 additions & 0 deletions ASM/src/hacks.asm
Original file line number Diff line number Diff line change
Expand Up @@ -4162,3 +4162,5 @@ DemoEffect_DrawJewel_AfterHook:
.include "hacks/ovl_en_okarina_tag.asm"
.include "hacks/sound.asm"
.include "hacks/z_player.asm"
.include "hacks/en_box.asm"
.include "hacks/z_scene.asm"
10 changes: 10 additions & 0 deletions ASM/src/hacks/en_box.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.headersize (0x80868750 - 0x00c06030)

; Call function to load extra object if neeeded for a trap.
; Replaces move s0,a0
; move s1,a1
; sw ra,44(sp)
.org 0x808687f4 ; in EnBox_Init
sw ra,44(sp)
jal EnBox_CallLoadObject
move s0,a0
11 changes: 11 additions & 0 deletions ASM/src/hacks/z_scene.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.headersize (0x80114dd0 - 0x00b8ad30)

; Object load: Add check to ensure that new object to be loaded
; fits within object context space, else return NULL
; Replaces addu t1,t4,t0
; addiu t1,t1,15
; and v0,t1,at
.org 0x8008178c ; in func_800982FC
jal Object_CheckMaxObjectSpace
addu t1,t4,t0 ; displaced
lw ra,12(sp) ; ra is already saved by another hack, but not saved in vanilla func_800982FC
10 changes: 10 additions & 0 deletions ASM/src/object_checkmaxobjectspace.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Object_CheckMaxObjectSpace:
addiu t1,t1,15 ; displaced
and v0,t1,at ; displaced
lw t1,4(a0) ; objectCtx space end
sltu at,v0,t1 ; next object start pointer < space end?
beqzl at,@@Return ; if yes, return pointer (v0)
move v0,zero ; if not - memory full, return NULL, let caller deal with it
@@Return:
jr ra
nop
2 changes: 1 addition & 1 deletion data/generated/patch_symbols.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading