From 9506da3c7d410f75dd0c5d9dc42379e8b994a840 Mon Sep 17 00:00:00 2001 From: Eduardo-V03 Date: Sat, 2 Aug 2025 22:55:19 -0300 Subject: [PATCH] Rumble docs update --- soh/include/functions.h | 3 - soh/include/padmgr.h | 99 +++++++++++ soh/include/regs.h | 9 + soh/include/rumble.h | 51 ++++++ soh/include/z64.h | 17 +- soh/src/code/code_800D2E30.c | 120 -------------- soh/src/code/game.c | 5 +- soh/src/code/padmgr.c | 94 +++++++++-- soh/src/code/sys_rumble.c | 154 ++++++++++++++++++ soh/src/code/z_actor.c | 9 +- soh/src/code/z_construct.c | 8 +- soh/src/code/z_debug.c | 3 +- soh/src/code/z_demo.c | 3 +- soh/src/code/z_game_over.c | 34 ++-- soh/src/code/z_kankyo.c | 3 +- soh/src/code/z_play.c | 5 +- soh/src/code/z_rumble.c | 138 ++++++++++++++++ .../ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c | 13 +- .../ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c | 9 +- .../actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c | 7 +- .../actors/ovl_Bg_Dodoago/z_bg_dodoago.c | 7 +- .../ovl_Bg_Heavy_Block/z_bg_heavy_block.c | 9 +- .../ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c | 7 +- .../ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c | 5 +- .../ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c | 7 +- .../ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c | 5 +- .../ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c | 5 +- .../ovl_Bg_Mizu_Water/z_bg_mizu_water.c | 7 +- .../z_bg_mori_rakkatenjo.c | 5 +- .../ovl_Bg_Relay_Objects/z_bg_relay_objects.c | 5 +- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 5 +- .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 7 +- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 11 +- .../actors/ovl_Boss_Goma/z_boss_goma.c | 7 +- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 6 +- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 7 +- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 7 +- .../overlays/actors/ovl_Demo_Gt/z_demo_gt.c | 4 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 6 +- .../actors/ovl_En_Bigokuta/z_en_bigokuta.c | 5 +- soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c | 5 +- .../overlays/actors/ovl_En_Bombf/z_en_bombf.c | 4 +- .../actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c | 6 +- .../overlays/actors/ovl_En_Horse/z_en_horse.c | 11 +- soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c | 5 +- .../overlays/actors/ovl_En_Ishi/z_en_ishi.c | 6 +- .../actors/ovl_En_M_Thunder/z_en_m_thunder.c | 5 +- soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c | 9 +- soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c | 12 +- soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c | 5 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 5 +- .../overlays/actors/ovl_Fishing/z_fishing.c | 27 +-- .../actors/ovl_Obj_Switch/z_obj_switch.c | 7 +- .../actors/ovl_player_actor/z_player.c | 4 +- .../ovl_file_choose/z_file_choose.c | 3 +- .../ovl_file_choose/z_file_copy_erase.c | 7 +- .../ovl_file_choose/z_file_nameset_PAL.c | 2 +- 57 files changed, 767 insertions(+), 267 deletions(-) create mode 100644 soh/include/padmgr.h create mode 100644 soh/include/rumble.h delete mode 100644 soh/src/code/code_800D2E30.c create mode 100644 soh/src/code/sys_rumble.c create mode 100644 soh/src/code/z_rumble.c diff --git a/soh/include/functions.h b/soh/include/functions.h index 8deb36953..eec4475c8 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -1818,9 +1818,6 @@ uintptr_t SysUcode_GetUCodeBoot(void); size_t SysUcode_GetUCodeBootSize(void); uint32_t SysUcode_GetUCode(void); uintptr_t SysUcode_GetUCodeData(void); -void func_800D2E30(UnkRumbleStruct* arg0); -void func_800D3140(UnkRumbleStruct* arg0); -void func_800D3178(UnkRumbleStruct* arg0); void func_800D31A0(void); void func_800D31F0(void); void func_800D3210(void); diff --git a/soh/include/padmgr.h b/soh/include/padmgr.h new file mode 100644 index 000000000..9859b501a --- /dev/null +++ b/soh/include/padmgr.h @@ -0,0 +1,99 @@ +#ifndef PADMGR_H +#define PADMGR_H + +#include "ultra64.h" +#include "libu64/pad.h" +#include "irqmgr.h" + +typedef enum ControllerPakType { + CONT_PAK_NONE, + CONT_PAK_RUMBLE, + CONT_PAK_OTHER +} ControllerPakType; + +typedef struct PadMgr { + /* 0x0000 */ OSContStatus padStatus[MAXCONTROLLERS]; + /* 0x0010 */ OSMesg serialMsg; + /* 0x0014 */ OSMesg lockMsg; + /* 0x0018 */ OSMesg interruptMsgBuf[4]; + /* 0x0028 */ OSMesgQueue serialLockQueue; + /* 0x0040 */ OSMesgQueue lockQueue; + /* 0x0058 */ OSMesgQueue interruptQueue; + /* 0x0070 */ IrqMgrClient irqClient; + /* 0x0078 */ IrqMgr* irqMgr; + /* 0x0080 */ OSThread thread; + /* 0x0230 */ Input inputs[MAXCONTROLLERS]; + /* 0x0290 */ OSContPad pads[MAXCONTROLLERS]; + /* 0x02A8 */ vu8 validCtrlrsMask; + /* 0x02A9 */ u8 nControllers; + /* 0x02AA */ u8 ctrlrIsConnected[MAXCONTROLLERS]; + /* 0x02AE */ u8 pakType[MAXCONTROLLERS]; + /* 0x02B2 */ vu8 rumbleEnable[MAXCONTROLLERS]; + /* 0x02B6 */ u8 rumbleTimer[MAXCONTROLLERS]; + /* 0x02BC */ OSPfs rumblePfs[MAXCONTROLLERS]; + /* 0x045C */ vu8 rumbleOffTimer; // amount of VI retraces to not rumble for, takes priority over rumbleOnTimer + /* 0x045D */ vu8 rumbleOnTimer; // amount of VI retraces to rumble for + /* 0x045E */ u8 isResetting; + /* 0x0460 */ void (*retraceCallback)(struct PadMgr* padMgr, void* arg); + /* 0x0464 */ void* retraceCallbackArg; +} PadMgr; // size = 0x468 + +// Initialization + +void PadMgr_Init(PadMgr* padMgr, OSMesgQueue* serialEventQueue, IrqMgr* irqMgr, OSId id, OSPri priority, void* stack); + +// Fetching inputs + +// This function cannot be prototyped here in all configurations because it is called incorrectly in fault_gc.c +// (see bug in `Fault_PadCallback`) +#if PLATFORM_N64 || defined(AVOID_UB) +void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 gameRequest); +#endif + +// For internal use by Controller Pak systems + +OSMesgQueue* PadMgr_AcquireSerialEventQueue(PadMgr* padMgr); +void PadMgr_ReleaseSerialEventQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue); + +// Rumble + +void PadMgr_RumbleStop(PadMgr* padMgr); +void PadMgr_RumbleReset(PadMgr* padMgr); +void PadMgr_RumbleSetSingle(PadMgr* padMgr, u32 port, u32 rumble); +void PadMgr_RumbleSet(PadMgr* padMgr, u8* enable); + +// Retrace callback + +/** + * Sets the padmgr retrace callback that runs while waiting for controller input. The callback may be passed a single + * user-provided argument. The callback function should be `void (*)(PadMgr*, void*)`. + * + * @param callback callback to run before rumble state is updated for the current VI + * @param arg the argument to pass to the callback + * + * @see PADMGR_UNSET_RETRACE_CALLACK + */ +#define PADMGR_SET_RETRACE_CALLACK(padmgr, callback, arg) \ + do { \ + (padmgr)->retraceCallback = (callback); \ + (padmgr)->retraceCallbackArg = (arg); \ + } while (0) + +/** + * Unsets the current padmgr retrace callback if it and the argument are the same as the ones already registered. + * + * @param callback the callback to unset, if it is set + * @param arg the argument to unset, if it is set + * + * @see PADMGR_SET_RETRACE_CALLACK + */ +#define PADMGR_UNSET_RETRACE_CALLACK(padmgr, callback, arg) \ + if ((padmgr)->retraceCallback == (callback) && (padmgr)->retraceCallbackArg == (arg)) { \ + (padmgr)->retraceCallback = NULL; \ + (padmgr)->retraceCallbackArg = NULL; \ + } \ + (void)0 + +extern PadMgr gPadMgr; + +#endif diff --git a/soh/include/regs.h b/soh/include/regs.h index cfbd1ae20..12fb7ced6 100644 --- a/soh/include/regs.h +++ b/soh/include/regs.h @@ -1,6 +1,11 @@ #ifndef REGS_H #define REGS_H +#include "ultra64.h" +#include "versions.h" + +struct PlayState; + #define REG_GROUPS 29 // number of REG groups, i.e. REG, SREG, OREG, etc. #define REG_PAGES 6 #define REG_PER_PAGE 16 @@ -121,6 +126,10 @@ #define R_ITEM_AMMO_Y(i) VREG(68 + i) #define R_ITEM_ICON_WIDTH(i) VREG(76 + i) #define R_ITEM_BTN_WIDTH(i) VREG(80 + i) +#define R_GAME_OVER_RUMBLE_STRENGTH VREG(90) +#define R_GAME_OVER_RUMBLE_DURATION VREG(91) +#define R_GAME_OVER_RUMBLE_DECREASE_RATE VREG(92) +#define R_ENABLE_ACTOR_DEBUG_PRINTF HREG(20) #define R_DISABLE_INPUT_DISPLAY HREG(47) #define R_EN_GOROIWA_SPEED mREG(12) #define R_NAVI_MSG_REGION_ALPHA nREG(87) diff --git a/soh/include/rumble.h b/soh/include/rumble.h new file mode 100644 index 000000000..f8e0b82cb --- /dev/null +++ b/soh/include/rumble.h @@ -0,0 +1,51 @@ +#ifndef RUMBLE_H +#define RUMBLE_H + +#include "ultra64.h" + +#define RUMBLE_MAX_REQUESTS 64 + +typedef enum RumbleState { + RUMBLE_STATE_CLEAR, + RUMBLE_STATE_RUNNING, + RUMBLE_STATE_RESET +} RumbleState; + +typedef struct RumbleMgr { + /* 0x000 */ u8 rumbleEnable[MAXCONTROLLERS]; + /* 0x004 */ u8 reqStrengths[RUMBLE_MAX_REQUESTS]; // Source strength modulated by distance to the source + /* 0x044 */ u8 reqDurations[RUMBLE_MAX_REQUESTS]; // Duration until decreaseRate kicks in + /* 0x084 */ u8 reqDecreaseRates[RUMBLE_MAX_REQUESTS]; // Decreases the strength by this much every Vertical Retrace, once the strength hits 0 the request slot is freed + /* 0x0C4 */ u8 reqAccumulators[RUMBLE_MAX_REQUESTS]; // Starts at 0, incremented by the strength every Vertical Retrace + /* 0x104 */ u8 state; + /* 0x105 */ u8 updateEnabled; + /* 0x106 */ u16 onTimer; // Duration for which there has been an active rumble request running + /* 0x108 */ u16 offTimer; // Duration for which there has not been an active rumble request running, capped at 5 + /* 0x10A */ u8 overrideStrength; // overrides requests with these parameters + /* 0x10B */ u8 overrideDuration; + /* 0x10C */ u8 overrideDecreaseRate; + /* 0x10D */ u8 overrideAccumulator; +} RumbleMgr; // size = 0x10E + +// internal + +void RumbleMgr_Init(RumbleMgr* rumbleMgr); +void RumbleMgr_Destroy(RumbleMgr* rumbleMgr); +void RumbleMgr_Update(RumbleMgr* rumbleMgr); + +// external + +void Rumble_Override(f32 distSq, u8 sourceStrength, u8 duration, u8 decreaseRate); +void Rumble_Request(f32 distSq, u8 sourceStrength, u8 duration, u8 decreaseRate); + +void Rumble_Init(void); +void Rumble_Destroy(void); + +s32 Rumble_Controller1HasRumblePak(void); + +void Rumble_Reset(void); +void Rumble_ClearRequests(void); + +void Rumble_SetUpdateEnabled(u32 enable); + +#endif diff --git a/soh/include/z64.h b/soh/include/z64.h index 79ecdabcd..4c2853bf8 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -33,6 +33,7 @@ #include "ichain.h" #include "regs.h" #include "gfx.h" +#include "rumble.h" #if defined(__LP64__) #define _SOH64 @@ -2239,22 +2240,6 @@ typedef struct { /* 0x0084 */ u32 unk_84; } ViMode; -typedef struct { - /* 0x000 */ u8 rumbleEnable[4]; - /* 0x004 */ u8 unk_04[0x40]; - /* 0x044 */ u8 unk_44[0x40]; - /* 0x084 */ u8 unk_84[0x40]; - /* 0x0C4 */ u8 unk_C4[0x40]; - /* 0x104 */ u8 unk_104; - /* 0x105 */ u8 unk_105; - /* 0x106 */ u16 unk_106; - /* 0x108 */ u16 unk_108; - /* 0x10A */ u8 unk_10A; - /* 0x10B */ u8 unk_10B; - /* 0x10C */ u8 unk_10C; - /* 0x10D */ u8 unk_10D; -} UnkRumbleStruct; // size = 0x10E - typedef struct { /* 0x00 */ char unk_00[0x18]; /* 0x18 */ s32 unk_18; diff --git a/soh/src/code/code_800D2E30.c b/soh/src/code/code_800D2E30.c deleted file mode 100644 index 725df18cc..000000000 --- a/soh/src/code/code_800D2E30.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "global.h" -#include - -void func_800D2E30(UnkRumbleStruct* arg0) { - static u8 D_8012DBB0 = 1; - s32 i; - s32 unk_a3; - s32 index = -1; - - for (i = 0; i < 4; i++) { - arg0->rumbleEnable[i] = 0; - } - - if (arg0->unk_105 == 0) { - if (D_8012DBB0 != 0) { - for (i = 0; i < 4; i++) { - gPadMgr.pakType[i] = 0; - } - } - D_8012DBB0 = arg0->unk_105; - return; - } - - D_8012DBB0 = arg0->unk_105; - - if (arg0->unk_104 == 2) { - for (i = 0; i < 4; ++i) { - gPadMgr.pakType[i] = 0; - } - - for (i = 0; i < 0x40; i++) { - arg0->unk_C4[i] = 0; - arg0->unk_84[i] = 0; - arg0->unk_44[i] = 0; - arg0->unk_04[i] = 0; - } - arg0->unk_106 = arg0->unk_108 = arg0->unk_10A = arg0->unk_10B = arg0->unk_10C = arg0->unk_10D = 0; - arg0->unk_104 = 1; - } - if (arg0->unk_104 != 0) { - for (i = 0; i < 0x40; i++) { - if (arg0->unk_04[i] != 0) { - if (arg0->unk_44[i] > 0) { - arg0->unk_44[i]--; - } else { - unk_a3 = arg0->unk_04[i] - arg0->unk_84[i]; - if (unk_a3 > 0) { - arg0->unk_04[i] = unk_a3; - } else { - arg0->unk_04[i] = 0; - } - } - - unk_a3 = arg0->unk_C4[i] + arg0->unk_04[i]; - arg0->unk_C4[i] = unk_a3; - if (index == -1) { - index = i; - arg0->rumbleEnable[0] = (unk_a3 >= 0x100); - } else if (arg0->unk_04[index] < arg0->unk_04[i]) { - index = i; - arg0->rumbleEnable[0] = (unk_a3 >= 0x100); - } - } - } - if (arg0->unk_10A != 0) { - if (arg0->unk_10B > 0) { - arg0->unk_10B--; - } else { - unk_a3 = arg0->unk_10A - arg0->unk_10C; - if (unk_a3 > 0) { - arg0->unk_10A = unk_a3; - } else { - arg0->unk_10A = 0; - } - } - unk_a3 = arg0->unk_10D + arg0->unk_10A; - arg0->unk_10D = unk_a3; - arg0->rumbleEnable[0] = (unk_a3 >= 0x100); - } - if (arg0->unk_10A != 0) { - unk_a3 = arg0->unk_10A; - } else { - if (index == -1) { - unk_a3 = 0; - } else { - unk_a3 = arg0->unk_04[index]; - } - } - if (unk_a3 == 0) { - if ((++arg0->unk_108) >= 6) { - arg0->unk_106 = 0; - arg0->unk_108 = 5; - } - } else { - arg0->unk_108 = 0; - if ((++arg0->unk_106) >= 0x1C21) { - arg0->unk_104 = 0; - } - } - } else { - for (i = 0; i < 0x40; i++) { - arg0->unk_C4[i] = 0; - arg0->unk_84[i] = 0; - arg0->unk_44[i] = 0; - arg0->unk_04[i] = 0; - } - - arg0->unk_106 = arg0->unk_108 = arg0->unk_10A = arg0->unk_10B = arg0->unk_10C = arg0->unk_10D = 0; - } -} - -void func_800D3140(UnkRumbleStruct* arg0) { - memset(arg0, 0, sizeof(UnkRumbleStruct)); - arg0->unk_104 = 2; - arg0->unk_105 = 1; -} - -void func_800D3178(UnkRumbleStruct* arg0) { - memset(arg0, 0, sizeof(UnkRumbleStruct)); -} diff --git a/soh/src/code/game.c b/soh/src/code/game.c index a31cf6474..82877b9e7 100644 --- a/soh/src/code/game.c +++ b/soh/src/code/game.c @@ -1,6 +1,7 @@ #include #include "global.h" #include "vt.h" +#include "rumble.h" #include "libultraship/bridge.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -450,7 +451,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g ViMode_Init(&sViMode); } SpeedMeter_Init(&D_801664D0); - func_800AA0B4(); + Rumble_Init(); osSendMesgPtr(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); endTime = osGetTime(); @@ -471,7 +472,7 @@ void GameState_Destroy(GameState* gameState) { if (gameState->destroy != NULL) { gameState->destroy(gameState); } - func_800AA0F0(); + Rumble_Destroy(); SpeedMeter_Destroy(&D_801664D0); VisCvg_Destroy(&sVisCvg); VisZBuf_Destroy(&sVisZBuf); diff --git a/soh/src/code/padmgr.c b/soh/src/code/padmgr.c index 173b03394..a636be4d3 100644 --- a/soh/src/code/padmgr.c +++ b/soh/src/code/padmgr.c @@ -1,38 +1,106 @@ -#include "global.h" -#include "vt.h" -#include +/** + * @file padmgr.c + * + * This file implements communicating with joybus devices at a high level and serving the results to other threads. + * + * Any device that can be plugged into one of the four controller ports such as a standard N64 controller is a joybus + * device. Some joybus devices are also located inside the cartridge such as EEPROM for save data or the Real-Time + * Clock, however neither of these are used in Zelda64 and so this type of communication is unimplemented. Of the + * possible devices that can be plugged into the controller ports, the only device that padmgr will recognize and + * attempt to communicate with is the standard N64 controller. + * + * Communicating with these devices is broken down into various layers: + * + * Other threads : The rest of the program that will use the polled data + * | + * PadMgr : Manages devices, submits polling commands at vertical retrace + * | + * Libultra osCont* routines : Interface for building commands and safely using the Serial Interface + * | + * Serial Interface : Hardware unit for sending joybus commands and receiving data via DMA + * | + * PIF : Forwards joybus commands and receives response data from the devices + * |---¬---¬---¬-------¬ + * 1 2 3 4 5 : The joybus devices plugged into the four controller ports or on the cartridge + * + * Joybus communication is handled on another thread as polling and receiving controller data is a slow process; the + * N64 programming manual section 26.2.4.1 quotes 2 milliseconds as the expected delay from calling + * `osContStartReadData` to receiving the data. By running this on a separate thread to the game state, work can be + * done while waiting for this operation to complete. + */ +#include "libu64/debug.h" +#include "libu64/padsetup.h" +#include "array_count.h" +#include "padmgr.h" +#include "printf.h" +#include "fault.h" +#include "terminal.h" +#include "translation.h" +#include "line_numbers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/controls/Mouse.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" -s32 D_8012D280 = 1; +#define PADMGR_LOG(controllerNum, msg) (void)0 + +#define LOG_SEVERITY_NOLOG 0 +#define LOG_SEVERITY_CRITICAL 1 +#define LOG_SEVERITY_ERROR 2 +#define LOG_SEVERITY_VERBOSE 3 + +s32 gPadMgrLogSeverity = LOG_SEVERITY_CRITICAL; void OTRControllerCallback(uint8_t rumble); -OSMesgQueue* PadMgr_LockSerialMesgQueue(PadMgr* padMgr) { - OSMesgQueue* ctrlrQ = NULL; +/** + * Acquires exclusive access to the serial event queue. + * + * When a DMA to/from PIF RAM completes, an SI interrupt is generated to notify the process that the DMA has completed + * and a message is posted to the serial event queue. If multiple processes are trying to use the SI at the same time + * it becomes ambiguous as to which DMA has completed, so a locking system is required to arbitrate access to the SI. + * + * Once the task requiring the serial event queue is complete, it should be released with a call to + * `PadMgr_ReleaseSerialEventQueue()`. + * + * If another process tries to acquire the event queue, the current thread will be blocked until the event queue is + * released. Note the possibility for a deadlock, if the thread that already holds the serial event queue attempts to + * acquire it again it will block forever. + * + * @return The message queue to which SI interrupt events are posted. + * + * @see PadMgr_ReleaseSerialEventQueue + */ +OSMesgQueue* PadMgr_AcquireSerialEventQueue(PadMgr* padMgr) { + OSMesgQueue* serialEventQueue = NULL; - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Waiting for lock" osSyncPrintf("%2d %d serialMsgQロック待ち %08x %08x %08x\n", osGetThreadId(NULL), padMgr->serialMsgQ.validCount, padMgr, &padMgr->serialMsgQ, &ctrlrQ); } - osRecvMesg(&padMgr->serialMsgQ, (OSMesg*)&ctrlrQ, OS_MESG_BLOCK); + osRecvMesg(&padMgr->serialLockQueue, (OSMesg*)&serialEventQueue, OS_MESG_BLOCK); - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Locked" osSyncPrintf("%2d %d serialMsgQをロックしました %08x\n", osGetThreadId(NULL), padMgr->serialMsgQ.validCount, ctrlrQ); } - return ctrlrQ; + return serialEventQueue; } -void PadMgr_UnlockSerialMesgQueue(PadMgr* padMgr, OSMesgQueue* ctrlrQ) { - if (D_8012D280 > 2) { +/** + * Relinquishes access to the serial message queue, allowing another process to acquire and use it. + * + * @param serialEventQueue The serial message queue acquired by `PadMgr_AcquireSerialEventQueue` + * + * @see PadMgr_AcquireSerialEventQueue + */ +void PadMgr_ReleaseSerialEventQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Unlock" osSyncPrintf("%2d %d serialMsgQロック解除します %08x %08x %08x\n", osGetThreadId(NULL), padMgr->serialMsgQ.validCount, padMgr, &padMgr->serialMsgQ, ctrlrQ); @@ -40,7 +108,7 @@ void PadMgr_UnlockSerialMesgQueue(PadMgr* padMgr, OSMesgQueue* ctrlrQ) { osSendMesgPtr(&padMgr->serialMsgQ, ctrlrQ, OS_MESG_BLOCK); - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Unlocked" osSyncPrintf("%2d %d serialMsgQロック解除しました %08x %08x %08x\n", osGetThreadId(NULL), padMgr->serialMsgQ.validCount, padMgr, &padMgr->serialMsgQ, ctrlrQ); diff --git a/soh/src/code/sys_rumble.c b/soh/src/code/sys_rumble.c new file mode 100644 index 000000000..57f61c921 --- /dev/null +++ b/soh/src/code/sys_rumble.c @@ -0,0 +1,154 @@ +/** + * @file sys_rumble.c + * + * This file implements a manager for storing and processing rumble pak requests made by the game state. Despite some + * parts of the system appearing to accommodate all four controller ports, only controller 1 will rumble according to + * the processed requests. + * This file is half of the system that runs on the padmgr thread alongside controller communications. The rest of the + * system that receives the requests from the game state runs on the graph thread and is implemented in `z_rumble.c`. + * + * @see RumbleMgr + * @see z_rumble.c + * + * @note Original filename is likely sys_vibrate.c or similar as it is ordered after sys_ucode.c + */ +#include "rumble.h" +#include "padmgr.h" + +/** + * Rumble manager update, runs on Vertical Retrace on the padmgr thread. + */ +void RumbleMgr_Update(RumbleMgr* rumbleMgr) { + static u8 sWasEnabled = true; + s32 i; + s32 strength; + s32 strongestIndex = -1; + + // Clear enable status for all controllers + for (i = 0; i < MAXCONTROLLERS; i++) { + rumbleMgr->rumbleEnable[i] = false; + } + + if (!rumbleMgr->updateEnabled) { + if (sWasEnabled) { + // If it was previously enabled, reset pak type + for (i = 0; i < MAXCONTROLLERS; i++) { + gPadMgr.pakType[i] = CONT_PAK_NONE; + } + } + sWasEnabled = rumbleMgr->updateEnabled; + return; + } + + sWasEnabled = rumbleMgr->updateEnabled; + + if (rumbleMgr->state == RUMBLE_STATE_RESET) { + // Reset + for (i = 0; i < MAXCONTROLLERS; i++) { + gPadMgr.pakType[i] = CONT_PAK_NONE; + } + + for (i = 0; i < RUMBLE_MAX_REQUESTS; i++) { + rumbleMgr->reqAccumulators[i] = 0; + rumbleMgr->reqDecreaseRates[i] = 0; + rumbleMgr->reqDurations[i] = 0; + rumbleMgr->reqStrengths[i] = 0; + } + + rumbleMgr->onTimer = rumbleMgr->offTimer = rumbleMgr->overrideStrength = rumbleMgr->overrideDuration = + rumbleMgr->overrideDecreaseRate = rumbleMgr->overrideAccumulator = 0; + + rumbleMgr->state = RUMBLE_STATE_RUNNING; + } + + if (rumbleMgr->state != RUMBLE_STATE_CLEAR) { + // Search for index with largest strength + for (i = 0; i < RUMBLE_MAX_REQUESTS; i++) { + if (rumbleMgr->reqStrengths[i] != 0) { + // Non-empty request slot + if (rumbleMgr->reqDurations[i] > 0) { + rumbleMgr->reqDurations[i]--; + } else { + // After duration, decrease the strength by the decrease rate + strength = rumbleMgr->reqStrengths[i] - rumbleMgr->reqDecreaseRates[i]; + rumbleMgr->reqStrengths[i] = MAX(strength, 0); + } + + // Increment accumulator by the strength + strength = rumbleMgr->reqAccumulators[i] + rumbleMgr->reqStrengths[i]; + rumbleMgr->reqAccumulators[i] = strength; + + if (strongestIndex == -1) { + strongestIndex = i; + // Rumble is enabled on the controller only when there is overflow of the accumulator, overflow + // will happen more often for larger request strengths making it feel stronger to the player + rumbleMgr->rumbleEnable[0] = strength > 255; + } else if (rumbleMgr->reqStrengths[i] > rumbleMgr->reqStrengths[strongestIndex]) { + strongestIndex = i; + rumbleMgr->rumbleEnable[0] = strength > 255; + } + } + } + + if (rumbleMgr->overrideStrength != 0) { + // Set override + if (rumbleMgr->overrideDuration > 0) { + rumbleMgr->overrideDuration--; + } else { + // Once the duration is over, start decrementing the strength + strength = rumbleMgr->overrideStrength - rumbleMgr->overrideDecreaseRate; + rumbleMgr->overrideStrength = MAX(strength, 0); + } + // Increment accumulator, set rumble enabled on overflow + strength = rumbleMgr->overrideAccumulator + rumbleMgr->overrideStrength; + rumbleMgr->overrideAccumulator = strength; + rumbleMgr->rumbleEnable[0] = strength > 255; + } + + if (rumbleMgr->overrideStrength != 0) { + strength = rumbleMgr->overrideStrength; + } else { + strength = (strongestIndex == -1) ? 0 : rumbleMgr->reqStrengths[strongestIndex]; + } + + if (strength == 0) { + // No rumble + if ((++rumbleMgr->offTimer) > 5) { + // After 5 VIs with no rumble, reset the rumble on timer + rumbleMgr->onTimer = 0; + rumbleMgr->offTimer = 5; + } + } else { + // Rumble + rumbleMgr->offTimer = 0; + if ((++rumbleMgr->onTimer) > 7200) { // 2 minutes at 60 VI/s, 2 minutes 24 seconds at 50 VI/s + // Clear all requests if rumble has been on for too long + rumbleMgr->state = RUMBLE_STATE_CLEAR; + } + } + } else { + // Clear all requests + for (i = 0; i < RUMBLE_MAX_REQUESTS; i++) { + rumbleMgr->reqAccumulators[i] = 0; + rumbleMgr->reqDecreaseRates[i] = 0; + rumbleMgr->reqDurations[i] = 0; + rumbleMgr->reqStrengths[i] = 0; + } + + // Clear override request + rumbleMgr->onTimer = rumbleMgr->offTimer = rumbleMgr->overrideStrength = rumbleMgr->overrideDuration = + rumbleMgr->overrideDecreaseRate = rumbleMgr->overrideAccumulator = 0; + } +} + +void RumbleMgr_Init(RumbleMgr* rumbleMgr) { + bzero(rumbleMgr, sizeof(RumbleMgr)); + rumbleMgr->state = RUMBLE_STATE_RESET; + rumbleMgr->updateEnabled = true; +} + +void RumbleMgr_Destroy(RumbleMgr* rumbleMgr) { +#if DEBUG_FEATURES + bzero(rumbleMgr, sizeof(RumbleMgr)); +#endif +} diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index d8263f5de..4f1d8c715 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -1,5 +1,6 @@ #include "global.h" #include "vt.h" +#include "rumble.h" #include "overlays/actors/ovl_Arms_Hook/z_arms_hook.h" #include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" @@ -4137,11 +4138,11 @@ void func_80033E1C(PlayState* play, s16 arg1, s16 arg2, s16 arg3) { Quake_SetCountdown(var, arg2); } -void func_80033E88(Actor* actor, PlayState* play, s16 arg2, s16 arg3) { - if (arg2 >= 5) { - func_800AA000(actor->xyzDistToPlayerSq, 0xFF, 0x14, 0x96); +void Actor_RequestQuakeAndRumble(Actor* actor, PlayState* play, s16 quakeY, s16 quakeDuration) { + if (quakeY >= 5) { + Rumble_Request(actor->xyzDistToPlayerSq, 255, 20, 150); } else { - func_800AA000(actor->xyzDistToPlayerSq, 0xB4, 0x14, 0x64); + Rumble_Request(actor->xyzDistToPlayerSq, 180, 20, 100); } func_80033DB8(play, arg2, arg3); diff --git a/soh/src/code/z_construct.c b/soh/src/code/z_construct.c index 06f872995..7c1e4b23a 100644 --- a/soh/src/code/z_construct.c +++ b/soh/src/code/z_construct.c @@ -573,9 +573,11 @@ void Regs_InitDataImpl(void) { VREG(87) = 64; VREG(88) = 66; VREG(89) = 0; - VREG(90) = 126; - VREG(91) = 124; - VREG(92) = -63; + R_GAME_OVER_RUMBLE_STRENGTH = 126; + R_GAME_OVER_RUMBLE_DURATION = 124; + //! @bug This is eventually cast to a u8 after some scaling in `GameOver_Update`, negative numbers typically + //! become large (fast) decrease rates + R_GAME_OVER_RUMBLE_DECREASE_RATE = -63; } void Regs_InitData(PlayState* play) { diff --git a/soh/src/code/z_debug.c b/soh/src/code/z_debug.c index aebd08f86..61da79097 100644 --- a/soh/src/code/z_debug.c +++ b/soh/src/code/z_debug.c @@ -1,4 +1,5 @@ #include "global.h" +#include "rumble.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" typedef struct { @@ -202,7 +203,7 @@ void func_8006390C(Input* input) { } if (iREG(0)) { iREG(0) = 0; - func_800AA000(0, iREG(1), iREG(2), iREG(3)); + Rumble_Request(0.0f, iREG(1), iREG(2), iREG(3)); } } } diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index b6ccedc7c..a11a2f229 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -1,5 +1,6 @@ #include "global.h" #include "z64camera.h" +#include "rumble.h" #include @@ -473,7 +474,7 @@ void Cutscene_Command_FadeBGM(PlayState* play, CutsceneContext* csCtx, CsCmdMusi // Command 9: ? void Cutscene_Command_09(PlayState* play, CutsceneContext* csCtx, CsCmdUnknown9* cmd) { if (csCtx->frames == cmd->startFrame) { - func_800AA000(0.0f, cmd->unk_06, cmd->unk_07, cmd->unk_08); + Rumble_Request(0.0f, cmd->unk_06, cmd->unk_07, cmd->unk_08); } } diff --git a/soh/src/code/z_game_over.c b/soh/src/code/z_game_over.c index da154f887..4a7403722 100644 --- a/soh/src/code/z_game_over.c +++ b/soh/src/code/z_game_over.c @@ -1,4 +1,5 @@ #include "global.h" +#include "rumble.h" #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -23,9 +24,9 @@ void GameOver_Update(PlayState* play) { GameOverContext* gameOverCtx = &play->gameOverCtx; s16 i; s16 j; - s32 v90; - s32 v91; - s32 v92; + s32 rumbleStrength; + s32 rumbleDuration; + s32 rumbleDecreaseRate; switch (gameOverCtx->state) { case GAMEOVER_DEATH_START: @@ -82,12 +83,15 @@ void GameOver_Update(PlayState* play) { Environment_InitGameOverLights(play); gGameOverTimer = 20; - v90 = VREG(90); - v91 = VREG(91); - v92 = VREG(92); - func_800AA000(0.0f, ((v90 > 0x64) ? 0xFF : (v90 * 0xFF) / 0x64), (CLAMP_MAX(v91 * 3, 0xFF)), - ((v92 > 0x64) ? 0xFF : (v92 * 0xFF) / 0x64)); + if (1) {} + rumbleStrength = R_GAME_OVER_RUMBLE_STRENGTH; + rumbleDuration = R_GAME_OVER_RUMBLE_DURATION; + rumbleDecreaseRate = R_GAME_OVER_RUMBLE_DECREASE_RATE; + + Rumble_Request(0.0f, ((rumbleStrength > 100) ? 255 : (rumbleStrength * 255) / 100), + (CLAMP_MAX(rumbleDuration * 3, 255)), + ((rumbleDecreaseRate > 100) ? 255 : (rumbleDecreaseRate * 255) / 100)); gameOverCtx->state = GAMEOVER_DEATH_WAIT_GROUND; break; @@ -101,7 +105,7 @@ void GameOver_Update(PlayState* play) { if (gGameOverTimer == 0) { play->pauseCtx.state = 8; gameOverCtx->state++; - func_800AA15C(); + Rumble_Reset(); } break; @@ -116,12 +120,14 @@ void GameOver_Update(PlayState* play) { gGameOverTimer = 50; gameOverCtx->state++; - v90 = VREG(90); - v91 = VREG(91); - v92 = VREG(92); + if (1) {} + rumbleStrength = R_GAME_OVER_RUMBLE_STRENGTH; + rumbleDuration = R_GAME_OVER_RUMBLE_DURATION; + rumbleDecreaseRate = R_GAME_OVER_RUMBLE_DECREASE_RATE; - func_800AA000(0.0f, ((v90 > 0x64) ? 0xFF : (v90 * 0xFF) / 0x64), (CLAMP_MAX(v91 * 3, 0xFF)), - ((v92 > 0x64) ? 0xFF : (v92 * 0xFF) / 0x64)); + Rumble_Request(0.0f, ((rumbleStrength > 100) ? 255 : (rumbleStrength * 255) / 100), + (CLAMP_MAX(rumbleDuration * 3, 255)), + ((rumbleDecreaseRate > 100) ? 255 : (rumbleDecreaseRate * 255) / 100)); break; case GAMEOVER_REVIVE_WAIT_GROUND: diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c index d78a93c6c..bd840ddb5 100644 --- a/soh/src/code/z_kankyo.c +++ b/soh/src/code/z_kankyo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "rumble.h" #include #include "vt.h" #include "objects/gameplay_keep/gameplay_keep.h" @@ -420,7 +421,7 @@ void Environment_Init(PlayState* play2, EnvironmentContext* envCtx, s32 unused) } gCustomLensFlareOn = false; - func_800AA15C(); + Rumble_Reset(); } u8 Environment_SmoothStepToU8(u8* pvalue, u8 target, u8 scale, u8 step, u8 minStep) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index dfc832fc7..885b8f2d0 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1,5 +1,6 @@ #include "global.h" #include "vt.h" +#include "rumble.h" #include @@ -1164,7 +1165,7 @@ void Play_Update(PlayState* play) { PLAY_LOG(3580); play->gameplayFrames++; - func_800AA178(true); + Rumble_SetUpdateEnabled(true); // Gameplay stat tracking if (!gSaveContext.ship.stats.gameComplete && @@ -1227,7 +1228,7 @@ void Play_Update(PlayState* play) { PLAY_LOG(3662); } } else { - func_800AA178(false); + Rumble_SetUpdateEnabled(false); } PLAY_LOG(3672); diff --git a/soh/src/code/z_rumble.c b/soh/src/code/z_rumble.c new file mode 100644 index 000000000..fcc39adee --- /dev/null +++ b/soh/src/code/z_rumble.c @@ -0,0 +1,138 @@ +/** + * @file z_rumble.c + * + * This file implements an interface for the game state to set up, manage and request use of the rumble pak. Despite + * some parts of the system appearing to accommodate all four controller ports, only controller 1 can be instructed + * to rumble. + * This file is half of the system that runs on the graph thread alongside the game state. The rest of the system that + * processes the requests runs on the padmgr thread and is implemented in `sys_rumble.c`. + * + * @see sys_rumble.c + * + * @note Original filename is likely z_vibrate.c or similar as it is ordered after z_ss_sram.c and before z_view.c + */ +#include "rumble.h" +#include "padmgr.h" +#include "z_math.h" + +static s32 sUnused[4]; +RumbleMgr sRumbleMgr; + +/** + * Padmgr callback to update the state of rumble on Vertical Retrace. + * + * Unlike every other function in this file, this runs on the padmgr thread. + */ +void Rumble_Update(PadMgr* padMgr, void* arg) { + RumbleMgr_Update(&sRumbleMgr); + PadMgr_RumbleSet(padMgr, sRumbleMgr.rumbleEnable); +} + +/** + * Forces the rumble state to use the supplied parameters. + * The parameters are the same as in `Rumble_Request`. + * + * @see Rumble_Request + */ +void Rumble_Override(f32 distSq, u8 sourceStrength, u8 duration, u8 decreaseRate) { + s32 dist; + s32 strength; + + if (distSq > SQ(1000)) { + dist = 1000; + } else { + dist = sqrtf(distSq); + } + + if (dist < 1000 && sourceStrength != 0 && decreaseRate != 0) { + // Decrease the strength linearly with distance + strength = sourceStrength - (dist * 255) / 1000; + + if (strength > 0) { + // Note: sRumbleMgr is a shared resource between the graph and padmgr threads, no locking is done + // to ensure that the entire request is written before it is possibly used. + sRumbleMgr.overrideStrength = strength; + sRumbleMgr.overrideDuration = duration; + sRumbleMgr.overrideDecreaseRate = decreaseRate; + } + } +} + +/** + * Submits a request to the rumble manager with the properties given in the arguments. If there is no free request slot + * the request is silently dropped. + * + * @param distSq + * Squared distance, usually taken to be from an apparent source to the player in world coordinates. + * @param sourceStrength + * The strength of the rumble at 0 distance from the source. + * The rumble source strength decreases linearly with distance, a distance of 0 results in the full source strength + * while a distance of 1000 or greater is discarded. A source strength of 0 is discarded. A minimum source strength + * of 1 drops to 0 at 3 units of distance from the source. A maximum source strength of 255 drops to 0 at 1000 + * units of distance from the source. + * Note that, once the request has been submitted, if the distance to the source changes in subsequent frames while + * the rumble request is still running, the request will not be updated with the new distance. + * @param duration + * The duration for which the rumble will sustain full strength. It is measured in Vertical Retraces rather than + * game frames. There are ~60 Retraces/s on NTSC and 50 Retraces/s on PAL. + * @param decreaseRate + * The amount by which to lower the strength every Vertical Retrace once duration has hit 0. + */ +void Rumble_Request(f32 distSq, u8 sourceStrength, u8 duration, u8 decreaseRate) { + s32 dist; + s32 strength; + s32 i; + + if (distSq > SQ(1000)) { + dist = 1000; + } else { + dist = sqrtf(distSq); + } + + if (dist < 1000 && sourceStrength != 0 && decreaseRate != 0) { + // Decrease the strength linearly with distance + strength = sourceStrength - (dist * 255) / 1000; + + for (i = 0; i < RUMBLE_MAX_REQUESTS; i++) { + // Search for an empty slot + if (sRumbleMgr.reqStrengths[i] == 0) { + if (strength > 0) { + // Note: sRumbleMgr is a shared resource between the graph and padmgr threads, no locking is done + // to ensure that the entire request is written before it is possibly used. + sRumbleMgr.reqStrengths[i] = strength; + sRumbleMgr.reqDurations[i] = duration; + sRumbleMgr.reqDecreaseRates[i] = decreaseRate; + } + break; + } + } + } +} + +void Rumble_Init(void) { + RumbleMgr_Init(&sRumbleMgr); + PADMGR_SET_RETRACE_CALLACK(&gPadMgr, Rumble_Update, NULL); +} + +void Rumble_Destroy(void) { + PadMgr* padmgr = &gPadMgr; + + PADMGR_UNSET_RETRACE_CALLACK(padmgr, Rumble_Update, NULL); + RumbleMgr_Destroy(&sRumbleMgr); +} + +s32 Rumble_Controller1HasRumblePak(void) { + return gPadMgr.pakType[0] == CONT_PAK_RUMBLE; +} + +void Rumble_Reset(void) { + sRumbleMgr.state = RUMBLE_STATE_RESET; +} + +void Rumble_ClearRequests(void) { + sRumbleMgr.state = RUMBLE_STATE_CLEAR; +} + +void Rumble_SetUpdateEnabled(u32 enable) { + sRumbleMgr.updateEnabled = !!enable; +} diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c index a30a1dcd3..2ecc7a90b 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c @@ -5,6 +5,9 @@ */ #include "z_bg_bdan_objects.h" + +#include "rumble.h" + #include "objects/object_bdan_objects/object_bdan_objects.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -183,7 +186,7 @@ void func_8086C054(BgBdanObjects* this, PlayState* play) { player->actor.world.pos.x = -1130.0f; player->actor.world.pos.y = -1025.0f; player->actor.world.pos.z = -3300.0f; - func_800AA000(0.0f, 0xFF, 0x14, 0x96); + Rumble_Request(0.0f, 255, 20, 150); } } else if (this->timer != 0) { if (this->timer != 0) { @@ -208,13 +211,13 @@ void func_8086C1A0(BgBdanObjects* this, PlayState* play) { this->actionFunc = func_8086C29C; this->timer = 30; BgBdanObjects_SetContactRu1(this, 2); - func_800AA000(0.0f, 0xFF, 0x14, 0x96); + Rumble_Request(0.0f, 255, 20, 150); } else { if (this->timer != 0) { this->timer--; } if (this->timer == 0) { - func_800AA000(0.0f, 0x78, 0x14, 0xA); + Rumble_Request(0.0f, 120, 20, 10); this->timer = 11; } func_8002F974(&this->dyna.actor, NA_SE_EV_BUYOSTAND_RISING - SFX_FLAG); @@ -262,14 +265,14 @@ void func_8086C3D8(BgBdanObjects* this, PlayState* play) { player->actor.world.pos.z = -3500.0f; player->actor.shape.rot.y = 0x7530; player->actor.world.rot.y = player->actor.shape.rot.y; - func_800AA000(0.0f, 0xFF, 0x1E, 0x96); + Rumble_Request(0.0f, 255, 30, 150); } else { func_8002F974(&this->dyna.actor, NA_SE_EV_BUYOSTAND_FALL - SFX_FLAG); if (this->timer != 0) { this->timer--; } if (this->timer == 0) { - func_800AA000(0.0f, 0x78, 0x14, 0xA); + Rumble_Request(0.0f, 120, 20, 10); this->timer = 11; } if (this->dyna.actor.child != NULL) { diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c index d2a5c3b70..cdd7ecb0d 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c @@ -5,6 +5,9 @@ */ #include "z_bg_bdan_switch.h" + +#include "rumble.h" + #include "objects/object_bdan_objects/object_bdan_objects.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -278,7 +281,7 @@ void func_8086D694(BgBdanSwitch* this, PlayState* play) { if (this->unk_1C8 <= 0.1f) { func_8086D730(this); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH); - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0x78, 0x14, 0xA); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); } } } @@ -341,7 +344,7 @@ void func_8086D8CC(BgBdanSwitch* this, PlayState* play) { if (this->unk_1C8 <= 0.6f) { func_8086D9F8(this); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH); - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0x78, 0x14, 0xA); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); } } @@ -356,7 +359,7 @@ void func_8086D95C(BgBdanSwitch* this, PlayState* play) { if (this->unk_1C8 <= 0.1f) { func_8086DB24(this); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH); - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0x78, 0x14, 0xA); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c b/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c index 307df9df4..eb3895665 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c +++ b/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c @@ -5,6 +5,9 @@ */ #include "z_bg_ddan_kd.h" + +#include "rumble.h" + #include "objects/object_ddan_objects/object_ddan_objects.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -130,7 +133,7 @@ void BgDdanKd_LowerStairs(BgDdanKd* this, PlayState* play) { f32 effectStrength; Math_SmoothStepToF(&this->dyna.actor.speedXZ, 4.0f, 0.5f, 0.025f, 0.0f); - func_800AA000(500.0f, 0x78, 0x14, 0xA); + Rumble_Request(500.0f, 120, 20, 10); if (Math_SmoothStepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 200.0f - 20.0f, 0.075f, this->dyna.actor.speedXZ, 0.0075f) == 0.0f) { @@ -199,4 +202,4 @@ void BgDdanKd_Reset(void) { sBgDdanKdAccel.x = 0.0f; sBgDdanKdAccel.y = -0.45f; sBgDdanKdAccel.z = 0.0f; -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c b/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c index ecd684ac6..ece0feedb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c +++ b/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c @@ -6,6 +6,9 @@ #include "z_bg_dodoago.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" + +#include "rumble.h" + #include "objects/object_ddan_objects/object_ddan_objects.h" #define FLAGS 0 @@ -246,7 +249,7 @@ void BgDodoago_OpenJaw(BgDodoago* this, PlayState* play) { BgDodoago_SpawnSparkles(&pos, play); Math_StepToS(&this->state, 100, 3); - func_800AA000(500.0f, 0x78, 0x14, 0xA); + Rumble_Request(500.0f, 120, 20, 10); if (Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, 0x1333, 110 - this->state, 0x3E8, 0x32) == 0) { BgDodoago_SetupAction(this, BgDodoago_DoNothing); @@ -327,4 +330,4 @@ void BgDodoago_Reset(void) { sBgDodoagoFirstExplosiveFlag = false; sBgDodoagoDisableBombCatcher = 0; sBgDodoagoTimer = 0; -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c index 9d950e24f..695fd15f6 100644 --- a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c +++ b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c @@ -5,6 +5,9 @@ */ #include "z_bg_heavy_block.h" + +#include "rumble.h" + #include "objects/object_heavy_object/object_heavy_object.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -192,7 +195,7 @@ void BgHeavyBlock_MovePiece(BgHeavyBlock* this, PlayState* play) { thisx->velocity.z = Rand_CenteredFloat(8.0f); BgHeavyBlock_SetPieceRandRot(this, 1.0f); Audio_PlayActorSound2(thisx, NA_SE_EV_ROCK_BROKEN); - func_800AA000(thisx->xzDistToPlayer, 0x96, 0xA, 8); + Rumble_Request(thisx->xzDistToPlayer, 150, 10, 8); } } @@ -351,7 +354,7 @@ void BgHeavyBlock_LiftedUp(BgHeavyBlock* this, PlayState* play) { f32 xOffset; if (this->timer == 11) { - func_800AA000(0.0f, 0xFF, 0x14, 0x14); + Rumble_Request(0.0f, 255, 20, 20); Player_PlaySfx(&player->actor, NA_SE_PL_PULL_UP_BIGROCK); LOG_STRING("NA_SE_PL_PULL_UP_BIGROCK"); } @@ -395,7 +398,7 @@ void BgHeavyBlock_Fly(BgHeavyBlock* this, PlayState* play) { this->dyna.actor.floorHeight = raycastResult; if (this->dyna.actor.home.pos.y <= raycastResult) { - func_800AA000(0.0f, 0xFF, 0x3C, 4); + Rumble_Request(0.0f, 255, 60, 4); switch (this->dyna.actor.params & 0xFF) { case HEAVYBLOCK_BREAKABLE: diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c index a3e18a079..d4e029870 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c @@ -5,6 +5,9 @@ */ #include "z_bg_hidan_hamstep.h" + +#include "rumble.h" + #include "objects/object_hidan_objects/object_hidan_objects.h" #define FLAGS 0 @@ -312,7 +315,7 @@ void func_80888860(BgHidanHamstep* this, PlayState* play) { Quake_SetQuakeValues(quakeIndex, 0, 0, 500, 0); Quake_SetCountdown(quakeIndex, 20); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 255, 20, 150); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 255, 20, 150); func_80888638(this, play); osSyncPrintf("A(%d)\n", this->dyna.actor.params); } @@ -370,7 +373,7 @@ void func_80888A58(BgHidanHamstep* this, PlayState* play) { Quake_SetCountdown(quakeIndex, 7); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); - func_800AA000(10000.0f, 255, 20, 150); + Rumble_Request(SQ(100.0f), 255, 20, 150); func_808884C8(this, play); if ((this->dyna.actor.params & 0xFF) == 5) { diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c index e0a1d87c4..ab6d7436b 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c @@ -5,6 +5,9 @@ */ #include "z_bg_hidan_hrock.h" + +#include "rumble.h" + #include "objects/object_hidan_objects/object_hidan_objects.h" #define FLAGS 0 @@ -162,7 +165,7 @@ void func_808894B0(BgHidanHrock* this, PlayState* play) { (Math_CosS(this->dyna.actor.world.rot.y + (this->unk_168 << 0xE)) * 5.0f) + this->dyna.actor.home.pos.z; if (!(this->unk_168 % 4)) { - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 180, 10, 100); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 180, 10, 100); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_SHAKE); } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c index 00793b681..e2987a063 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c @@ -5,6 +5,9 @@ */ #include "z_bg_hidan_rock.h" + +#include "rumble.h" + #include "objects/object_hidan_objects/object_hidan_objects.h" #define FLAGS 0 @@ -237,7 +240,7 @@ void func_8088B69C(BgHidanRock* this, PlayState* play) { } if (!(this->timer % 4)) { - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0xB4, 0x0A, 0x64); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 180, 10, 100); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_SHAKE); } } @@ -403,4 +406,4 @@ void BgHidanRock_Draw(Actor* thisx, PlayState* play) { void BgHidanRock_Reset(void) { D_8088BFC0 = 0; -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c index eea4a8a59..8a0e5109f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c @@ -5,6 +5,9 @@ */ #include "z_bg_hidan_sima.h" + +#include "rumble.h" + #include "objects/object_hidan_objects/object_hidan_objects.h" #define FLAGS 0 @@ -145,7 +148,7 @@ void func_8088E5D0(BgHidanSima* this, PlayState* play) { this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z; } if (!(this->timer % 4)) { - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 180, 10, 100); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 180, 10, 100); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_SHAKE); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c b/soh/src/overlays/actors/ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c index 19985b2ce..e50192a64 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c +++ b/soh/src/overlays/actors/ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c @@ -1,4 +1,7 @@ #include "z_bg_mizu_shutter.h" + +#include "rumble.h" + #include "objects/object_mizu_objects/object_mizu_objects.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -129,7 +132,7 @@ void BgMizuShutter_Move(BgMizuShutter* this, PlayState* play) { if ((this->dyna.actor.world.pos.x == this->closedPos.x) && (this->dyna.actor.world.pos.y == this->closedPos.y) && (this->dyna.actor.world.pos.z == this->closedPos.z)) { - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0x78, 0x14, 0xA); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); this->actionFunc = BgMizuShutter_WaitForSwitch; } diff --git a/soh/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c b/soh/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c index 2fcf27301..d5f172530 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c +++ b/soh/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c @@ -5,6 +5,9 @@ */ #include "z_bg_mizu_water.h" + +#include "rumble.h" + #include "objects/object_mizu_objects/object_mizu_objects.h" #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) @@ -281,10 +284,10 @@ void BgMizuWater_ChangeWaterLevel(BgMizuWater* this, PlayState* play) { } if (this->targetY < this->actor.world.pos.y) { - func_800AA000(0.0f, 0x78, 0x14, 0xA); + Rumble_Request(0.0f, 120, 20, 10); func_8002F948(&this->actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); } else if (this->targetY > this->actor.world.pos.y) { - func_800AA000(0.0f, 0x78, 0x14, 0xA); + Rumble_Request(0.0f, 120, 20, 10); func_8002F948(&this->actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c b/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c index 524be20a0..eab7cf6eb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c @@ -5,6 +5,9 @@ */ #include "z_bg_mori_rakkatenjo.h" + +#include "rumble.h" + #include "objects/object_mori_objects/object_mori_objects.h" #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) @@ -157,7 +160,7 @@ void BgMoriRakkatenjo_Fall(BgMoriRakkatenjo* this, PlayState* play) { if (this->bounceCount == 0) { this->fallCount++; Sfx_PlaySfxCentered2(NA_SE_EV_STONE_BOUND); - func_800AA000(SQ(thisx->yDistToPlayer), 0xFF, 0x14, 0x96); + Rumble_Request(SQ(thisx->yDistToPlayer), 255, 20, 150); } thisx->world.pos.y = 403.0f - (thisx->world.pos.y - 403.0f) * bounceVel[this->bounceCount] / fabsf(thisx->velocity.y); diff --git a/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c b/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c index ce37bfd13..21960fff5 100644 --- a/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c @@ -5,6 +5,9 @@ */ #include "z_bg_relay_objects.h" + +#include "rumble.h" + #include "objects/object_relay_objects/object_relay_objects.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -148,7 +151,7 @@ void func_808A91AC(BgRelayObjects* this, PlayState* play) { void func_808A9234(BgRelayObjects* this, PlayState* play) { this->dyna.actor.velocity.y += this->dyna.actor.gravity; if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, this->dyna.actor.velocity.y)) { - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 180, 20, 100); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 180, 20, 100); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); if (this->unk_169 != play->roomCtx.curRoom.num) { Sfx_PlaySfxCentered2(NA_SE_EN_PO_LAUGH); diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index acba457ab..56a0a7cce 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -1,4 +1,7 @@ #include "z_boss_dodongo.h" + +#include "rumble.h" + #include "textures/boss_title_cards/object_kingdodongo.h" #include "objects/object_kingdodongo/object_kingdodongo.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" @@ -860,7 +863,7 @@ void BossDodongo_Walk(BossDodongo* this, PlayState* play) { func_80033E88(&this->actor, play, 4, 10); } else { this->unk_1B6 = 10; - func_800A9F6C(0.0f, 180, 20, 100); + Rumble_Override(0.0f, 180, 20, 100); } } } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index f845f323a..9d6f9b4d6 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -1,4 +1,5 @@ #include "z_boss_ganon.h" +#include "rumble.h" #include "overlays/ovl_Boss_Ganon/ovl_Boss_Ganon.h" #include "overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.h" #include "overlays/actors/ovl_En_Zl3/z_en_zl3.h" @@ -4016,7 +4017,7 @@ void BossGanon_LightBall_Update(Actor* thisx, PlayState* play2) { Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xyzDistToPlayerSq, 255, 20, 150); } else { spBA = 1; this->actor.world.rot.y = Math_Atan2S(zDistFromGanondorf, xDistFromGanondorf); @@ -4027,7 +4028,7 @@ void BossGanon_LightBall_Update(Actor* thisx, PlayState* play2) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - func_800AA000(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); + Rumble_Request(this->actor.xyzDistToPlayerSq, 180, 20, 100); if (hitWithBottle == false) { // if ganondorf is 250 units away from link, at least 3 volleys are required @@ -4496,7 +4497,7 @@ void func_808E2544(Actor* thisx, PlayState* play) { this->collider.base.acFlags &= ~2; if (!(acHitInfo->toucher.dmgFlags & 0x100000) || Player_HasMirrorShieldEquipped(play)) { - func_800AA000(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); + Rumble_Request(this->actor.xyzDistToPlayerSq, 180, 20, 100); this->unk_1C2 = 0xC; this->actor.speedXZ = -30.0f; diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index 1799dafd0..f036f0bed 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -1,6 +1,9 @@ #include "z_boss_ganon2.h" #include "overlays/actors/ovl_Demo_Gj/z_demo_gj.h" #include "overlays/actors/ovl_En_Zl3/z_en_zl3.h" + +#include "rumble.h" + #include "objects/object_ganon/object_ganon.h" #include "textures/boss_title_cards/object_ganon2.h" #include "objects/object_ganon2/object_ganon2.h" @@ -472,7 +475,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (this->csTimer == 30) { D_80906D78 = 1; this->unk_314 = 1; - func_800A9F6C(0.0f, 0xC8, 0x14, 0x14); + Rumble_Override(0.0f, 200, 20, 20); } if (this->csTimer == 30) { Sfx_PlaySfxCentered(NA_SE_EV_GRAVE_EXPLOSION); @@ -690,7 +693,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->actor.velocity.y = 0.0f; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonUncurlAndFlailAnim, 0.0f); func_808FD4D4(this, play, 0, 3); - func_800A9F6C(0.0f, 0xC8, 0x14, 0x14); + Rumble_Override(0.0f, 200, 20, 20); } break; case 21: @@ -767,7 +770,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { if (this->csTimer == 228) { Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_REFLECT_SW); Player_SetCsActionWithHaltedActors(play, &this->actor, 0x56); - func_800A9F6C(0.0f, 0xFF, 0xA, 0x32); + Rumble_Override(0.0f, 255, 10, 50); } if (this->csTimer >= 229) { play->envCtx.fillScreen = true; @@ -969,7 +972,7 @@ void func_808FF898(BossGanon2* this, PlayState* play) { sp28.z = 1.0f; Matrix_MultVec3f(&sp28, &gj->unk_26C); gj->killFlag = true; - func_800A9F6C(0.0f, 0x96, 0x14, 0x32); + Rumble_Override(0.0f, 150, 20, 50); this->unk_392 = 6; return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 503e41472..5364e7246 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -4,6 +4,9 @@ #include "overlays/actors/ovl_En_Goma/z_en_goma.h" #include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" + +#include "rumble.h" + #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -897,7 +900,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) { this->currentAnimFrameCount = Animation_GetLastFrame(&gGohmaInitialLandingAnim); BossGoma_PlayEffectsAndSfx(this, play, 0, 5); this->framesUntilNextAction = 15; - func_800A9F6C(0.0f, 0xC8, 0x14, 0x14); + Rumble_Override(0.0f, 200, 20, 20); } break; @@ -1007,7 +1010,7 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) { if (Animation_OnFrame(&this->skelanime, 107.0f)) { BossGoma_PlayEffectsAndSfx(this, play, 0, 8); - func_800A9F6C(0.0f, 0x96, 0x14, 0x14); + Rumble_Override(0.0f, 150, 20, 20); } this->visualState = VISUALSTATE_DEFEATED; diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index b80c39f3b..922bc96da 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -11,6 +11,8 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "vt.h" +#include "rumble.h" + #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -530,7 +532,7 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { if ((this->sfxTimer % 32) == 0) { Audio_PlaySoundIncreasinglyTransposed(&this->tentTipPos, NA_SE_EN_MOFER_WAVE, gMorphaTransposeTable); - func_800AA000(0, 100, 5, 2); + Rumble_Request(0, 100, 5, 2); Player_PlaySfx(&player->actor, NA_SE_VO_LI_FREEZE + player->ageProperties->unk_92); } } else { @@ -545,7 +547,7 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { if ((this->sfxTimer % 16) == 0) { Audio_PlaySoundIncreasinglyTransposed(&this->tentTipPos, NA_SE_EN_MOFER_WAVE, gMorphaTransposeTable); - func_800AA000(0, 160, 5, 4); + Rumble_Request(0, 160, 5, 4); Player_PlaySfx(&player->actor, NA_SE_VO_LI_FREEZE + player->ageProperties->unk_92); } } diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index 6e1db9049..154102e4d 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -10,6 +10,9 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" + +#include "rumble.h" + #include "soh/frame_interpolation.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -457,7 +460,7 @@ void BossSst_HeadIntro(BossSst* this, PlayState* play) { if (!this->ready) { sFloor->dyna.actor.params = BONGOFLOOR_HIT; this->ready = true; - func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xyzDistToPlayerSq, 255, 20, 150); Audio_PlayActorSound2(&sFloor->dyna.actor, NA_SE_EN_SHADEST_TAIKO_HIGH); } else if (Flags_GetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE)) { sHands[RIGHT]->actor.draw = BossSst_DrawHand; @@ -1311,7 +1314,7 @@ void BossSst_HandDownbeat(BossSst* this, PlayState* play) { } else { BossSst_HandSetupDownbeatEnd(this); } - func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xyzDistToPlayerSq, 255, 20, 150); Audio_PlayActorSound2(&this->actor, NA_SE_EN_SHADEST_TAIKO_HIGH); } } diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 1fee8de96..52e2d059c 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -3,6 +3,9 @@ #include "textures/boss_title_cards/object_tw.h" #include "objects/object_tw/object_tw.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" + +#include "rumble.h" + #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -1091,7 +1094,7 @@ void BossTw_ShootBeam(BossTw* this, PlayState* play) { this->groundBlastPos.y = 0.0f; this->groundBlastPos.z = 0.0f; play->envCtx.unk_D8 = 1.0f; - func_800AA000(0.0f, 0x64, 5, 4); + Rumble_Request(0.0f, 100, 5, 4); } else if (beamReflection == 0) { BossTw_BeamHitPlayerCheck(this, play); @@ -4299,7 +4302,7 @@ s32 BossTw_BlastShieldCheck(BossTw* this, PlayState* play) { if (info->toucher.dmgFlags & DMG_SHIELD) { this->work[INVINC_TIMER] = 7; play->envCtx.unk_D8 = 1.0f; - func_800AA000(0.0f, 100, 5, 4); + Rumble_Request(0.0f, 100, 5, 4); if (Player_HasMirrorShieldEquipped(play)) { if (this->blastType == 1) { diff --git a/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c b/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c index bac92747f..b528e267f 100644 --- a/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c +++ b/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c @@ -4,6 +4,8 @@ #include "vt.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" +#include "rumble.h" + #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) void DemoGt_Init(Actor* thisx, PlayState* play); @@ -32,7 +34,7 @@ void DemoGt_PlayExplosion2Sfx(PlayState* play, Vec3f* pos) { } void DemoGt_Rumble(PlayState* play) { - func_800AA000(0.0f, 0x32, 0xA, 5); + Rumble_Request(0.0f, 50, 10, 5); } void DemoGt_SpawnDust(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, f32 scale, s16 scaleStep, s16 life) { diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 1a491064a..3be267933 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -7,6 +7,8 @@ #include "z_door_shutter.h" #include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" +#include "rumble.h" + #include "objects/object_gnd/object_gnd.h" #include "objects/object_goma/object_goma.h" #include "objects/object_ydan_objects/object_ydan_objects.h" @@ -594,7 +596,7 @@ void func_809973E8(DoorShutter* this, PlayState* play) { Quake_SetSpeed(quakeId, -32536); Quake_SetQuakeValues(quakeId, 2, 0, 0, 0); Quake_SetCountdown(quakeId, 10); - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 180, 20, 100); func_80997220(this, play); } } @@ -785,7 +787,7 @@ void DoorShutter_Draw(Actor* thisx, PlayState* play) { void func_8099803C(PlayState* play, s16 y, s16 countdown, s16 camId) { s16 quakeId = Quake_Add(Play_GetCamera(play, camId), 3); - func_800A9F6C(0.0f, 180, 20, 100); + Rumble_Override(0.0f, 180, 20, 100); Quake_SetSpeed(quakeId, 20000); Quake_SetQuakeValues(quakeId, y, 0, 0, 0); Quake_SetCountdown(quakeId, countdown); diff --git a/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c b/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c index 368bf865b..31e4e5d00 100644 --- a/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c +++ b/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c @@ -1,4 +1,7 @@ #include "z_en_bigokuta.h" + +#include "rumble.h" + #include "objects/object_bigokuta/object_bigokuta.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ResourceManagerHelpers.h" @@ -442,7 +445,7 @@ void func_809BD8DC(EnBigokuta* this, PlayState* play) { EffectSsGSplash_Spawn(play, &effectPos, NULL, NULL, 1, 2000); Audio_PlayActorSound2(&this->actor, NA_SE_EN_DAIOCTA_LAND_WATER); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_LAND_BIG); - func_800AA000(0.0f, 0xFF, 0x14, 0x96); + Rumble_Request(0.0f, 255, 20, 150); } } else if (this->unk_196 < -1) { this->actor.world.pos.y = this->actor.home.pos.y - (sinf((this->unk_196 + 1) * (M_PI / 10)) * 20.0f); diff --git a/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c b/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c index 9fe450695..ccfc149ce 100644 --- a/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c +++ b/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c @@ -6,6 +6,9 @@ #include "z_en_bom.h" #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" + +#include "rumble.h" + #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include @@ -196,7 +199,7 @@ void EnBom_Explode(EnBom* this, PlayState* play) { if (this->explosionCollider.elements[0].dim.modelSphere.radius == 0) { this->actor.flags |= ACTOR_FLAG_DRAW_CULLING_DISABLED; - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); } if (CVarGetInteger(CVAR_ENHANCEMENT("StaticExplosionRadius"), 0)) { diff --git a/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c b/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c index 0eaee1f3b..5a4bed44d 100644 --- a/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c +++ b/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c @@ -8,6 +8,8 @@ #include "objects/object_bombf/object_bombf.h" #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" +#include "rumble.h" + #define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_UPDATE_CULLING_DISABLED) void EnBombf_Init(Actor* thisx, PlayState* play); @@ -262,7 +264,7 @@ void EnBombf_Explode(EnBombf* this, PlayState* play) { if (this->explosionCollider.elements[0].dim.modelSphere.radius == 0) { this->actor.flags |= ACTOR_FLAG_DRAW_CULLING_DISABLED; - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); } this->explosionCollider.elements[0].dim.modelSphere.radius += 8; diff --git a/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c b/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c index 3bd05c3f6..701a1e2ea 100644 --- a/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c +++ b/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c @@ -11,6 +11,8 @@ #include "overlays/actors/ovl_En_fHG/z_en_fhg.h" #include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h" +#include "rumble.h" + #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) typedef enum { @@ -496,7 +498,7 @@ void EnFhgFire_EnergyBall(EnFhgFire* this, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xyzDistToPlayerSq, 255, 20, 150); } else { if (bossGnd->flyMode == GND_FLY_NEUTRAL) { angleModX = Rand_CenteredFloat(0x2000); @@ -526,7 +528,7 @@ void EnFhgFire_EnergyBall(EnFhgFire* this, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - func_800AA000(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); + Rumble_Request(this->actor.xyzDistToPlayerSq, 180, 20, 100); } } else if (sqrtf(SQ(dxL) + SQ(dyL) + SQ(dzL)) <= 25.0f) { killMode = BALL_BURST; diff --git a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c index c4d46035d..6928e80a8 100644 --- a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c +++ b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c @@ -6,6 +6,9 @@ #include "z_en_horse.h" #include "overlays/actors/ovl_En_In/z_en_in.h" + +#include "rumble.h" + #include "objects/object_horse/object_horse.h" #include "objects/object_hni/object_hni.h" #include "scenes/overworld/spot09/spot09_scene.h" @@ -1315,7 +1318,7 @@ void EnHorse_MountedTrot(EnHorse* this, PlayState* play) { this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.375f; if (SkelAnime_Update(&this->skin.skelAnime)) { EnHorse_PlayTrottingSound(this); - func_800AA000(0.0f, 60, 8, 255); + Rumble_Request(0.0f, 60, 8, 255); if (this->actor.speedXZ >= 6.0f) { EnHorse_StartGallopingInterruptable(this); } else if (this->actor.speedXZ < 3.0f) { @@ -1383,7 +1386,7 @@ void EnHorse_MountedGallop(EnHorse* this, PlayState* play) { this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.3f; if (SkelAnime_Update(&this->skin.skelAnime)) { EnHorse_PlayGallopingSound(this); - func_800AA000(0, 120, 8, 255); + Rumble_Request(0, 120, 8, 255); if (EnHorse_PlayerCanMove(this, play) == true) { if (stickMag >= 10.0f && Math_CosS(stickAngle) <= -0.5f) { EnHorse_StartBraking(this, play); @@ -1407,7 +1410,7 @@ void EnHorse_StartRearing(EnHorse* this) { Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } - func_800AA000(0.0f, 180, 20, 100); + Rumble_Request(0.0f, 180, 20, 100); Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); } @@ -1422,7 +1425,7 @@ void EnHorse_MountedRearing(EnHorse* this, PlayState* play) { this->stateFlags |= ENHORSE_LAND2_SOUND; Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - func_800AA000(0, 180, 20, 100); + Rumble_Request(0.0f, 180, 20, 100); } } diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c index c4dbe3f3a..59a8bb185 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -5,6 +5,9 @@ */ #include "z_en_ik.h" + +#include "rumble.h" + #include "scenes/dungeons/jyasinboss/jyasinboss_scene.h" #include "objects/object_ik/object_ik.h" #include "vt.h" @@ -444,7 +447,7 @@ void func_80A74EBC(EnIk* this, PlayState* play) { sp2C.y = this->actor.world.pos.y; Audio_PlayActorSound2(&this->actor, NA_SE_EN_IRONNACK_HIT_GND); Camera_AddQuake(&play->mainCamera, 2, 0x19, 5); - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); CollisionCheck_SpawnShieldParticles(play, &sp2C); } diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index 37dc1fa9d..ef0c13416 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -9,6 +9,8 @@ #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/OTRGlobals.h" +#include "rumble.h" + #include "vt.h" #define FLAGS ACTOR_FLAG_THROW_ONLY @@ -444,7 +446,7 @@ void EnIshi_Fly(EnIshi* this, PlayState* play) { Quake_SetSpeed(quakeIdx, -0x3CB0); Quake_SetQuakeValues(quakeIdx, 3, 0, 0, 0); Quake_SetCountdown(quakeIdx, 7); - func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xyzDistToPlayerSq, 255, 20, 150); } Actor_Kill(&this->actor); return; @@ -512,4 +514,4 @@ void EnIshi_Draw(Actor* thisx, PlayState* play) { void EnIshi_Reset(void) { sRockRotSpeedX = 0; sRockRotSpeedY = 0; -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c index 5ac6ef18c..9ff2cde86 100644 --- a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c +++ b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c @@ -1,4 +1,7 @@ #include "z_en_m_thunder.h" + +#include "rumble.h" + #include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0 @@ -174,7 +177,7 @@ void func_80A9F408(EnMThunder* this, PlayState* play) { } if (player->unk_858 >= 0.1f) { - func_800AA000(0.0f, (s32)(player->unk_858 * 150.0f) & 0xFF, 2, (s32)(player->unk_858 * 150.0f) & 0xFF); + Rumble_Request(0.0f, (s32)(player->unk_858 * 150.0f) & 0xFF, 2, (s32)(player->unk_858 * 150.0f) & 0xFF); } if (player->stateFlags2 & PLAYER_STATE2_SPIN_ATTACKING) { diff --git a/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c b/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c index 78f75dabd..895a6a475 100644 --- a/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c +++ b/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c @@ -5,6 +5,9 @@ */ #include "z_en_mb.h" + +#include "rumble.h" + #include "objects/object_mb/object_mb.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ResourceManagerHelpers.h" @@ -886,7 +889,7 @@ void EnMb_ClubAttack(EnMb* this, PlayState* play) { effSpawnPos = this->effSpawnPos; effSpawnPos.y = this->actor.floorHeight; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MONBLIN_HAM_LAND); - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); EffectSsBlast_SpawnWhiteShockwave(play, &effSpawnPos, &effWhiteShockwaveDynamics, &effWhiteShockwaveDynamics); func_80033480(play, &effSpawnPos, 2.0f, 3, 0x12C, 0xB4, 1); @@ -1076,7 +1079,7 @@ void EnMb_ClubDamaged(EnMb* this, PlayState* play) { if (this->timer3 != 0) { Animation_PlayOnce(&this->skelAnime, &gEnMbClubStandUpAnim); this->timer3 = 0; - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); Camera_AddQuake(&play->mainCamera, 2, 25, 5); } else { EnMb_SetupClubWaitPlayerNear(this); @@ -1135,7 +1138,7 @@ void EnMb_ClubDead(EnMb* this, PlayState* play) { Actor_Kill(&this->actor); } } else if ((s32)this->skelAnime.curFrame == 15 || (s32)this->skelAnime.curFrame == 22) { - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); Actor_SpawnFloorDustRing(play, &this->actor, &effPos, 50.0f, 10, 3.0f, 400, 60, false); Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_DOWN); Camera_AddQuake(&play->mainCamera, 2, 25, 5); diff --git a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c index 062be3268..84802731a 100644 --- a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -1,4 +1,7 @@ #include "z_en_rd.h" + +#include "rumble.h" + #include "objects/object_rd/object_rd.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ResourceManagerHelpers.h" @@ -348,7 +351,8 @@ void func_80AE2C1C(EnRd* this, PlayState* play) { player->actor.freezeTimer = 40; Player_SetAutoLockOnActor(play, &this->actor); GET_PLAYER(play)->autoLockOnActor = &this->actor; - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); } this->unk_306 = 0x3C; Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); @@ -503,7 +507,7 @@ void func_80AE3454(EnRd* this, PlayState* play) { Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadGrabAttackAnim); this->unk_304++; play->damagePlayer(play, -8); - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 1, 0xC); + Rumble_Request(this->actor.xzDistToPlayer, 255, 1, 12); this->unk_319 = 20; case 0: Math_SmoothStepToS(&this->unk_30E, 0, 1, 0x5DC, 0); @@ -537,7 +541,7 @@ void func_80AE3454(EnRd* this, PlayState* play) { if (this->unk_319 == 0) { play->damagePlayer(play, -8); - func_800AA000(this->actor.xzDistToPlayer, 0xF0, 1, 0xC); + Rumble_Request(this->actor.xzDistToPlayer, 240, 1, 12); this->unk_319 = 20; Player_PlaySfx(&player->actor, NA_SE_VO_LI_DAMAGE_S + player->ageProperties->unk_92); } @@ -577,7 +581,7 @@ void func_80AE3834(EnRd* this, PlayState* play) { if (ABS(temp_v0) < 0x2008) { if (!(this->unk_312 & 0x80) && GameInteractor_Should(VB_REDEAD_GIBDO_FREEZE_LINK, true, this)) { player->actor.freezeTimer = 60; - func_800AA000(this->actor.xzDistToPlayer, 0xFF, 0x14, 0x96); + Rumble_Request(this->actor.xzDistToPlayer, 255, 20, 150); Player_SetAutoLockOnActor(play, &this->actor); } Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); diff --git a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c index 831e11b8c..cec446e3a 100644 --- a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -5,6 +5,9 @@ */ #include "z_en_rr.h" + +#include "rumble.h" + #include "objects/object_rr/object_rr.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -624,7 +627,7 @@ void EnRr_Reach(EnRr* this, PlayState* play) { void EnRr_GrabPlayer(EnRr* this, PlayState* play) { Player* player = GET_PLAYER(play); - func_800AA000(this->actor.xyzDistToPlayerSq, 120, 2, 120); + Rumble_Request(this->actor.xyzDistToPlayerSq, 120, 2, 120); if ((this->frameCount % 8) == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIKE_EAT); } diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index aab3e9505..9833638a4 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -5,6 +5,9 @@ */ #include "z_en_zl4.h" + +#include "rumble.h" + #include "objects/object_zl4/object_zl4.h" #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" #include "soh/OTRGlobals.h" @@ -922,7 +925,7 @@ s32 EnZl4_CsLookWindow(EnZl4* this, PlayState* play) { play->csCtx.state = CS_STATE_UNSKIPPABLE_INIT; } } else { - func_800AA000(0.0f, 0xA0, 0xA, 0x28); + Rumble_Request(0.0f, 160, 10, 40); Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_30); EnZl4_SetCsCameraAngle(play, 11); diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index 4d42de65f..60e5b59fb 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Kanban/z_en_kanban.h" #include "objects/object_fish/object_fish.h" #include "vt.h" +#include "rumble.h" #include "soh/frame_interpolation.h" #include "soh/OTRGlobals.h" @@ -3568,7 +3569,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { } sLureBitTimer = timer; sRumbleDelay = timer; - func_800A9F6C(0.0f, 60, timer * 3, 10); + Rumble_Override(0.0f, 60, timer * 3, 10); } else { if (this->fishLength > 70.0f) { timer = (s16)Rand_ZeroFloat(5.0f) + 10; @@ -3581,7 +3582,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { } sLureBitTimer = timer; sRumbleDelay = timer; - func_800A9F6C(0.0f, 180, timer * 3, 10); + Rumble_Override(0.0f, 180, timer * 3, 10); } sLineHooked = 0; @@ -3623,11 +3624,11 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { if (sLureEquipped == FS_LURE_SINKING) { sLureBitTimer = 30; sRumbleDelay = 100; - func_800A9F6C(0.0f, 60, 90, 10); + Rumble_Override(0.0f, 60, 90, 10); } else { sLureBitTimer = 30; sRumbleDelay = 40; - func_800A9F6C(0.0f, 180, 90, 10); + Rumble_Override(0.0f, 180, 90, 10); } sLineHooked = false; @@ -3680,7 +3681,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { rumbleStrength = 255.0f; } - func_800A9F6C(0.0f, rumbleStrength, 120, 5); + Rumble_Override(0.0f, rumbleStrength, 120, 5); sRumbleDelay = 40; sRodHitTimer = 10; Sfx_PlaySfxCentered(NA_SE_IT_FISHING_HIT); @@ -3711,7 +3712,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { rumbleStrength *= 3.0f / 4.0f; } - func_800A9F6C(0.0f, rumbleStrength, (s16)Rand_ZeroFloat(5.0f) + 10, 5); + Rumble_Override(0.0f, rumbleStrength, (s16)Rand_ZeroFloat(5.0f) + 10, 5); } if (this->timerArray[1] > 30) { @@ -3742,7 +3743,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { } else { rumbleStrength8 = 180; } - func_800A9F6C(0.0f, rumbleStrength8, 90, 2); + Rumble_Override(0.0f, rumbleStrength8, 90, 2); this->timerArray[0] = 20; this->timerArray[1] = 100; this->timerArray[2] = 20; @@ -3873,7 +3874,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { } } else { sFishingCaughtTextId = 0x4082; - func_800A9F6C(0.0f, 1, 3, 1); + Rumble_Override(0.0f, 1, 3, 1); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x0A00FF); } @@ -3896,7 +3897,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { this->fishState = 6; this->timerArray[0] = 100; player->unk_860 = 3; - func_800A9F6C(0.0f, 1, 3, 1); + Rumble_Override(0.0f, 1, 3, 1); sFishesCaught++; func_80064520(play, &play->csCtx); sFishingPlayerCinematicState = 100; @@ -4852,7 +4853,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { case 0: if (gSaveContext.rupees >= 20) { Rupees_ChangeBy(-20); - if (func_800AA148() == 0) { + if (!Rumble_Controller1HasRumblePak()) { this->actor.textId = 0x407C; } else { this->actor.textId = 0x407D; @@ -5365,7 +5366,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { (fabsf(player->actor.world.pos.z - sSinkingLureLocationPos[sSinkingLureLocation - 1].z) < 25.0f)) { sSinkingLureLocation = 0; sFishingPlayerCinematicState = 20; - func_800A9F6C(0.0f, 150, 10, 10); + Rumble_Override(0.0f, 150, 10, 10); Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x1400FF); } @@ -5374,7 +5375,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { KREG(0) = 0; sLureEquipped = FS_LURE_STOCK; sFishingPlayerCinematicState = 20; - func_800A9F6C(0.0f, 150, 10, 10); + Rumble_Override(0.0f, 150, 10, 10); Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x1400FF); } @@ -5534,7 +5535,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { sCameraAt.z = mainCam->at.z; Message_StartTextbox(play, 0x409E, NULL); sFishingPlayerCinematicState = 11; - func_800A9F6C(0.0f, 150, 10, 10); + Rumble_Override(0.0f, 150, 10, 10); // fallthrough } diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index 1b9edc917..5dd02095a 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -5,6 +5,9 @@ */ #include "z_obj_switch.h" + +#include "rumble.h" + #include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -430,7 +433,7 @@ void ObjSwitch_FloorPress(ObjSwitch* this, PlayState* play) { if (this->dyna.actor.scale.y <= 33.0f / 2000.0f) { ObjSwitch_FloorDownInit(this); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH); - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); } } } @@ -488,7 +491,7 @@ void ObjSwitch_FloorRelease(ObjSwitch* this, PlayState* play) { ObjSwitch_FloorUpInit(this); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH); if (subType == OBJSWITCH_SUBTYPE_FLOOR_1) { - func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + Rumble_Request(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); } } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 3571ca135..e78c5e532 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -34,6 +34,8 @@ #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" +#include "rumble.h" + #include #include #include @@ -1740,7 +1742,7 @@ void func_80832630(PlayState* play) { void Player_RequestRumble(Player* this, s32 sourceStrength, s32 duration, s32 decreaseRate, s32 distSq) { if (this->actor.category == ACTORCAT_PLAYER) { - func_800AA000(distSq, sourceStrength, duration, decreaseRate); + Rumble_Request(distSq, sourceStrength, duration, decreaseRate); } } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 8fa504748..dbe04e44f 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -2,6 +2,7 @@ #include #include +#include "rumble.h" #include "textures/title_static/title_static.h" #include "textures/parameter_static/parameter_static.h" @@ -3224,7 +3225,7 @@ void FileChoose_ConfirmFile(GameState* thisx) { if (CHECK_BTN_ALL(input->press.button, BTN_START) || (CHECK_BTN_ALL(input->press.button, BTN_A))) { if (this->confirmButtonIndex == FS_BTN_CONFIRM_YES) { - func_800AA000(300.0f, 180, 20, 100); + Rumble_Request(300.0f, 180, 20, 100); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->selectMode = SM_FADE_OUT; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c index fe8c33fa1..df48f10d5 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c @@ -1,4 +1,7 @@ #include "file_choose.h" + +#include "rumble.h" + #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/SaveManager.h" @@ -396,7 +399,7 @@ void FileChoose_CopyConfirm(GameState* thisx) { this->nextTitleLabel = FS_TITLE_COPY_COMPLETE; this->actionTimer = 8; this->configMode = CM_COPY_ANIM_1; - func_800AA000(300.0f, 0xB4, 0x14, 0x64); + Rumble_Request(300.0f, 180, 20, 100); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { @@ -872,7 +875,7 @@ void FileChoose_EraseConfirm(GameState* thisx) { this->actionTimer = 8; this->configMode = CM_ERASE_ANIM_1; this->nextTitleLabel = FS_TITLE_ERASE_COMPLETE; - func_800AA000(200.0f, 0xFF, 0x14, 0x96); + Rumble_Request(200.0f, 255, 20, 150); sEraseDelayTimer = 15; } else if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c index d82ec3844..dd5a0fb46 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c @@ -465,7 +465,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) { CVarSetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0); this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200; this->connectorAlpha[this->buttonIndex] = 255; - func_800AA000(300.0f, 0xB4, 0x14, 0x64); + Rumble_Request(300.0f, 180, 20, 100); } else { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);