diff --git a/src/audio/soundplayer.c b/src/audio/soundplayer.c index d7cab12..ebb97dd 100644 --- a/src/audio/soundplayer.c +++ b/src/audio/soundplayer.c @@ -7,6 +7,7 @@ #include "clips.h" #include "../physics/collision_scene.h" #include "../math/transform.h" +#include "../savefile/savefile.h" struct SoundArray* gSoundClipArray; ALSndPlayer gSoundPlayer; @@ -28,7 +29,9 @@ struct ActiveSound { struct Vector3 pos3D; struct Vector3 velocity3D; float volume; + float originalVolume; float basePitch; + enum SoundType soundType; }; struct SoundListener { @@ -194,7 +197,8 @@ float soundPlayerEstimateLength(ALSound* sound, float speed) { return sampleCount * (1.0f / OUTPUT_RATE) / speed; } -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, enum SoundType type) { + if (gActiveSoundCount >= MAX_ACTIVE_SOUNDS || soundClipId < 0 || soundClipId >= gSoundClipArray->soundCount) { return SOUND_ID_NONE; } @@ -216,9 +220,16 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto sound->flags = 0; sound->estimatedTimeLeft = soundPlayerEstimateLength(alSound, pitch); sound->volume = volume; + sound->originalVolume = volume; sound->basePitch = pitch; + sound->soundType = type; + + float newVolume = sound->originalVolume * gSaveData.audio.soundVolume/0xFFFF; + if (type == SoundTypeMusic){ + newVolume = newVolume * gSaveData.audio.musicVolume/0xFFFF; + } + sound->volume = newVolume; - float startingVolume = volume; int panning = 64; if (at) { @@ -226,7 +237,7 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto sound->pos3D = *at; sound->velocity3D = *velocity; float pitchBend; - soundPlayerDetermine3DSound(at, velocity, &startingVolume, &startingVolume, &panning, &pitchBend); + soundPlayerDetermine3DSound(at, velocity, &newVolume, &newVolume, &panning, &pitchBend); pitch = pitch * pitchBend; } @@ -234,14 +245,18 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto sound->flags |= SOUND_FLAGS_LOOPING; } + + alSndpSetSound(&gSoundPlayer, result); - alSndpSetVol(&gSoundPlayer, (short)(32767 * startingVolume)); + alSndpSetVol(&gSoundPlayer, (short)(32767 * newVolume)); alSndpSetPitch(&gSoundPlayer, pitch); alSndpSetPan(&gSoundPlayer, panning); alSndpPlay(&gSoundPlayer); ++gActiveSoundCount; + + return result; } @@ -254,6 +269,48 @@ float soundClipDuration(int soundClipId, float pitch) { return soundPlayerEstimateLength(alSound, pitch); } +void soundPlayerGameVolumeUpdate(enum SoundType type) { + int index = 0; + while (index < gActiveSoundCount) { + struct ActiveSound* sound = &gActiveSounds[index]; + if (!sound){ + ++index; + continue; + } + + float newVolume = sound->originalVolume * gSaveData.audio.soundVolume/0xFFFF; + if (type == SoundTypeMusic){ + newVolume = newVolume* gSaveData.audio.musicVolume/0xFFFF; + } + + if (sound->flags & SOUND_FLAGS_PAUSED) { + sound->volume = newVolume; + ++index; + continue; + } + if (sound->flags & SOUND_FLAGS_3D){ + sound->volume = newVolume; + float volume; + float pitch; + int panning; + soundPlayerDetermine3DSound(&sound->pos3D, &sound->velocity3D, &sound->volume, &volume, &panning, &pitch); + alSndpSetSound(&gSoundPlayer, sound->soundId); + alSndpSetVol(&gSoundPlayer, (short)(32767 * volume)); + alSndpSetPan(&gSoundPlayer, panning); + alSndpSetPitch(&gSoundPlayer, sound->basePitch * pitch); + ++index; + continue; + + } else { + alSndpSetSound(&gSoundPlayer, sound->soundId); + alSndpSetVol(&gSoundPlayer, (short)(32767 * newVolume)); + sound->volume = newVolume; + ++index; + continue; + } + } +} + void soundPlayerUpdate() { int index = 0; int writeIndex = 0; @@ -356,6 +413,10 @@ void soundPlayerAdjustVolume(ALSndId soundId, float newVolume) { struct ActiveSound* activeSound = soundPlayerFindActiveSound(soundId); if (activeSound) { + newVolume = newVolume * gSaveData.audio.soundVolume/0xFFFF; + if (activeSound->soundType == SoundTypeMusic){ + newVolume = newVolume * gSaveData.audio.musicVolume/0xFFFF; + } if (activeSound->flags & SOUND_FLAGS_3D){ activeSound->volume = newVolume; } else { diff --git a/src/audio/soundplayer.h b/src/audio/soundplayer.h index 58429c7..812d777 100644 --- a/src/audio/soundplayer.h +++ b/src/audio/soundplayer.h @@ -18,9 +18,16 @@ extern char _soundsSegmentRomEnd[]; extern char _soundsTblSegmentRomStart[]; extern char _soundsTblSegmentRomEnd[]; +enum SoundType{ + SoundTypeNone, + SoundTypeMusic, + SoundTypeAll, +}; + void soundPlayerInit(); +void soundPlayerGameVolumeUpdate(); 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, enum SoundType); float soundClipDuration(int soundClipId, float pitch); void soundPlayerStop(ALSndId soundId); void soundPlayerStopAll(); diff --git a/src/decor/decor_object.c b/src/decor/decor_object.c index d96125c..09e8307 100644 --- a/src/decor/decor_object.c +++ b/src/decor/decor_object.c @@ -165,7 +165,7 @@ int decorObjectUpdate(struct DecorObject* decorObject) { decorObject->playingSound = SOUND_ID_NONE; if (decorObject->definition->soundFizzleId != SOUND_ID_NONE) { - decorObject->playingSound = soundPlayerPlay(decorObject->definition->soundFizzleId, 2.0f, 0.5f, &decorObject->rigidBody.transform.position, &decorObject->rigidBody.velocity); + decorObject->playingSound = soundPlayerPlay(decorObject->definition->soundFizzleId, 2.0f, 0.5f, &decorObject->rigidBody.transform.position, &decorObject->rigidBody.velocity, SoundTypeAll); } } } else if (fizzleResult == FizzleCheckResultEnd) { @@ -183,7 +183,7 @@ int decorObjectUpdate(struct DecorObject* decorObject) { } if (decorObject->definition->soundClipId != -1 && decorObject->playingSound == SOUND_ID_NONE && decorObject->fizzleTime == 0.0f && !(decorObject->definition->flags & DecorObjectFlagsMuted)) { - decorObject->playingSound = soundPlayerPlay(decorObject->definition->soundClipId, 1.0f, 1.0f, &decorObject->rigidBody.transform.position, &decorObject->rigidBody.velocity); + decorObject->playingSound = soundPlayerPlay(decorObject->definition->soundClipId, 1.0f, 1.0f, &decorObject->rigidBody.transform.position, &decorObject->rigidBody.velocity, SoundTypeAll); } dynamicSceneSetRoomFlags(decorObject->dynamicId, ROOM_FLAG_FROM_INDEX(decorObject->rigidBody.currentRoom)); diff --git a/src/levels/cutscene_runner.c b/src/levels/cutscene_runner.c index 2fda2e0..8222005 100644 --- a/src/levels/cutscene_runner.c +++ b/src/levels/cutscene_runner.c @@ -137,7 +137,8 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) { step->playSound.volume * (1.0f / 255.0f), step->playSound.pitch * (1.0f / 64.0f), NULL, - NULL + NULL, + SoundTypeAll ); break; case CutsceneStepTypeQueueSound: @@ -396,8 +397,8 @@ void cutscenesUpdateSounds() { if (gCutsceneSoundQueues[i]) { struct QueuedSound* curr = gCutsceneSoundQueues[i]; - gCutsceneCurrentSound[i] = soundPlayerPlay(curr->soundId, curr->volume, gCutsceneChannelPitch[i], NULL, NULL); - hudShowSubtitle(&gScene.hud, curr->subtitleId); + gCutsceneCurrentSound[i] = soundPlayerPlay(curr->soundId, curr->volume, gCutsceneChannelPitch[i], NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, curr->subtitleId, SubtitleTypeCloseCaption); gCutsceneSoundQueues[i] = curr->next; @@ -405,7 +406,7 @@ void cutscenesUpdateSounds() { gCutsceneNextFreeSound = curr; } else { if (gCutsceneCurrentSound[i] != SOUND_ID_NONE) { - soundPlayerPlay(soundsIntercom[1], 1.0f, gCutsceneChannelPitch[i], NULL, NULL); + soundPlayerPlay(soundsIntercom[1], 1.0f, gCutsceneChannelPitch[i], NULL, NULL, SoundTypeAll); hudResolveSubtitle(&gScene.hud); } diff --git a/src/main.c b/src/main.c index 72e7e6e..0c860bd 100644 --- a/src/main.c +++ b/src/main.c @@ -203,7 +203,7 @@ static void gameProc(void* arg) { contactSolverInit(&gContactSolver); portalSurfaceCleanupQueueInit(); savefileLoad(); - levelLoadWithCallbacks(MAIN_MENU); + levelLoadWithCallbacks(5); gCurrentTestSubject = 0; cutsceneRunnerReset(); controllersInit(); diff --git a/src/menu/audio_options.c b/src/menu/audio_options.c index 49f70fb..e35f86c 100644 --- a/src/menu/audio_options.c +++ b/src/menu/audio_options.c @@ -13,28 +13,12 @@ #define GAMEPLAY_HEIGHT 124 #define GAMEPLAY_X ((SCREEN_WD - GAMEPLAY_WIDTH) / 2) -#define SCROLL_TICKS (int)maxf(NUM_SUBTITLE_LANGUAGES, 1) +#define SCROLL_TICKS 10//(int)maxf(NUM_SUBTITLE_LANGUAGES, 1) #define SCROLL_INTERVALS (int)maxf((SCROLL_TICKS - 1), 1) #define FULL_SCROLL_TIME 2.0f #define SCROLL_MULTIPLIER (int)(0xFFFF * FIXED_DELTA_TIME / (80 * FULL_SCROLL_TIME)) #define SCROLL_CHUNK_SIZE (0x10000 / SCROLL_INTERVALS) -void audioOptionsInit(struct AudioOptions* audioOptions) { - audioOptions->selectedItem = AudioOptionSubtitlesEnabled; - - if (NUM_SUBTITLE_LANGUAGES){ - audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "Closed Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 8); - audioOptions->subtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0; - - audioOptions->subtitlesLanguageText = menuBuildText(&gDejaVuSansFont, "Captions Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 28); - audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 28); - - audioOptions->subtitlesLanguage= menuBuildSlider(GAMEPLAY_X + 8, GAMEPLAY_Y + 48, 200, SCROLL_TICKS); - audioOptions->subtitles_language_temp = (0xFFFF/SCROLL_TICKS)* gSaveData.controls.subtitleLanguage; - audioOptions->subtitlesLanguage.value = (int)gSaveData.controls.subtitleLanguage * (0xFFFF/SCROLL_TICKS); - } -} - void audioOptionsHandleSlider(unsigned short* settingValue, float* sliderValue) { OSContPad* pad = controllersGetControllerData(0); @@ -66,6 +50,31 @@ void audioOptionsHandleSlider(unsigned short* settingValue, float* sliderValue) *sliderValue = (float)newValue / 0xFFFF; } +void audioOptionsInit(struct AudioOptions* audioOptions) { + audioOptions->selectedItem = AudioOptionGameVolume; + + audioOptions->gameVolumeText = menuBuildText(&gDejaVuSansFont, "Game Volume", GAMEPLAY_X + 8, GAMEPLAY_Y + 8); + audioOptions->gameVolume = menuBuildSlider(GAMEPLAY_X + 120, GAMEPLAY_Y + 8, 120, SCROLL_TICKS); + audioOptions->gameVolume.value = gSaveData.audio.soundVolume/0xFFFF; + + audioOptions->musicVolumeText = menuBuildText(&gDejaVuSansFont, "Music Volume", GAMEPLAY_X + 8, GAMEPLAY_Y + 28); + audioOptions->musicVolume = menuBuildSlider(GAMEPLAY_X + 120, GAMEPLAY_Y + 28, 120, SCROLL_TICKS); + audioOptions->musicVolume.value = gSaveData.audio.musicVolume/0xFFFF; + + audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "Closed Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 48); + audioOptions->subtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0; + + audioOptions->allSubtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "All Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 68); + audioOptions->allSubtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) != 0; + + audioOptions->subtitlesLanguageText = menuBuildText(&gDejaVuSansFont, "Captions Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 88); + audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 88); + + audioOptions->subtitlesLanguage= menuBuildSlider(GAMEPLAY_X + 8, GAMEPLAY_Y + 108, 200, NUM_SUBTITLE_LANGUAGES); + audioOptions->subtitles_language_temp = (0xFFFF/NUM_SUBTITLE_LANGUAGES)* gSaveData.controls.subtitleLanguage; + audioOptions->subtitlesLanguage.value = (int)gSaveData.controls.subtitleLanguage * (0xFFFF/NUM_SUBTITLE_LANGUAGES); +} + enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) { int controllerDir = controllerGetDirectionDown(0); @@ -89,31 +98,56 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) { } } - if (NUM_SUBTITLE_LANGUAGES){ switch (audioOptions->selectedItem) { + case AudioOptionGameVolume: + audioOptionsHandleSlider(&gSaveData.audio.soundVolume, &audioOptions->gameVolume.value); + soundPlayerGameVolumeUpdate(SoundTypeAll); + break; + case AudioOptionMusicVolume: + audioOptionsHandleSlider(&gSaveData.audio.musicVolume, &audioOptions->musicVolume.value); + soundPlayerGameVolumeUpdate(SoundTypeMusic); + break; case AudioOptionSubtitlesEnabled: if (controllerGetButtonDown(0, A_BUTTON)) { audioOptions->subtitlesEnabled.checked = !audioOptions->subtitlesEnabled.checked; - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); if (audioOptions->subtitlesEnabled.checked) { gSaveData.controls.flags |= ControlSaveSubtitlesEnabled; + gSaveData.controls.flags &= ~ControlSaveAllSubtitlesEnabled; + audioOptions->allSubtitlesEnabled.checked = 0; } else { gSaveData.controls.flags &= ~ControlSaveSubtitlesEnabled; } } break; + case AudioOptionAllSubtitlesEnabled: + if (controllerGetButtonDown(0, A_BUTTON)) { + audioOptions->allSubtitlesEnabled.checked = !audioOptions->allSubtitlesEnabled.checked; + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + + if (audioOptions->allSubtitlesEnabled.checked) { + gSaveData.controls.flags |= ControlSaveAllSubtitlesEnabled; + gSaveData.controls.flags &= ~ControlSaveSubtitlesEnabled; + audioOptions->subtitlesEnabled.checked = 0; + } else { + gSaveData.controls.flags &= ~ControlSaveAllSubtitlesEnabled; + } + } + break; case AudioOptionSubtitlesLanguage: audioOptionsHandleSlider(&audioOptions->subtitles_language_temp, &audioOptions->subtitlesLanguage.value); int temp = (int)((audioOptions->subtitles_language_temp * (1.0f/0xFFFF) * NUM_SUBTITLE_LANGUAGES)); temp = (int)minf(maxf(0.0, temp), NUM_SUBTITLE_LANGUAGES-1); gSaveData.controls.subtitleLanguage = temp; - audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 28); + audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 88); break; } - } + - if (audioOptions->selectedItem == AudioOptionSubtitlesLanguage){ + if (audioOptions->selectedItem == AudioOptionSubtitlesLanguage || + audioOptions->selectedItem == AudioOptionGameVolume || + audioOptions->selectedItem == AudioOptionMusicVolume){ if ((controllerGetButtonDown(0, L_TRIG) || controllerGetButtonDown(0, Z_TRIG))) { return MenuDirectionLeft; } @@ -135,32 +169,52 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) { void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* renderState, struct GraphicsTask* task) { gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]); - - if (NUM_SUBTITLE_LANGUAGES){ - gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.outline); - renderState->dl = menuCheckboxRender(&audioOptions->subtitlesEnabled, renderState->dl); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguage.back); - renderState->dl = menuSliderRender(&audioOptions->subtitlesLanguage, renderState->dl); - } + gSPDisplayList(renderState->dl++, audioOptions->gameVolume.back); + renderState->dl = menuSliderRender(&audioOptions->gameVolume, renderState->dl); + + gSPDisplayList(renderState->dl++, audioOptions->musicVolume.back); + renderState->dl = menuSliderRender(&audioOptions->musicVolume, renderState->dl); + + + gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.outline); + renderState->dl = menuCheckboxRender(&audioOptions->subtitlesEnabled, renderState->dl); + + gSPDisplayList(renderState->dl++, audioOptions->allSubtitlesEnabled.outline); + renderState->dl = menuCheckboxRender(&audioOptions->allSubtitlesEnabled, renderState->dl); + + gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguage.back); + renderState->dl = menuSliderRender(&audioOptions->subtitlesLanguage, renderState->dl); + gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]); gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]); - if (NUM_SUBTITLE_LANGUAGES){ - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesEnabled, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.text); + gDPPipeSync(renderState->dl++); + menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionGameVolume, &gSelectionGray, &gColorWhite); + gSPDisplayList(renderState->dl++, audioOptions->gameVolumeText); - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageText); + gDPPipeSync(renderState->dl++); + menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionMusicVolume, &gSelectionGray, &gColorWhite); + gSPDisplayList(renderState->dl++, audioOptions->musicVolumeText); + + gDPPipeSync(renderState->dl++); + menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesEnabled, &gSelectionGray, &gColorWhite); + gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.text); + + gDPPipeSync(renderState->dl++); + menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAllSubtitlesEnabled, &gSelectionGray, &gColorWhite); + gSPDisplayList(renderState->dl++, audioOptions->allSubtitlesEnabled.text); + + gDPPipeSync(renderState->dl++); + menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); + gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageText); + + gDPPipeSync(renderState->dl++); + menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); + gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageDynamicText); - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageDynamicText); - } gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]); } \ No newline at end of file diff --git a/src/menu/audio_options.h b/src/menu/audio_options.h index 45e34c0..6e3f2fd 100644 --- a/src/menu/audio_options.h +++ b/src/menu/audio_options.h @@ -5,15 +5,23 @@ #include "../graphics/graphics.h" enum AudioOption { + AudioOptionGameVolume, + AudioOptionMusicVolume, AudioOptionSubtitlesEnabled, + AudioOptionAllSubtitlesEnabled, AudioOptionSubtitlesLanguage, AudioOptionCount, }; struct AudioOptions { + struct MenuSlider gameVolume; + struct MenuSlider musicVolume; struct MenuCheckbox subtitlesEnabled; + struct MenuCheckbox allSubtitlesEnabled; struct MenuSlider subtitlesLanguage; + Gfx* gameVolumeText; + Gfx* musicVolumeText; Gfx* subtitlesLanguageText; Gfx* subtitlesLanguageDynamicText; unsigned short subtitles_language_temp; diff --git a/src/menu/controls.c b/src/menu/controls.c index fa3aca2..aeafb08 100644 --- a/src/menu/controls.c +++ b/src/menu/controls.c @@ -283,7 +283,7 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu) { controlsLayout(controlsMenu); - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } return MenuDirectionStay; @@ -338,7 +338,7 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu) { controlsLayout(controlsMenu); } - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } if (controllerGetButtonDown(0, B_BUTTON)) { @@ -510,7 +510,7 @@ void controlsRenderPrompt(enum ControllerAction action, char* message, float opa gSPDisplayList(renderState->dl++, ui_material_revert_list[BUTTON_ICONS_INDEX]); } -void controlsRenderSubtitle(char* message, float textOpacity, float backgroundOpacity, struct RenderState* renderState) { +void controlsRenderSubtitle(char* message, float textOpacity, float backgroundOpacity, struct RenderState* renderState, enum SubtitleType subtitleType) { struct Vector2s16 size = fontMeasure(&gDejaVuSansFont, message); int textOpacityAsInt = (int)(255 * textOpacity); @@ -544,7 +544,12 @@ void controlsRenderSubtitle(char* message, float textOpacity, float backgroundOp gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_TRANSPARENT_OVERLAY_INDEX]); gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]); - gDPSetEnvColor(renderState->dl++, 255, 140, 155, textOpacityAsInt); + if (subtitleType == SubtitleTypeCloseCaption){ + gDPSetEnvColor(renderState->dl++, 255, 140, 155, textOpacityAsInt); + } else if (subtitleType == SubtitleTypeCaption){ + gDPSetEnvColor(renderState->dl++, 255, 255, 255, textOpacityAsInt); + } + renderState->dl = fontRender( &gDejaVuSansFont, message, diff --git a/src/menu/controls.h b/src/menu/controls.h index 2d5119a..ef64a28 100644 --- a/src/menu/controls.h +++ b/src/menu/controls.h @@ -4,6 +4,7 @@ #include "./menu.h" #include "../controls/controller_actions.h" #include "../graphics/graphics.h" +#include "../scene/hud.h" #define MAX_SOURCES_PER_ACTION 4 #define MAX_CONTROLS_SECTIONS 4 @@ -42,6 +43,6 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu); void controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* renderState, struct GraphicsTask* task); void controlsRenderPrompt(enum ControllerAction action, char* message, float opacity, struct RenderState* renderState); -void controlsRenderSubtitle(char* message, float textOpacity, float backgroundOpacity, struct RenderState* renderState); +void controlsRenderSubtitle(char* message, float textOpacity, float backgroundOpacity, struct RenderState* renderState, enum SubtitleType subtitleType); #endif \ No newline at end of file diff --git a/src/menu/gameplay_options.c b/src/menu/gameplay_options.c index 2d6315f..8aa6f36 100644 --- a/src/menu/gameplay_options.c +++ b/src/menu/gameplay_options.c @@ -95,7 +95,7 @@ enum MenuDirection gameplayOptionsUpdate(struct GameplayOptions* gameplayOptions case GameplayOptionMovingPortals: if (controllerGetButtonDown(0, A_BUTTON)) { gameplayOptions->movingPortals.checked = !gameplayOptions->movingPortals.checked; - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); if (gameplayOptions->movingPortals.checked) { gSaveData.controls.flags |= ControlSaveMoveablePortals; @@ -108,7 +108,7 @@ enum MenuDirection gameplayOptionsUpdate(struct GameplayOptions* gameplayOptions case GameplayOptionWideScreen: if (controllerGetButtonDown(0, A_BUTTON)) { gameplayOptions->wideScreen.checked = !gameplayOptions->wideScreen.checked; - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); if (gameplayOptions->wideScreen.checked) { gSaveData.controls.flags |= ControlSaveWideScreen; diff --git a/src/menu/joystick_options.c b/src/menu/joystick_options.c index 4ca5901..eadc619 100644 --- a/src/menu/joystick_options.c +++ b/src/menu/joystick_options.c @@ -106,7 +106,7 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions case JoystickOptionInvert: if (controllerGetButtonDown(0, A_BUTTON)) { joystickOptions->invertControls.checked = !joystickOptions->invertControls.checked; - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); if (joystickOptions->invertControls.checked) { gSaveData.controls.flags |= ControlSaveFlagsInvert; @@ -119,7 +119,7 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions case JoystickOptionInvertYaw: if (controllerGetButtonDown(0, A_BUTTON)) { joystickOptions->invertControlsYaw.checked = !joystickOptions->invertControlsYaw.checked; - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); if (joystickOptions->invertControlsYaw.checked) { gSaveData.controls.flags |= ControlSaveFlagsInvertYaw; @@ -132,7 +132,7 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions case JoystickOptionTankControls: if (controllerGetButtonDown(0, A_BUTTON)) { joystickOptions->tankControls.checked = !joystickOptions->tankControls.checked; - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); if (joystickOptions->tankControls.checked) { gSaveData.controls.flags |= ControlSaveTankControls; diff --git a/src/menu/landing_menu.c b/src/menu/landing_menu.c index 5956952..3ec8d34 100644 --- a/src/menu/landing_menu.c +++ b/src/menu/landing_menu.c @@ -73,16 +73,16 @@ void landingMenuInit(struct LandingMenu* landingMenu, struct LandingMenuOption* struct LandingMenuOption* landingMenuUpdate(struct LandingMenu* landingMenu) { if ((controllerGetDirectionDown(0) & ControllerDirectionUp) != 0 && landingMenu->selectedItem > 0) { --landingMenu->selectedItem; - soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } if ((controllerGetDirectionDown(0) & ControllerDirectionDown) != 0 && landingMenu->selectedItem + 1 < landingMenu->optionCount) { ++landingMenu->selectedItem; - soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } if (controllerGetButtonDown(0, A_BUTTON)) { - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); return &landingMenu->options[landingMenu->selectedItem]; } diff --git a/src/menu/load_game.c b/src/menu/load_game.c index 1997102..a07fa22 100644 --- a/src/menu/load_game.c +++ b/src/menu/load_game.c @@ -41,7 +41,7 @@ enum MenuDirection loadGameUpdate(struct LoadGameMenu* loadGame) { stackMallocFree(save); - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } return savefileListUpdate(loadGame->savefileList); diff --git a/src/menu/main_menu.c b/src/menu/main_menu.c index d62cb75..a6cf673 100644 --- a/src/menu/main_menu.c +++ b/src/menu/main_menu.c @@ -28,7 +28,7 @@ void mainMenuPlayAmbientSound() { static ALSndId soundId = -1; if (soundId == -1 || !soundPlayerIsPlaying(soundId)) { - soundId = soundPlayerPlay(SOUNDS_PORTAL_PROCEDURAL_JIGGLE_BONE, 1.0f, 0.5f, NULL, NULL); + soundId = soundPlayerPlay(SOUNDS_PORTAL_PROCEDURAL_JIGGLE_BONE, 1.0f, 0.5f, NULL, NULL, SoundTypeMusic); } } diff --git a/src/menu/new_game_menu.c b/src/menu/new_game_menu.c index eacb307..ecf999c 100644 --- a/src/menu/new_game_menu.c +++ b/src/menu/new_game_menu.c @@ -136,7 +136,7 @@ enum MenuDirection newGameUpdate(struct NewGameMenu* newGameMenu) { if (controllerGetButtonDown(0, A_BUTTON) && gChapters[newGameMenu->selectedChapter].testChamberNumber >= 0) { gCurrentTestSubject = savefileNextTestSubject(); - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); levelQueueLoad(gChapters[newGameMenu->selectedChapter].testChamberNumber, NULL, NULL); } @@ -144,12 +144,12 @@ enum MenuDirection newGameUpdate(struct NewGameMenu* newGameMenu) { newGameMenu->selectedChapter + 1 < newGameMenu->chapterCount && gChapters[newGameMenu->selectedChapter + 1].imageData) { newGameMenu->selectedChapter = newGameMenu->selectedChapter + 1; - soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } if ((controllerGetDirectionDown(0) & ControllerDirectionLeft) != 0 && newGameMenu->selectedChapter > 0) { newGameMenu->selectedChapter = newGameMenu->selectedChapter - 1; - soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } int nextChapterOffset = newGameMenu->selectedChapter & ~1; diff --git a/src/menu/save_game_menu.c b/src/menu/save_game_menu.c index f458d09..c9cad68 100644 --- a/src/menu/save_game_menu.c +++ b/src/menu/save_game_menu.c @@ -64,7 +64,7 @@ enum MenuDirection saveGameUpdate(struct SaveGameMenu* saveGame) { saveGamePopulate(saveGame, 0); } stackMallocFree(save); - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } return savefileListUpdate(saveGame->savefileList); diff --git a/src/menu/savefile_list.c b/src/menu/savefile_list.c index 4107464..1f93cc3 100644 --- a/src/menu/savefile_list.c +++ b/src/menu/savefile_list.c @@ -152,7 +152,7 @@ enum MenuDirection savefileListUpdate(struct SavefileListMenu* savefileList) { if (savefileList->selectedSave == savefileList->numberOfSaves) { savefileList->selectedSave = 0; } - soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } if (controllerDir & ControllerDirectionUp) { @@ -161,7 +161,7 @@ enum MenuDirection savefileListUpdate(struct SavefileListMenu* savefileList) { if (savefileList->selectedSave < 0) { savefileList->selectedSave = savefileList->numberOfSaves - 1; } - soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } int selectTop = SCROLLED_ROW_Y(savefileList->selectedSave, savefileList->scrollOffset) - 8; diff --git a/src/player/player.c b/src/player/player.c index 744cfe7..ee5cb3a 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -110,7 +110,7 @@ void playerRender(void* data, struct DynamicRenderDataList* renderList, struct R } void playerInit(struct Player* player, struct Location* startLocation, struct Vector3* velocity) { - player->flyingSoundLoopId = soundPlayerPlay(soundsFastFalling, 0.0f, 0.5f, NULL, NULL); + player->flyingSoundLoopId = soundPlayerPlay(soundsFastFalling, 0.0f, 0.5f, NULL, NULL, SoundTypeAll); collisionObjectInit(&player->collisionObject, &gPlayerColliderData, &player->body, 1.0f, PLAYER_COLLISION_LAYERS); @@ -217,7 +217,7 @@ void playerHandleCollision(struct Player* player) { if (((isColliderForBall(contact->shapeA) || isColliderForBall(contact->shapeB)) && !playerIsDead(player))) { playerKill(player, 0); - soundPlayerPlay(soundsBallKill, 1.0f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsBallKill, 1.0f, 1.0f, NULL, NULL, SoundTypeAll); } } } @@ -427,6 +427,9 @@ void playerUpdateSpeedSound(struct Player* player) { soundPlayerVolume = sqrtf(vector3MagSqrd(&player->body.velocity))*(0.6f / MAX_PORTAL_SPEED); soundPlayerVolume = clampf(soundPlayerVolume, 0.0, 1.0f); soundPlayerAdjustVolume(player->flyingSoundLoopId, soundPlayerVolume); + if (soundPlayerVolume >= 0.75){ + hudShowSubtitle(&gScene.hud, PORTALPLAYER_WOOSH, SubtitleTypeCaption); + } } void playerKill(struct Player* player, int isUnderwater) { @@ -741,8 +744,10 @@ void playerUpdate(struct Player* player) { quatIdent(&player->body.transform.rotation); if (didPassThroughPortal) { - soundPlayerPlay(soundsPortalEnter[didPassThroughPortal - 1], 0.75f, 1.0f, NULL, NULL); - soundPlayerPlay(soundsPortalExit[2 - didPassThroughPortal], 0.75f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsPortalEnter[didPassThroughPortal - 1], 0.75f, 1.0f, NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTALPLAYER_ENTERPORTAL, SubtitleTypeCaption); + soundPlayerPlay(soundsPortalExit[2 - didPassThroughPortal], 0.75f, 1.0f, NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTALPLAYER_EXITPORTAL, SubtitleTypeCaption); gPlayerCollider.extendDownward = 0.0f; } else { gPlayerCollider.extendDownward = mathfMoveTowards(gPlayerCollider.extendDownward, TARGET_CAPSULE_EXTEND_HEIGHT, STAND_SPEED * FIXED_DELTA_TIME); diff --git a/src/savefile/savefile.c b/src/savefile/savefile.c index 4b72764..2131652 100755 --- a/src/savefile/savefile.c +++ b/src/savefile/savefile.c @@ -96,9 +96,8 @@ void savefileNew() { gSaveData.controls.deadzone = 0x4000; gSaveData.controls.portalRenderDepth = 2; gSaveData.controls.subtitleLanguage = 0; - - gSaveData.audio.soundVolume = 0xFF; - gSaveData.audio.musicVolume = 0xFF; + gSaveData.audio.soundVolume = 0xFFFF; + gSaveData.audio.musicVolume = 0xFFFF; controllerSetDeadzone(gSaveData.controls.deadzone * (1.0f / 0xFFFF) * MAX_DEADZONE); } diff --git a/src/savefile/savefile.h b/src/savefile/savefile.h index fa2bdf4..6da593f 100755 --- a/src/savefile/savefile.h +++ b/src/savefile/savefile.h @@ -39,6 +39,7 @@ enum ControlSaveFlags { ControlSaveTankControls = (1 << 2), ControlSaveSubtitlesEnabled = (1 << 5), + ControlSaveAllSubtitlesEnabled = (1 << 6), ControlSaveMoveablePortals = (1 << 8), ControlSaveWideScreen = (1 << 9), @@ -55,8 +56,8 @@ struct ControlSaveState { }; struct AudioSettingsSaveState { - unsigned char soundVolume; - unsigned char musicVolume; + unsigned short soundVolume; + unsigned short musicVolume; }; #define NO_TEST_CHAMBER 0xFF diff --git a/src/scene/ball.c b/src/scene/ball.c index 8ec8be3..6c17bf6 100644 --- a/src/scene/ball.c +++ b/src/scene/ball.c @@ -115,7 +115,7 @@ void ballInit(struct Ball* ball, struct Vector3* position, struct Vector3* veloc dynamicSceneSetRoomFlags(ball->dynamicId, ROOM_FLAG_FROM_INDEX(startingRoom)); - ball->soundLoopId = soundPlayerPlay(soundsBallLoop, 1.5f, 1.0f, &ball->rigidBody.transform.position, &ball->rigidBody.velocity); + ball->soundLoopId = soundPlayerPlay(soundsBallLoop, 1.5f, 1.0f, &ball->rigidBody.transform.position, &ball->rigidBody.velocity, SoundTypeAll); } void ballTurnOnCollision(struct Ball* ball) { @@ -138,7 +138,8 @@ void ballInitBurn(struct Ball* ball, struct ContactManifold* manifold) { if (manifold->shapeA->body) { transformPoint(&manifold->shapeA->body->transform, &position, &position); } - soundPlayerPlay(soundsBallBounce, 1.5f, 1.0f, &position, &gZeroVec); + soundPlayerPlay(soundsBallBounce, 1.5f, 1.0f, &position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, ENERGYBALL_IMPACT, SubtitleTypeCaption); ball->flags |= BallJustBounced; } @@ -209,7 +210,8 @@ void ballUpdate(struct Ball* ball) { collisionSceneRemoveDynamicObject(&ball->collisionObject); dynamicSceneRemove(ball->dynamicId); soundPlayerStop(ball->soundLoopId); - soundPlayerPlay(soundsBallExplode, 2.0f, 1.0f, &ball->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsBallExplode, 2.0f, 1.0f, &ball->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, ENERGYBALL_EXPLOSION, SubtitleTypeCaption); effectsSplashPlay(&gScene.effects, &gBallBurst, &ball->rigidBody.transform.position, &gUp); ball->soundLoopId = SOUND_ID_NONE; } diff --git a/src/scene/ball_catcher.c b/src/scene/ball_catcher.c index ed2a251..073e1f7 100644 --- a/src/scene/ball_catcher.c +++ b/src/scene/ball_catcher.c @@ -107,7 +107,7 @@ void ballCatcherCheckBalls(struct BallCatcher* catcher, struct BallLauncher* bal } catcher->caughtBall = &launcher->currentBall; - soundPlayerPlay(soundsBallCatcher, 5.0f, 1.0f, &catcher->rigidBody.transform.position, &catcher->rigidBody.velocity); + soundPlayerPlay(soundsBallCatcher, 5.0f, 1.0f, &catcher->rigidBody.transform.position, &catcher->rigidBody.velocity, SoundTypeAll); ballMarkCaught(catcher->caughtBall); skAnimatorRunClip(&catcher->animator, dynamicAssetClip(PROPS_COMBINE_BALL_CATCHER_DYNAMIC_ANIMATED_MODEL, PROPS_COMBINE_BALL_CATCHER_ARMATURE_CATCH_CLIP_INDEX), 0.0f, 0); } diff --git a/src/scene/ball_launcher.c b/src/scene/ball_launcher.c index 164d8d7..2ac622a 100644 --- a/src/scene/ball_launcher.c +++ b/src/scene/ball_launcher.c @@ -99,7 +99,7 @@ void ballLauncherUpdate(struct BallLauncher* launcher) { ballInit(&launcher->currentBall, &launcher->rigidBody.transform.position, &initialVelocity, launcher->rigidBody.currentRoom, launcher->ballLifetime); skAnimatorRunClip(&launcher->animator, dynamicAssetClip(PROPS_COMBINE_BALL_LAUNCHER_DYNAMIC_ANIMATED_MODEL, PROPS_COMBINE_BALL_LAUNCHER_ARMATURE_LAUNCH_CLIP_INDEX), 0.0f, 0); - soundPlayerPlay(soundsBallLaunch, 1.0f, 1.0f, &launcher->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsBallLaunch, 1.0f, 1.0f, &launcher->rigidBody.transform.position, &gZeroVec, SoundTypeAll); } if (ballIsActive(&launcher->currentBall) && !ballIsCollisionOn(&launcher->currentBall)) { diff --git a/src/scene/box_dropper.c b/src/scene/box_dropper.c index fa4249c..84016d3 100644 --- a/src/scene/box_dropper.c +++ b/src/scene/box_dropper.c @@ -12,6 +12,8 @@ #include "../../build/assets/models/props/box_dropper.h" #include "../../build/assets/models/dynamic_model_list.h" #include "../../build/assets/models/dynamic_animated_model_list.h" +#include "hud.h" +#include "scene.h" #define DROOPER_RELOAD_TIME 2.0f #define DROPPER_DROP_TIME 0.5f @@ -150,7 +152,8 @@ void boxDropperUpdate(struct BoxDropper* dropper) { decorObjectInit(&dropper->activeCube, decorObjectDefinitionForId(DECOR_TYPE_CUBE_UNIMPORTANT), &pendingCubePos, dropper->roomIndex); skAnimatorRunClip(&dropper->animator, dynamicAssetClip(PROPS_BOX_DROPPER_DYNAMIC_ANIMATED_MODEL, PROPS_BOX_DROPPER_ARMATURE_DROPCUBE_CLIP_INDEX), 0.0f, 0); - soundPlayerPlay(soundsReleaseCube, 5.0f, 0.5f, &dropper->activeCube.rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsReleaseCube, 5.0f, 0.5f, &dropper->activeCube.rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, ESCAPE_CAKE_RIDE_1, SubtitleTypeCaption); dropper->flags &= ~BoxDropperFlagsCubeRequested; dropper->flags |= BoxDropperFlagsCubeIsActive; diff --git a/src/scene/button.c b/src/scene/button.c index b81a717..3a69cfa 100644 --- a/src/scene/button.c +++ b/src/scene/button.c @@ -12,6 +12,8 @@ #include "../../build/assets/models/dynamic_animated_model_list.h" #include "../build/assets/materials/static.h" #include "../../build/assets/models/props/button.h" +#include "../scene/hud.h" +#include "../scene/scene.h" struct Vector2 gButtonCylinderEdgeVectors[] = { {0.0f, 1.0f}, @@ -141,14 +143,16 @@ void buttonUpdate(struct Button* button) { //actively going down if (shouldPress){ if (!(button->flags & ButtonFlagsBeingPressed)){ - soundPlayerPlay(soundsButton, 2.5f, 0.5f, &button->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsButton, 2.5f, 0.5f, &button->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_BUTTON_DOWN, SubtitleTypeCaption); } button->flags |= ButtonFlagsBeingPressed; } // actively going up else{ if ((button->flags & ButtonFlagsBeingPressed)){ - soundPlayerPlay(soundsButtonRelease, 2.5f, 0.4f, &button->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsButtonRelease, 2.5f, 0.4f, &button->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_BUTTON_UP, SubtitleTypeCaption); } button->flags &= ~ButtonFlagsBeingPressed; } diff --git a/src/scene/door.c b/src/scene/door.c index 447cd66..1315fd7 100644 --- a/src/scene/door.c +++ b/src/scene/door.c @@ -9,6 +9,8 @@ #include "../physics/collision_box.h" #include "../physics/collision_scene.h" #include "../util/dynamic_asset_loader.h" +#include "hud.h" +#include "scene.h" #include "../build/assets/materials/static.h" #include "../../build/assets/models/dynamic_animated_model_list.h" @@ -131,7 +133,8 @@ void doorUpdate(struct Door* door) { skAnimatorRunClip(&door->animator, dynamicAssetClip(typeDefinition->armatureIndex, typeDefinition->closeClipIndex), 0.0f, 0); } - soundPlayerPlay(soundsDoor, 3.0f, 0.5f, &door->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsDoor, 3.0f, 0.5f, &door->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_DOORCLOSE, SubtitleTypeCaption); if (signal) { door->flags |= DoorFlagsIsOpen; diff --git a/src/scene/elevator.c b/src/scene/elevator.c index e763f03..6b9e859 100644 --- a/src/scene/elevator.c +++ b/src/scene/elevator.c @@ -183,9 +183,10 @@ int elevatorUpdate(struct Elevator* elevator, struct Player* player) { } if ((elevator->openAmount == 0.0f && shouldBeOpen) || (elevator->openAmount == 1.0f && !shouldBeOpen)) { - soundPlayerPlay(soundsElevatorDoor, 1.0f, 0.5f, &elevator->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsElevatorDoor, 1.0f, 0.5f, &elevator->rigidBody.transform.position, &gZeroVec, SoundTypeAll); if ((elevator->openAmount == 0.0f && shouldBeOpen) && (elevator->flags & ElevatorFlagsHasHadPlayer)){ - soundPlayerPlay(soundsElevatorChime, 1.5f, 0.5f, &elevator->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsElevatorChime, 1.5f, 0.5f, &elevator->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_ELEVATOR_CHIME, SubtitleTypeCaption); } } @@ -195,7 +196,8 @@ int elevatorUpdate(struct Elevator* elevator, struct Player* player) { } if ((elevator->flags & ElevatorFlagsIsLocked) && (elevator->openAmount == 0.0f) && !(elevator->flags & ElevatorFlagsMovingSoundPlayed) && (elevator->movingTimer <= 0.0f) && inside){ - soundPlayerPlay(soundsElevatorMoving, 1.25f, 0.5f, &elevator->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsElevatorMoving, 1.25f, 0.5f, &elevator->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_ELEVATOR_START, SubtitleTypeCaption); player->shakeTimer = SHAKE_DURATION; elevator->flags |= ElevatorFlagsMovingSoundPlayed; } diff --git a/src/scene/hud.c b/src/scene/hud.c index 7641ffd..d1f3d5e 100644 --- a/src/scene/hud.c +++ b/src/scene/hud.c @@ -1,7 +1,6 @@ #include "hud.h" #include "../../build/assets/materials/hud.h" -#include "../../build/src/audio/subtitles.h" #include "../menu/controls.h" #include "../graphics/graphics.h" #include "../util/time.h" @@ -32,15 +31,23 @@ #define RETICLE_WIDTH 16 #define RETICLE_HEIGHT 16 -#define PROMPT_FADE_TIME 2.0f -#define SUBTITLE_FADE_TIME 0.75f +#define PROMPT_FADE_TIME 2.0f +#define SUBTITLE_SLOW_FADE_TIME 0.75f +#define SUBTITLE_FAST_FADE_TIME 0.25f +#define CAPTION_EXPIRE_TIME 1.5f + + void hudInit(struct Hud* hud) { hud->promptType = CutscenePromptTypeNone; + hud->subtitleKey = SubtitleKeyNone; + hud->queuedSubtitleKey = SubtitleKeyNone; + hud->subtitleType = SubtitleTypeNone; + hud->queuedSubtitleType = SubtitleTypeNone; hud->promptOpacity = 0.0f; hud->subtitleOpacity = 0.0f; hud->backgroundOpacity = 0.0f; - hud->subtitleFadeTime = 0.75; + hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME; hud->chosenLanguage = gSaveData.controls.subtitleLanguage; hud->flags = 0; hud->resolvedPrompts = 0; @@ -63,11 +70,19 @@ void hudUpdate(struct Hud* hud) { } } + if (hud->subtitleExpireTimer > 0.0f) { + hud->subtitleExpireTimer -= FIXED_DELTA_TIME; + + if (hud->subtitleExpireTimer < 0.0f) { + hud->subtitleExpireTimer = 0.0f; + } + } + hud->chosenLanguage = gSaveData.controls.subtitleLanguage; float targetPromptOpacity = (hud->flags & HudFlagsShowingPrompt) ? 1.0 : 0.0f; - float targetSubtitleOpacity = ((hud->flags & HudFlagsShowingSubtitle) && !(hud->flags & HudFlagsSubtitleQueued)) ? 0.85: 0.0f; - float targetBackgroundOpacity = (hud->flags & HudFlagsShowingSubtitle && !(hud->flags & HudFlagsSubtitleQueued)) ? 0.45: 0.0f; + float targetSubtitleOpacity = ((hud->flags & HudFlagsShowingSubtitle) && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.85: 0.0f; + float targetBackgroundOpacity = (hud->flags & HudFlagsShowingSubtitle && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.45: 0.0f; if (targetPromptOpacity != hud->promptOpacity) { hud->promptOpacity = mathfMoveTowards(hud->promptOpacity, targetPromptOpacity, FIXED_DELTA_TIME / PROMPT_FADE_TIME); @@ -77,10 +92,22 @@ void hudUpdate(struct Hud* hud) { hud->subtitleOpacity = mathfMoveTowards(hud->subtitleOpacity, targetSubtitleOpacity, FIXED_DELTA_TIME / hud->subtitleFadeTime); } - if ((hud->subtitleOpacity == 0.0f) && (hud->flags & HudFlagsSubtitleQueued)){ - hud->flags &= ~HudFlagsSubtitleQueued; - hud->subtitleType = hud->queuedSubtitleType; - hud->queuedSubtitleType = SubtitleKeyNone; + if ((hud->subtitleOpacity <= 0.0f) && (hud->flags & HudFlagsSubtitleQueued)){ + if (!((hud->subtitleType == SubtitleTypeCaption) && (hud->queuedSubtitleType == SubtitleTypeCaption) && (hud->subtitleExpireTimer > 0.0))){ + hud->flags &= ~HudFlagsSubtitleQueued; + hud->flags |= HudFlagsShowingSubtitle; + hud->subtitleKey = hud->queuedSubtitleKey; + hud->subtitleType= hud->queuedSubtitleType; + hud->queuedSubtitleKey = SubtitleKeyNone; + hud->queuedSubtitleType = SubtitleTypeNone; + if (hud->subtitleType == SubtitleTypeCaption){ + hud->subtitleExpireTimer = CAPTION_EXPIRE_TIME; + } + } + } + + if (hud->subtitleExpireTimer <= 0.0f && hud->subtitleType == SubtitleTypeCaption){ + hudResolveSubtitle(&gScene.hud); } if (targetBackgroundOpacity != hud->backgroundOpacity) { @@ -152,30 +179,64 @@ void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType) { hud->promptType = promptType; } -void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleType) { - if (subtitleType == hud->subtitleType){ +void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum SubtitleType subtitleType) { + if (!(gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled)){ + return; + } + if (subtitleKey == hud->subtitleKey){ return; } - if (subtitleType == SubtitleKeyNone) { + if (subtitleType == SubtitleTypeNone) { hud->flags &= ~HudFlagsShowingSubtitle; hud->flags &= ~HudFlagsSubtitleQueued; - hud->subtitleFadeTime = 0.75; + hud->queuedSubtitleType = SubtitleTypeNone; + hud->queuedSubtitleKey = SubtitleKeyNone; + hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME; return; } - if (hud->flags & HudFlagsShowingSubtitle){ - hud->flags |= HudFlagsSubtitleQueued; - hud->queuedSubtitleType = subtitleType; - hud->subtitleFadeTime = 0.3; + else if (subtitleType == SubtitleTypeCaption) { + if (!(gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled)){ + return; + } + if ((hud->flags & HudFlagsShowingSubtitle) && ((hud->subtitleType > subtitleType) || (hud->queuedSubtitleType > subtitleType))){ + return; // dont push off screen a higher importance subtitle + } + else if ((hud->flags & HudFlagsShowingSubtitle) && (hud->subtitleType <= subtitleType)){ + hud->flags |= HudFlagsSubtitleQueued; + hud->queuedSubtitleKey = subtitleKey; + hud->queuedSubtitleType = subtitleType; + hud->subtitleFadeTime = SUBTITLE_FAST_FADE_TIME; + } + else{ + hud->flags |= HudFlagsShowingSubtitle; + hud->subtitleKey = subtitleKey; + hud->subtitleType = subtitleType; + hud->queuedSubtitleType = SubtitleTypeNone; + hud->queuedSubtitleKey = SubtitleKeyNone; + hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME; + hud->subtitleExpireTimer = CAPTION_EXPIRE_TIME; + } + return; } - else{ - hud->flags |= HudFlagsShowingSubtitle; - hud->subtitleType = subtitleType; - hud->subtitleFadeTime = 0.75; + else if (subtitleType == SubtitleTypeCloseCaption) { + if (hud->flags & HudFlagsShowingSubtitle){ + hud->flags |= HudFlagsSubtitleQueued; + hud->queuedSubtitleKey = subtitleKey; + hud->queuedSubtitleType = subtitleType; + hud->subtitleFadeTime = SUBTITLE_FAST_FADE_TIME; + } + else{ + hud->flags |= HudFlagsShowingSubtitle; + hud->flags &= ~HudFlagsSubtitleQueued; + hud->subtitleKey = subtitleKey; + hud->subtitleType = subtitleType; + hud->queuedSubtitleType = SubtitleTypeNone; + hud->queuedSubtitleKey = SubtitleKeyNone; + hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME; + } + return; } - - - } void hudResolvePrompt(struct Hud* hud, enum CutscenePromptType promptType) { @@ -183,7 +244,9 @@ void hudResolvePrompt(struct Hud* hud, enum CutscenePromptType promptType) { } void hudResolveSubtitle(struct Hud* hud) { + hud->flags &= ~HudFlagsShowingSubtitle; + hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME; } void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState) { @@ -301,7 +364,7 @@ void hudRender(struct Hud* hud, struct Player* player, struct RenderState* rende controlsRenderPrompt(gPromptActions[hud->promptType], gPromptText[hud->promptType], hud->promptOpacity, renderState); } - if (hud->subtitleOpacity > 0.0f && gSaveData.controls.flags & ControlSaveSubtitlesEnabled) { - controlsRenderSubtitle(SubtitleLanguageValues[hud->chosenLanguage][hud->subtitleType], hud->subtitleOpacity, hud->backgroundOpacity, renderState); + if (hud->subtitleOpacity > 0.0f && (gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) && hud->subtitleKey != SubtitleKeyNone) { + controlsRenderSubtitle(SubtitleLanguageValues[hud->chosenLanguage][hud->subtitleKey], hud->subtitleOpacity, hud->backgroundOpacity, renderState, hud->subtitleType); } } \ No newline at end of file diff --git a/src/scene/hud.h b/src/scene/hud.h index e827f97..1cac6f8 100644 --- a/src/scene/hud.h +++ b/src/scene/hud.h @@ -4,29 +4,39 @@ #include "../graphics/renderstate.h" #include "../player/player.h" #include "../controls/controller_actions.h" +#include "../../build/src/audio/subtitles.h" #define INTRO_BLACK_TIME 3.0f #define INTRO_FADE_TIME 1.0f #define INTRO_TOTAL_TIME (INTRO_BLACK_TIME + INTRO_FADE_TIME) +enum SubtitleType { + SubtitleTypeNone, + SubtitleTypeCaption, + SubtitleTypeCloseCaption, +}; + enum HudFlags { HudFlagsLookedPortalable0 = (1 << 0), HudFlagsLookedPortalable1 = (1 << 1), HudFlagsShowingPrompt = (1 << 2), - HudFlagsShowingSubtitle= (1 << 3), - HudFlagsSubtitleQueued= (1 << 4), + HudFlagsShowingSubtitle = (1 << 3), + HudFlagsSubtitleQueued = (1 << 4), }; struct Hud { int chosenLanguage; enum CutscenePromptType promptType; - enum SubtitleKey subtitleType; - enum SubtitleKey queuedSubtitleType; + enum SubtitleKey subtitleKey; + enum SubtitleKey queuedSubtitleKey; + enum SubtitleType subtitleType; + enum SubtitleType queuedSubtitleType; float promptOpacity; float subtitleOpacity; float backgroundOpacity; float subtitleFadeTime; + float subtitleExpireTimer; float fadeInTimer; u16 flags; @@ -43,7 +53,7 @@ void hudUpdatePortalIndicators(struct Hud* hud, struct Ray* raycastRay, struct void hudPortalFired(struct Hud* hud, int index); void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType); void hudResolvePrompt(struct Hud* hud, enum CutscenePromptType promptType); -void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleType); +void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum SubtitleType subtitleType); void hudResolveSubtitle(struct Hud* hud); void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState); diff --git a/src/scene/pedestal.c b/src/scene/pedestal.c index 7990d21..14fd767 100644 --- a/src/scene/pedestal.c +++ b/src/scene/pedestal.c @@ -9,6 +9,8 @@ #include "../build/assets/models/pedestal.h" #include "../../build/assets/models/dynamic_animated_model_list.h" #include "../../build/assets/models/portal_gun/w_portalgun.h" +#include "../scene/hud.h" +#include "../scene/scene.h" struct Vector2 gMaxPedistalRotation; #define MAX_PEDISTAL_ROTATION_DEGREES_PER_SEC (M_PI / 3.0f) @@ -95,13 +97,14 @@ void pedestalUpdate(struct Pedestal* pedestal) { if (vector2RotateTowards(&pedestal->currentRotation, &target, &gMaxPedistalRotation, &pedestal->currentRotation)) { if (!(pedestal->flags & PedestalFlagsDown)){ - soundPlayerPlay(soundsPedestalShooting, 5.0f, 0.5f, &pedestal->transform.position, &gZeroVec); + soundPlayerPlay(soundsPedestalShooting, 5.0f, 0.5f, &pedestal->transform.position, &gZeroVec, SoundTypeAll); } pedestal->flags &= ~PedestalFlagsIsPointing; } else{ if (!(pedestal->flags & PedestalFlagsAlreadyMoving) && !(pedestal->flags & PedestalFlagsDown)){ - soundPlayerPlay(soundsPedestalMoving, 5.0f, 0.5f, &pedestal->transform.position, &gZeroVec); + soundPlayerPlay(soundsPedestalMoving, 5.0f, 0.5f, &pedestal->transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTALGUN_PEDESTAL_ROTATE, SubtitleTypeCaption); pedestal->flags |= PedestalFlagsAlreadyMoving; } } @@ -115,7 +118,8 @@ void pedestalUpdate(struct Pedestal* pedestal) { } void pedestalHide(struct Pedestal* pedestal) { - soundPlayerPlay(soundsReleaseCube, 3.0f, 0.5f, &pedestal->transform.position, &gZeroVec); + soundPlayerPlay(soundsReleaseCube, 3.0f, 0.5f, &pedestal->transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, WEAPON_PORTALGUN_POWERUP, SubtitleTypeCaption); pedestal->flags |= PedestalFlagsDown; skAnimatorRunClip(&pedestal->animator, dynamicAssetClip(PEDESTAL_DYNAMIC_ANIMATED_MODEL, PEDESTAL_ARMATURE_HIDE_CLIP_INDEX), 0.0f, 0); } diff --git a/src/scene/scene.c b/src/scene/scene.c index b65836a..a7f13f8 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -312,11 +312,13 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gSPGeometryMode(renderState->dl++, G_ZBUFFER | G_LIGHTING | G_CULL_BOTH, G_SHADE); - hudRender(&scene->hud, &scene->player, renderState); - if (gGameMenu.state != GameMenuStateResumeGame) { gameMenuRender(&gGameMenu, renderState, task); } + else{ + hudRender(&scene->hud, &scene->player, renderState); + } + // sceneRenderPerformanceMetrics(scene, renderState, task); @@ -360,7 +362,8 @@ void sceneCheckPortals(struct Scene* scene) { portalGunFire(&scene->portalGun, 0, &raycastRay, &playerUp, scene->player.body.currentRoom); scene->player.flags |= PlayerJustShotPortalGun; hudPortalFired(&scene->hud, 0); - soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, WEAPON_PORTALGUN_FIRE_RED, SubtitleTypeCaption); rumblePakClipPlay(&gFireGunRumbleWave); } @@ -368,7 +371,8 @@ void sceneCheckPortals(struct Scene* scene) { portalGunFire(&scene->portalGun, 1, &raycastRay, &playerUp, scene->player.body.currentRoom); scene->player.flags |= PlayerJustShotPortalGun; hudPortalFired(&scene->hud, 1); - soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, WEAPON_PORTALGUN_FIRE_BLUE, SubtitleTypeCaption); rumblePakClipPlay(&gFireGunRumbleWave); } @@ -377,27 +381,27 @@ void sceneCheckPortals(struct Scene* scene) { } if ((scene->player.flags & PlayerFlagsGrounded) && (scene->player.flags & PlayerIsStepping)){ - soundPlayerPlay(soundsConcreteFootstep[scene->player.currentFoot], 1.0f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsConcreteFootstep[scene->player.currentFoot], 1.0f, 1.0f, NULL, NULL, SoundTypeAll); scene->player.flags &= ~PlayerIsStepping; } if (scene->player.flags & PlayerJustJumped){ - soundPlayerPlay(soundsConcreteFootstep[3], 1.0f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsConcreteFootstep[3], 1.0f, 1.0f, NULL, NULL, SoundTypeAll); scene->player.flags &= ~PlayerJustJumped; } if (scene->player.flags & PlayerJustLanded){ - soundPlayerPlay(soundsConcreteFootstep[2], 1.0f, 1.0f, NULL, NULL); + soundPlayerPlay(soundsConcreteFootstep[2], 1.0f, 1.0f, NULL, NULL, SoundTypeAll); scene->player.flags &= ~PlayerJustLanded; } if (scene->player.flags & PlayerJustSelect){ - soundPlayerPlay(soundsSelecting[1], 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(soundsSelecting[1], 1.0f, 0.5f, NULL, NULL, SoundTypeAll); scene->player.flags &= ~PlayerJustSelect; } if (scene->player.flags & PlayerJustDeniedSelect){ if (scene->player.flags & PlayerHasFirstPortalGun){ - soundPlayerPlay(soundsSelecting[0], 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(soundsSelecting[0], 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } else{ - soundPlayerPlay(soundsSelecting[2], 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(soundsSelecting[2], 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } scene->player.flags &= ~PlayerJustDeniedSelect; } @@ -798,7 +802,12 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde collisionSceneSetPortal(portalIndex, &portal->rigidBody.transform, roomIndex, portal->colliderIndex); collisionObjectUpdateBB(&portal->collisionObject); - soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &portal->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &portal->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + if (portalIndex == 0){ + hudShowSubtitle(&gScene.hud, PORTAL_OPEN_RED, SubtitleTypeCaption); + } else { + hudShowSubtitle(&gScene.hud, PORTAL_OPEN_BLUE, SubtitleTypeCaption); + } if (fromPlayer) { portal->flags |= PortalFlagsPlayerPortal; @@ -815,7 +824,7 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int transformInde // something changed and play sound near other portal struct Portal* otherPortal = &scene->portals[1 - portalIndex]; otherPortal->opacity = 1.0f; - soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &otherPortal->rigidBody.transform.position, &gZeroVec); + soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &otherPortal->rigidBody.transform.position, &gZeroVec, SoundTypeAll); } sceneCheckSecurityCamera(scene, portal); @@ -971,7 +980,8 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player void sceneClosePortal(struct Scene* scene, int portalIndex) { if (gCollisionScene.portalTransforms[portalIndex]) { - soundPlayerPlay(soundsPortalFizzle, 1.0f, 1.0f, &gCollisionScene.portalTransforms[portalIndex]->position, &gZeroVec); + soundPlayerPlay(soundsPortalFizzle, 1.0f, 1.0f, &gCollisionScene.portalTransforms[portalIndex]->position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_FIZZLE_MOVED, SubtitleTypeCaption); gCollisionScene.portalTransforms[portalIndex] = NULL; gCollisionScene.portalColliderIndex[portalIndex] = -1; scene->portals[portalIndex].portalSurfaceIndex = -1; diff --git a/src/scene/scene_animator.c b/src/scene/scene_animator.c index a14dedc..b08e984 100644 --- a/src/scene/scene_animator.c +++ b/src/scene/scene_animator.c @@ -60,7 +60,7 @@ void sceneAnimatorUpdate(struct SceneAnimator* sceneAnimator) { if (audioInfo->loopSoundId != SOUND_ID_NONE) { if (isMoving && state->soundId == SOUND_ID_NONE) { - state->soundId = soundPlayerPlay(audioInfo->loopSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec); + state->soundId = soundPlayerPlay(audioInfo->loopSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec, SoundTypeAll); } else if (isMoving && state->soundId != SOUND_ID_NONE) { soundPlayerUpdatePosition(state->soundId, ¤tPos, &gZeroVec); } else if (!isMoving && state->soundId != SOUND_ID_NONE) { @@ -70,11 +70,11 @@ void sceneAnimatorUpdate(struct SceneAnimator* sceneAnimator) { } if (isMoving && !wasMoving && audioInfo->startSoundId != SOUND_ID_NONE) { - soundPlayerPlay(audioInfo->startSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec); + soundPlayerPlay(audioInfo->startSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec, SoundTypeAll); } if (!wasMoving && isMoving && audioInfo->endSoundId != SOUND_ID_NONE) { - soundPlayerPlay(audioInfo->endSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec); + soundPlayerPlay(audioInfo->endSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec, SoundTypeAll); } state->lastPosition = currentPos; diff --git a/src/scene/switch.c b/src/scene/switch.c index b30ef80..e4b6e48 100644 --- a/src/scene/switch.c +++ b/src/scene/switch.c @@ -11,6 +11,8 @@ #include "../../build/assets/models/dynamic_animated_model_list.h" #include "../util/time.h" +#include "../scene/hud.h" +#include "../scene/scene.h" #define COLLIDER_HEIGHT 0.7f #define TICKTOCK_PAUSE_LENGTH 0.25f @@ -104,8 +106,10 @@ void switchActivate(struct Switch* switchObj) { if (switchObj->timeLeft > 0.0f) { return; } - soundPlayerPlay(soundsButton, 1.0f, 0.5f, &switchObj->rigidBody.transform.position, &gZeroVec); - switchObj->ticktockSoundLoopId = soundPlayerPlay(soundsTickTock, 1.0f, 0.5f, NULL, NULL); + soundPlayerPlay(soundsButton, 1.0f, 0.5f, &switchObj->rigidBody.transform.position, &gZeroVec, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_BUTTON_DOWN, SubtitleTypeCaption); + switchObj->ticktockSoundLoopId = soundPlayerPlay(soundsTickTock, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_ROOM1_TICKTOCK, SubtitleTypeCaption); switchObj->flags |= SwitchFlagsDepressed; switchObj->timeLeft = switchObj->duration; signalsSend(switchObj->signalIndex); @@ -143,7 +147,8 @@ void switchUpdate(struct Switch* switchObj) { switchObj->ticktockPauseTimer += FIXED_DELTA_TIME; }else{ switchObj->ticktockPauseTimer = 0; - switchObj->ticktockSoundLoopId = soundPlayerPlay(soundsTickTock, 1.0f, 0.5f, NULL, NULL); + switchObj->ticktockSoundLoopId = soundPlayerPlay(soundsTickTock, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + hudShowSubtitle(&gScene.hud, PORTAL_ROOM1_TICKTOCK, SubtitleTypeCaption); } }else{ switchObj->ticktockPauseTimer = 0; diff --git a/tools/level_scripts/subtitle_generate.py b/tools/level_scripts/subtitle_generate.py index 580e267..a890c5b 100644 --- a/tools/level_scripts/subtitle_generate.py +++ b/tools/level_scripts/subtitle_generate.py @@ -43,7 +43,7 @@ def get_caption_keys_values_language(lines): last_space = 0 addition = 0 for i,ch in enumerate(val): - if (i%40 == 0) and (i != 0): + if (i%38 == 0) and (i != 0): newval = newval[:last_space+addition] + '\\n' + newval[last_space+addition+1:] addition += 1 newval = newval + ch