diff options
| author | Anghelo Carvajal <angheloalf95@gmail.com> | 2022-06-29 17:08:03 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-29 22:08:03 +0100 |
| commit | 45eed680d613642bc3e1591f95902f6d57e0f8e6 (patch) | |
| tree | e5967531bb726e49708d5814d78c32d3a197f50c /src/code | |
| parent | 158d1b26b0455c2214741ebc4406130a559b8f8f (diff) | |
`code_8013EC10` and `code_80182CE0` (`z_rumble` and `sys_rumble`) (#763)
* First pass
* import bss
* cleanup warnings
* PadMgr_ControllerHasRumblePak
* z64rumble.h
* rename file to z_rumble.c
* format
* Update src/code/z_rumble.c
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
* Update src/code/z_rumble.c
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
* name a temp
* minor cleaning
* bss
* match code_80182CE0
* import data and cleanups
* Rename RumbleManager struct and sys_rumble file
* Rename functions from sys_rumble
* Rename parameter to distSq
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
* more notes and a bit of cleaning
* Name Rumble_Add and Rumble_AddForced
* some extra notes
* Rename Rumble_Override and Rumble_Request
* document states
* minor renames
* actorfixer
* format
* very minor docs
* whoops
* remove redundant prevent_bss_reordering
* Update src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* Update src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* Update src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* namefixer
* Update src/code/sys_rumble.c
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
* fix
* Elliptic review
Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
* minor cleanups
* Update include/z64rumble.h
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
* review
Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
* Update src/code/sys_rumble.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* Update src/code/z_rumble.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* review
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/code_8013EC10.c | 19 | ||||
| -rw-r--r-- | src/code/code_80182CE0.c | 7 | ||||
| -rw-r--r-- | src/code/game.c | 5 | ||||
| -rw-r--r-- | src/code/padmgr.c | 4 | ||||
| -rw-r--r-- | src/code/sys_rumble.c | 160 | ||||
| -rw-r--r-- | src/code/z_actor.c | 6 | ||||
| -rw-r--r-- | src/code/z_demo.c | 5 | ||||
| -rw-r--r-- | src/code/z_game_over.c | 7 | ||||
| -rw-r--r-- | src/code/z_kaleido_setup.c | 3 | ||||
| -rw-r--r-- | src/code/z_lifemeter.c | 1 | ||||
| -rw-r--r-- | src/code/z_rumble.c | 104 |
11 files changed, 282 insertions, 39 deletions
diff --git a/src/code/code_8013EC10.c b/src/code/code_8013EC10.c deleted file mode 100644 index b44ed73a8..000000000 --- a/src/code/code_8013EC10.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EC10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EC44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013ECE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013ED9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EDD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EE04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EE24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EE38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8013EC10/func_8013EE48.s") diff --git a/src/code/code_80182CE0.c b/src/code/code_80182CE0.c deleted file mode 100644 index 6ff8736e5..000000000 --- a/src/code/code_80182CE0.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80182CE0/func_80182CE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80182CE0/func_80183020.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80182CE0/func_80183058.s") diff --git a/src/code/game.c b/src/code/game.c index 6f796bc12..c8d3e14ba 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -1,5 +1,6 @@ #include "global.h" #include "system_malloc.h" +#include "z64rumble.h" s32 gFramerateDivisor = 1; f32 gFramerateDivisorF = 1.0f; @@ -216,7 +217,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g VisMono_Init(&sMonoColors); func_80140898(&D_801F8048); func_801773A0(&D_801F7FF0); - func_8013ED9C(); + Rumble_Init(); osSendMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); } @@ -231,7 +232,7 @@ void GameState_Destroy(GameState* gameState) { gameState->destroy(gameState); } - func_8013EDD0(); + Rumble_Destroy(); func_801773C4(&D_801F7FF0); func_80140D04(&D_801F8010); func_801420F4(&D_801F8020); diff --git a/src/code/padmgr.c b/src/code/padmgr.c index 0d539126a..077ef1b2b 100644 --- a/src/code/padmgr.c +++ b/src/code/padmgr.c @@ -31,9 +31,9 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/func_8017544C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/func_80175474.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/PadMgr_RumbleSet.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/func_801754C0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/PadMgr_ControllerHasRumblePak.s") #pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/Padmgr_CalcStickEdges.s") diff --git a/src/code/sys_rumble.c b/src/code/sys_rumble.c new file mode 100644 index 000000000..4101758be --- /dev/null +++ b/src/code/sys_rumble.c @@ -0,0 +1,160 @@ +/* + * File: sys_rumble.c + * Description: Internal scheduler system for rumble requests + */ + +#include "global.h" +#include "z64rumble.h" + +// sRumbleWasEnabledOnLastTick/sWillDisableRumble? Probably name it after updateEnabled +u8 D_801D1E70 = true; + +void RumbleManager_Update(RumbleManager* rumbleMgr) { + s32 strongestIndex = -1; + s32 i; + s32 temp; + + // Turn rumbling off for all controllers + for (i = 0; i < ARRAY_COUNT(rumbleMgr->rumbleEnabled); i++) { + rumbleMgr->rumbleEnabled[i] = false; + } + + if (!rumbleMgr->updateEnabled) { + // Rumbling update is disabled + + if (D_801D1E70) { + for (i = 0; i < MAXCONTROLLERS; i++) { + func_8017544C(i, false); + } + } + + D_801D1E70 = rumbleMgr->updateEnabled; + func_80175434(); + + return; + } + + D_801D1E70 = rumbleMgr->updateEnabled; + + // Start up the manager by wiping old requests + if (rumbleMgr->state == RUMBLEMANAGER_STATE_INITIAL) { + for (i = 0; i < MAXCONTROLLERS; i++) { + func_8017544C(i, false); + } + + for (i = 0; i < RUMBLE_REQUEST_BUFFER_SIZE; i++) { + rumbleMgr->requestIntensities[i] = 0; + rumbleMgr->requestDecayTimers[i] = 0; + rumbleMgr->requestDecaySteps[i] = 0; + rumbleMgr->requestAccumulators[i] = 0; + } + + rumbleMgr->rumblingDuration = 0; + rumbleMgr->downTime = 0; + + rumbleMgr->overrideIntensity = 0; + rumbleMgr->overrideDecayTimer = 0; + rumbleMgr->overrideDecayStep = 0; + rumbleMgr->overrideAccumulator = 0; + + rumbleMgr->state = RUMBLEMANAGER_STATE_RUNNING; + + func_80175434(); + } + + if (rumbleMgr->state != RUMBLEMANAGER_STATE_WIPE) { + // Process arrays of rumble requests + for (i = 0; i < RUMBLE_REQUEST_BUFFER_SIZE; i++) { + if (rumbleMgr->requestIntensities[i] != 0) { // This entry has a non-empty rumble request + if (rumbleMgr->requestDecayTimers[i] > 0) { + rumbleMgr->requestDecayTimers[i]--; + } else { + temp = rumbleMgr->requestIntensities[i] - rumbleMgr->requestDecaySteps[i]; + if (temp > 0) { + rumbleMgr->requestIntensities[i] = temp; + } else { + rumbleMgr->requestIntensities[i] = 0; + } + } + + temp = rumbleMgr->requestAccumulators[i] + rumbleMgr->requestIntensities[i]; + rumbleMgr->requestAccumulators[i] = temp; // overflows + if (strongestIndex == -1) { + strongestIndex = i; + rumbleMgr->rumbleEnabled[0] = (temp >= 0x100); + } else if (rumbleMgr->requestIntensities[strongestIndex] < rumbleMgr->requestIntensities[i]) { + strongestIndex = i; + rumbleMgr->rumbleEnabled[0] = (temp >= 0x100); + } + } + } + + // Process Override request. Note it takes priority over the values set by the request arrays + if (rumbleMgr->overrideIntensity != 0) { + if (rumbleMgr->overrideDecayTimer > 0) { + rumbleMgr->overrideDecayTimer--; + } else { + temp = rumbleMgr->overrideIntensity - rumbleMgr->overrideDecayStep; + if (temp > 0) { + rumbleMgr->overrideIntensity = temp; + } else { + rumbleMgr->overrideIntensity = 0; + } + } + + temp = rumbleMgr->overrideAccumulator + rumbleMgr->overrideIntensity; + rumbleMgr->overrideAccumulator = temp; // overflows + rumbleMgr->rumbleEnabled[0] = (temp >= 0x100); + } + + if (rumbleMgr->overrideIntensity != 0) { + temp = rumbleMgr->overrideIntensity; + } else if (strongestIndex == -1) { + temp = 0; + } else { + temp = rumbleMgr->requestIntensities[strongestIndex]; + } + + // Keep track of how long this have been rumbling (almost) nonstop + if (temp == 0) { + rumbleMgr->downTime++; + if (rumbleMgr->downTime > 5) { + rumbleMgr->rumblingDuration = 0; + rumbleMgr->downTime = 5; + } + } else { + rumbleMgr->downTime = 0; + rumbleMgr->rumblingDuration++; + if (rumbleMgr->rumblingDuration > 2 * 60 * 60) { // 2 minutes + // Rumbling has lasted too long, clear system + rumbleMgr->state = RUMBLEMANAGER_STATE_WIPE; + } + } + } else { // RUMBLEMANAGER_STATE_WIPE + for (i = 0; i < RUMBLE_REQUEST_BUFFER_SIZE; i++) { + rumbleMgr->requestIntensities[i] = 0; + rumbleMgr->requestDecayTimers[i] = 0; + rumbleMgr->requestDecaySteps[i] = 0; + rumbleMgr->requestAccumulators[i] = 0; + } + + rumbleMgr->rumblingDuration = 0; + rumbleMgr->downTime = 0; + + rumbleMgr->overrideIntensity = 0; + rumbleMgr->overrideDecayTimer = 0; + rumbleMgr->overrideDecayStep = 0; + rumbleMgr->overrideAccumulator = 0; + + func_80175434(); + } +} + +void RumbleManager_Init(RumbleManager* rumbleMgr) { + bzero(rumbleMgr, sizeof(RumbleManager)); + rumbleMgr->state = RUMBLEMANAGER_STATE_INITIAL; + rumbleMgr->updateEnabled = true; +} + +void RumbleManager_Destroy(RumbleManager* rumbleMgr) { +} diff --git a/src/code/z_actor.c b/src/code/z_actor.c index fe5927c17..273581621 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -5,6 +5,7 @@ #include "global.h" #include "z64load.h" +#include "z64rumble.h" #include "overlays/actors/ovl_En_Horse/z_en_horse.h" #include "overlays/actors/ovl_En_Part/z_en_part.h" #include "overlays/actors/ovl_En_Box/z_en_box.h" @@ -3793,11 +3794,12 @@ void func_800BC7D8(PlayState* play, s16 y, s16 countdown, s16 speed) { Quake_SetCountdown(idx, countdown); } +// Actor_RequestRumble? void func_800BC848(Actor* actor, PlayState* play, s16 y, s16 countdown) { if (y >= 5) { - func_8013ECE0(actor->xyzDistToPlayerSq, 255, 20, 150); + Rumble_Request(actor->xyzDistToPlayerSq, 255, 20, 150); } else { - func_8013ECE0(actor->xyzDistToPlayerSq, 180, 20, 100); + Rumble_Request(actor->xyzDistToPlayerSq, 180, 20, 100); } func_800BC770(play, y, countdown); } diff --git a/src/code/z_demo.c b/src/code/z_demo.c index 8356f21e3..1367198c1 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "z64rumble.h" #include "overlays/gamestates/ovl_daytelop/z_daytelop.h" void Cutscene_DoNothing(PlayState* play, CutsceneContext* csCtx); @@ -505,14 +506,14 @@ void Cutscene_Command_Rumble(PlayState* play, CutsceneContext* csCtx, CsCmdRumbl switch (cmd->type) { case 1: if (csCtx->frames == cmd->startFrame) { - func_8013ECE0(0.0f, cmd->unk6, cmd->unk7, cmd->unk8); + Rumble_Request(0.0f, cmd->intensity, cmd->decayTimer, cmd->decayStep); } break; case 2: if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { if ((csCtx->frames == cmd->startFrame) || (play->state.frames % 64 == 0)) { - func_8013ECE0(0.0f, cmd->unk6, cmd->unk7, cmd->unk8); + Rumble_Request(0.0f, cmd->intensity, cmd->decayTimer, cmd->decayStep); } } break; diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c index b7f6dfa5e..18df07783 100644 --- a/src/code/z_game_over.c +++ b/src/code/z_game_over.c @@ -1,4 +1,5 @@ #include "global.h" +#include "z64rumble.h" void GameOver_Init(PlayState* play) { play->gameOverCtx.state = GAMEOVER_INACTIVE; @@ -62,7 +63,7 @@ void GameOver_Update(PlayState* play) { gSaveContext.unk_3F24 = 0; Kankyo_InitGameOverLights(play); sGameOverTimer = 20; - func_8013ECE0(0.0f, 126, 124, 63); + Rumble_Request(0.0f, 126, 124, 63); gameOverCtx->state = GAMEOVER_DEATH_WAIT_GROUND; break; case GAMEOVER_DEATH_FADE_OUT: @@ -78,7 +79,7 @@ void GameOver_Update(PlayState* play) { gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; gSaveContext.save.equippedMask = PLAYER_MASK_NONE; } - func_8013EE24(); + Rumble_StateReset(); } break; case GAMEOVER_REVIVE_START: @@ -90,7 +91,7 @@ void GameOver_Update(PlayState* play) { case GAMEOVER_REVIVE_RUMBLE: sGameOverTimer = 50; gameOverCtx->state++; - func_8013ECE0(0.0f, 126, 124, 63); + Rumble_Request(0.0f, 126, 124, 63); break; case GAMEOVER_REVIVE_WAIT_GROUND: sGameOverTimer--; diff --git a/src/code/z_kaleido_setup.c b/src/code/z_kaleido_setup.c index fe985d7c3..b5ec93f5a 100644 --- a/src/code/z_kaleido_setup.c +++ b/src/code/z_kaleido_setup.c @@ -1,4 +1,5 @@ #include "global.h" +#include "z64rumble.h" #include "overlays/gamestates/ovl_file_choose/z_file_choose.h" s16 D_801BDB00[] = { PAUSE_1, PAUSE_2, PAUSE_3, PAUSE_0 }; @@ -9,7 +10,7 @@ void func_800F4A10(PlayState* play) { PauseContext* pauseCtx = &play->pauseCtx; s16 i; - func_8013EE24(); + Rumble_StateReset(); pauseCtx->unk_206 = 0; pauseCtx->unk_200 = 1; diff --git a/src/code/z_lifemeter.c b/src/code/z_lifemeter.c index 651afe6c0..c31cf0016 100644 --- a/src/code/z_lifemeter.c +++ b/src/code/z_lifemeter.c @@ -1,7 +1,6 @@ #include "prevent_bss_reordering.h" #include "global.h" #include "interface/parameter_static/parameter_static.h" -#include "prevent_bss_reordering.h" s16 sHeartsPrimColors[3][3] = { { 255, 70, 50 }, { 255, 190, 0 }, { 100, 100, 255 } }; s16 sHeartsEnvColors[3][3] = { { 50, 40, 60 }, { 255, 0, 0 }, { 0, 0, 255 } }; diff --git a/src/code/z_rumble.c b/src/code/z_rumble.c new file mode 100644 index 000000000..ce5cc16b4 --- /dev/null +++ b/src/code/z_rumble.c @@ -0,0 +1,104 @@ +/* + * File: z_rumble.c + * Description: Rumble request system + * + * Provides a simple interface to allow scheduling up to RUMBLE_REQUEST_BUFFER_SIZE rumble requests to the RumblePak. + * There's an additional Override type of rumble request for requests which should take priorities over any other + * scheduled request. + */ + +#include "global.h" +#include "z64rumble.h" + +RumbleManager gRumbleMgr; + +void Rumble_Update(void* arg0) { + RumbleManager_Update(&gRumbleMgr); + PadMgr_RumbleSet(gRumbleMgr.rumbleEnabled); +} + +// Used by some bosses (and fishing) +void Rumble_Override(f32 distSq, u8 sourceIntensity, u8 decayTimer, u8 decayStep) { + s32 intensity; + s32 distance; + + if (SQ(1000.0f) < distSq) { + distance = 1000; + } else { + distance = sqrtf(distSq); + } + + if ((distance < 1000) && (sourceIntensity != 0) && (decayStep != 0)) { + intensity = sourceIntensity - (distance * 255) / 1000; + + if (intensity > 0) { + gRumbleMgr.overrideIntensity = intensity; + gRumbleMgr.overrideDecayTimer = decayTimer; + gRumbleMgr.overrideDecayStep = decayStep; + } + } +} + +void Rumble_Request(f32 distSq, u8 sourceIntensity, u8 decayTimer, u8 decayStep) { + s32 intensity; + s32 distance; + s32 i; + + if (SQ(1000.0f) < distSq) { + distance = 1000; + } else { + distance = sqrtf(distSq); + } + + if ((distance < 1000) && (sourceIntensity != 0) && (decayStep != 0)) { + intensity = sourceIntensity - (distance * 255) / 1000; + + for (i = 0; i < RUMBLE_REQUEST_BUFFER_SIZE; i++) { + if (gRumbleMgr.requestIntensities[i] == 0) { + if (intensity > 0) { + gRumbleMgr.requestIntensities[i] = intensity; + gRumbleMgr.requestDecayTimers[i] = decayTimer; + gRumbleMgr.requestDecaySteps[i] = decayStep; + } + break; + } + } + } +} + +void Rumble_Init(void) { + RumbleManager_Init(&gRumbleMgr); + func_80174F24(Rumble_Update, NULL); +} + +void Rumble_Destroy(void) { + func_80174F44(Rumble_Update, NULL); + RumbleManager_Destroy(&gRumbleMgr); +} + +s32 Rumble_ControllerOneHasRumblePak(void) { + return PadMgr_ControllerHasRumblePak(0); +} + +/** + * Wipes every old request for a fresh start, then proceeds to process them as normal + */ +void Rumble_StateReset(void) { + gRumbleMgr.state = RUMBLEMANAGER_STATE_INITIAL; +} + +/** + * Changes the state of the manager to WIPE + * + * In this state, every request is deleted + */ +void Rumble_StateWipeRequests(void) { + gRumbleMgr.state = RUMBLEMANAGER_STATE_WIPE; +} + +/** + * Request processing is paused if updateEnabled is set to false + */ +void Rumble_SetUpdateEnabled(s32 updateEnabled) { + gRumbleMgr.updateEnabled = !!updateEnabled; +} |
