Implement modular multi-audio-language support.
This commit is contained in:
parent
738f3c73fa
commit
44217fb546
59
Makefile
59
Makefile
|
@ -69,21 +69,48 @@ default: english_audio
|
||||||
english_audio: portal_pak_dir
|
english_audio: portal_pak_dir
|
||||||
@$(MAKE) buildgame
|
@$(MAKE) buildgame
|
||||||
|
|
||||||
german_audio: vpk/portal_sound_vo_german_dir.vpk vpk/portal_sound_vo_german_000.vpk portal_pak_dir
|
all_languages: portal_pak_dir german_audio french_audio russian_audio spanish_audio
|
||||||
vpk -x portal_pak_dir vpk/portal_sound_vo_german_dir.vpk
|
|
||||||
@$(MAKE) buildgame
|
@$(MAKE) buildgame
|
||||||
|
|
||||||
|
german_audio: vpk/portal_sound_vo_german_dir.vpk vpk/portal_sound_vo_german_000.vpk portal_pak_dir
|
||||||
|
rm -rf portal_pak_dir/locales/de/
|
||||||
|
vpk -x portal_pak_dir/locales/de/ vpk/portal_sound_vo_german_dir.vpk
|
||||||
|
cd portal_pak_dir/locales/de/sound/vo/aperture_ai/; ls | xargs -I {} mv {} de_{}
|
||||||
|
rm -rf assets/locales/de/sound/vo/aperture_ai/
|
||||||
|
@mkdir -p assets/locales/de/sound/vo/aperture_ai/
|
||||||
|
cp assets/sound/vo/aperture_ai/*.sox assets/locales/de/sound/vo/aperture_ai/
|
||||||
|
cd assets/locales/de/sound/vo/aperture_ai/; rm -f ding_off.sox ding_on.sox
|
||||||
|
cd assets/locales/de/sound/vo/aperture_ai/; ls | xargs -I {} mv {} de_{}
|
||||||
|
|
||||||
french_audio: vpk/portal_sound_vo_french_dir.vpk vpk/portal_sound_vo_french_000.vpk portal_pak_dir
|
french_audio: vpk/portal_sound_vo_french_dir.vpk vpk/portal_sound_vo_french_000.vpk portal_pak_dir
|
||||||
vpk -x portal_pak_dir vpk/portal_sound_vo_french_dir.vpk
|
rm -rf portal_pak_dir/locales/fr/
|
||||||
@$(MAKE) buildgame
|
vpk -x portal_pak_dir/locales/fr/ vpk/portal_sound_vo_french_dir.vpk
|
||||||
|
cd portal_pak_dir/locales/fr/sound/vo/aperture_ai/; ls | xargs -I {} mv {} fr_{}
|
||||||
|
rm -rf assets/locales/fr/sound/vo/aperture_ai/
|
||||||
|
@mkdir -p assets/locales/fr/sound/vo/aperture_ai/
|
||||||
|
cp assets/sound/vo/aperture_ai/*.sox assets/locales/fr/sound/vo/aperture_ai/
|
||||||
|
cd assets/locales/fr/sound/vo/aperture_ai/; rm -f ding_off.sox ding_on.sox
|
||||||
|
cd assets/locales/fr/sound/vo/aperture_ai/; ls | xargs -I {} mv {} fr_{}
|
||||||
|
|
||||||
russian_audio: vpk/portal_sound_vo_russian_dir.vpk vpk/portal_sound_vo_russian_000.vpk portal_pak_dir
|
russian_audio: vpk/portal_sound_vo_russian_dir.vpk vpk/portal_sound_vo_russian_000.vpk portal_pak_dir
|
||||||
vpk -x portal_pak_dir vpk/portal_sound_vo_russian_dir.vpk
|
rm -rf portal_pak_dir/locales/ru/
|
||||||
@$(MAKE) buildgame
|
vpk -x portal_pak_dir/locales/ru/ vpk/portal_sound_vo_russian_dir.vpk
|
||||||
|
cd portal_pak_dir/locales/ru/sound/vo/aperture_ai/; ls | xargs -I {} mv {} ru_{}
|
||||||
|
rm -rf assets/locales/ru/sound/vo/aperture_ai/
|
||||||
|
@mkdir -p assets/locales/ru/sound/vo/aperture_ai/
|
||||||
|
cp assets/sound/vo/aperture_ai/*.sox assets/locales/ru/sound/vo/aperture_ai/
|
||||||
|
cd assets/locales/ru/sound/vo/aperture_ai/; rm -f ding_off.sox ding_on.sox
|
||||||
|
cd assets/locales/ru/sound/vo/aperture_ai/; ls | xargs -I {} mv {} ru_{}
|
||||||
|
|
||||||
spanish_audio: vpk/portal_sound_vo_spanish_dir.vpk vpk/portal_sound_vo_spanish_000.vpk portal_pak_dir
|
spanish_audio: vpk/portal_sound_vo_spanish_dir.vpk vpk/portal_sound_vo_spanish_000.vpk portal_pak_dir
|
||||||
vpk -x portal_pak_dir vpk/portal_sound_vo_spanish_dir.vpk
|
rm -rf portal_pak_dir/locales/es/
|
||||||
@$(MAKE) buildgame
|
vpk -x portal_pak_dir/locales/es/ vpk/portal_sound_vo_spanish_dir.vpk
|
||||||
|
cd portal_pak_dir/locales/es/sound/vo/aperture_ai/; ls | xargs -I {} mv {} es_{}
|
||||||
|
rm -rf assets/locales/es/sound/vo/aperture_ai/
|
||||||
|
@mkdir -p assets/locales/es/sound/vo/aperture_ai/
|
||||||
|
cp assets/sound/vo/aperture_ai/*.sox assets/locales/es/sound/vo/aperture_ai/
|
||||||
|
cd assets/locales/es/sound/vo/aperture_ai/; rm -f ding_off.sox ding_on.sox
|
||||||
|
cd assets/locales/es/sound/vo/aperture_ai/; ls | xargs -I {} mv {} es_{}
|
||||||
|
|
||||||
buildgame: $(BASE_TARGET_NAME).z64
|
buildgame: $(BASE_TARGET_NAME).z64
|
||||||
|
|
||||||
|
@ -92,7 +119,7 @@ include $(COMMONRULES)
|
||||||
.s.o:
|
.s.o:
|
||||||
$(AS) -Wa,-Iasm -o $@ $<
|
$(AS) -Wa,-Iasm -o $@ $<
|
||||||
|
|
||||||
build/%.o: %.c
|
build/%.o: %.c
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
$(CC) $(CFLAGS) -MM $^ -MF "$(@:.o=.d)" -MT"$@"
|
$(CC) $(CFLAGS) -MM $^ -MF "$(@:.o=.d)" -MT"$@"
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
@ -286,6 +313,7 @@ build/src/decor/decor_object_list.o: build/assets/models/dynamic_model_list.h bu
|
||||||
build/src/effects/effect_definitions.o: build/assets/materials/static.h
|
build/src/effects/effect_definitions.o: build/assets/materials/static.h
|
||||||
build/src/effects/portal_trail.o: build/assets/materials/static.h build/assets/models/portal_gun/ball_trail.h
|
build/src/effects/portal_trail.o: build/assets/materials/static.h build/assets/models/portal_gun/ball_trail.h
|
||||||
build/src/levels/level_definition.o: build/src/audio/subtitles.h
|
build/src/levels/level_definition.o: build/src/audio/subtitles.h
|
||||||
|
build/src/locales/locales.o: build/src/audio/clips.h build/src/audio/languages.h
|
||||||
build/src/menu/controls.o: build/assets/materials/ui.h build/src/audio/clips.h
|
build/src/menu/controls.o: build/assets/materials/ui.h build/src/audio/clips.h
|
||||||
build/src/menu/game_menu.o: build/src/audio/clips.h build/assets/materials/ui.h build/assets/materials/images.h build/assets/test_chambers/test_chamber_00/test_chamber_00.h
|
build/src/menu/game_menu.o: build/src/audio/clips.h build/assets/materials/ui.h build/assets/materials/images.h build/assets/test_chambers/test_chamber_00/test_chamber_00.h
|
||||||
build/src/menu/gameplay_options.o: build/assets/materials/ui.h build/src/audio/clips.h
|
build/src/menu/gameplay_options.o: build/assets/materials/ui.h build/src/audio/clips.h
|
||||||
|
@ -437,9 +465,9 @@ build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl: $(SOUND_C
|
||||||
|
|
||||||
build/asm/sound_data.o: build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl
|
build/asm/sound_data.o: build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl
|
||||||
|
|
||||||
build/src/audio/clips.h: tools/generate_sound_ids.js $(SOUND_CLIPS)
|
build/src/audio/clips.h build/src/audio/languages.h build/src/audio/languages.c: tools/generate_sound_ids.js $(SOUND_CLIPS)
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
node tools/generate_sound_ids.js -o $@ -p SOUNDS_ $(SOUND_CLIPS)
|
node tools/generate_sound_ids.js -o $(@D) -p SOUNDS_ $(SOUND_CLIPS)
|
||||||
|
|
||||||
build/src/audio/clips.o: build/src/audio/clips.h
|
build/src/audio/clips.o: build/src/audio/clips.h
|
||||||
build/src/decor/decor_object_list.o: build/src/audio/clips.h
|
build/src/decor/decor_object_list.o: build/src/audio/clips.h
|
||||||
|
@ -449,7 +477,7 @@ build/src/decor/decor_object_list.o: build/src/audio/clips.h
|
||||||
####################
|
####################
|
||||||
|
|
||||||
build/src/audio/subtitles.h build/src/audio/subtitles.c: resource/closecaption_english.txt tools/level_scripts/subtitle_generate.py
|
build/src/audio/subtitles.h build/src/audio/subtitles.c: resource/closecaption_english.txt tools/level_scripts/subtitle_generate.py
|
||||||
@python tools/level_scripts/subtitle_generate.py
|
@python3 tools/level_scripts/subtitle_generate.py
|
||||||
|
|
||||||
####################
|
####################
|
||||||
## Linking
|
## Linking
|
||||||
|
@ -465,7 +493,8 @@ CODEOBJECTS = $(patsubst %.c, build/%.o, $(CODEFILES)) \
|
||||||
build/assets/materials/static_mat.o \
|
build/assets/materials/static_mat.o \
|
||||||
build/assets/materials/ui_mat.o \
|
build/assets/materials/ui_mat.o \
|
||||||
build/assets/materials/hud_mat.o \
|
build/assets/materials/hud_mat.o \
|
||||||
build/src/audio/subtitles.o
|
build/src/audio/subtitles.o \
|
||||||
|
build/src/audio/languages.o
|
||||||
|
|
||||||
CODEOBJECTS_NO_DEBUG = $(CODEOBJECTS)
|
CODEOBJECTS_NO_DEBUG = $(CODEOBJECTS)
|
||||||
|
|
||||||
|
@ -508,7 +537,8 @@ $(BASE_TARGET_NAME)_debug.z64: $(CODESEGMENT)_debug.o $(OBJECTS) $(DATA_OBJECTS)
|
||||||
clean:
|
clean:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
rm -rf portal_pak_dir
|
rm -rf portal_pak_dir
|
||||||
rm -rf portal_pak_modified
|
rm -rf portal_pak_modified
|
||||||
|
rm -rf assets/locales/
|
||||||
|
|
||||||
clean-src:
|
clean-src:
|
||||||
rm -rf build/src
|
rm -rf build/src
|
||||||
|
@ -521,6 +551,7 @@ clean-src:
|
||||||
|
|
||||||
clean-assets:
|
clean-assets:
|
||||||
rm -rf build/assets
|
rm -rf build/assets
|
||||||
|
rm -rf assets/locales/
|
||||||
rm -f $(CODESEGMENT)_debug.o
|
rm -f $(CODESEGMENT)_debug.o
|
||||||
rm -f $(CODESEGMENT)_no_debug.o
|
rm -f $(CODESEGMENT)_no_debug.o
|
||||||
rm -f $(BASE_TARGET_NAME)_debug.elf
|
rm -f $(BASE_TARGET_NAME)_debug.elf
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../levels/levels.h"
|
#include "../levels/levels.h"
|
||||||
#include "../util/memory.h"
|
#include "../util/memory.h"
|
||||||
#include "../savefile/checkpoint.h"
|
#include "../savefile/checkpoint.h"
|
||||||
|
#include "../locales/locales.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
@ -142,6 +143,7 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
||||||
break;
|
break;
|
||||||
case CutsceneStepTypeQueueSound:
|
case CutsceneStepTypeQueueSound:
|
||||||
{
|
{
|
||||||
|
step->queueSound.soundId = mapLocaleSound(step->queueSound.soundId);
|
||||||
cutsceneQueueSoundInChannel(step->queueSound.soundId, step->queueSound.volume * (1.0f / 255.0f), step->queueSound.channel, step->queueSound.subtitleId);
|
cutsceneQueueSoundInChannel(step->queueSound.soundId, step->queueSound.volume * (1.0f / 255.0f), step->queueSound.channel, step->queueSound.subtitleId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
21
src/locales/locales.c
Normal file
21
src/locales/locales.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "locales.h"
|
||||||
|
#include "../build/src/audio/languages.h"
|
||||||
|
#include "../savefile/savefile.h"
|
||||||
|
|
||||||
|
int getAudioLanguage() {
|
||||||
|
return (int)gSaveData.audio.audioLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mapLocaleSound(int soundId) {
|
||||||
|
int language = getAudioLanguage();
|
||||||
|
|
||||||
|
switch(language) {
|
||||||
|
default:
|
||||||
|
soundId = AudioLanguageValues[language][soundId];
|
||||||
|
break;
|
||||||
|
case AUDIO_LANGUAGE_EN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundId;
|
||||||
|
}
|
2
src/locales/locales.h
Normal file
2
src/locales/locales.h
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
int getAudioLanguage();
|
||||||
|
int mapLocaleSound(int soundId);
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../build/src/audio/subtitles.h"
|
#include "../build/src/audio/subtitles.h"
|
||||||
#include "../build/assets/materials/ui.h"
|
#include "../build/assets/materials/ui.h"
|
||||||
#include "../build/src/audio/clips.h"
|
#include "../build/src/audio/clips.h"
|
||||||
|
#include "../build/src/audio/languages.h"
|
||||||
|
|
||||||
#define GAMEPLAY_Y 54
|
#define GAMEPLAY_Y 54
|
||||||
#define GAMEPLAY_WIDTH 252
|
#define GAMEPLAY_WIDTH 252
|
||||||
|
@ -15,14 +16,19 @@
|
||||||
|
|
||||||
#define SCROLL_TICKS (int)maxf(NUM_SUBTITLE_LANGUAGES, 1)
|
#define SCROLL_TICKS (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_TICKS_LANGUAGE (int)maxf(NUM_AUDIO_LANGUAGES, 1)
|
||||||
|
#define SCROLL_INTERVALS_LANGUAGE (int)maxf((SCROLL_TICKS_LANGUAGE - 1), 1)
|
||||||
|
#define SCROLL_CHUNK_SIZE_LANGUAGE (0x10000 / SCROLL_INTERVALS_LANGUAGE)
|
||||||
|
|
||||||
#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))
|
||||||
#define SCROLL_CHUNK_SIZE (0x10000 / SCROLL_INTERVALS)
|
|
||||||
|
|
||||||
void audioOptionsInit(struct AudioOptions* audioOptions) {
|
void audioOptionsInit(struct AudioOptions* audioOptions) {
|
||||||
audioOptions->selectedItem = AudioOptionSubtitlesEnabled;
|
audioOptions->selectedItem = AudioOptionSubtitlesEnabled;
|
||||||
|
|
||||||
if (NUM_SUBTITLE_LANGUAGES){
|
if (NUM_SUBTITLE_LANGUAGES) {
|
||||||
audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "Closed Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 8);
|
audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "Closed Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 8);
|
||||||
audioOptions->subtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0;
|
audioOptions->subtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0;
|
||||||
|
|
||||||
|
@ -33,6 +39,15 @@ void audioOptionsInit(struct AudioOptions* audioOptions) {
|
||||||
audioOptions->subtitles_language_temp = (0xFFFF/SCROLL_TICKS)* gSaveData.controls.subtitleLanguage;
|
audioOptions->subtitles_language_temp = (0xFFFF/SCROLL_TICKS)* gSaveData.controls.subtitleLanguage;
|
||||||
audioOptions->subtitlesLanguage.value = (int)gSaveData.controls.subtitleLanguage * (0xFFFF/SCROLL_TICKS);
|
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) {
|
||||||
|
@ -44,14 +59,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;
|
newValue = newValue + SCROLL_CHUNK_SIZE_LANGUAGE;
|
||||||
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE);
|
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE_LANGUAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controllerGetButtonDown(0, L_JPAD)) {
|
if (controllerGetButtonDown(0, L_JPAD)) {
|
||||||
newValue = newValue - 1;
|
newValue = newValue - 1;
|
||||||
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE);
|
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE_LANGUAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newValue < 0) {
|
if (newValue < 0) {
|
||||||
|
@ -89,7 +104,6 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NUM_SUBTITLE_LANGUAGES){
|
|
||||||
switch (audioOptions->selectedItem) {
|
switch (audioOptions->selectedItem) {
|
||||||
case AudioOptionSubtitlesEnabled:
|
case AudioOptionSubtitlesEnabled:
|
||||||
if (controllerGetButtonDown(0, A_BUTTON)) {
|
if (controllerGetButtonDown(0, A_BUTTON)) {
|
||||||
|
@ -110,10 +124,16 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
|
||||||
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 + 150, GAMEPLAY_Y + 28);
|
||||||
break;
|
break;
|
||||||
}
|
case AudioOptionAudioLanguage:
|
||||||
|
audioOptionsHandleSlider(&audioOptions->audio_language_temp, &audioOptions->audioLanguage.value);
|
||||||
|
int tempAudio = (int)((audioOptions->audio_language_temp * (1.0f/0xFFFF) * NUM_AUDIO_LANGUAGES));
|
||||||
|
tempAudio = (int)minf(maxf(0.0, tempAudio), NUM_AUDIO_LANGUAGES-1);
|
||||||
|
gSaveData.audio.audioLanguage = tempAudio;
|
||||||
|
audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 150, GAMEPLAY_Y + 68);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioOptions->selectedItem == AudioOptionSubtitlesLanguage){
|
if (audioOptions->selectedItem == AudioOptionSubtitlesLanguage || 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;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +164,11 @@ void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* r
|
||||||
renderState->dl = menuSliderRender(&audioOptions->subtitlesLanguage, renderState->dl);
|
renderState->dl = menuSliderRender(&audioOptions->subtitlesLanguage, renderState->dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NUM_AUDIO_LANGUAGES > 1) {
|
||||||
|
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]);
|
||||||
|
@ -162,5 +187,14 @@ void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* r
|
||||||
gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageDynamicText);
|
gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageDynamicText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NUM_AUDIO_LANGUAGES > 1) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
|
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
enum AudioOption {
|
enum AudioOption {
|
||||||
AudioOptionSubtitlesEnabled,
|
AudioOptionSubtitlesEnabled,
|
||||||
AudioOptionSubtitlesLanguage,
|
AudioOptionSubtitlesLanguage,
|
||||||
|
AudioOptionAudioLanguage,
|
||||||
AudioOptionCount,
|
AudioOptionCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ struct AudioOptions {
|
||||||
Gfx* subtitlesLanguageText;
|
Gfx* subtitlesLanguageText;
|
||||||
Gfx* subtitlesLanguageDynamicText;
|
Gfx* subtitlesLanguageDynamicText;
|
||||||
unsigned short subtitles_language_temp;
|
unsigned short subtitles_language_temp;
|
||||||
|
struct MenuSlider audioLanguage;
|
||||||
|
Gfx* audioLanguageText;
|
||||||
|
Gfx* audioLanguageDynamicText;
|
||||||
|
unsigned short audio_language_temp;
|
||||||
short selectedItem;
|
short selectedItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,4 +28,4 @@ void audioOptionsInit(struct AudioOptions* audioOptions);
|
||||||
enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions);
|
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,6 +99,7 @@ void savefileNew() {
|
||||||
|
|
||||||
gSaveData.audio.soundVolume = 0xFF;
|
gSaveData.audio.soundVolume = 0xFF;
|
||||||
gSaveData.audio.musicVolume = 0xFF;
|
gSaveData.audio.musicVolume = 0xFF;
|
||||||
|
gSaveData.audio.audioLanguage = 0;
|
||||||
|
|
||||||
controllerSetDeadzone(gSaveData.controls.deadzone * (1.0f / 0xFFFF) * MAX_DEADZONE);
|
controllerSetDeadzone(gSaveData.controls.deadzone * (1.0f / 0xFFFF) * MAX_DEADZONE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct ControlSaveState {
|
||||||
struct AudioSettingsSaveState {
|
struct AudioSettingsSaveState {
|
||||||
unsigned char soundVolume;
|
unsigned char soundVolume;
|
||||||
unsigned char musicVolume;
|
unsigned char musicVolume;
|
||||||
|
unsigned char audioLanguage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NO_TEST_CHAMBER 0xFF
|
#define NO_TEST_CHAMBER 0xFF
|
||||||
|
|
|
@ -7,6 +7,15 @@ let inputs = [];
|
||||||
let definePrefix = '';
|
let definePrefix = '';
|
||||||
let lastCommand = '';
|
let lastCommand = '';
|
||||||
|
|
||||||
|
let outputLanguagesSourceFile = '';
|
||||||
|
let outputLanguagesHeader = '';
|
||||||
|
let allSounds = [];
|
||||||
|
let languages = [];
|
||||||
|
let languages_codes = ["EN", "DE", "FR", "RU", "ES"];
|
||||||
|
let language_names = {"EN": "English", "DE": "German", "FR": "French", "RU": "Russian", "ES": "Spanish"};
|
||||||
|
let lookup = [];
|
||||||
|
languages.push("EN"); // Always included by default
|
||||||
|
|
||||||
for (let i = 2; i < process.argv.length; ++i) {
|
for (let i = 2; i < process.argv.length; ++i) {
|
||||||
const arg = process.argv[i];
|
const arg = process.argv[i];
|
||||||
if (lastCommand) {
|
if (lastCommand) {
|
||||||
|
@ -23,6 +32,10 @@ for (let i = 2; i < process.argv.length; ++i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputLanguagesSourceFile = output + '/languages.c';
|
||||||
|
outputLanguagesHeader += output + '/languages.h';
|
||||||
|
output += '/clips.h';
|
||||||
|
|
||||||
inputs.push('TOTAL_COUNT');
|
inputs.push('TOTAL_COUNT');
|
||||||
|
|
||||||
const invalidCharactersRegex = /[^\w\d_]+/gm;
|
const invalidCharactersRegex = /[^\w\d_]+/gm;
|
||||||
|
@ -31,6 +44,8 @@ function formatSoundName(soundFilename, index) {
|
||||||
const extension = path.extname(soundFilename);
|
const extension = path.extname(soundFilename);
|
||||||
const lastPart = path.basename(soundFilename, extension);
|
const lastPart = path.basename(soundFilename, extension);
|
||||||
const defineName = definePrefix + lastPart.replace(invalidCharactersRegex, '_').toUpperCase();
|
const defineName = definePrefix + lastPart.replace(invalidCharactersRegex, '_').toUpperCase();
|
||||||
|
|
||||||
|
trackSoundLanguages(soundFilename, defineName, index);
|
||||||
return `#define ${defineName} ${index}`;
|
return `#define ${defineName} ${index}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,4 +59,78 @@ ${soundFilenames.map(formatSoundName).join('\n')}
|
||||||
#endif`
|
#endif`
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(output, formatFile(output, inputs));
|
fs.writeFileSync(output, formatFile(output, inputs));
|
||||||
|
|
||||||
|
function trackSoundLanguages(soundFilename, defineName, index) {
|
||||||
|
languages_codes.forEach((language) => {
|
||||||
|
if (defineName.includes("_" + language + "_") && !languages.includes(language))
|
||||||
|
languages.push(language);
|
||||||
|
});
|
||||||
|
if (soundFilename != "TOTAL_COUNT")
|
||||||
|
allSounds.push({defineName: defineName, index: index});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillOverrideLookup() {
|
||||||
|
for (let language of languages) {
|
||||||
|
for (let overrideSound of allSounds) {
|
||||||
|
let baseSound = overrideSound;
|
||||||
|
let overrideName = overrideSound.defineName;
|
||||||
|
// check if current sound has base version of default language
|
||||||
|
if (overrideName.includes('_' + language + '_') && language != "EN") {
|
||||||
|
baseSound = allSounds.find(element => element.defineName == overrideName.replace('_' + language + '_', '_'));
|
||||||
|
}
|
||||||
|
lookup.push({language: language, baseIndex: baseSound.index, index: overrideSound.index, defineName: overrideSound.defineName});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateLanguagesHeader() {
|
||||||
|
|
||||||
|
let header = `#ifndef __LANGUAGES_H__
|
||||||
|
#define __LANGUAGES_H__
|
||||||
|
|
||||||
|
#define NUM_AUDIO_LANGUAGES ${languages.length}
|
||||||
|
|
||||||
|
extern char* AudioLanguages[];
|
||||||
|
extern int AudioLanguageValues[][${allSounds.length}];
|
||||||
|
|
||||||
|
`
|
||||||
|
header += 'enum AudioLanguagesKey\n{\n';
|
||||||
|
header += (languages.length > 0 ? '\tAUDIO_LANGUAGE_' + languages.join(',\n\tAUDIO_LANGUAGE_') + ',\n' : '');
|
||||||
|
header += '};\n';
|
||||||
|
header += '#endif';
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateLanguagesSourceFile() {
|
||||||
|
fillOverrideLookup();
|
||||||
|
let sourcefile = '#include "languages.h"\n';
|
||||||
|
sourcefile += '\n';
|
||||||
|
|
||||||
|
sourcefile += 'char* AudioLanguages[] = \n{\n';
|
||||||
|
|
||||||
|
for (let language of languages) {
|
||||||
|
sourcefile += '\t"' + language_names[language].toUpperCase() + '",\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
sourcefile += '};\n';
|
||||||
|
|
||||||
|
sourcefile += 'int AudioLanguageValues[][' + allSounds.length + '] = \n{\n';
|
||||||
|
|
||||||
|
for (let language of languages) {
|
||||||
|
sourcefile += '\t//' + language + '\n\t{\n';
|
||||||
|
|
||||||
|
for (let baseSound of allSounds) {
|
||||||
|
let overrideSound = lookup.find(lookElement => lookElement.language == language && lookElement.baseIndex == baseSound.index && lookElement.baseIndex != lookElement.index);
|
||||||
|
if (overrideSound === undefined) overrideSound = baseSound; // no override, use default
|
||||||
|
sourcefile += '\t' + overrideSound.index + ', // ' + baseSound.defineName + ' ('+baseSound.index+') -> ' + overrideSound.defineName + ' ('+ overrideSound.index+')' + '\n';
|
||||||
|
}
|
||||||
|
sourcefile += '\t},\n';
|
||||||
|
}
|
||||||
|
sourcefile += '};';
|
||||||
|
return sourcefile;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(outputLanguagesHeader, generateLanguagesHeader());
|
||||||
|
fs.writeFileSync(outputLanguagesSourceFile, generateLanguagesSourceFile());
|
||||||
|
|
Loading…
Reference in a new issue