mm/src/code/z_rumble.c

105 lines
2.7 KiB
C

/*
* 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;
}