Allow for more than one cutscene to run at once
This commit is contained in:
parent
e788782e57
commit
5d25fb2cfb
|
@ -233,6 +233,16 @@ struct ActiveSound* soundPlayerFindActiveSound(ALSndId soundId) {
|
|||
}
|
||||
|
||||
|
||||
void soundPlayerStop(ALSndId soundId) {
|
||||
struct ActiveSound* activeSound = soundPlayerFindActiveSound(soundId);
|
||||
|
||||
if (activeSound) {
|
||||
alSndpSetSound(&gSoundPlayer, soundId);
|
||||
alSndpStop(&gSoundPlayer);
|
||||
activeSound->estimatedTimeLeft = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void soundPlayerUpdatePosition(ALSndId soundId, struct Vector3* at) {
|
||||
struct ActiveSound* activeSound = soundPlayerFindActiveSound(soundId);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ extern char _soundsTblSegmentRomEnd[];
|
|||
void soundPlayerInit();
|
||||
void soundPlayerUpdate();
|
||||
ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vector3* at);
|
||||
void soundPlayerStop(ALSndId soundId);
|
||||
|
||||
void soundPlayerUpdatePosition(ALSndId soundId, struct Vector3* at);
|
||||
|
||||
|
|
|
@ -4,11 +4,44 @@
|
|||
#include "../scene/scene.h"
|
||||
#include "../scene/signals.h"
|
||||
#include "../levels/levels.h"
|
||||
#include "../util/memory.h"
|
||||
|
||||
struct CutsceneRunner gCutsceneRunner;
|
||||
struct CutsceneRunner* gRunningCutscenes;
|
||||
struct CutsceneRunner* gUnusedRunners;
|
||||
|
||||
struct CutsceneRunner* cutsceneRunnerNew() {
|
||||
struct CutsceneRunner* result;
|
||||
|
||||
if (gUnusedRunners) {
|
||||
result = gUnusedRunners;
|
||||
gUnusedRunners = result->nextRunner;
|
||||
} else {
|
||||
result = malloc(sizeof(struct CutsceneRunner));
|
||||
}
|
||||
|
||||
result->nextRunner = NULL;
|
||||
result->currentCutscene = NULL;
|
||||
result->currentStep = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void cutsceneRunnerCancel(struct CutsceneRunner* runner) {
|
||||
struct CutsceneStep* step = &runner->currentCutscene->steps[runner->currentStep];
|
||||
|
||||
switch (step->type) {
|
||||
case CutsceneStepTypePlaySound:
|
||||
soundPlayerStop(runner->state.playSound.soundId);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
runner->currentStep = 0;
|
||||
runner->currentCutscene = NULL;
|
||||
}
|
||||
|
||||
void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
||||
struct CutsceneStep* step = &runner->currentCutscene.steps[runner->currentStep];
|
||||
struct CutsceneStep* step = &runner->currentCutscene->steps[runner->currentStep];
|
||||
switch (step->type) {
|
||||
case CutsceneStepTypePlaySound:
|
||||
case CutsceneStepTypeStartSound:
|
||||
|
@ -51,7 +84,7 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
|||
}
|
||||
|
||||
int cutsceneRunnerUpdateCurrentStep(struct CutsceneRunner* runner) {
|
||||
struct CutsceneStep* step = &runner->currentCutscene.steps[runner->currentStep];
|
||||
struct CutsceneStep* step = &runner->currentCutscene->steps[runner->currentStep];
|
||||
switch (step->type) {
|
||||
case CutsceneStepTypePlaySound:
|
||||
return !soundPlayerIsPlaying(runner->state.playSound.soundId);
|
||||
|
@ -66,13 +99,13 @@ int cutsceneRunnerUpdateCurrentStep(struct CutsceneRunner* runner) {
|
|||
}
|
||||
|
||||
void cutsceneRunnerRun(struct CutsceneRunner* runner, struct Cutscene* cutscene) {
|
||||
runner->currentCutscene = *cutscene;
|
||||
runner->currentCutscene = cutscene;
|
||||
runner->currentStep = 0;
|
||||
cutsceneRunnerStartStep(runner);
|
||||
}
|
||||
|
||||
int cutsceneRunnerIsRunning(struct CutsceneRunner* runner) {
|
||||
return runner->currentStep < runner->currentCutscene.stepCount;
|
||||
return runner->currentStep < runner->currentCutscene->stepCount;
|
||||
}
|
||||
|
||||
void cutsceneRunnerUpdate(struct CutsceneRunner* runner) {
|
||||
|
@ -83,4 +116,63 @@ void cutsceneRunnerUpdate(struct CutsceneRunner* runner) {
|
|||
cutsceneRunnerStartStep(runner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cutsceneStart(struct Cutscene* cutscene) {
|
||||
struct CutsceneRunner* runner = cutsceneRunnerNew();
|
||||
cutsceneRunnerRun(runner, cutscene);
|
||||
runner->nextRunner = gRunningCutscenes;
|
||||
gRunningCutscenes = runner;
|
||||
}
|
||||
|
||||
void cutsceneStop(struct Cutscene* cutscene) {
|
||||
struct CutsceneRunner* previousCutscene = NULL;
|
||||
struct CutsceneRunner* current = gRunningCutscenes;
|
||||
|
||||
while (current) {
|
||||
if (current->currentCutscene == cutscene) {
|
||||
struct CutsceneRunner* toRemove = current;
|
||||
current = current->nextRunner;
|
||||
|
||||
cutsceneRunnerCancel(toRemove);
|
||||
|
||||
if (previousCutscene) {
|
||||
previousCutscene->nextRunner = toRemove->nextRunner;
|
||||
} else {
|
||||
gRunningCutscenes = toRemove->nextRunner;
|
||||
}
|
||||
|
||||
toRemove->nextRunner = gUnusedRunners;
|
||||
gUnusedRunners = toRemove;
|
||||
} else {
|
||||
previousCutscene = current;
|
||||
current = current->nextRunner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cutscenesUpdate() {
|
||||
struct CutsceneRunner* previousCutscene = NULL;
|
||||
struct CutsceneRunner* current = gRunningCutscenes;
|
||||
|
||||
while (current) {
|
||||
cutsceneRunnerUpdate(current);
|
||||
|
||||
if (!cutsceneRunnerIsRunning(current)) {
|
||||
struct CutsceneRunner* toRemove = current;
|
||||
current = current->nextRunner;
|
||||
|
||||
if (previousCutscene) {
|
||||
previousCutscene->nextRunner = toRemove->nextRunner;
|
||||
} else {
|
||||
gRunningCutscenes = toRemove->nextRunner;
|
||||
}
|
||||
|
||||
toRemove->nextRunner = gUnusedRunners;
|
||||
gUnusedRunners = toRemove;
|
||||
} else {
|
||||
previousCutscene = current;
|
||||
current = current->nextRunner;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
#include "level_definition.h"
|
||||
|
||||
struct CutsceneRunner {
|
||||
struct Cutscene currentCutscene;
|
||||
struct Cutscene* currentCutscene;
|
||||
u16 currentStep;
|
||||
|
||||
union {
|
||||
|
@ -14,13 +14,13 @@ struct CutsceneRunner {
|
|||
} playSound;
|
||||
float delay;
|
||||
} state;
|
||||
|
||||
struct CutsceneRunner* nextRunner;
|
||||
};
|
||||
|
||||
extern struct CutsceneRunner gCutsceneRunner;
|
||||
|
||||
void cutsceneRunnerRun(struct CutsceneRunner* runner, struct Cutscene* cutscene);
|
||||
void cutsceneRunnerUpdate(struct CutsceneRunner* runner);
|
||||
|
||||
int cutsceneRunnerIsRunning(struct CutsceneRunner* runner);
|
||||
void cutsceneStart(struct Cutscene* cutscene);
|
||||
void cutsceneStop(struct Cutscene* cutscene);
|
||||
void cutscenesUpdate();
|
||||
|
||||
#endif
|
|
@ -8,6 +8,7 @@
|
|||
#include "cutscene_runner.h"
|
||||
|
||||
struct LevelDefinition* gCurrentLevel;
|
||||
u64 gTriggeredCutscenes;
|
||||
|
||||
int levelCount() {
|
||||
return LEVEL_COUNT;
|
||||
|
@ -19,6 +20,7 @@ void levelLoad(int index) {
|
|||
}
|
||||
|
||||
gCurrentLevel = gLevelList[index];
|
||||
gTriggeredCutscenes = 0;
|
||||
|
||||
collisionSceneInit(&gCollisionScene, gCurrentLevel->collisionQuads, gCurrentLevel->collisionQuadCount, &gCurrentLevel->world);
|
||||
}
|
||||
|
@ -62,10 +64,11 @@ int levelQuadIndex(struct CollisionObject* pointer) {
|
|||
void levelCheckTriggers(struct Vector3* playerPos) {
|
||||
for (int i = 0; i < gCurrentLevel->triggerCount; ++i) {
|
||||
struct Trigger* trigger = &gCurrentLevel->triggers[i];
|
||||
if (trigger->cutscene.stepCount && box3DContainsPoint(&trigger->box, playerPos)) {
|
||||
cutsceneRunnerRun(&gCutsceneRunner, &trigger->cutscene);
|
||||
u64 cutsceneMask = 1LL << i;
|
||||
if (!(gTriggeredCutscenes & cutsceneMask) && box3DContainsPoint(&trigger->box, playerPos)) {
|
||||
cutsceneStart(&trigger->cutscene);
|
||||
// prevent the trigger from happening again
|
||||
trigger->cutscene.stepCount = 0;
|
||||
gTriggeredCutscenes |= cutsceneMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ void sceneUpdate(struct Scene* scene) {
|
|||
collisionSceneUpdateDynamics();
|
||||
|
||||
levelCheckTriggers(&scene->player.lookTransform.position);
|
||||
cutsceneRunnerUpdate(&gCutsceneRunner);
|
||||
cutscenesUpdate();
|
||||
|
||||
scene->cpuTime = osGetTime() - frameStart;
|
||||
scene->lastFrameStart = frameStart;
|
||||
|
|
Loading…
Reference in a new issue