diff --git a/USAGE.md b/USAGE.md index 435ec6ac..1033d2eb 100644 --- a/USAGE.md +++ b/USAGE.md @@ -515,6 +515,12 @@ The following commands are available: entrance as if Link voided out. *Default: `A + B + L`* - **toggle age:** Toggles between Adult and Child Link. Takes effect when entering a new area. *Default: `unbound`* + **equip iron boots:** Equip or unequip iron boots, if you have them. + *Default: `unbound`* + **equip hover boots:** Equip or unequip hover boots, if you have them. + *Default: `unbound`* + **use ocarina:** Use ocarina, if you have one. + *Default: `unbound`* - **save state:** Save the state of the game to the currently selected state slot. *Default: `D-Left`* - **load state:** Load the state saved in the currently selected state slot. diff --git a/lib/liboot-1.0.a b/lib/liboot-1.0.a index 5ef56e49..91d8eab8 100644 --- a/lib/liboot-1.0.a +++ b/lib/liboot-1.0.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C2EA0 ; z64_afx_rand_call = 0x800C3A50 ; z64_OcarinaUpdate = 0x800C3DC8 ; z64_ResetAudio = 0x800C7E98 ; +z64_PlaySfx = 0x800C806C ; z64_CheckAfxConfigBusy = 0x800CB798 ; z64_LoadOverlay = 0x800CCBB8 ; z64_SeedRandom = 0x800CDCC0 ; @@ -118,6 +119,9 @@ z64_song_ptr = 0x80102B3C ; z64_ocarina_button_state = 0x80102B7C ; z64_sfx_write_pos = 0x80104360 ; z64_sfx_read_pos = 0x80104364 ; +z64_sfx_unk1 = 0x80104394 ; +z64_sfx_unk2 = 0x801043A0 ; +z64_sfx_unk3 = 0x801043A8 ; z64_audio_cmd_write_pos = 0x801043B0 ; z64_audio_cmd_read_pos = 0x801043B4 ; z64_afx_cfg = 0x801043C0 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016A640 ; z64_ctxt = 0x801C84A0 ; z64_game = z64_ctxt ; z64_link = 0x801DAA30 ; +z64_UseButton = 0x8038C9A0 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x80829D9C ; diff --git a/lib/liboot-1.1.a b/lib/liboot-1.1.a index 989f1b52..ab265004 100644 --- a/lib/liboot-1.1.a +++ b/lib/liboot-1.1.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C2EFC ; z64_afx_rand_call = 0x800C3AC0 ; z64_OcarinaUpdate = 0x800C3E38 ; z64_ResetAudio = 0x800C8070 ; +z64_PlaySfx = 0x800C823C ; z64_CheckAfxConfigBusy = 0x800CB958 ; z64_LoadOverlay = 0x800CCD78 ; z64_SeedRandom = 0x800CDE80 ; @@ -118,6 +119,9 @@ z64_song_ptr = 0x80102CFC ; z64_ocarina_button_state = 0x80102D3C ; z64_sfx_write_pos = 0x80104520 ; z64_sfx_read_pos = 0x80104524 ; +z64_sfx_unk1 = 0x80104554 ; +z64_sfx_unk2 = 0x80104560 ; +z64_sfx_unk3 = 0x80104568 ; z64_audio_cmd_write_pos = 0x80104570 ; z64_audio_cmd_read_pos = 0x80104574 ; z64_afx_cfg = 0x80104580 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016A800 ; z64_ctxt = 0x801C8660 ; z64_game = z64_ctxt ; z64_link = 0x801DABF0 ; +z64_UseButton = 0x8038CB18 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x80829D9C ; diff --git a/lib/liboot-1.2.a b/lib/liboot-1.2.a index 165e14dd..cb6307f5 100644 --- a/lib/liboot-1.2.a +++ b/lib/liboot-1.2.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C355C ; z64_afx_rand_call = 0x800C4118 ; z64_OcarinaUpdate = 0x800C4490 ; z64_ResetAudio = 0x800C86E8 ; +z64_PlaySfx = 0x800C88BC ; z64_CheckAfxConfigBusy = 0x800CBFD8 ; z64_LoadOverlay = 0x800CD3F8 ; z64_SeedRandom = 0x800CE500 ; @@ -118,6 +119,9 @@ z64_song_ptr = 0x8010317C ; z64_ocarina_button_state = 0x801031BC ; z64_sfx_write_pos = 0x801049A0 ; z64_sfx_read_pos = 0x801049A4 ; +z64_sfx_unk1 = 0x801049D4 ; +z64_sfx_unk2 = 0x801049E0 ; +z64_sfx_unk3 = 0x801049E8 ; z64_audio_cmd_write_pos = 0x801049F0 ; z64_audio_cmd_read_pos = 0x801049F4 ; z64_afx_cfg = 0x80104A00 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016AF00 ; z64_ctxt = 0x801C8D60 ; z64_game = z64_ctxt ; z64_link = 0x801DB2F0 ; +z64_UseButton = 0x8038D15C ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x80829D9C ; diff --git a/lib/liboot-ce-j.a b/lib/liboot-ce-j.a index f7372d9a..807e71ed 100644 --- a/lib/liboot-ce-j.a +++ b/lib/liboot-ce-j.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C38A8 ; z64_afx_rand_call = 0x800C4458 ; z64_OcarinaUpdate = 0x800C47D0 ; z64_ResetAudio = 0x800C8884 ; +z64_PlaySfx = 0x800C8A5C ; z64_CheckAfxConfigBusy = 0x800CC188 ; z64_LoadOverlay = 0x800CD420 ; z64_SeedRandom = 0x800CE3D0 ; @@ -117,6 +118,9 @@ z64_song_ptr = 0x80101BAC ; z64_ocarina_button_state = 0x80101BEC ; z64_sfx_write_pos = 0x801033D0 ; z64_sfx_read_pos = 0x801033D4 ; +z64_sfx_unk1 = 0x80103404 ; +z64_sfx_unk2 = 0x80103410 ; +z64_sfx_unk3 = 0x80103418 ; z64_audio_cmd_write_pos = 0x80103420 ; z64_audio_cmd_read_pos = 0x80103424 ; z64_afx_cfg = 0x80103430 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016B840 ; z64_ctxt = 0x801C9660 ; z64_game = z64_ctxt ; z64_link = 0x801DBBB0 ; +z64_UseButton = 0x8038D9A4 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x8082996C ; diff --git a/lib/liboot-gc-j.a b/lib/liboot-gc-j.a index a1654eb7..5b026854 100644 --- a/lib/liboot-gc-j.a +++ b/lib/liboot-gc-j.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C38C8 ; z64_afx_rand_call = 0x800C4478 ; z64_OcarinaUpdate = 0x800C47F0 ; z64_ResetAudio = 0x800C88A4 ; +z64_PlaySfx = 0x800C8A7C ; z64_CheckAfxConfigBusy = 0x800CC1A8 ; z64_LoadOverlay = 0x800CD440 ; z64_SeedRandom = 0x800CE3F0 ; @@ -117,6 +118,9 @@ z64_song_ptr = 0x80101BCC ; z64_ocarina_button_state = 0x80101C0C ; z64_sfx_write_pos = 0x801033F0 ; z64_sfx_read_pos = 0x801033F4 ; +z64_sfx_unk1 = 0x80103424 ; +z64_sfx_unk2 = 0x80103430 ; +z64_sfx_unk3 = 0x80103438 ; z64_audio_cmd_write_pos = 0x80103440 ; z64_audio_cmd_read_pos = 0x80103444 ; z64_afx_cfg = 0x80103450 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016B840 ; z64_ctxt = 0x801C9660 ; z64_game = z64_ctxt ; z64_link = 0x801DBBB0 ; +z64_UseButton = 0x8038D9A4 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x8082999C ; diff --git a/lib/liboot-gc-u.a b/lib/liboot-gc-u.a index 996884c0..cdd1030d 100644 --- a/lib/liboot-gc-u.a +++ b/lib/liboot-gc-u.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C38A8 ; z64_afx_rand_call = 0x800C4458 ; z64_OcarinaUpdate = 0x800C47D0 ; z64_ResetAudio = 0x800C8884 ; +z64_PlaySfx = 0x800C8A5C ; z64_CheckAfxConfigBusy = 0x800CC188 ; z64_LoadOverlay = 0x800CD420 ; z64_SeedRandom = 0x800CE3D0 ; @@ -117,6 +118,9 @@ z64_song_ptr = 0x80101BAC ; z64_ocarina_button_state = 0x80101BEC ; z64_sfx_write_pos = 0x801033D0 ; z64_sfx_read_pos = 0x801033D4 ; +z64_sfx_unk1 = 0x80103404 ; +z64_sfx_unk2 = 0x80103410 ; +z64_sfx_unk3 = 0x80103418 ; z64_audio_cmd_write_pos = 0x80103420 ; z64_audio_cmd_read_pos = 0x80103424 ; z64_afx_cfg = 0x80103430 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016B840 ; z64_ctxt = 0x801C9660 ; z64_game = z64_ctxt ; z64_link = 0x801DBBB0 ; +z64_UseButton = 0x8038D9A4 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x8082997C ; diff --git a/lib/liboot-mq-j.a b/lib/liboot-mq-j.a index 782d854d..25ed05a4 100644 --- a/lib/liboot-mq-j.a +++ b/lib/liboot-mq-j.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C38A8 ; z64_afx_rand_call = 0x800C4458 ; z64_OcarinaUpdate = 0x800C47D0 ; z64_ResetAudio = 0x800C8884 ; +z64_PlaySfx = 0x800C8A5C ; z64_CheckAfxConfigBusy = 0x800CC188 ; z64_LoadOverlay = 0x800CD420 ; z64_SeedRandom = 0x800CE3D0 ; @@ -117,6 +118,9 @@ z64_song_ptr = 0x80101BAC ; z64_ocarina_button_state = 0x80101BEC ; z64_sfx_write_pos = 0x801033D0 ; z64_sfx_read_pos = 0x801033D4 ; +z64_sfx_unk1 = 0x80103404 ; +z64_sfx_unk2 = 0x80103410 ; +z64_sfx_unk3 = 0x80103418 ; z64_audio_cmd_write_pos = 0x80103420 ; z64_audio_cmd_read_pos = 0x80103424 ; z64_afx_cfg = 0x80103430 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016B840 ; z64_ctxt = 0x801C9660 ; z64_game = z64_ctxt ; z64_link = 0x801DBBB0 ; +z64_UseButton = 0x8038D9A4 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x8082999C ; diff --git a/lib/liboot-mq-u.a b/lib/liboot-mq-u.a index 81cd7060..94a17c40 100644 --- a/lib/liboot-mq-u.a +++ b/lib/liboot-mq-u.a @@ -65,6 +65,7 @@ z64_ocarina_sync_hook = 0x800C3888 ; z64_afx_rand_call = 0x800C4438 ; z64_OcarinaUpdate = 0x800C47B0 ; z64_ResetAudio = 0x800C8864 ; +z64_PlaySfx = 0x800C8A3C ; z64_CheckAfxConfigBusy = 0x800CC168 ; z64_LoadOverlay = 0x800CD400 ; z64_SeedRandom = 0x800CE3B0 ; @@ -117,6 +118,9 @@ z64_song_ptr = 0x80101B8C ; z64_ocarina_button_state = 0x80101BCC ; z64_sfx_write_pos = 0x801033B0 ; z64_sfx_read_pos = 0x801033B4 ; +z64_sfx_unk1 = 0x801033E4 ; +z64_sfx_unk2 = 0x801033F0 ; +z64_sfx_unk3 = 0x801033F8 ; z64_audio_cmd_write_pos = 0x80103400 ; z64_audio_cmd_read_pos = 0x80103404 ; z64_afx_cfg = 0x80103410 ; @@ -165,5 +169,6 @@ z64_disp = 0x8016B800 ; z64_ctxt = 0x801C9620 ; z64_game = z64_ctxt ; z64_link = 0x801DBB70 ; +z64_UseButton = 0x8038D964 ; z64_cimg = 0x803B5000 ; z64_item_highlight_vram = 0x8082997C ; diff --git a/src/gz/gz.h b/src/gz/gz.h index e6f9aa6c..25379251 100644 --- a/src/gz/gz.h +++ b/src/gz/gz.h @@ -249,6 +249,9 @@ void command_fileselect(void); void command_reload(void); void command_void(void); void command_age(void); +void command_equip_irons(void); +void command_equip_hovers(void); +void command_use_ocarina(void); void command_savestate(void); void command_loadstate(void); void command_savepos(void); diff --git a/src/gz/gz_command.c b/src/gz/gz_command.c index 6f0b9a95..3ae3ddbc 100644 --- a/src/gz/gz_command.c +++ b/src/gz/gz_command.c @@ -26,6 +26,9 @@ struct command_info command_info[COMMAND_MAX] = {"reload scene", command_reload, CMDACT_PRESS_ONCE}, {"void out", command_void, CMDACT_PRESS_ONCE}, {"toggle age", command_age, CMDACT_PRESS_ONCE}, + {"equip iron boots", command_equip_irons, CMDACT_PRESS_ONCE}, + {"equip hover boots", command_equip_hovers, CMDACT_PRESS_ONCE}, + {"use ocarina", command_use_ocarina, CMDACT_PRESS_ONCE}, {"save state", command_savestate, CMDACT_PRESS_ONCE}, {"load state", command_loadstate, CMDACT_PRESS_ONCE}, {"save position", command_savepos, CMDACT_HOLD}, @@ -209,6 +212,57 @@ void command_age(void) z64_UpdateEquipment(&z64_game, &z64_link); } +void command_equip_irons(void) +{ + if (zu_in_game() + && z64_file.link_age == 0 + && z64_file.iron_boots + && (z64_link.state_flags_1 & 0x30000483) == 0 + && z64_file.interface_flag != 1 + && (z64_event_state_1 & 0x20) == 0) + { + if (z64_file.equip_boots == 2) + z64_file.equip_boots = 1; + else + z64_file.equip_boots = 2; + z64_UpdateEquipment(&z64_game, &z64_link); + z64_PlaySfx(0x0835, &z64_sfx_unk1, 0x04, &z64_sfx_unk2, &z64_sfx_unk2, + &z64_sfx_unk3); + } +} + +void command_equip_hovers(void) +{ + if (zu_in_game() + && z64_file.link_age == 0 + && z64_file.hover_boots + && (z64_link.state_flags_1 & 0x30000483) == 0 + && z64_file.interface_flag != 1 + && (z64_event_state_1 & 0x20) == 0) + { + if (z64_file.equip_boots == 3) + z64_file.equip_boots = 1; + else + z64_file.equip_boots = 3; + z64_UpdateEquipment(&z64_game, &z64_link); + z64_PlaySfx(0x0835, &z64_sfx_unk1, 0x04, &z64_sfx_unk2, &z64_sfx_unk2, + &z64_sfx_unk3); + } +} + +void command_use_ocarina(void) +{ + if (zu_in_game() + && z64_game.pause_ctxt.state == 0 + && !z64_game.if_ctxt.restriction_flags.ocarina + && (z64_file.items[Z64_SLOT_OCARINA] == Z64_ITEM_FAIRY_OCARINA + || z64_file.items[Z64_SLOT_OCARINA] == Z64_ITEM_OCARINA_OF_TIME) + && (z64_link.state_flags_1 & 0x08C00800) == 0) + { + z64_UseButton(&z64_game, &z64_link, z64_file.items[Z64_SLOT_OCARINA], 2); + } +} + void command_savestate(void) { if (!zu_in_game()) diff --git a/src/gz/settings.c b/src/gz/settings.c index 9cde88e1..54cf08c9 100644 --- a/src/gz/settings.c +++ b/src/gz/settings.c @@ -110,6 +110,9 @@ void settings_load_default(void) d->binds[COMMAND_RELOAD] = bind_make(2, BUTTON_A, BUTTON_L); d->binds[COMMAND_VOID] = bind_make(3, BUTTON_A, BUTTON_B, BUTTON_L); d->binds[COMMAND_AGE] = bind_make(0); + d->binds[COMMAND_EQUIP_IRONS] = bind_make(0); + d->binds[COMMAND_EQUIP_HOVERS] = bind_make(0); + d->binds[COMMAND_USE_OCARINA] = bind_make(0); d->binds[COMMAND_SAVESTATE] = bind_make(1, BUTTON_D_LEFT); d->binds[COMMAND_LOADSTATE] = bind_make(1, BUTTON_D_RIGHT); d->binds[COMMAND_SAVEPOS] = bind_make(0); diff --git a/src/gz/settings.h b/src/gz/settings.h index c235d684..eb708b6e 100644 --- a/src/gz/settings.h +++ b/src/gz/settings.h @@ -64,6 +64,9 @@ enum commands COMMAND_RELOAD, COMMAND_VOID, COMMAND_AGE, + COMMAND_EQUIP_IRONS, + COMMAND_EQUIP_HOVERS, + COMMAND_USE_OCARINA, COMMAND_SAVESTATE, COMMAND_LOADSTATE, COMMAND_SAVEPOS, diff --git a/src/gz/state.c b/src/gz/state.c index 4805d6f5..c61510ab 100644 --- a/src/gz/state.c +++ b/src/gz/state.c @@ -1700,7 +1700,7 @@ void load_state(const struct state_meta *state) } else { /* event state */ - serial_read(&p, z64_event_state_1, 0x0008); + serial_read(&p, &z64_event_state_1, 0x0008); serial_read(&p, z64_event_state_2, 0x0004); /* event camera parameters */ for (int i = 0; i < 24; ++i) diff --git a/src/gz/z64.h b/src/gz/z64.h index 2d6c806f..98c3f5f2 100644 --- a/src/gz/z64.h +++ b/src/gz/z64.h @@ -2230,7 +2230,7 @@ z64_extern z64_part_ovl_t z64_part_ovl_tab[37]; z64_extern z64_actor_ovl_t z64_actor_ovl_tab[471]; z64_extern char z_camera_c_data[]; z64_extern char z64_hud_state[]; -z64_extern char z64_event_state_1[]; +z64_extern uint32_t z64_event_state_1; z64_extern uint32_t z64_letterbox_time; z64_extern char z64_event_state_2[]; z64_extern char z64_event_camera[]; @@ -2270,6 +2270,9 @@ z64_extern char z64_song_ptr[]; z64_extern uint8_t z64_ocarina_button_state; z64_extern uint8_t z64_sfx_write_pos; z64_extern uint8_t z64_sfx_read_pos; +z64_extern z64_xyzf_t z64_sfx_unk1; +z64_extern float z64_sfx_unk2; +z64_extern int8_t z64_sfx_unk3; z64_extern uint8_t z64_audio_cmd_write_pos; z64_extern uint8_t z64_audio_cmd_read_pos; z64_extern uint8_t z64_afx_cfg; @@ -2370,10 +2373,15 @@ void z64_ConfigureAfx (uint8_t cfg); uint32_t z64_AfxRand (void); void z64_OcarinaUpdate (void); void z64_ResetAudio (uint8_t cfg); +void z64_PlaySfx (uint16_t sfx, z64_xyzf_t *a1, + uint8_t a2, float *a3, + float *sp10, int8_t *sp14); int z64_CheckAfxConfigBusy (void); uint32_t z64_LoadOverlay (uint32_t vrom_start, uint32_t vrom_end, uint32_t vram_start, uint32_t vram_end, void *dst); void z64_SeedRandom (uint32_t seed); +void z64_UseButton (z64_game_t *game, z64_link_t *link, + uint8_t item, uint8_t button); #endif