summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2022-06-29 17:08:03 -0400
committerGitHub <noreply@github.com>2022-06-29 22:08:03 +0100
commit45eed680d613642bc3e1591f95902f6d57e0f8e6 (patch)
treee5967531bb726e49708d5814d78c32d3a197f50c /src/code
parent158d1b26b0455c2214741ebc4406130a559b8f8f (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.c19
-rw-r--r--src/code/code_80182CE0.c7
-rw-r--r--src/code/game.c5
-rw-r--r--src/code/padmgr.c4
-rw-r--r--src/code/sys_rumble.c160
-rw-r--r--src/code/z_actor.c6
-rw-r--r--src/code/z_demo.c5
-rw-r--r--src/code/z_game_over.c7
-rw-r--r--src/code/z_kaleido_setup.c3
-rw-r--r--src/code/z_lifemeter.c1
-rw-r--r--src/code/z_rumble.c104
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;
+}