Merge branch 'master' into multi-audio-2

This commit is contained in:
hackgrid 2023-10-15 11:03:14 +02:00 committed by GitHub
commit 340837b931
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 419 additions and 172 deletions

View file

@ -189,9 +189,9 @@ That will generate the rom at `/build/portal64.z64`
## Current New Feature TODO List ## Current New Feature TODO List
- [ ] polish up subtitles - [ ] polish up subtitles
- [ ] more sound settings - [ ] more sound settings
- [ ] add desk chairs and monitors
- [ ] rumble pak support - [ ] rumble pak support
- [ ] pausing while glados is speaking can end her speech early - [ ] pausing while glados is speaking can end her speech early
- [x] add desk chairs and monitors
- [x] Add auto save checkpoints - [x] Add auto save checkpoints
- [x] Correct elevator timing - [x] Correct elevator timing

View file

@ -5,6 +5,7 @@
#include "util/time.h" #include "util/time.h"
#include "math/mathf.h" #include "math/mathf.h"
#include "clips.h" #include "clips.h"
#include "../savefile/savefile.h"
struct SoundArray* gSoundClipArray; struct SoundArray* gSoundClipArray;
ALSndPlayer gSoundPlayer; ALSndPlayer gSoundPlayer;
@ -26,7 +27,9 @@ struct ActiveSound {
struct Vector3 pos3D; struct Vector3 pos3D;
struct Vector3 velocity3D; struct Vector3 velocity3D;
float volume; float volume;
float originalVolume;
float basePitch; float basePitch;
enum SoundType soundType;
}; };
struct SoundListener { struct SoundListener {
@ -149,7 +152,8 @@ float soundPlayerEstimateLength(ALSound* sound, float speed) {
return sampleCount * (1.0f / OUTPUT_RATE) / 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) { if (gActiveSoundCount >= MAX_ACTIVE_SOUNDS || soundClipId < 0 || soundClipId >= gSoundClipArray->soundCount) {
return SOUND_ID_NONE; return SOUND_ID_NONE;
} }
@ -171,9 +175,16 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto
sound->flags = 0; sound->flags = 0;
sound->estimatedTimeLeft = soundPlayerEstimateLength(alSound, pitch); sound->estimatedTimeLeft = soundPlayerEstimateLength(alSound, pitch);
sound->volume = volume; sound->volume = volume;
sound->originalVolume = volume;
sound->basePitch = pitch; 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; int panning = 64;
if (at) { if (at) {
@ -181,7 +192,7 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto
sound->pos3D = *at; sound->pos3D = *at;
sound->velocity3D = *velocity; sound->velocity3D = *velocity;
float pitchBend; float pitchBend;
soundPlayerDetermine3DSound(at, velocity, &startingVolume, &startingVolume, &panning, &pitchBend); soundPlayerDetermine3DSound(at, velocity, &newVolume, &newVolume, &panning, &pitchBend);
pitch = pitch * pitchBend; pitch = pitch * pitchBend;
} }
@ -189,14 +200,18 @@ ALSndId soundPlayerPlay(int soundClipId, float volume, float pitch, struct Vecto
sound->flags |= SOUND_FLAGS_LOOPING; sound->flags |= SOUND_FLAGS_LOOPING;
} }
alSndpSetSound(&gSoundPlayer, result); alSndpSetSound(&gSoundPlayer, result);
alSndpSetVol(&gSoundPlayer, (short)(32767 * startingVolume)); alSndpSetVol(&gSoundPlayer, (short)(32767 * newVolume));
alSndpSetPitch(&gSoundPlayer, pitch); alSndpSetPitch(&gSoundPlayer, pitch);
alSndpSetPan(&gSoundPlayer, panning); alSndpSetPan(&gSoundPlayer, panning);
alSndpPlay(&gSoundPlayer); alSndpPlay(&gSoundPlayer);
++gActiveSoundCount; ++gActiveSoundCount;
return result; return result;
} }
@ -209,6 +224,48 @@ float soundClipDuration(int soundClipId, float pitch) {
return soundPlayerEstimateLength(alSound, 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() { void soundPlayerUpdate() {
int index = 0; int index = 0;
int writeIndex = 0; int writeIndex = 0;
@ -311,6 +368,10 @@ void soundPlayerAdjustVolume(ALSndId soundId, float newVolume) {
struct ActiveSound* activeSound = soundPlayerFindActiveSound(soundId); struct ActiveSound* activeSound = soundPlayerFindActiveSound(soundId);
if (activeSound) { if (activeSound) {
newVolume = newVolume * gSaveData.audio.soundVolume/0xFFFF;
if (activeSound->soundType == SoundTypeMusic){
newVolume = newVolume * gSaveData.audio.musicVolume/0xFFFF;
}
if (activeSound->flags & SOUND_FLAGS_3D){ if (activeSound->flags & SOUND_FLAGS_3D){
activeSound->volume = newVolume; activeSound->volume = newVolume;
} else { } else {

View file

@ -18,9 +18,16 @@ extern char _soundsSegmentRomEnd[];
extern char _soundsTblSegmentRomStart[]; extern char _soundsTblSegmentRomStart[];
extern char _soundsTblSegmentRomEnd[]; extern char _soundsTblSegmentRomEnd[];
enum SoundType{
SoundTypeNone,
SoundTypeMusic,
SoundTypeAll,
};
void soundPlayerInit(); void soundPlayerInit();
void soundPlayerGameVolumeUpdate();
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, enum SoundType);
float soundClipDuration(int soundClipId, float pitch); float soundClipDuration(int soundClipId, float pitch);
void soundPlayerStop(ALSndId soundId); void soundPlayerStop(ALSndId soundId);
void soundPlayerStopAll(); void soundPlayerStopAll();

View file

@ -165,7 +165,7 @@ int decorObjectUpdate(struct DecorObject* decorObject) {
decorObject->playingSound = SOUND_ID_NONE; decorObject->playingSound = SOUND_ID_NONE;
if (decorObject->definition->soundFizzleId != 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) { } 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)) { 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)); dynamicSceneSetRoomFlags(decorObject->dynamicId, ROOM_FLAG_FROM_INDEX(decorObject->rigidBody.currentRoom));

View file

@ -138,7 +138,8 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
step->playSound.volume * (1.0f / 255.0f), step->playSound.volume * (1.0f / 255.0f),
step->playSound.pitch * (1.0f / 64.0f), step->playSound.pitch * (1.0f / 64.0f),
NULL, NULL,
NULL NULL,
SoundTypeAll
); );
break; break;
case CutsceneStepTypeQueueSound: case CutsceneStepTypeQueueSound:
@ -398,8 +399,8 @@ void cutscenesUpdateSounds() {
if (gCutsceneSoundQueues[i]) { if (gCutsceneSoundQueues[i]) {
struct QueuedSound* curr = gCutsceneSoundQueues[i]; struct QueuedSound* curr = gCutsceneSoundQueues[i];
gCutsceneCurrentSound[i] = soundPlayerPlay(curr->soundId, curr->volume, gCutsceneChannelPitch[i], NULL, NULL); gCutsceneCurrentSound[i] = soundPlayerPlay(curr->soundId, curr->volume, gCutsceneChannelPitch[i], NULL, NULL, SoundTypeAll);
hudShowSubtitle(&gScene.hud, curr->subtitleId); hudShowSubtitle(&gScene.hud, curr->subtitleId, SubtitleTypeCloseCaption);
gCutsceneSoundQueues[i] = curr->next; gCutsceneSoundQueues[i] = curr->next;
@ -407,7 +408,7 @@ void cutscenesUpdateSounds() {
gCutsceneNextFreeSound = curr; gCutsceneNextFreeSound = curr;
} else { } else {
if (gCutsceneCurrentSound[i] != SOUND_ID_NONE) { 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); hudResolveSubtitle(&gScene.hud);
} }

View file

@ -14,7 +14,7 @@
#define GAMEPLAY_HEIGHT 124 #define GAMEPLAY_HEIGHT 124
#define GAMEPLAY_X ((SCREEN_WD - GAMEPLAY_WIDTH) / 2) #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 SCROLL_INTERVALS (int)maxf((SCROLL_TICKS - 1), 1)
#define SCROLL_CHUNK_SIZE (0x10000 / SCROLL_INTERVALS) #define SCROLL_CHUNK_SIZE (0x10000 / SCROLL_INTERVALS)
@ -25,31 +25,6 @@
#define FULL_SCROLL_TIME 2.0f #define FULL_SCROLL_TIME 2.0f
#define SCROLL_MULTIPLIER (int)(0xFFFF * FIXED_DELTA_TIME / (80 * FULL_SCROLL_TIME)) #define SCROLL_MULTIPLIER (int)(0xFFFF * FIXED_DELTA_TIME / (80 * FULL_SCROLL_TIME))
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);
}
if (NUM_AUDIO_LANGUAGES > 1) {
audioOptions->audioLanguageText = menuBuildText(&gDejaVuSansFont, "Audio Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 68);
audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 68);
audioOptions->audioLanguage= menuBuildSlider(GAMEPLAY_X + 8, GAMEPLAY_Y + 88, 200, SCROLL_TICKS_LANGUAGE);
audioOptions->audio_language_temp = (0xFFFF/SCROLL_TICKS)* gSaveData.audio.audioLanguage;
audioOptions->audioLanguage.value = (int)gSaveData.audio.audioLanguage * (0xFFFF/SCROLL_TICKS_LANGUAGE);
}
}
void audioOptionsHandleSlider(unsigned short* settingValue, float* sliderValue) { void audioOptionsHandleSlider(unsigned short* settingValue, float* sliderValue) {
OSContPad* pad = controllersGetControllerData(0); OSContPad* pad = controllersGetControllerData(0);
@ -59,14 +34,14 @@ void audioOptionsHandleSlider(unsigned short* settingValue, float* sliderValue)
if (newValue >= 0xFFFF && controllerGetButtonDown(0, A_BUTTON)) { if (newValue >= 0xFFFF && controllerGetButtonDown(0, A_BUTTON)) {
newValue = 0; newValue = 0;
} else { } else {
newValue = newValue + SCROLL_CHUNK_SIZE_LANGUAGE; newValue = newValue + SCROLL_CHUNK_SIZE;
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE_LANGUAGE); newValue = newValue - (newValue % SCROLL_CHUNK_SIZE);
} }
} }
if (controllerGetButtonDown(0, L_JPAD)) { if (controllerGetButtonDown(0, L_JPAD)) {
newValue = newValue - 1; newValue = newValue - 1;
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE_LANGUAGE); newValue = newValue - (newValue % SCROLL_CHUNK_SIZE);
} }
if (newValue < 0) { if (newValue < 0) {
@ -81,6 +56,39 @@ void audioOptionsHandleSlider(unsigned short* settingValue, float* sliderValue)
*sliderValue = (float)newValue / 0xFFFF; *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);
audioOptions->audioLanguageText = menuBuildText(&gDejaVuSansFont, "Audio Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 128);
audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 128);
audioOptions->audioLanguage= menuBuildSlider(GAMEPLAY_X + 8, GAMEPLAY_Y + 148, 200, SCROLL_TICKS_LANGUAGE);
audioOptions->audio_language_temp = (0xFFFF/SCROLL_TICKS)* gSaveData.audio.audioLanguage;
audioOptions->audioLanguage.value = (int)gSaveData.audio.audioLanguage * (0xFFFF/SCROLL_TICKS_LANGUAGE);
}
enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) { enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
int controllerDir = controllerGetDirectionDown(0); int controllerDir = controllerGetDirectionDown(0);
@ -105,35 +113,64 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
} }
switch (audioOptions->selectedItem) { 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: case AudioOptionSubtitlesEnabled:
if (controllerGetButtonDown(0, A_BUTTON)) { if (controllerGetButtonDown(0, A_BUTTON)) {
audioOptions->subtitlesEnabled.checked = !audioOptions->subtitlesEnabled.checked; 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) { if (audioOptions->subtitlesEnabled.checked) {
gSaveData.controls.flags |= ControlSaveSubtitlesEnabled; gSaveData.controls.flags |= ControlSaveSubtitlesEnabled;
gSaveData.controls.flags &= ~ControlSaveAllSubtitlesEnabled;
audioOptions->allSubtitlesEnabled.checked = 0;
} else { } else {
gSaveData.controls.flags &= ~ControlSaveSubtitlesEnabled; gSaveData.controls.flags &= ~ControlSaveSubtitlesEnabled;
} }
} }
break; 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: case AudioOptionSubtitlesLanguage:
audioOptionsHandleSlider(&audioOptions->subtitles_language_temp, &audioOptions->subtitlesLanguage.value); audioOptionsHandleSlider(&audioOptions->subtitles_language_temp, &audioOptions->subtitlesLanguage.value);
int temp = (int)((audioOptions->subtitles_language_temp * (1.0f/0xFFFF) * NUM_SUBTITLE_LANGUAGES)); int temp = (int)((audioOptions->subtitles_language_temp * (1.0f/0xFFFF) * NUM_SUBTITLE_LANGUAGES));
temp = (int)minf(maxf(0.0, temp), NUM_SUBTITLE_LANGUAGES-1); temp = (int)minf(maxf(0.0, temp), NUM_SUBTITLE_LANGUAGES-1);
gSaveData.controls.subtitleLanguage = temp; 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; break;
case AudioOptionAudioLanguage: case AudioOptionAudioLanguage:
audioOptionsHandleSlider(&audioOptions->audio_language_temp, &audioOptions->audioLanguage.value); audioOptionsHandleSlider(&audioOptions->audio_language_temp, &audioOptions->audioLanguage.value);
int tempAudio = (int)((audioOptions->audio_language_temp * (1.0f/0xFFFF) * NUM_AUDIO_LANGUAGES)); int tempAudio = (int)((audioOptions->audio_language_temp * (1.0f/0xFFFF) * NUM_AUDIO_LANGUAGES));
tempAudio = (int)minf(maxf(0.0, tempAudio), NUM_AUDIO_LANGUAGES-1); tempAudio = (int)minf(maxf(0.0, tempAudio), NUM_AUDIO_LANGUAGES-1);
gSaveData.audio.audioLanguage = tempAudio; gSaveData.audio.audioLanguage = tempAudio;
audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 68); audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 128);
break; break;
} }
if (audioOptions->selectedItem == AudioOptionSubtitlesLanguage || audioOptions->selectedItem == AudioOptionAudioLanguage){
if (audioOptions->selectedItem == AudioOptionSubtitlesLanguage ||
audioOptions->selectedItem == AudioOptionGameVolume ||
audioOptions->selectedItem == AudioOptionMusicVolume ||
audioOptions->selectedItem == AudioOptionAudioLanguage){
if ((controllerGetButtonDown(0, L_TRIG) || controllerGetButtonDown(0, Z_TRIG))) { if ((controllerGetButtonDown(0, L_TRIG) || controllerGetButtonDown(0, Z_TRIG))) {
return MenuDirectionLeft; return MenuDirectionLeft;
} }
@ -156,45 +193,60 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* renderState, struct GraphicsTask* task) { void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* renderState, struct GraphicsTask* task) {
gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]); gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]);
if (NUM_SUBTITLE_LANGUAGES){ gSPDisplayList(renderState->dl++, audioOptions->gameVolume.back);
gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.outline); renderState->dl = menuSliderRender(&audioOptions->gameVolume, renderState->dl);
renderState->dl = menuCheckboxRender(&audioOptions->subtitlesEnabled, renderState->dl);
gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguage.back); gSPDisplayList(renderState->dl++, audioOptions->musicVolume.back);
renderState->dl = menuSliderRender(&audioOptions->subtitlesLanguage, renderState->dl); renderState->dl = menuSliderRender(&audioOptions->musicVolume, renderState->dl);
}
if (NUM_AUDIO_LANGUAGES > 1) {
gSPDisplayList(renderState->dl++, audioOptions->audioLanguage.back); gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.outline);
renderState->dl = menuSliderRender(&audioOptions->audioLanguage, renderState->dl); 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++, audioOptions->audioLanguage.back);
renderState->dl = menuSliderRender(&audioOptions->audioLanguage, renderState->dl);
gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]); gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]);
gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]); gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]);
if (NUM_SUBTITLE_LANGUAGES){ gDPPipeSync(renderState->dl++);
gDPPipeSync(renderState->dl++); menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionGameVolume, &gSelectionGray, &gColorWhite);
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesEnabled, &gSelectionGray, &gColorWhite); gSPDisplayList(renderState->dl++, audioOptions->gameVolumeText);
gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.text);
gDPPipeSync(renderState->dl++); gDPPipeSync(renderState->dl++);
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionMusicVolume, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageText); gSPDisplayList(renderState->dl++, audioOptions->musicVolumeText);
gDPPipeSync(renderState->dl++); gDPPipeSync(renderState->dl++);
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesEnabled, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageDynamicText); gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.text);
}
if (NUM_AUDIO_LANGUAGES > 1) { gDPPipeSync(renderState->dl++);
gDPPipeSync(renderState->dl++); menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAllSubtitlesEnabled, &gSelectionGray, &gColorWhite);
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAudioLanguage, &gSelectionGray, &gColorWhite); gSPDisplayList(renderState->dl++, audioOptions->allSubtitlesEnabled.text);
gSPDisplayList(renderState->dl++, audioOptions->audioLanguageText);
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 == AudioOptionAudioLanguage, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, audioOptions->audioLanguageText);
gDPPipeSync(renderState->dl++);
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAudioLanguage, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, audioOptions->audioLanguageDynamicText);
gDPPipeSync(renderState->dl++);
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAudioLanguage, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, audioOptions->audioLanguageDynamicText);
}
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]); gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
} }

View file

@ -5,15 +5,23 @@
#include "../graphics/graphics.h" #include "../graphics/graphics.h"
enum AudioOption { enum AudioOption {
AudioOptionGameVolume,
AudioOptionMusicVolume,
AudioOptionSubtitlesEnabled, AudioOptionSubtitlesEnabled,
AudioOptionAllSubtitlesEnabled,
AudioOptionSubtitlesLanguage, AudioOptionSubtitlesLanguage,
AudioOptionAudioLanguage, AudioOptionAudioLanguage,
AudioOptionCount, AudioOptionCount,
}; };
struct AudioOptions { struct AudioOptions {
struct MenuSlider gameVolume;
struct MenuSlider musicVolume;
struct MenuCheckbox subtitlesEnabled; struct MenuCheckbox subtitlesEnabled;
struct MenuCheckbox allSubtitlesEnabled;
struct MenuSlider subtitlesLanguage; struct MenuSlider subtitlesLanguage;
Gfx* gameVolumeText;
Gfx* musicVolumeText;
Gfx* subtitlesLanguageText; Gfx* subtitlesLanguageText;
Gfx* subtitlesLanguageDynamicText; Gfx* subtitlesLanguageDynamicText;
unsigned short subtitles_language_temp; unsigned short subtitles_language_temp;

View file

@ -283,7 +283,7 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu) {
controlsLayout(controlsMenu); controlsLayout(controlsMenu);
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL); soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
} }
return MenuDirectionStay; return MenuDirectionStay;
@ -338,7 +338,7 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu) {
controlsLayout(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)) { 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]); 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); struct Vector2s16 size = fontMeasure(&gDejaVuSansFont, message);
int textOpacityAsInt = (int)(255 * textOpacity); 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_revert_list[SOLID_TRANSPARENT_OVERLAY_INDEX]);
gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_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( renderState->dl = fontRender(
&gDejaVuSansFont, &gDejaVuSansFont,
message, message,

View file

@ -4,6 +4,7 @@
#include "./menu.h" #include "./menu.h"
#include "../controls/controller_actions.h" #include "../controls/controller_actions.h"
#include "../graphics/graphics.h" #include "../graphics/graphics.h"
#include "../scene/hud.h"
#define MAX_SOURCES_PER_ACTION 4 #define MAX_SOURCES_PER_ACTION 4
#define MAX_CONTROLS_SECTIONS 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 controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* renderState, struct GraphicsTask* task);
void controlsRenderPrompt(enum ControllerAction action, char* message, float opacity, struct RenderState* renderState); 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 #endif

View file

@ -95,7 +95,7 @@ enum MenuDirection gameplayOptionsUpdate(struct GameplayOptions* gameplayOptions
case GameplayOptionMovingPortals: case GameplayOptionMovingPortals:
if (controllerGetButtonDown(0, A_BUTTON)) { if (controllerGetButtonDown(0, A_BUTTON)) {
gameplayOptions->movingPortals.checked = !gameplayOptions->movingPortals.checked; 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) { if (gameplayOptions->movingPortals.checked) {
gSaveData.controls.flags |= ControlSaveMoveablePortals; gSaveData.controls.flags |= ControlSaveMoveablePortals;
@ -108,7 +108,7 @@ enum MenuDirection gameplayOptionsUpdate(struct GameplayOptions* gameplayOptions
case GameplayOptionWideScreen: case GameplayOptionWideScreen:
if (controllerGetButtonDown(0, A_BUTTON)) { if (controllerGetButtonDown(0, A_BUTTON)) {
gameplayOptions->wideScreen.checked = !gameplayOptions->wideScreen.checked; 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) { if (gameplayOptions->wideScreen.checked) {
gSaveData.controls.flags |= ControlSaveWideScreen; gSaveData.controls.flags |= ControlSaveWideScreen;

View file

@ -106,7 +106,7 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions
case JoystickOptionInvert: case JoystickOptionInvert:
if (controllerGetButtonDown(0, A_BUTTON)) { if (controllerGetButtonDown(0, A_BUTTON)) {
joystickOptions->invertControls.checked = !joystickOptions->invertControls.checked; 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) { if (joystickOptions->invertControls.checked) {
gSaveData.controls.flags |= ControlSaveFlagsInvert; gSaveData.controls.flags |= ControlSaveFlagsInvert;
@ -119,7 +119,7 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions
case JoystickOptionInvertYaw: case JoystickOptionInvertYaw:
if (controllerGetButtonDown(0, A_BUTTON)) { if (controllerGetButtonDown(0, A_BUTTON)) {
joystickOptions->invertControlsYaw.checked = !joystickOptions->invertControlsYaw.checked; 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) { if (joystickOptions->invertControlsYaw.checked) {
gSaveData.controls.flags |= ControlSaveFlagsInvertYaw; gSaveData.controls.flags |= ControlSaveFlagsInvertYaw;
@ -132,7 +132,7 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions
case JoystickOptionTankControls: case JoystickOptionTankControls:
if (controllerGetButtonDown(0, A_BUTTON)) { if (controllerGetButtonDown(0, A_BUTTON)) {
joystickOptions->tankControls.checked = !joystickOptions->tankControls.checked; 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) { if (joystickOptions->tankControls.checked) {
gSaveData.controls.flags |= ControlSaveTankControls; gSaveData.controls.flags |= ControlSaveTankControls;

View file

@ -73,16 +73,16 @@ void landingMenuInit(struct LandingMenu* landingMenu, struct LandingMenuOption*
struct LandingMenuOption* landingMenuUpdate(struct LandingMenu* landingMenu) { struct LandingMenuOption* landingMenuUpdate(struct LandingMenu* landingMenu) {
if ((controllerGetDirectionDown(0) & ControllerDirectionUp) != 0 && landingMenu->selectedItem > 0) { if ((controllerGetDirectionDown(0) & ControllerDirectionUp) != 0 && landingMenu->selectedItem > 0) {
--landingMenu->selectedItem; --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) { if ((controllerGetDirectionDown(0) & ControllerDirectionDown) != 0 && landingMenu->selectedItem + 1 < landingMenu->optionCount) {
++landingMenu->selectedItem; ++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)) { 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]; return &landingMenu->options[landingMenu->selectedItem];
} }

View file

@ -41,7 +41,7 @@ enum MenuDirection loadGameUpdate(struct LoadGameMenu* loadGame) {
stackMallocFree(save); 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); return savefileListUpdate(loadGame->savefileList);

View file

@ -28,7 +28,7 @@ void mainMenuPlayAmbientSound() {
static ALSndId soundId = -1; static ALSndId soundId = -1;
if (soundId == -1 || !soundPlayerIsPlaying(soundId)) { 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);
} }
} }

View file

@ -136,7 +136,7 @@ enum MenuDirection newGameUpdate(struct NewGameMenu* newGameMenu) {
if (controllerGetButtonDown(0, A_BUTTON) && gChapters[newGameMenu->selectedChapter].testChamberNumber >= 0) { if (controllerGetButtonDown(0, A_BUTTON) && gChapters[newGameMenu->selectedChapter].testChamberNumber >= 0) {
gCurrentTestSubject = savefileNextTestSubject(); 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); levelQueueLoad(gChapters[newGameMenu->selectedChapter].testChamberNumber, NULL, NULL);
} }
@ -144,12 +144,12 @@ enum MenuDirection newGameUpdate(struct NewGameMenu* newGameMenu) {
newGameMenu->selectedChapter + 1 < newGameMenu->chapterCount && newGameMenu->selectedChapter + 1 < newGameMenu->chapterCount &&
gChapters[newGameMenu->selectedChapter + 1].imageData) { gChapters[newGameMenu->selectedChapter + 1].imageData) {
newGameMenu->selectedChapter = newGameMenu->selectedChapter + 1; 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) { if ((controllerGetDirectionDown(0) & ControllerDirectionLeft) != 0 && newGameMenu->selectedChapter > 0) {
newGameMenu->selectedChapter = newGameMenu->selectedChapter - 1; 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; int nextChapterOffset = newGameMenu->selectedChapter & ~1;

View file

@ -64,7 +64,7 @@ enum MenuDirection saveGameUpdate(struct SaveGameMenu* saveGame) {
saveGamePopulate(saveGame, 0); saveGamePopulate(saveGame, 0);
} }
stackMallocFree(save); 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); return savefileListUpdate(saveGame->savefileList);

View file

@ -152,7 +152,7 @@ enum MenuDirection savefileListUpdate(struct SavefileListMenu* savefileList) {
if (savefileList->selectedSave == savefileList->numberOfSaves) { if (savefileList->selectedSave == savefileList->numberOfSaves) {
savefileList->selectedSave = 0; 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) { if (controllerDir & ControllerDirectionUp) {
@ -161,7 +161,7 @@ enum MenuDirection savefileListUpdate(struct SavefileListMenu* savefileList) {
if (savefileList->selectedSave < 0) { if (savefileList->selectedSave < 0) {
savefileList->selectedSave = savefileList->numberOfSaves - 1; 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; int selectTop = SCROLLED_ROW_Y(savefileList->selectedSave, savefileList->scrollOffset) - 8;

View file

@ -110,7 +110,7 @@ void playerRender(void* data, struct DynamicRenderDataList* renderList, struct R
} }
void playerInit(struct Player* player, struct Location* startLocation, struct Vector3* velocity) { 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); 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))) { if (((isColliderForBall(contact->shapeA) || isColliderForBall(contact->shapeB)) && !playerIsDead(player))) {
playerKill(player, 0); 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 = sqrtf(vector3MagSqrd(&player->body.velocity))*(0.6f / MAX_PORTAL_SPEED);
soundPlayerVolume = clampf(soundPlayerVolume, 0.0, 1.0f); soundPlayerVolume = clampf(soundPlayerVolume, 0.0, 1.0f);
soundPlayerAdjustVolume(player->flyingSoundLoopId, soundPlayerVolume); soundPlayerAdjustVolume(player->flyingSoundLoopId, soundPlayerVolume);
if (soundPlayerVolume >= 0.75){
hudShowSubtitle(&gScene.hud, PORTALPLAYER_WOOSH, SubtitleTypeCaption);
}
} }
void playerKill(struct Player* player, int isUnderwater) { void playerKill(struct Player* player, int isUnderwater) {
@ -741,8 +744,10 @@ void playerUpdate(struct Player* player) {
quatIdent(&player->body.transform.rotation); quatIdent(&player->body.transform.rotation);
if (didPassThroughPortal) { if (didPassThroughPortal) {
soundPlayerPlay(soundsPortalEnter[didPassThroughPortal - 1], 0.75f, 1.0f, NULL, NULL); soundPlayerPlay(soundsPortalEnter[didPassThroughPortal - 1], 0.75f, 1.0f, NULL, NULL, SoundTypeAll);
soundPlayerPlay(soundsPortalExit[2 - didPassThroughPortal], 0.75f, 1.0f, NULL, NULL); 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; gPlayerCollider.extendDownward = 0.0f;
} else { } else {
gPlayerCollider.extendDownward = mathfMoveTowards(gPlayerCollider.extendDownward, TARGET_CAPSULE_EXTEND_HEIGHT, STAND_SPEED * FIXED_DELTA_TIME); gPlayerCollider.extendDownward = mathfMoveTowards(gPlayerCollider.extendDownward, TARGET_CAPSULE_EXTEND_HEIGHT, STAND_SPEED * FIXED_DELTA_TIME);

View file

@ -97,8 +97,8 @@ void savefileNew() {
gSaveData.controls.portalRenderDepth = 2; gSaveData.controls.portalRenderDepth = 2;
gSaveData.controls.subtitleLanguage = 0; gSaveData.controls.subtitleLanguage = 0;
gSaveData.audio.soundVolume = 0xFF; gSaveData.audio.soundVolume = 0xFFFF;
gSaveData.audio.musicVolume = 0xFF; gSaveData.audio.musicVolume = 0xFFFF;
gSaveData.audio.audioLanguage = 0; gSaveData.audio.audioLanguage = 0;
controllerSetDeadzone(gSaveData.controls.deadzone * (1.0f / 0xFFFF) * MAX_DEADZONE); controllerSetDeadzone(gSaveData.controls.deadzone * (1.0f / 0xFFFF) * MAX_DEADZONE);

View file

@ -39,6 +39,7 @@ enum ControlSaveFlags {
ControlSaveTankControls = (1 << 2), ControlSaveTankControls = (1 << 2),
ControlSaveSubtitlesEnabled = (1 << 5), ControlSaveSubtitlesEnabled = (1 << 5),
ControlSaveAllSubtitlesEnabled = (1 << 6),
ControlSaveMoveablePortals = (1 << 8), ControlSaveMoveablePortals = (1 << 8),
ControlSaveWideScreen = (1 << 9), ControlSaveWideScreen = (1 << 9),
@ -55,8 +56,8 @@ struct ControlSaveState {
}; };
struct AudioSettingsSaveState { struct AudioSettingsSaveState {
unsigned char soundVolume; unsigned short soundVolume;
unsigned char musicVolume; unsigned short musicVolume;
unsigned char audioLanguage; unsigned char audioLanguage;
}; };

View file

@ -115,7 +115,7 @@ void ballInit(struct Ball* ball, struct Vector3* position, struct Vector3* veloc
dynamicSceneSetRoomFlags(ball->dynamicId, ROOM_FLAG_FROM_INDEX(startingRoom)); 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) { void ballTurnOnCollision(struct Ball* ball) {
@ -138,7 +138,8 @@ void ballInitBurn(struct Ball* ball, struct ContactManifold* manifold) {
if (manifold->shapeA->body) { if (manifold->shapeA->body) {
transformPoint(&manifold->shapeA->body->transform, &position, &position); 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; ball->flags |= BallJustBounced;
} }
@ -209,7 +210,8 @@ void ballUpdate(struct Ball* ball) {
collisionSceneRemoveDynamicObject(&ball->collisionObject); collisionSceneRemoveDynamicObject(&ball->collisionObject);
dynamicSceneRemove(ball->dynamicId); dynamicSceneRemove(ball->dynamicId);
soundPlayerStop(ball->soundLoopId); 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); effectsSplashPlay(&gScene.effects, &gBallBurst, &ball->rigidBody.transform.position, &gUp);
ball->soundLoopId = SOUND_ID_NONE; ball->soundLoopId = SOUND_ID_NONE;
} }

View file

@ -107,7 +107,7 @@ void ballCatcherCheckBalls(struct BallCatcher* catcher, struct BallLauncher* bal
} }
catcher->caughtBall = &launcher->currentBall; 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); 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); skAnimatorRunClip(&catcher->animator, dynamicAssetClip(PROPS_COMBINE_BALL_CATCHER_DYNAMIC_ANIMATED_MODEL, PROPS_COMBINE_BALL_CATCHER_ARMATURE_CATCH_CLIP_INDEX), 0.0f, 0);
} }

View file

@ -99,7 +99,7 @@ void ballLauncherUpdate(struct BallLauncher* launcher) {
ballInit(&launcher->currentBall, &launcher->rigidBody.transform.position, &initialVelocity, launcher->rigidBody.currentRoom, launcher->ballLifetime); 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); 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)) { if (ballIsActive(&launcher->currentBall) && !ballIsCollisionOn(&launcher->currentBall)) {

View file

@ -12,6 +12,8 @@
#include "../../build/assets/models/props/box_dropper.h" #include "../../build/assets/models/props/box_dropper.h"
#include "../../build/assets/models/dynamic_model_list.h" #include "../../build/assets/models/dynamic_model_list.h"
#include "../../build/assets/models/dynamic_animated_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 DROOPER_RELOAD_TIME 2.0f
#define DROPPER_DROP_TIME 0.5f #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); 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); 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 &= ~BoxDropperFlagsCubeRequested;
dropper->flags |= BoxDropperFlagsCubeIsActive; dropper->flags |= BoxDropperFlagsCubeIsActive;

View file

@ -12,6 +12,8 @@
#include "../../build/assets/models/dynamic_animated_model_list.h" #include "../../build/assets/models/dynamic_animated_model_list.h"
#include "../build/assets/materials/static.h" #include "../build/assets/materials/static.h"
#include "../../build/assets/models/props/button.h" #include "../../build/assets/models/props/button.h"
#include "../scene/hud.h"
#include "../scene/scene.h"
struct Vector2 gButtonCylinderEdgeVectors[] = { struct Vector2 gButtonCylinderEdgeVectors[] = {
{0.0f, 1.0f}, {0.0f, 1.0f},
@ -141,14 +143,16 @@ void buttonUpdate(struct Button* button) {
//actively going down //actively going down
if (shouldPress){ if (shouldPress){
if (!(button->flags & ButtonFlagsBeingPressed)){ 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; button->flags |= ButtonFlagsBeingPressed;
} }
// actively going up // actively going up
else{ else{
if ((button->flags & ButtonFlagsBeingPressed)){ 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; button->flags &= ~ButtonFlagsBeingPressed;
} }

View file

@ -9,6 +9,8 @@
#include "../physics/collision_box.h" #include "../physics/collision_box.h"
#include "../physics/collision_scene.h" #include "../physics/collision_scene.h"
#include "../util/dynamic_asset_loader.h" #include "../util/dynamic_asset_loader.h"
#include "hud.h"
#include "scene.h"
#include "../build/assets/materials/static.h" #include "../build/assets/materials/static.h"
#include "../../build/assets/models/dynamic_animated_model_list.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); 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) { if (signal) {
door->flags |= DoorFlagsIsOpen; door->flags |= DoorFlagsIsOpen;

View file

@ -183,9 +183,10 @@ int elevatorUpdate(struct Elevator* elevator, struct Player* player) {
} }
if ((elevator->openAmount == 0.0f && shouldBeOpen) || (elevator->openAmount == 1.0f && !shouldBeOpen)) { 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)){ 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){ 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; player->shakeTimer = SHAKE_DURATION;
elevator->flags |= ElevatorFlagsMovingSoundPlayed; elevator->flags |= ElevatorFlagsMovingSoundPlayed;
} }

View file

@ -1,7 +1,6 @@
#include "hud.h" #include "hud.h"
#include "../../build/assets/materials/hud.h" #include "../../build/assets/materials/hud.h"
#include "../../build/src/audio/subtitles.h"
#include "../menu/controls.h" #include "../menu/controls.h"
#include "../graphics/graphics.h" #include "../graphics/graphics.h"
#include "../util/time.h" #include "../util/time.h"
@ -32,15 +31,23 @@
#define RETICLE_WIDTH 16 #define RETICLE_WIDTH 16
#define RETICLE_HEIGHT 16 #define RETICLE_HEIGHT 16
#define PROMPT_FADE_TIME 2.0f #define PROMPT_FADE_TIME 2.0f
#define SUBTITLE_FADE_TIME 0.75f #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) { void hudInit(struct Hud* hud) {
hud->promptType = CutscenePromptTypeNone; hud->promptType = CutscenePromptTypeNone;
hud->subtitleKey = SubtitleKeyNone;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->subtitleType = SubtitleTypeNone;
hud->queuedSubtitleType = SubtitleTypeNone;
hud->promptOpacity = 0.0f; hud->promptOpacity = 0.0f;
hud->subtitleOpacity = 0.0f; hud->subtitleOpacity = 0.0f;
hud->backgroundOpacity = 0.0f; hud->backgroundOpacity = 0.0f;
hud->subtitleFadeTime = 0.75; hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
hud->chosenLanguage = gSaveData.controls.subtitleLanguage; hud->chosenLanguage = gSaveData.controls.subtitleLanguage;
hud->flags = 0; hud->flags = 0;
hud->resolvedPrompts = 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; hud->chosenLanguage = gSaveData.controls.subtitleLanguage;
float targetPromptOpacity = (hud->flags & HudFlagsShowingPrompt) ? 1.0 : 0.0f; float targetPromptOpacity = (hud->flags & HudFlagsShowingPrompt) ? 1.0 : 0.0f;
float targetSubtitleOpacity = ((hud->flags & HudFlagsShowingSubtitle) && !(hud->flags & HudFlagsSubtitleQueued)) ? 0.85: 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)) ? 0.45: 0.0f; float targetBackgroundOpacity = (hud->flags & HudFlagsShowingSubtitle && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.45: 0.0f;
if (targetPromptOpacity != hud->promptOpacity) { if (targetPromptOpacity != hud->promptOpacity) {
hud->promptOpacity = mathfMoveTowards(hud->promptOpacity, targetPromptOpacity, FIXED_DELTA_TIME / PROMPT_FADE_TIME); 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); hud->subtitleOpacity = mathfMoveTowards(hud->subtitleOpacity, targetSubtitleOpacity, FIXED_DELTA_TIME / hud->subtitleFadeTime);
} }
if ((hud->subtitleOpacity == 0.0f) && (hud->flags & HudFlagsSubtitleQueued)){ if ((hud->subtitleOpacity <= 0.0f) && (hud->flags & HudFlagsSubtitleQueued)){
hud->flags &= ~HudFlagsSubtitleQueued; if (!((hud->subtitleType == SubtitleTypeCaption) && (hud->queuedSubtitleType == SubtitleTypeCaption) && (hud->subtitleExpireTimer > 0.0))){
hud->subtitleType = hud->queuedSubtitleType; hud->flags &= ~HudFlagsSubtitleQueued;
hud->queuedSubtitleType = SubtitleKeyNone; 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) { if (targetBackgroundOpacity != hud->backgroundOpacity) {
@ -152,30 +179,64 @@ void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType) {
hud->promptType = promptType; hud->promptType = promptType;
} }
void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleType) { void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum SubtitleType subtitleType) {
if (subtitleType == hud->subtitleType){ if (!(gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled)){
return;
}
if (subtitleKey == hud->subtitleKey){
return; return;
} }
if (subtitleType == SubtitleKeyNone) { if (subtitleType == SubtitleTypeNone) {
hud->flags &= ~HudFlagsShowingSubtitle; hud->flags &= ~HudFlagsShowingSubtitle;
hud->flags &= ~HudFlagsSubtitleQueued; hud->flags &= ~HudFlagsSubtitleQueued;
hud->subtitleFadeTime = 0.75; hud->queuedSubtitleType = SubtitleTypeNone;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
return; return;
} }
if (hud->flags & HudFlagsShowingSubtitle){ else if (subtitleType == SubtitleTypeCaption) {
hud->flags |= HudFlagsSubtitleQueued; if (!(gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled)){
hud->queuedSubtitleType = subtitleType; return;
hud->subtitleFadeTime = 0.3; }
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{ else if (subtitleType == SubtitleTypeCloseCaption) {
hud->flags |= HudFlagsShowingSubtitle; if (hud->flags & HudFlagsShowingSubtitle){
hud->subtitleType = subtitleType; hud->flags |= HudFlagsSubtitleQueued;
hud->subtitleFadeTime = 0.75; 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) { 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) { void hudResolveSubtitle(struct Hud* hud) {
hud->flags &= ~HudFlagsShowingSubtitle; hud->flags &= ~HudFlagsShowingSubtitle;
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
} }
void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState) { 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); controlsRenderPrompt(gPromptActions[hud->promptType], gPromptText[hud->promptType], hud->promptOpacity, renderState);
} }
if (hud->subtitleOpacity > 0.0f && gSaveData.controls.flags & ControlSaveSubtitlesEnabled) { if (hud->subtitleOpacity > 0.0f && (gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) && hud->subtitleKey != SubtitleKeyNone) {
controlsRenderSubtitle(SubtitleLanguageValues[hud->chosenLanguage][hud->subtitleType], hud->subtitleOpacity, hud->backgroundOpacity, renderState); controlsRenderSubtitle(SubtitleLanguageValues[hud->chosenLanguage][hud->subtitleKey], hud->subtitleOpacity, hud->backgroundOpacity, renderState, hud->subtitleType);
} }
} }

View file

@ -4,29 +4,39 @@
#include "../graphics/renderstate.h" #include "../graphics/renderstate.h"
#include "../player/player.h" #include "../player/player.h"
#include "../controls/controller_actions.h" #include "../controls/controller_actions.h"
#include "../../build/src/audio/subtitles.h"
#define INTRO_BLACK_TIME 3.0f #define INTRO_BLACK_TIME 3.0f
#define INTRO_FADE_TIME 1.0f #define INTRO_FADE_TIME 1.0f
#define INTRO_TOTAL_TIME (INTRO_BLACK_TIME + INTRO_FADE_TIME) #define INTRO_TOTAL_TIME (INTRO_BLACK_TIME + INTRO_FADE_TIME)
enum SubtitleType {
SubtitleTypeNone,
SubtitleTypeCaption,
SubtitleTypeCloseCaption,
};
enum HudFlags { enum HudFlags {
HudFlagsLookedPortalable0 = (1 << 0), HudFlagsLookedPortalable0 = (1 << 0),
HudFlagsLookedPortalable1 = (1 << 1), HudFlagsLookedPortalable1 = (1 << 1),
HudFlagsShowingPrompt = (1 << 2), HudFlagsShowingPrompt = (1 << 2),
HudFlagsShowingSubtitle= (1 << 3), HudFlagsShowingSubtitle = (1 << 3),
HudFlagsSubtitleQueued= (1 << 4), HudFlagsSubtitleQueued = (1 << 4),
}; };
struct Hud { struct Hud {
int chosenLanguage; int chosenLanguage;
enum CutscenePromptType promptType; enum CutscenePromptType promptType;
enum SubtitleKey subtitleType; enum SubtitleKey subtitleKey;
enum SubtitleKey queuedSubtitleType; enum SubtitleKey queuedSubtitleKey;
enum SubtitleType subtitleType;
enum SubtitleType queuedSubtitleType;
float promptOpacity; float promptOpacity;
float subtitleOpacity; float subtitleOpacity;
float backgroundOpacity; float backgroundOpacity;
float subtitleFadeTime; float subtitleFadeTime;
float subtitleExpireTimer;
float fadeInTimer; float fadeInTimer;
u16 flags; u16 flags;
@ -43,7 +53,7 @@ void hudUpdatePortalIndicators(struct Hud* hud, struct Ray* raycastRay, struct
void hudPortalFired(struct Hud* hud, int index); void hudPortalFired(struct Hud* hud, int index);
void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType); void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType);
void hudResolvePrompt(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 hudResolveSubtitle(struct Hud* hud);
void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState); void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState);

View file

@ -9,6 +9,8 @@
#include "../build/assets/models/pedestal.h" #include "../build/assets/models/pedestal.h"
#include "../../build/assets/models/dynamic_animated_model_list.h" #include "../../build/assets/models/dynamic_animated_model_list.h"
#include "../../build/assets/models/portal_gun/w_portalgun.h" #include "../../build/assets/models/portal_gun/w_portalgun.h"
#include "../scene/hud.h"
#include "../scene/scene.h"
struct Vector2 gMaxPedistalRotation; struct Vector2 gMaxPedistalRotation;
#define MAX_PEDISTAL_ROTATION_DEGREES_PER_SEC (M_PI / 3.0f) #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 (vector2RotateTowards(&pedestal->currentRotation, &target, &gMaxPedistalRotation, &pedestal->currentRotation)) {
if (!(pedestal->flags & PedestalFlagsDown)){ 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; pedestal->flags &= ~PedestalFlagsIsPointing;
} }
else{ else{
if (!(pedestal->flags & PedestalFlagsAlreadyMoving) && !(pedestal->flags & PedestalFlagsDown)){ 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; pedestal->flags |= PedestalFlagsAlreadyMoving;
} }
} }
@ -115,7 +118,8 @@ void pedestalUpdate(struct Pedestal* pedestal) {
} }
void pedestalHide(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; pedestal->flags |= PedestalFlagsDown;
skAnimatorRunClip(&pedestal->animator, dynamicAssetClip(PEDESTAL_DYNAMIC_ANIMATED_MODEL, PEDESTAL_ARMATURE_HIDE_CLIP_INDEX), 0.0f, 0); skAnimatorRunClip(&pedestal->animator, dynamicAssetClip(PEDESTAL_DYNAMIC_ANIMATED_MODEL, PEDESTAL_ARMATURE_HIDE_CLIP_INDEX), 0.0f, 0);
} }

View file

@ -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); gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
gSPGeometryMode(renderState->dl++, G_ZBUFFER | G_LIGHTING | G_CULL_BOTH, G_SHADE); gSPGeometryMode(renderState->dl++, G_ZBUFFER | G_LIGHTING | G_CULL_BOTH, G_SHADE);
hudRender(&scene->hud, &scene->player, renderState);
if (gGameMenu.state != GameMenuStateResumeGame) { if (gGameMenu.state != GameMenuStateResumeGame) {
gameMenuRender(&gGameMenu, renderState, task); gameMenuRender(&gGameMenu, renderState, task);
} }
else{
hudRender(&scene->hud, &scene->player, renderState);
}
// sceneRenderPerformanceMetrics(scene, renderState, task); // sceneRenderPerformanceMetrics(scene, renderState, task);
@ -360,7 +362,8 @@ void sceneCheckPortals(struct Scene* scene) {
portalGunFire(&scene->portalGun, 0, &raycastRay, &playerUp, scene->player.body.currentRoom); portalGunFire(&scene->portalGun, 0, &raycastRay, &playerUp, scene->player.body.currentRoom);
scene->player.flags |= PlayerJustShotPortalGun; scene->player.flags |= PlayerJustShotPortalGun;
hudPortalFired(&scene->hud, 0); 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); rumblePakClipPlay(&gFireGunRumbleWave);
} }
@ -368,7 +371,8 @@ void sceneCheckPortals(struct Scene* scene) {
portalGunFire(&scene->portalGun, 1, &raycastRay, &playerUp, scene->player.body.currentRoom); portalGunFire(&scene->portalGun, 1, &raycastRay, &playerUp, scene->player.body.currentRoom);
scene->player.flags |= PlayerJustShotPortalGun; scene->player.flags |= PlayerJustShotPortalGun;
hudPortalFired(&scene->hud, 1); 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); rumblePakClipPlay(&gFireGunRumbleWave);
} }
@ -377,27 +381,27 @@ void sceneCheckPortals(struct Scene* scene) {
} }
if ((scene->player.flags & PlayerFlagsGrounded) && (scene->player.flags & PlayerIsStepping)){ 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; scene->player.flags &= ~PlayerIsStepping;
} }
if (scene->player.flags & PlayerJustJumped){ 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; scene->player.flags &= ~PlayerJustJumped;
} }
if (scene->player.flags & PlayerJustLanded){ 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; scene->player.flags &= ~PlayerJustLanded;
} }
if (scene->player.flags & PlayerJustSelect){ 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; scene->player.flags &= ~PlayerJustSelect;
} }
if (scene->player.flags & PlayerJustDeniedSelect){ if (scene->player.flags & PlayerJustDeniedSelect){
if (scene->player.flags & PlayerHasFirstPortalGun){ 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{ else{
soundPlayerPlay(soundsSelecting[2], 1.0f, 0.5f, NULL, NULL); soundPlayerPlay(soundsSelecting[2], 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
} }
scene->player.flags &= ~PlayerJustDeniedSelect; 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); collisionSceneSetPortal(portalIndex, &portal->rigidBody.transform, roomIndex, portal->colliderIndex);
collisionObjectUpdateBB(&portal->collisionObject); 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) { if (fromPlayer) {
portal->flags |= PortalFlagsPlayerPortal; 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 // something changed and play sound near other portal
struct Portal* otherPortal = &scene->portals[1 - portalIndex]; struct Portal* otherPortal = &scene->portals[1 - portalIndex];
otherPortal->opacity = 1.0f; 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); 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) { void sceneClosePortal(struct Scene* scene, int portalIndex) {
if (gCollisionScene.portalTransforms[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.portalTransforms[portalIndex] = NULL;
gCollisionScene.portalColliderIndex[portalIndex] = -1; gCollisionScene.portalColliderIndex[portalIndex] = -1;
scene->portals[portalIndex].portalSurfaceIndex = -1; scene->portals[portalIndex].portalSurfaceIndex = -1;

View file

@ -60,7 +60,7 @@ void sceneAnimatorUpdate(struct SceneAnimator* sceneAnimator) {
if (audioInfo->loopSoundId != SOUND_ID_NONE) { if (audioInfo->loopSoundId != SOUND_ID_NONE) {
if (isMoving && state->soundId == SOUND_ID_NONE) { if (isMoving && state->soundId == SOUND_ID_NONE) {
state->soundId = soundPlayerPlay(audioInfo->loopSoundId, 1.0f, audioInfo->pitch, &currentPos, &gZeroVec); state->soundId = soundPlayerPlay(audioInfo->loopSoundId, 1.0f, audioInfo->pitch, &currentPos, &gZeroVec, SoundTypeAll);
} else if (isMoving && state->soundId != SOUND_ID_NONE) { } else if (isMoving && state->soundId != SOUND_ID_NONE) {
soundPlayerUpdatePosition(state->soundId, &currentPos, &gZeroVec); soundPlayerUpdatePosition(state->soundId, &currentPos, &gZeroVec);
} else if (!isMoving && state->soundId != SOUND_ID_NONE) { } 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) { if (isMoving && !wasMoving && audioInfo->startSoundId != SOUND_ID_NONE) {
soundPlayerPlay(audioInfo->startSoundId, 1.0f, audioInfo->pitch, &currentPos, &gZeroVec); soundPlayerPlay(audioInfo->startSoundId, 1.0f, audioInfo->pitch, &currentPos, &gZeroVec, SoundTypeAll);
} }
if (!wasMoving && isMoving && audioInfo->endSoundId != SOUND_ID_NONE) { if (!wasMoving && isMoving && audioInfo->endSoundId != SOUND_ID_NONE) {
soundPlayerPlay(audioInfo->endSoundId, 1.0f, audioInfo->pitch, &currentPos, &gZeroVec); soundPlayerPlay(audioInfo->endSoundId, 1.0f, audioInfo->pitch, &currentPos, &gZeroVec, SoundTypeAll);
} }
state->lastPosition = currentPos; state->lastPosition = currentPos;

View file

@ -11,6 +11,8 @@
#include "../../build/assets/models/dynamic_animated_model_list.h" #include "../../build/assets/models/dynamic_animated_model_list.h"
#include "../util/time.h" #include "../util/time.h"
#include "../scene/hud.h"
#include "../scene/scene.h"
#define COLLIDER_HEIGHT 0.7f #define COLLIDER_HEIGHT 0.7f
#define TICKTOCK_PAUSE_LENGTH 0.25f #define TICKTOCK_PAUSE_LENGTH 0.25f
@ -104,8 +106,10 @@ void switchActivate(struct Switch* switchObj) {
if (switchObj->timeLeft > 0.0f) { if (switchObj->timeLeft > 0.0f) {
return; return;
} }
soundPlayerPlay(soundsButton, 1.0f, 0.5f, &switchObj->rigidBody.transform.position, &gZeroVec); soundPlayerPlay(soundsButton, 1.0f, 0.5f, &switchObj->rigidBody.transform.position, &gZeroVec, SoundTypeAll);
switchObj->ticktockSoundLoopId = soundPlayerPlay(soundsTickTock, 1.0f, 0.5f, NULL, NULL); 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->flags |= SwitchFlagsDepressed;
switchObj->timeLeft = switchObj->duration; switchObj->timeLeft = switchObj->duration;
signalsSend(switchObj->signalIndex); signalsSend(switchObj->signalIndex);
@ -143,7 +147,8 @@ void switchUpdate(struct Switch* switchObj) {
switchObj->ticktockPauseTimer += FIXED_DELTA_TIME; switchObj->ticktockPauseTimer += FIXED_DELTA_TIME;
}else{ }else{
switchObj->ticktockPauseTimer = 0; 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{ }else{
switchObj->ticktockPauseTimer = 0; switchObj->ticktockPauseTimer = 0;

View file

@ -43,7 +43,7 @@ def get_caption_keys_values_language(lines):
last_space = 0 last_space = 0
addition = 0 addition = 0
for i,ch in enumerate(val): 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:] newval = newval[:last_space+addition] + '\\n' + newval[last_space+addition+1:]
addition += 1 addition += 1
newval = newval + ch newval = newval + ch