Finish up clock implementation

This commit is contained in:
James Lambert 2023-06-29 21:10:58 -06:00
parent bcba882efd
commit 9ab44568d8
9 changed files with 159 additions and 2 deletions

View file

@ -843,7 +843,8 @@ materials:
clock_digits: clock_digits:
gDPSetTile: gDPSetTile:
filename: ./signage/clock_digits.png filename: ./signage/clock_digits.png
siz: G_IM_SIZ_16b siz: G_IM_SIZ_4b
twoTone: true
gDPSetCombineMode: G_CC_DECALRGBA gDPSetCombineMode: G_CC_DECALRGBA
gDPSetCycleType: G_CYC_1CYCLE gDPSetCycleType: G_CYC_1CYCLE

Binary file not shown.

View file

@ -195,6 +195,15 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto
return result; return result;
} }
float soundClipDuration(int soundClipId, float pitch) {
if (soundClipId < 0 || soundClipId >= gSoundClipArray->soundCount) {
return 0.0f;
}
ALSound* alSound = gSoundClipArray->sounds[soundClipId];
return soundPlayerEstimateLength(alSound, pitch);
}
void soundPlayerUpdate() { void soundPlayerUpdate() {
int index = 0; int index = 0;
int writeIndex = 0; int writeIndex = 0;
@ -321,6 +330,16 @@ int soundPlayerIsPlaying(ALSndId soundId) {
return activeSound->estimatedTimeLeft > 0.0f && alSndpGetState(&gSoundPlayer) != AL_STOPPED; return activeSound->estimatedTimeLeft > 0.0f && alSndpGetState(&gSoundPlayer) != AL_STOPPED;
} }
float soundPlayerTimeLeft(ALSndId soundId) {
struct ActiveSound* activeSound = soundPlayerFindActiveSound(soundId);
if (!activeSound) {
return 0.0f;
}
return activeSound->estimatedTimeLeft;
}
void soundListenerUpdate(struct Vector3* position, struct Quaternion* rotation, struct Vector3* velocity, int listenerIndex) { void soundListenerUpdate(struct Vector3* position, struct Quaternion* rotation, struct Vector3* velocity, int listenerIndex) {
gSoundListeners[listenerIndex].worldPos = *position; gSoundListeners[listenerIndex].worldPos = *position;
gSoundListeners[listenerIndex].velocity = *velocity; gSoundListeners[listenerIndex].velocity = *velocity;

View file

@ -21,6 +21,7 @@ extern char _soundsTblSegmentRomEnd[];
void soundPlayerInit(); void soundPlayerInit();
void soundPlayerUpdate(); void soundPlayerUpdate();
ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vector3* at, struct Vector3* velocity); ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vector3* at, struct Vector3* velocity);
float soundClipDuration(int soundClipId, float pitch);
void soundPlayerStop(ALSndId soundId); void soundPlayerStop(ALSndId soundId);
void soundPlayerStopAll(); void soundPlayerStopAll();
@ -31,6 +32,7 @@ void soundPlayerUpdatePosition(ALSndId soundId, struct Vector3* at, struct Vecto
void soundPlayerAdjustVolume(ALSndId soundId, float newVolume); void soundPlayerAdjustVolume(ALSndId soundId, float newVolume);
int soundPlayerIsPlaying(ALSndId soundId); int soundPlayerIsPlaying(ALSndId soundId);
float soundPlayerTimeLeft(ALSndId soundId);
void soundListenerUpdate(struct Vector3* position, struct Quaternion* rotation, struct Vector3* velocity, int listenerIndex); void soundListenerUpdate(struct Vector3* position, struct Quaternion* rotation, struct Vector3* velocity, int listenerIndex);
void soundListenerSetCount(int count); void soundListenerSetCount(int count);

View file

@ -7,6 +7,8 @@
#include "../util/memory.h" #include "../util/memory.h"
#include "../savefile/checkpoint.h" #include "../savefile/checkpoint.h"
#include <math.h>
struct CutsceneRunner* gRunningCutscenes; struct CutsceneRunner* gRunningCutscenes;
struct CutsceneRunner* gUnusedRunners; struct CutsceneRunner* gUnusedRunners;
u64 gTriggeredCutscenes; u64 gTriggeredCutscenes;
@ -283,6 +285,32 @@ int cutsceneRunnerUpdateCurrentStep(struct CutsceneRunner* runner) {
} }
} }
float cutsceneSoundQueueTime(int channel);
float cutsceneStepEstimateTime(struct CutsceneStep* step, union CutsceneStepState* state) {
switch (step->type) {
case CutsceneStepTypePlaySound:
return state ? soundPlayerTimeLeft(state->playSound.soundId) : soundClipDuration(step->playSound.soundId, step->playSound.pitch * (1.0f / 64.0f));
case CutsceneStepTypeQueueSound:
return state ? soundPlayerTimeLeft(state->playSound.soundId) : soundClipDuration(step->queueSound.soundId, gCutsceneChannelPitch[step->queueSound.channel]);
case CutsceneStepTypeWaitForChannel:
{
return state ? cutsceneSoundQueueTime(step->waitForChannel.channel) : 0.0f;
}
case CutsceneStepTypeDelay:
return state ? state->delay : step->delay;
case CutsceneStepTypeWaitForSignal:
return 0.0f;
case CutsceneStepTypeWaitForCutscene:
return cutsceneEstimateTimeLeft(&gCurrentLevel->cutscenes[step->cutscene.cutsceneIndex]);
case CutsceneStepWaitForAnimation:
// Maybe todo
return 0.0f;
default:
return 0.0f;
}
}
void cutsceneRunnerRun(struct CutsceneRunner* runner, struct Cutscene* cutscene) { void cutsceneRunnerRun(struct CutsceneRunner* runner, struct Cutscene* cutscene) {
runner->currentCutscene = cutscene; runner->currentCutscene = cutscene;
runner->currentStep = 0; runner->currentStep = 0;
@ -352,6 +380,23 @@ int cutsceneIsRunning(struct Cutscene* cutscene) {
return 0; return 0;
} }
float cutsceneSoundQueueTime(int channel) {
float result = 0.0f;
if (soundPlayerIsPlaying(gCutsceneCurrentSound[channel])) {
result += soundPlayerTimeLeft(gCutsceneCurrentSound[channel]);
}
struct QueuedSound* curr = gCutsceneSoundQueues[channel];
while (curr) {
result += soundClipDuration(curr->soundId, gCutsceneChannelPitch[channel]);
curr = curr->next;
}
return result;
}
void cutscenesUpdateSounds() { void cutscenesUpdateSounds() {
for (int i = 0; i < CH_COUNT; ++i) { for (int i = 0; i < CH_COUNT; ++i) {
if (!soundPlayerIsPlaying(gCutsceneCurrentSound[i])) { if (!soundPlayerIsPlaying(gCutsceneCurrentSound[i])) {
@ -397,6 +442,30 @@ void cutscenesUpdate() {
} }
} }
float cutsceneRunnerEstimateTimeLeft(struct CutsceneRunner* cutsceneRunner) {
float result = 0.0f;
for (int i = cutsceneRunner->currentStep; i < cutsceneRunner->currentCutscene->stepCount; ++i) {
result += cutsceneStepEstimateTime(&cutsceneRunner->currentCutscene->steps[i], i == cutsceneRunner->currentStep ? &cutsceneRunner->state : NULL);
}
return result;
}
float cutsceneEstimateTimeLeft(struct Cutscene* cutscene) {
struct CutsceneRunner* current = gRunningCutscenes;
while (current) {
if (current->currentCutscene == cutscene) {
return cutsceneRunnerEstimateTimeLeft(current);
}
current = current->nextRunner;
}
return 0.0f;
}
void cutsceneCheckTriggers(struct Vector3* playerPos) { void cutsceneCheckTriggers(struct Vector3* playerPos) {
for (int i = 0; i < gCurrentLevel->triggerCount; ++i) { for (int i = 0; i < gCurrentLevel->triggerCount; ++i) {

View file

@ -32,6 +32,7 @@ void cutsceneStart(struct Cutscene* cutscene);
void cutsceneStop(struct Cutscene* cutscene); void cutsceneStop(struct Cutscene* cutscene);
int cutsceneIsRunning(struct Cutscene* cutscene); int cutsceneIsRunning(struct Cutscene* cutscene);
void cutscenesUpdate(); void cutscenesUpdate();
float cutsceneEstimateTimeLeft(struct Cutscene* cutscene);
void cutsceneCheckTriggers(struct Vector3* playerPos); void cutsceneCheckTriggers(struct Vector3* playerPos);

View file

@ -3,11 +3,68 @@
#include "../scene/dynamic_scene.h" #include "../scene/dynamic_scene.h"
#include "../defs.h" #include "../defs.h"
#include "../levels/levels.h"
#include "../levels/cutscene_runner.h"
#include "../build/assets/models/signage/clock.h" #include "../build/assets/models/signage/clock.h"
#include "../build/assets/models/signage/clock_digits.h" #include "../build/assets/models/signage/clock_digits.h"
#include "../../build/assets/materials/static.h" #include "../../build/assets/materials/static.h"
#include <math.h>
#define DIGIT_WIDTH 512
u8 gCurrentClockDigits[5];
Vtx* gClockDigits[] = {
signage_clock_digits_clock_digits_minute_01_color,
signage_clock_digits_clock_digits_second_10_color,
signage_clock_digits_clock_digits_second_01_color,
signage_clock_digits_clock_digits_ms_10_color,
signage_clock_digits_clock_digits_ms_01_color,
};
void clockSetDigit(int digitIndex, int currDigit) {
int prevDigit = gCurrentClockDigits[digitIndex];
if (prevDigit == currDigit) {
return;
}
for (int i = 0; i < 4; ++i) {
gClockDigits[digitIndex][i].v.tc[0] += (currDigit - prevDigit) * DIGIT_WIDTH;
}
gCurrentClockDigits[digitIndex] = (u8)currDigit;
osWritebackDCache(gClockDigits[digitIndex], sizeof(Vtx) * 4);
}
void clockSetTime(float timeInSeconds) {
float minutes = floor(timeInSeconds * (1.0f / 60.0f));
clockSetDigit(0, (int)minutes);
timeInSeconds -= minutes *= 60.0f;
float tenSeconds = floor(timeInSeconds * 0.1f);
clockSetDigit(1, (int)tenSeconds);
timeInSeconds -= tenSeconds * 10.0f;
float seconds = floor(timeInSeconds);
clockSetDigit(2, (int)seconds);
timeInSeconds -= seconds;
float tenthsOfSecond = floor(timeInSeconds * 10.0f);
clockSetDigit(3, (int)tenthsOfSecond);
timeInSeconds -= tenthsOfSecond * 0.1f;
clockSetDigit(4, (int)floor(timeInSeconds * 100.0f));
}
void clockRenderRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) { void clockRenderRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState) {
struct Clock* clock = (struct Clock*)data; struct Clock* clock = (struct Clock*)data;
@ -17,6 +74,14 @@ void clockRenderRender(void* data, struct DynamicRenderDataList* renderList, str
return; return;
} }
float time = 0.0f;
if (clock->cutsceneIndex != -1) {
time = cutsceneEstimateTimeLeft(&gCurrentLevel->cutscenes[clock->cutsceneIndex]);
}
clockSetTime(time);
transformToMatrixL(&clock->transform, matrix, SCENE_SCALE); transformToMatrixL(&clock->transform, matrix, SCENE_SCALE);
dynamicRenderListAddData( dynamicRenderListAddData(
@ -30,7 +95,7 @@ void clockRenderRender(void* data, struct DynamicRenderDataList* renderList, str
dynamicRenderListAddData( dynamicRenderListAddData(
renderList, renderList,
signage_clock_model_gfx, signage_clock_digits_model_gfx,
matrix, matrix,
CLOCK_DIGITS_INDEX, CLOCK_DIGITS_INDEX,
&clock->transform.position, &clock->transform.position,