From bab60422bf81f6b35286ca24bc8f9718b0076918 Mon Sep 17 00:00:00 2001 From: James Lambert Date: Fri, 3 Nov 2023 22:15:01 -0600 Subject: [PATCH] Add some translations to the audio menu --- Makefile | 28 +++---- assets/translations/extra_english.txt | Bin 0 -> 138 bytes resource/.gitignore | 1 - src/main.c | 2 +- src/menu/audio_options.c | 93 ++++++++++++----------- src/menu/audio_options.h | 13 ++-- src/menu/game_menu.c | 1 + src/menu/gameplay_options.c | 8 +- src/menu/joystick_options.c | 6 +- src/menu/menu.c | 10 ++- src/menu/menu.h | 9 ++- src/menu/options_menu.c | 4 + src/menu/options_menu.h | 1 + src/savefile/savefile.c | 3 +- tools/level_scripts/subtitle_generate.py | 88 ++++++++++++++++----- 15 files changed, 169 insertions(+), 98 deletions(-) create mode 100644 assets/translations/extra_english.txt delete mode 100644 resource/.gitignore diff --git a/Makefile b/Makefile index 70158bf..6d472ba 100644 --- a/Makefile +++ b/Makefile @@ -497,25 +497,25 @@ build/src/decor/decor_object_list.o: build/src/audio/clips.h ## Subtitles #################### -SUBTITLE_LANGUAGES = english \ - brazilian \ +SUBTITLE_LANGUAGES = brazilian \ bulgarian \ czech \ danish \ - dutch \ - finnish \ - french \ german \ - greek \ - hungarian \ - italian \ - latam \ - norwegian \ - polish \ - portuguese \ - romanian \ - russian \ + english \ spanish \ + greek \ + french \ + italian \ + polish \ + latam \ + hungarian \ + dutch \ + norwegian \ + portuguese \ + russian \ + romanian \ + finnish \ swedish \ turkish \ ukrainian diff --git a/assets/translations/extra_english.txt b/assets/translations/extra_english.txt new file mode 100644 index 0000000000000000000000000000000000000000..92523addd8b56d667ef5e07b1f386f34cb1b856e GIT binary patch literal 138 zcmYj~u?m1N3`E~*Kcj!*F1WahV5wrULhU5|bv2|84oA3`yX3hofr%ZD#c+u%-AA%a qj}y{}oTdURiAB?vfykztq@?zH4o=BMX(UEkGPC-6>F*6ieimN8Iu|hj literal 0 HcmV?d00001 diff --git a/resource/.gitignore b/resource/.gitignore deleted file mode 100644 index f59ec20..0000000 --- a/resource/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/src/main.c b/src/main.c index a0aa785..30fe595 100644 --- a/src/main.c +++ b/src/main.c @@ -234,7 +234,7 @@ static void gameProc(void* arg) { setViMode(0); osViBlack(1); - levelLoadWithCallbacks(MAIN_MENU); + levelLoadWithCallbacks(INTRO_MENU); gCurrentTestSubject = 0; cutsceneRunnerReset(); controllersInit(); diff --git a/src/menu/audio_options.c b/src/menu/audio_options.c index 99dcd4d..86b3132 100644 --- a/src/menu/audio_options.c +++ b/src/menu/audio_options.c @@ -83,27 +83,43 @@ void audioOptionsHandleSlider(short selectedItem, unsigned short* settingValue, *sliderValue = (float)newValue / 0xFFFF; } +void audioOptionsRenderText(struct AudioOptions* audioOptions) { + audioOptions->gameVolumeText = menuBuildPrerenderedText(&gDejaVuSansFont, translationsGet(GAMEUI_SOUNDEFFECTVOLUME), GAMEPLAY_X + 8, GAMEPLAY_Y + 8); + audioOptions->musicVolumeText = menuBuildPrerenderedText(&gDejaVuSansFont, translationsGet(GAMEUI_MUSICVOLUME), GAMEPLAY_X + 8, GAMEPLAY_Y + 28); + audioOptions->subtitlesEnabled.prerenderedText = menuBuildPrerenderedText( + &gDejaVuSansFont, + translationsGet(GAMEUI_SUBTITLESANDSOUNDEFFECTS), + audioOptions->subtitlesEnabled.x + CHECKBOX_SIZE + 6, + audioOptions->subtitlesEnabled.y + ); + audioOptions->allSubtitlesEnabled.prerenderedText = menuBuildPrerenderedText( + &gDejaVuSansFont, + "All Captions", + audioOptions->allSubtitlesEnabled.x + CHECKBOX_SIZE + 6, + audioOptions->allSubtitlesEnabled.y + ); + audioOptions->subtitlesLanguageText = menuBuildPrerenderedText(&gDejaVuSansFont, "Captions Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 88); + audioOptions->subtitlesLanguageDynamicText = menuBuildPrerenderedText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 88); + audioOptions->audioLanguageText = menuBuildPrerenderedText(&gDejaVuSansFont, "Audio Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 124); + audioOptions->audioLanguageDynamicText = menuBuildPrerenderedText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 124); +} + void audioOptionsInit(struct AudioOptions* audioOptions) { audioOptions->selectedItem = AudioOptionGameVolume; int temp; - audioOptions->gameVolumeText = menuBuildText(&gDejaVuSansFont, "Game Volume", GAMEPLAY_X + 8, GAMEPLAY_Y + 8); audioOptions->gameVolume = menuBuildSlider(GAMEPLAY_X + 120, GAMEPLAY_Y + 8, 120, SCROLL_TICKS_VOLUME); audioOptions->gameVolume.value = (float)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_VOLUME); audioOptions->musicVolume.value = (float)gSaveData.audio.musicVolume/0xFFFF; - audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "Closed Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 48); + audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, translationsGet(GAMEUI_SUBTITLESANDSOUNDEFFECTS), GAMEPLAY_X + 8, GAMEPLAY_Y + 48, 1); audioOptions->subtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0; - audioOptions->allSubtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "All Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 68); + audioOptions->allSubtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "All Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 68, 1); 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 + 104, 232, NUM_SUBTITLE_LANGUAGES); temp = (int)(maxf(NUM_SUBTITLE_LANGUAGES-1, 1)); audioOptions->subtitles_language_temp = (0xFFFF/temp)* gSaveData.controls.subtitleLanguage; @@ -111,8 +127,6 @@ void audioOptionsInit(struct AudioOptions* audioOptions) { audioOptions->subtitles_language_temp = 0xFFFF; audioOptions->subtitlesLanguage.value = (float)(audioOptions->subtitles_language_temp)/0xFFFF; - audioOptions->audioLanguageText = menuBuildText(&gDejaVuSansFont, "Audio Language: ", GAMEPLAY_X + 8, GAMEPLAY_Y + 124); - audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 124); audioOptions->audioLanguage= menuBuildSlider(GAMEPLAY_X + 8, GAMEPLAY_Y + 140, 232, NUM_AUDIO_LANGUAGES); temp = (int)(maxf(NUM_AUDIO_LANGUAGES-1, 1)); @@ -120,7 +134,21 @@ void audioOptionsInit(struct AudioOptions* audioOptions) { if ((0xFFFF - audioOptions->audio_language_temp) > 0 && (0xFFFF - audioOptions->audio_language_temp) < (0xFFFF/temp)) audioOptions->audio_language_temp = 0xFFFF; audioOptions->audioLanguage.value = (float)(audioOptions->audio_language_temp)/0xFFFF; - + + audioOptionsRenderText(audioOptions); +} + +void audioOptionsRebuildtext(struct AudioOptions* audioOptions) { + prerenderedTextFree(audioOptions->gameVolumeText); + prerenderedTextFree(audioOptions->musicVolumeText); + prerenderedTextFree(audioOptions->subtitlesEnabled.prerenderedText); + prerenderedTextFree(audioOptions->allSubtitlesEnabled.prerenderedText); + prerenderedTextFree(audioOptions->subtitlesLanguageText); + prerenderedTextFree(audioOptions->subtitlesLanguageDynamicText); + prerenderedTextFree(audioOptions->audioLanguageText); + prerenderedTextFree(audioOptions->audioLanguageDynamicText); + + audioOptionsRenderText(audioOptions); } enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) { @@ -191,14 +219,13 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) { temp = (int)minf(maxf(0.0, temp), NUM_SUBTITLE_LANGUAGES-1); gSaveData.controls.subtitleLanguage = temp; translationsReload(temp); - audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 88); break; case AudioOptionAudioLanguage: audioOptionsHandleSlider(audioOptions->selectedItem, &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.0f, tempAudio), NUM_AUDIO_LANGUAGES-1); gSaveData.audio.audioLanguage = tempAudio; - audioOptions->audioLanguageDynamicText = menuBuildText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 124); + audioOptions->audioLanguageDynamicText = menuBuildPrerenderedText(&gDejaVuSansFont, AudioLanguages[gSaveData.audio.audioLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 124); break; } @@ -236,7 +263,6 @@ void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* r gSPDisplayList(renderState->dl++, audioOptions->musicVolume.back); renderState->dl = menuSliderRender(&audioOptions->musicVolume, renderState->dl); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.outline); renderState->dl = menuCheckboxRender(&audioOptions->subtitlesEnabled, renderState->dl); @@ -252,39 +278,18 @@ void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* r gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]); - gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_0_INDEX]); + struct PrerenderedTextBatch* batch = prerenderedBatchStart(); - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionGameVolume, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->gameVolumeText); + prerenderedBatchAdd(batch, audioOptions->gameVolumeText, audioOptions->selectedItem == AudioOptionGameVolume ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->musicVolumeText, audioOptions->selectedItem == AudioOptionMusicVolume ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->subtitlesEnabled.prerenderedText, audioOptions->selectedItem == AudioOptionSubtitlesEnabled ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->allSubtitlesEnabled.prerenderedText, audioOptions->selectedItem == AudioOptionAllSubtitlesEnabled ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->subtitlesLanguageText, audioOptions->selectedItem == AudioOptionSubtitlesLanguage ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->subtitlesLanguageDynamicText, audioOptions->selectedItem == AudioOptionSubtitlesLanguage ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->audioLanguageText, audioOptions->selectedItem == AudioOptionAudioLanguage ? &gSelectionGray : &gColorWhite); + prerenderedBatchAdd(batch, audioOptions->audioLanguageDynamicText, audioOptions->selectedItem == AudioOptionAudioLanguage ? &gSelectionGray : &gColorWhite); - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionMusicVolume, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->musicVolumeText); - - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesEnabled, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.text); - - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAllSubtitlesEnabled, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->allSubtitlesEnabled.text); - - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageText); - - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesLanguage, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->subtitlesLanguageDynamicText); - - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAudioLanguage, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->audioLanguageText); - - gDPPipeSync(renderState->dl++); - menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionAudioLanguage, &gSelectionGray, &gColorWhite); - gSPDisplayList(renderState->dl++, audioOptions->audioLanguageDynamicText); + renderState->dl = prerenderedBatchFinish(batch, gDejaVuSansImages, renderState->dl); gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_0_INDEX]); } diff --git a/src/menu/audio_options.h b/src/menu/audio_options.h index eed4b7d..d83fe7f 100644 --- a/src/menu/audio_options.h +++ b/src/menu/audio_options.h @@ -20,19 +20,20 @@ struct AudioOptions { struct MenuCheckbox subtitlesEnabled; struct MenuCheckbox allSubtitlesEnabled; struct MenuSlider subtitlesLanguage; - Gfx* gameVolumeText; - Gfx* musicVolumeText; - Gfx* subtitlesLanguageText; - Gfx* subtitlesLanguageDynamicText; + struct PrerenderedText* gameVolumeText; + struct PrerenderedText* musicVolumeText; + struct PrerenderedText* subtitlesLanguageText; + struct PrerenderedText* subtitlesLanguageDynamicText; unsigned short subtitles_language_temp; struct MenuSlider audioLanguage; - Gfx* audioLanguageText; - Gfx* audioLanguageDynamicText; + struct PrerenderedText* audioLanguageText; + struct PrerenderedText* audioLanguageDynamicText; unsigned short audio_language_temp; short selectedItem; }; void audioOptionsInit(struct AudioOptions* audioOptions); +void audioOptionsRebuildtext(struct AudioOptions* audioOptions); enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions); void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* renderState, struct GraphicsTask* task); diff --git a/src/menu/game_menu.c b/src/menu/game_menu.c index 9b571ad..96fea73 100644 --- a/src/menu/game_menu.c +++ b/src/menu/game_menu.c @@ -25,6 +25,7 @@ void gameMenuInit(struct GameMenu* gameMenu, struct LandingMenuOption* options, void gameMenuRebuildText(struct GameMenu* gameMenu) { if (gameMenu->currentRenderedLanguage != translationsCurrentLanguage()) { landingMenuRebuildText(&gameMenu->landingMenu); + optionsMenuRebuildText(&gameMenu->optionsMenu); gameMenu->currentRenderedLanguage = translationsCurrentLanguage(); } } diff --git a/src/menu/gameplay_options.c b/src/menu/gameplay_options.c index a767939..e990130 100644 --- a/src/menu/gameplay_options.c +++ b/src/menu/gameplay_options.c @@ -59,11 +59,11 @@ void gameplayOptionsHandleSlider(unsigned short* settingValue, float* sliderValu void gameplayOptionsInit(struct GameplayOptions* gameplayOptions) { gameplayOptions->selectedItem = GameplayOptionWideScreen; - gameplayOptions->wideScreen = menuBuildCheckbox(&gDejaVuSansFont, "Wide Screen", GAMEPLAY_X + 8, GAMEPLAY_Y + 8); - gameplayOptions->interlacedMode = menuBuildCheckbox(&gDejaVuSansFont, "Interlaced Video", GAMEPLAY_X + 8, GAMEPLAY_Y + 28); + gameplayOptions->wideScreen = menuBuildCheckbox(&gDejaVuSansFont, "Wide Screen", GAMEPLAY_X + 8, GAMEPLAY_Y + 8, 0); + gameplayOptions->interlacedMode = menuBuildCheckbox(&gDejaVuSansFont, "Interlaced Video", GAMEPLAY_X + 8, GAMEPLAY_Y + 28, 0); - gameplayOptions->movingPortals = menuBuildCheckbox(&gDejaVuSansFont, "Movable Portals", GAMEPLAY_X + 8, GAMEPLAY_Y + 48); - gameplayOptions->portalFunnel = menuBuildCheckbox(&gDejaVuSansFont, "Portal Funneling", GAMEPLAY_X + 8, GAMEPLAY_Y + 68); + gameplayOptions->movingPortals = menuBuildCheckbox(&gDejaVuSansFont, "Movable Portals", GAMEPLAY_X + 8, GAMEPLAY_Y + 48, 0); + gameplayOptions->portalFunnel = menuBuildCheckbox(&gDejaVuSansFont, "Portal Funneling", GAMEPLAY_X + 8, GAMEPLAY_Y + 68, 0); gameplayOptions->portalRenderDepthText = menuBuildText(&gDejaVuSansFont, "Portal Render Depth", GAMEPLAY_X + 8, GAMEPLAY_Y + 88); gameplayOptions->portalRenderDepth = menuBuildSlider(GAMEPLAY_X + 126, GAMEPLAY_Y + 88, 126, SCROLL_TICKS); diff --git a/src/menu/joystick_options.c b/src/menu/joystick_options.c index aaa1726..92cd92b 100644 --- a/src/menu/joystick_options.c +++ b/src/menu/joystick_options.c @@ -20,11 +20,11 @@ void joystickOptionsInit(struct JoystickOptions* joystickOptions) { joystickOptions->selectedItem = JoystickOptionInvert; - joystickOptions->invertControls = menuBuildCheckbox(&gDejaVuSansFont, "Invert Camera Pitch", JOYSTICK_X + 8, JOYSTICK_Y + 8); + joystickOptions->invertControls = menuBuildCheckbox(&gDejaVuSansFont, "Invert Camera Pitch", JOYSTICK_X + 8, JOYSTICK_Y + 8, 0); - joystickOptions->invertControlsYaw = menuBuildCheckbox(&gDejaVuSansFont, "Invert Camera Yaw", JOYSTICK_X + 8, JOYSTICK_Y + 28); + joystickOptions->invertControlsYaw = menuBuildCheckbox(&gDejaVuSansFont, "Invert Camera Yaw", JOYSTICK_X + 8, JOYSTICK_Y + 28, 0); - joystickOptions->tankControls = menuBuildCheckbox(&gDejaVuSansFont, "Tank Controls", JOYSTICK_X + 8, JOYSTICK_Y + 48); + joystickOptions->tankControls = menuBuildCheckbox(&gDejaVuSansFont, "Tank Controls", JOYSTICK_X + 8, JOYSTICK_Y + 48, 0); joystickOptions->lookSensitivityText = menuBuildText(&gDejaVuSansFont, "Look Sensitivity", JOYSTICK_X + 8, JOYSTICK_Y + 68); joystickOptions->lookSensitivity = menuBuildSlider(JOYSTICK_X + 120, JOYSTICK_Y + 68, 120, SCROLL_TICKS); diff --git a/src/menu/menu.c b/src/menu/menu.c index 0ce7417..ada46b9 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -181,9 +181,7 @@ void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct } } -#define CHECKBOX_SIZE 12 - -struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y) { +struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y, int shouldUsePrerendered) { struct MenuCheckbox result; result.x = x; @@ -199,7 +197,11 @@ struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, i dl = menuRenderOutline(x, y, CHECKBOX_SIZE, CHECKBOX_SIZE, 1, dl); gSPEndDisplayList(dl++); - result.text = menuBuildText(font, message, x + CHECKBOX_SIZE + 6, y); + if (shouldUsePrerendered) { + result.prerenderedText = menuBuildPrerenderedText(font, message, x + CHECKBOX_SIZE + 6, y); + } else { + result.text = menuBuildText(font, message, x + CHECKBOX_SIZE + 6, y); + } result.checked = 0; diff --git a/src/menu/menu.h b/src/menu/menu.h index b2af21c..59a439f 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -6,6 +6,8 @@ #include "../graphics/color.h" #include "../graphics/graphics.h" +#define CHECKBOX_SIZE 12 + struct MenuButton { Gfx* outline; Gfx* text; @@ -15,7 +17,10 @@ struct MenuButton { struct MenuCheckbox { Gfx* outline; - Gfx* text; + union { + Gfx* text; + struct PrerenderedText* prerenderedText; + }; Gfx* checkedIndicator; short x, y; short checked; @@ -56,7 +61,7 @@ Gfx* menuBuildOutline(int x, int y, int width, int height, int invert); struct MenuButton menuBuildButton(struct Font* font, char* message, int x, int y, int width, int height); void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct Coloru8* selected, struct Coloru8* defaultColor); -struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y); +struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y, int shouldUsePrerendered); Gfx* menuCheckboxRender(struct MenuCheckbox* checkbox, Gfx* dl); struct MenuSlider menuBuildSlider(int x, int y, int w, int tickCount); diff --git a/src/menu/options_menu.c b/src/menu/options_menu.c index dc6b8b3..ebbc70d 100644 --- a/src/menu/options_menu.c +++ b/src/menu/options_menu.c @@ -54,6 +54,10 @@ void optionsMenuInit(struct OptionsMenu* options) { gameplayOptionsInit(&options->gameplayOptions); } +void optionsMenuRebuildText(struct OptionsMenu* options) { + audioOptionsRebuildtext(&options->audioOptions); +} + enum MenuDirection optionsMenuUpdate(struct OptionsMenu* options) { enum MenuDirection menuDirection = MenuDirectionStay; diff --git a/src/menu/options_menu.h b/src/menu/options_menu.h index 0f21f5d..131fc3c 100644 --- a/src/menu/options_menu.h +++ b/src/menu/options_menu.h @@ -31,6 +31,7 @@ struct OptionsMenu { }; void optionsMenuInit(struct OptionsMenu* options); +void optionsMenuRebuildText(struct OptionsMenu* options); enum MenuDirection optionsMenuUpdate(struct OptionsMenu* options); void optionsMenuRender(struct OptionsMenu* options, struct RenderState* renderState, struct GraphicsTask* task); diff --git a/src/savefile/savefile.c b/src/savefile/savefile.c index 2ed30ad..f1931fc 100755 --- a/src/savefile/savefile.c +++ b/src/savefile/savefile.c @@ -4,6 +4,7 @@ #include "controls/controller.h" #include "../controls/controller_actions.h" +#include "../build/src/audio/subtitles.h" struct SaveData __attribute__((aligned(8))) gSaveData; int gCurrentTestSubject = -1; @@ -97,7 +98,7 @@ void savefileNew() { gSaveData.controls.acceleration = 0x4000; gSaveData.controls.deadzone = 0x4000; gSaveData.controls.portalRenderDepth = 2; - gSaveData.controls.subtitleLanguage = 0; + gSaveData.controls.subtitleLanguage = LANGUAGE_ENGLISH; gSaveData.audio.soundVolume = 0xFFFF; gSaveData.audio.musicVolume = 0x8000; diff --git a/tools/level_scripts/subtitle_generate.py b/tools/level_scripts/subtitle_generate.py index 8e64fbd..f042121 100644 --- a/tools/level_scripts/subtitle_generate.py +++ b/tools/level_scripts/subtitle_generate.py @@ -3,6 +3,7 @@ import os import re import sys import json +from os.path import exists hl_gameui_whitelist = { "GAMEUI_GAMEMENU_RESUMEGAME", @@ -11,6 +12,35 @@ hl_gameui_whitelist = { "GAMEUI_NEWGAME", "GAMEUI_OPTIONS", "GAMEUI_GAMEMENU_QUIT", + + "GAMEUI_SOUNDEFFECTVOLUME", + "GAMEUI_MUSICVOLUME", + "GAMEUI_SUBTITLESANDSOUNDEFFECTS", +} + +language_translations = { + 'brazilian': 'Brasileiro', + 'bulgarian': 'Български език', + 'czech': 'Čeština', + 'danish': 'Dansk', + 'german': 'Deutsch', + 'english': 'English', + 'spanish': 'Español', + 'greek': 'Ελληνικά', + 'french': 'Français', + 'italian': 'Italiano', + 'polish': 'Język polski', + 'latam': 'Latam', + 'hungarian': 'Magyar nyelv', + 'dutch': 'Nederlands', + 'norwegian': 'Norsk', + 'portuguese': 'Português', + 'russian': 'Русский язык', + 'romanian': 'Românește', + 'finnish': 'Suomi', + 'swedish': 'Svenska', + 'turkish': 'Türkçe', + 'ukrainian': 'Українська мова', } def get_supported_characters(): @@ -92,6 +122,13 @@ def make_overall_subtitles_header(all_header_lines, languages_list, message_coun header_lines.append("extern char* SubtitleLanguages[];\n") header_lines.append("extern struct SubtitleBlock SubtitleLanguageBlocks[];\n") header_lines.append("\n") + + for idx, language in enumerate(languages_list): + header_lines.append(f"#define LANGUAGE_{language.upper()} {idx}\n") + + header_lines.append("\n") + + if len(languages_list) > 0: header_lines.extend(all_header_lines) else: @@ -120,15 +157,12 @@ def make_SubtitleKey_headerlines(keys): def make_subtitle_for_language(lang_lines, lang_name, keys): lines = [] - idx = 0 - lines.append('#include "subtitles.h"') lines.append("\n") lines.append("\n") - for value in lang_lines: + for idx, value in enumerate(lang_lines): lines.append(f'char __translation_{lang_name}_{keys[idx]}[] = "{value}";\n') - idx = idx + 1 lines.append("\n") lines.append(f"char* gSubtitle{lang_name}[NUM_SUBTITLE_MESSAGES] = {'{'}\n") @@ -136,11 +170,8 @@ def make_subtitle_for_language(lang_lines, lang_name, keys): # SubtitleKeyNone lines.append(' "",\n') - idx = 0 - - for value in lang_lines: + for idx, value in enumerate(lang_lines): lines.append(f' __translation_{lang_name}_{keys[idx]},\n') - idx = idx + 1 lines.append("};\n") @@ -190,7 +221,7 @@ def make_overall_subtitles_sourcefile(language_list): sourcefile_lines.append(f' "",\n') else: for language in language_list: - sourcefile_lines.append(f' "{language.upper()}",\n') + sourcefile_lines.append(f' "{language_translations[language]}",\n') sourcefile_lines.append("};\n") sourcefile_lines.append("\n") @@ -215,6 +246,9 @@ def make_overall_subtitles_sourcefile(language_list): dump_lines("build/src/audio/subtitles.c", sourcefile_lines) def read_translation_file(filepath): + if not exists(filepath): + return [], [], '' + lines = [] with open(filepath, "r", encoding='utf-16-le') as f: @@ -244,8 +278,8 @@ def process_all_closecaption_files(dir, language_names): header_lines = [] language_list = [] language_with_values_list = [] - SubtitleKey_generated = False - keys = None + key_order = None + default_values = None for langauge_name in language_names: filename = f"closecaption_{langauge_name}.txt" @@ -259,14 +293,31 @@ def process_all_closecaption_files(dir, language_names): gamepad_k, gamepad_v = filter_whitelist(gamepad_k, gamepad_v, hl_gameui_whitelist) - k = k + gamepad_k - v = v + gamepad_v + extra_k, extra_v, _ = read_translation_file(f"assets/translations/extra_{langauge_name}.txt") + + k = k + gamepad_k + extra_k + v = v + gamepad_v + extra_v + + if not key_order: + header_lines = make_SubtitleKey_headerlines(k) + key_order = k + default_values = v + else: + index_mapping = {} + for idx, x in enumerate(k): + index_mapping[x] = idx + + new_values = [] + + for idx, key in enumerate(key_order): + if key in index_mapping: + new_values.append(v[index_mapping[key]]) + else: + new_values.append(default_values[idx]) + + v = new_values values_list.append(v) - if not SubtitleKey_generated: - header_lines = make_SubtitleKey_headerlines(k) - SubtitleKey_generated = True - keys = k language_list.append(l) language_with_values_list.append({ @@ -277,6 +328,7 @@ def process_all_closecaption_files(dir, language_names): except Exception as e: print(e) print(filename, " - FAILED") + raise continue good_characters = get_supported_characters() @@ -285,7 +337,7 @@ def process_all_closecaption_files(dir, language_names): max_message_length = 0 for language in language_with_values_list: - make_subtitle_for_language(language['value'], language['name'], keys) + make_subtitle_for_language(language['value'], language['name'], key_order) used_characters = used_characters | determine_invalid_characters(language['name'], language['value'], good_characters) for value in language['value']: