Finish up clock implementation
This commit is contained in:
parent
bcba882efd
commit
9ab44568d8
|
@ -843,7 +843,8 @@ materials:
|
|||
clock_digits:
|
||||
gDPSetTile:
|
||||
filename: ./signage/clock_digits.png
|
||||
siz: G_IM_SIZ_16b
|
||||
siz: G_IM_SIZ_4b
|
||||
twoTone: true
|
||||
|
||||
gDPSetCombineMode: G_CC_DECALRGBA
|
||||
gDPSetCycleType: G_CYC_1CYCLE
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -195,6 +195,15 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto
|
|||
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() {
|
||||
int index = 0;
|
||||
int writeIndex = 0;
|
||||
|
@ -321,6 +330,16 @@ int soundPlayerIsPlaying(ALSndId soundId) {
|
|||
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) {
|
||||
gSoundListeners[listenerIndex].worldPos = *position;
|
||||
gSoundListeners[listenerIndex].velocity = *velocity;
|
||||
|
|
|
@ -21,6 +21,7 @@ extern char _soundsTblSegmentRomEnd[];
|
|||
void soundPlayerInit();
|
||||
void soundPlayerUpdate();
|
||||
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 soundPlayerStopAll();
|
||||
|
||||
|
@ -31,6 +32,7 @@ void soundPlayerUpdatePosition(ALSndId soundId, struct Vector3* at, struct Vecto
|
|||
void soundPlayerAdjustVolume(ALSndId soundId, float newVolume);
|
||||
|
||||
int soundPlayerIsPlaying(ALSndId soundId);
|
||||
float soundPlayerTimeLeft(ALSndId soundId);
|
||||
|
||||
void soundListenerUpdate(struct Vector3* position, struct Quaternion* rotation, struct Vector3* velocity, int listenerIndex);
|
||||
void soundListenerSetCount(int count);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "../util/memory.h"
|
||||
#include "../savefile/checkpoint.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
struct CutsceneRunner* gRunningCutscenes;
|
||||
struct CutsceneRunner* gUnusedRunners;
|
||||
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) {
|
||||
runner->currentCutscene = cutscene;
|
||||
runner->currentStep = 0;
|
||||
|
@ -352,6 +380,23 @@ int cutsceneIsRunning(struct Cutscene* cutscene) {
|
|||
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() {
|
||||
for (int i = 0; i < CH_COUNT; ++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) {
|
||||
for (int i = 0; i < gCurrentLevel->triggerCount; ++i) {
|
||||
|
|
|
@ -32,6 +32,7 @@ void cutsceneStart(struct Cutscene* cutscene);
|
|||
void cutsceneStop(struct Cutscene* cutscene);
|
||||
int cutsceneIsRunning(struct Cutscene* cutscene);
|
||||
void cutscenesUpdate();
|
||||
float cutsceneEstimateTimeLeft(struct Cutscene* cutscene);
|
||||
|
||||
void cutsceneCheckTriggers(struct Vector3* playerPos);
|
||||
|
||||
|
|
|
@ -3,11 +3,68 @@
|
|||
#include "../scene/dynamic_scene.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_digits.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) {
|
||||
struct Clock* clock = (struct Clock*)data;
|
||||
|
||||
|
@ -17,6 +74,14 @@ void clockRenderRender(void* data, struct DynamicRenderDataList* renderList, str
|
|||
return;
|
||||
}
|
||||
|
||||
float time = 0.0f;
|
||||
|
||||
if (clock->cutsceneIndex != -1) {
|
||||
time = cutsceneEstimateTimeLeft(&gCurrentLevel->cutscenes[clock->cutsceneIndex]);
|
||||
}
|
||||
|
||||
clockSetTime(time);
|
||||
|
||||
transformToMatrixL(&clock->transform, matrix, SCENE_SCALE);
|
||||
|
||||
dynamicRenderListAddData(
|
||||
|
@ -30,7 +95,7 @@ void clockRenderRender(void* data, struct DynamicRenderDataList* renderList, str
|
|||
|
||||
dynamicRenderListAddData(
|
||||
renderList,
|
||||
signage_clock_model_gfx,
|
||||
signage_clock_digits_model_gfx,
|
||||
matrix,
|
||||
CLOCK_DIGITS_INDEX,
|
||||
&clock->transform.position,
|
||||
|
|
Loading…
Reference in a new issue