CMake cleanup

* Use "strings" instead of "subtitles" for translation-related files and types
* Remove CMAKE preprocessor define
* Remove makefile hack in generate_sound_ids
This commit is contained in:
Matt Penny 2024-11-18 21:56:20 -05:00
parent fb31e1b2d0
commit e884e283fa
46 changed files with 254 additions and 282 deletions

View File

@ -2,7 +2,7 @@ operators:
[]
cutscenes:
INTRO:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
- play_animation player player_intro
- play_animation glass_cover_0 glass_cover_0_open
- play_animation glass_cover_1 glass_cover_1_open

View File

@ -2,7 +2,7 @@ operators:
[]
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
- delay 1
- start_cutscene portal_loop
- set_signal FIRST_ELEVATOR
@ -11,7 +11,7 @@ cutscenes:
- q_sound SOUNDS_01_PART1_ENTRY_1 CH_GLADOS PORTAL_01_PART1_ENTRY_1
- q_sound SOUNDS_01_PART1_ENTRY_2 CH_GLADOS PORTAL_01_PART1_ENTRY_2
- wait_for_channel CH_GLADOS
- q_sound PORTAL_TASTE_OF_BLOOD CH_MUSIC SubtitleKeyNone
- q_sound PORTAL_TASTE_OF_BLOOD CH_MUSIC
- set_signal room_0_entrance
GET_GUN:
- close_portal 1

View File

@ -1,6 +1,6 @@
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
INTRO:
- activate_signage 4
- q_sound SOUNDS_02_PART1_ENTRY_1 CH_GLADOS PORTAL_02_PART1_ENTRY_1

View File

@ -2,7 +2,7 @@ operators:
- not_on_piston = not on_piston
cutscenes:
START_BALL:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
- set_signal launch_ball
- wait_for_signal exit_activate
- label piston_loop

View File

@ -1,11 +1,11 @@
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
INTRO_CUTSCENE:
- activate_signage 8
- q_sound SOUNDS_04_PART1_ENTRY_1 CH_GLADOS PORTAL_04_PART1_ENTRY_1
- wait_for_channel CH_GLADOS
- q_sound PORTAL_PROCEDURAL_JIGGLE_BONE CH_MUSIC SubtitleKeyNone
- q_sound PORTAL_PROCEDURAL_JIGGLE_BONE CH_MUSIC
SUCCESS:
- q_sound SOUNDS_04_PART1_SUCCESS_1 CH_GLADOS PORTAL_04_PART1_SUCCESS_1
DROWN_PLAYER:

View File

@ -2,7 +2,7 @@ operators:
[]
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
INTRO_CUTSCENE:
- activate_signage 9
- set_signal cube_dropper

View File

@ -2,7 +2,7 @@ operators:
[]
cutscenes:
OPEN_FIRST_DOOR:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
- set_signal room_0_exit
FIRST_ROOM:
- activate_signage 10
@ -12,7 +12,7 @@ cutscenes:
- delay 2
- open_portal first_room_portal 0
- wait_for_channel CH_GLADOS
- q_sound PORTAL_SELF_ESTEEM_FUND CH_MUSIC SubtitleKeyNone
- q_sound PORTAL_SELF_ESTEEM_FUND CH_MUSIC
SECOND_ROOM:
- close_portal 0
- close_portal 1

View File

@ -1,6 +1,6 @@
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
INTRO:
- delay 1
- start_cutscene portal_loop
@ -55,7 +55,7 @@ cutscenes:
- q_sound 07_PART1_GET_DEVICE_COMPONENT_2 CH_GLADOS PORTAL_07_PART1_GET_DEVICE_COMPONENT_2
- q_sound 07_PART1_GET_DEVICE_COMPONENT_3 CH_GLADOS PORTAL_07_PART1_GET_DEVICE_COMPONENT_3
- wait_for_channel CH_GLADOS
- q_sound PORTAL_SUBJECT_NAME_HERE CH_MUSIC SubtitleKeyNone
- q_sound PORTAL_SUBJECT_NAME_HERE CH_MUSIC
- wait_for_signal trapped
- q_sound 07_PART1_TRAPPED_1 CH_GLADOS PORTAL_07_PART1_TRAPPED_1
- q_sound 07_PART1_TRAPPED_2 CH_GLADOS PORTAL_07_PART1_TRAPPED_2

View File

@ -1,6 +1,6 @@
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
- set_signal launch_ball
- start_cutscene CHECK_TRAPPED
- wait_for_signal move_platform

View File

@ -1,6 +1,6 @@
cutscenes:
START:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
- start_cutscene CHECK_STAIRS
- start_cutscene CHECK_CUBE_ON_PISTON
- start_cutscene CHECK_CUBE_OFF_BUTTON

View File

@ -1,6 +1,6 @@
cutscenes:
INTRO:
- q_sound AMBIENCE_BASE CH_AMBIENT SubtitleKeyNone 0.55
- q_sound AMBIENCE_BASE CH_AMBIENT StringIdNone 0.55
SIGNAGE:
- activate_signage 15
- q_sound 10_PART1_ENTRY_1 CH_GLADOS PORTAL_10_PART1_ENTRY_1

View File

@ -1,7 +1,7 @@
set(BUILD_AUDIO_DIR "${PROJECT_BINARY_DIR}/src/audio")
set(BUILD_STRINGS_DIR "${PROJECT_BINARY_DIR}/src/strings")
set(FONT_DEF "${PROJECT_SOURCE_DIR}/assets/fonts/dejavu_sans/dejavu_sans_all.json")
set(GENERATE_STRINGS "${PROJECT_SOURCE_DIR}/tools/text/subtitle_generate.py")
set(GENERATE_STRINGS "${PROJECT_SOURCE_DIR}/tools/text/generate_strings.py")
##################
## Translations ##
@ -9,11 +9,11 @@ set(GENERATE_STRINGS "${PROJECT_SOURCE_DIR}/tools/text/subtitle_generate.py")
set(STRING_INPUT_FILES "")
set(SUBTITLES_H "${BUILD_AUDIO_DIR}/subtitles.h")
set(SUBTITLES_C "${BUILD_AUDIO_DIR}/subtitles.c")
set(STRINGS_H "${BUILD_STRINGS_DIR}/strings.h")
set(STRINGS_C "${BUILD_STRINGS_DIR}/strings.c")
set(STRING_LOOKUP_TABLE_FILES
${SUBTITLES_H}
${SUBTITLES_C}
${STRINGS_H}
${STRINGS_C}
)
set(STRING_DATA_TABLE_FILES "")
@ -27,7 +27,7 @@ foreach(LANGUAGE ${TEXT_LANGUAGES_LIST})
)
list(APPEND STRING_DATA_TABLE_FILES
"${BUILD_AUDIO_DIR}/subtitles_${LANGUAGE}.c"
"${BUILD_STRINGS_DIR}/strings_${LANGUAGE}.c"
)
endforeach()
@ -42,7 +42,7 @@ add_custom_command(
--languages ${TEXT_LANGUAGES}
--game-root-dir ${VPK_DIR}
--extra-translations-dir ${CMAKE_CURRENT_SOURCE_DIR}
--output-dir ${BUILD_AUDIO_DIR}
--output-dir ${BUILD_STRINGS_DIR}
--check-font ${FONT_DEF}
COMMENT
"Generating strings"
@ -69,7 +69,7 @@ target_sources(string_lookup_tables INTERFACE
# Add command for generating strings linker script fragment
set(STRING_LINKER_SCRIPT "${LINKER_SCRIPT_DIR}/subtitles.ld")
set(STRING_LINKER_SCRIPT "${LINKER_SCRIPT_DIR}/strings.ld")
add_custom_command(
DEPENDS
${GEN_SEGMENT_LD}

View File

@ -11,10 +11,10 @@ q_sound SOUND_ID CHANNEL_NAME SUBTITLE_ID [VOLUME]
## Arguments
| Name | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SOUND_ID` | The ID of the sound to queue. `SOUNDS_` prefix can be omitted. |
| `CHANNEL_NAME` | The name of the channel to queue the sound on |
| `SUBTITLE_ID` | The ID of the subtitle to display when playing the sound with subtitles enabled, or `SubtitleKeyNone`. Only shown for `CH_GLADOS` channel. |
| `SUBTITLE_ID` | The ID of the string to display as a subtitle when playing the sound with subtitles enabled, or `StringIdNone`. Only shown for `CH_GLADOS` channel. |
| `VOLUME` (optional) | The volume multiplier for playback. 0 is muted and 1 is normal volume. Defaults to 1. |
## Notes

View File

@ -93,7 +93,7 @@ SECTIONS
#include "levels.ld"
#include "dynamic_models.ld"
#include "anims.ld"
#include "subtitles.ld"
#include "strings.ld"
/* Discard standard sections not mentioned above, keep debug info */
/DISCARD/ :

View File

@ -89,7 +89,6 @@ target_sources(engine INTERFACE
menu/savefile_list.c
menu/tabs.c
menu/text_manipulation.c
menu/translations.c
menu/video_options.c
physics/collision.c
physics/collision_box.c
@ -152,6 +151,7 @@ target_sources(engine INTERFACE
scene/trigger_listener.c
sk64/skeletool_animator.c
sk64/skeletool_armature.c
strings/translations.c
util/assert.c
util/dynamic_asset_loader.c
util/memory.c
@ -210,14 +210,10 @@ add_custom_target(version_header
# Make sure version header is always up to date
add_dependencies(engine version_header)
# TODO: remove when makefile is no longer in use
target_compile_definitions(engine INTERFACE CMAKE)
###########################
## Library-specific code ##
###########################
# TODO: make this conditional
target_sources(engine INTERFACE
system/libultra/controller_libultra.c
system/libultra/time_libultra.c

View File

@ -2,9 +2,11 @@
#define __FONT_FONT_H__
#include <ultra64.h>
#include "../math/vector2s16.h"
#include "../graphics/color.h"
#include "../build/src/audio/subtitles.h"
#include "graphics/color.h"
#include "math/vector2s16.h"
#include "../build/src/strings/strings.h"
struct FontKerning {
char amount;
@ -47,7 +49,7 @@ struct SymbolLocation {
char imageIndex;
};
#define FONT_RENDERER_MAX_SYBMOLS MAX_SUBTITLE_LENGTH
#define FONT_RENDERER_MAX_SYBMOLS MAX_STRING_LENGTH
struct FontRenderer {
struct SymbolLocation symbols[FONT_RENDERER_MAX_SYBMOLS];

View File

@ -66,7 +66,7 @@ void cutsceneRunnerReset() {
gCutsceneSoundQueues[i] = NULL;
gCutsceneCurrentSound[i] = SOUND_ID_NONE;
gCutsceneCurrentSoundId[i] = SOUND_ID_NONE;
gCutsceneCurrentSubtitleId[i] = SubtitleKeyNone;
gCutsceneCurrentSubtitleId[i] = StringIdNone;
gCutsceneCurrentVolume[i] = 0.0f;
}
@ -502,7 +502,7 @@ void cutscenesUpdateSounds() {
gCutsceneCurrentSoundId[i] = curr->soundId;
gCutsceneCurrentSubtitleId[i] = curr->subtitleId;
gCutsceneCurrentVolume[i] = curr->volume;
if (curr->subtitleId != SubtitleKeyNone){
if (curr->subtitleId != StringIdNone){
hudShowSubtitle(&gScene.hud, curr->subtitleId, subtitleType);
}
@ -518,7 +518,7 @@ void cutscenesUpdateSounds() {
gCutsceneCurrentSound[i] = SOUND_ID_NONE;
gCutsceneCurrentSoundId[i] = SOUND_ID_NONE;
gCutsceneCurrentSubtitleId[i] = SubtitleKeyNone;
gCutsceneCurrentSubtitleId[i] = StringIdNone;
gCutsceneCurrentVolume[i] = 0.0f;
}
}

View File

@ -12,7 +12,7 @@
#include "levels/intro.h"
#include "levels/credits.h"
#include "menu/main_menu.h"
#include "menu/translations.h"
#include "strings/translations.h"
#include "savefile/savefile.h"
#include "scene/dynamic_scene.h"
#include "scene/portal_surface.h"
@ -257,11 +257,11 @@ static void gameProc(void* arg) {
initAudio(fps);
timeSetFrameRate(fps);
soundPlayerInit();
translationsLoad(gSaveData.controls.subtitleLanguage);
translationsLoad(gSaveData.controls.textLanguage);
skSetSegmentLocation(CHARACTER_ANIMATION_SEGMENT, (unsigned)_animation_segmentSegmentRomStart);
gSceneCallbacks->initCallback(gSceneCallbacks->data);
// this prevents the intro from crashing
gGameMenu.currentRenderedLanguage = gSaveData.controls.subtitleLanguage;
gGameMenu.currentRenderedLanguage = gSaveData.controls.textLanguage;
while (1) {
OSScMsg *msg = NULL;
@ -285,7 +285,7 @@ static void gameProc(void* arg) {
portalSurfaceCleanupQueueInit();
heapInit(_heapStart, memoryEnd);
profileClearAddressMap();
translationsLoad(gSaveData.controls.subtitleLanguage);
translationsLoad(gSaveData.controls.textLanguage);
levelLoadWithCallbacks(levelGetQueued());
rumblePakClipInit();
cutsceneRunnerReset();

View File

@ -1,12 +1,12 @@
#include "audio_options.h"
#include "../system/controller.h"
#include "../savefile/savefile.h"
#include "../font/dejavu_sans.h"
#include "../audio/soundplayer.h"
#include "../build/src/audio/subtitles.h"
#include "audio/soundplayer.h"
#include "font/dejavu_sans.h"
#include "savefile/savefile.h"
#include "system/controller.h"
#include "../build/src/audio/languages.h"
#include "./translations.h"
#include "../build/src/strings/strings.h"
#define GAMEPLAY_Y 54
#define GAMEPLAY_WIDTH 252

View File

@ -1,13 +1,11 @@
#include "./confirmation_dialog.h"
#include "confirmation_dialog.h"
#include "../font/dejavu_sans.h"
#include "../system/controller.h"
#include "../audio/soundplayer.h"
#include "./translations.h"
#include "audio/soundplayer.h"
#include "font/dejavu_sans.h"
#include "system/controller.h"
#include "../build/assets/materials/ui.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#define DIALOG_LEFT 40
#define DIALOG_WIDTH (SCREEN_WD - (DIALOG_LEFT * 2))

View File

@ -1,16 +1,16 @@
#include "controls.h"
#include "../font/dejavu_sans.h"
#include "../font/font.h"
#include "../system/controller.h"
#include "../audio/soundplayer.h"
#include "../util/memory.h"
#include "./translations.h"
#include "audio/soundplayer.h"
#include "font/dejavu_sans.h"
#include "font/font.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "util/memory.h"
#include "../build/assets/materials/ui.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
#define CONTROL_ROW_HEIGHT 14

View File

@ -1,13 +1,14 @@
#include "./game_menu.h"
#include "game_menu.h"
#include "../util/memory.h"
#include "../util/rom.h"
#include "menu.h"
#include "scene/render_plan.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "util/memory.h"
#include "util/rom.h"
#include "../build/assets/materials/ui.h"
#include "../scene/render_plan.h"
#include "../system/controller.h"
#include "./translations.h"
#include "../build/src/strings/strings.h"
void gameMenuInit(struct GameMenu* gameMenu, struct LandingMenuOption* options, int optionCount, int darkenBackground) {
landingMenuInit(&gameMenu->landingMenu, options, optionCount, darkenBackground);

View File

@ -1,13 +1,10 @@
#include "gameplay_options.h"
#include "../system/controller.h"
#include "../font/dejavu_sans.h"
#include "../audio/soundplayer.h"
#include "../savefile/savefile.h"
#include "../build/src/audio/subtitles.h"
#include "../main.h"
#include "audio/soundplayer.h"
#include "font/dejavu_sans.h"
#include "main.h"
#include "savefile/savefile.h"
#include "system/controller.h"
#define MENU_Y 54
#define MENU_WIDTH 252

View File

@ -1,20 +1,17 @@
#include "landing_menu.h"
#include "../font/font.h"
#include "../font/dejavu_sans.h"
#include "../system/controller.h"
#include "../util/memory.h"
#include "../audio/soundplayer.h"
#include "audio/soundplayer.h"
#include "cheat_codes.h"
#include "font/font.h"
#include "font/dejavu_sans.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "util/memory.h"
#include "../build/assets/materials/ui.h"
#include "../build/src/audio/clips.h"
#include "cheat_codes.h"
#include "./translations.h"
// TODO: remove when makefile is no longer in use
#ifdef CMAKE
#include "../build/version.h"
#endif
#define PORTAL_LOGO_X 30
#define PORTAL_LOGO_Y 74

View File

@ -1,14 +1,14 @@
#include "load_game.h"
#include "../savefile/savefile.h"
#include "../system/controller.h"
#include "../levels/levels.h"
#include "../util/memory.h"
#include "../audio/soundplayer.h"
#include "./translations.h"
#include "audio/soundplayer.h"
#include "levels/levels.h"
#include "savefile/savefile.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "util/memory.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
void loadGameMenuInit(struct LoadGameMenu* loadGame, struct SavefileListMenu* savefileList) {
loadGame->savefileList = savefileList;

View File

@ -1,16 +1,15 @@
#include "main_menu.h"
#include "../util/memory.h"
#include "../util/rom.h"
#include "menu.h"
#include "scene/render_plan.h"
#include "system/controller.h"
#include "util/memory.h"
#include "util/rom.h"
#include "../build/assets/materials/ui.h"
#include "../scene/render_plan.h"
#include "../system/controller.h"
#include "../build/assets/test_chambers/test_chamber_00/test_chamber_00.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
struct LandingMenuOption gMainMenuOptions[] = {
{GAMEUI_NEWGAME, GameMenuStateNewGame},

View File

@ -1,11 +1,11 @@
#include "menu_builder.h"
#include "../util/memory.h"
#include "../system/controller.h"
#include "./translations.h"
#include "../audio/soundplayer.h"
#include "audio/soundplayer.h"
#include "math/mathf.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "system/time.h"
#include "../math/mathf.h"
#include "util/memory.h"
#include "../font/dejavu_sans.h"
#include "../build/assets/materials/ui.h"

View File

@ -1,24 +1,23 @@
#include "new_game_menu.h"
#include "./translations.h"
#include "font/font.h"
#include "font/dejavu_sans.h"
#include "../font/font.h"
#include "../font/dejavu_sans.h"
#include "audio/soundplayer.h"
#include "graphics/image.h"
#include "levels/levels.h"
#include "strings/translations.h"
#include "savefile/savefile.h"
#include "system/controller.h"
#include "text_manipulation.h"
#include "util/memory.h"
#include "util/rom.h"
#include "../graphics/image.h"
#include "../util/memory.h"
#include "../util/rom.h"
#include "../audio/soundplayer.h"
#include "./text_manipulation.h"
#include "../build/assets/materials/ui.h"
#include "../build/assets/materials/images.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#include "../levels/levels.h"
#include "../savefile/savefile.h"
#include "../system/controller.h"
#include "../build/src/strings/strings.h"
struct Chapter gChapters[] = {
{images_chapter1_rgba_16b, 0, 0},

View File

@ -9,7 +9,7 @@
#include "../system/controller.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
struct Tab gOptionTabs[] = {

View File

@ -1,14 +1,14 @@
#include "./save_game_menu.h"
#include "save_game_menu.h"
#include "../savefile/savefile.h"
#include "../levels/levels.h"
#include "../system/controller.h"
#include "../util/memory.h"
#include "../audio/soundplayer.h"
#include "./translations.h"
#include "audio/soundplayer.h"
#include "levels/levels.h"
#include "savefile/savefile.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "util/memory.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
void saveGameMenuInit(struct SaveGameMenu* saveGame, struct SavefileListMenu* savefileList) {
saveGame->savefileList = savefileList;

View File

@ -1,18 +1,18 @@
#include "./savefile_list.h"
#include "savefile_list.h"
#include "../font/dejavu_sans.h"
#include "../system/controller.h"
#include "../util/rom.h"
#include "../graphics/image.h"
#include "../audio/soundplayer.h"
#include "./text_manipulation.h"
#include "./controls.h"
#include "./translations.h"
#include "audio/soundplayer.h"
#include "controls.h"
#include "font/dejavu_sans.h"
#include "graphics/image.h"
#include "strings/translations.h"
#include "system/controller.h"
#include "text_manipulation.h"
#include "util/rom.h"
#include "util/string.h"
#include "../build/assets/materials/ui.h"
#include "../build/src/audio/clips.h"
#include "../util/string.h"
#include "../build/src/strings/strings.h"
#define SAVE_SLOT_RENDER_W (SAVE_SLOT_IMAGE_W * 2)
#define SAVE_SLOT_RENDER_H (SAVE_SLOT_IMAGE_H * 2)

View File

@ -1,8 +1,8 @@
#include "tabs.h"
#include "../util/memory.h"
#include "./translations.h"
#include "./menu.h"
#include "menu.h"
#include "strings/translations.h"
#include "util/memory.h"
#define LEFT_TEXT_PADDING 4
#define RIGHT_TEXT_PADDING 16

View File

@ -2,10 +2,10 @@
#include <ultra64.h>
#include "translations.h"
#include "strings/translations.h"
#include "util/string.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
void textManipTestChamberMessage(char* result, int testChamber) {
strCopy(result, translationsGet(PORTAL_CHAPTER1_TITLE));

View File

@ -1,11 +1,11 @@
#include "video_options.h"
#include "../font/dejavu_sans.h"
#include "./translations.h"
#include "../savefile/savefile.h"
#include "../main.h"
#include "font/dejavu_sans.h"
#include "main.h"
#include "savefile/savefile.h"
#include "strings/translations.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
#define MENU_Y 54
#define MENU_WIDTH 252
@ -80,7 +80,7 @@ struct MenuElementParams gVideoMenuParams[] = {
.params = {
.slider = {
.width = 232,
.numberOfTicks = NUM_SUBTITLE_LANGUAGES,
.numberOfTicks = NUM_STRING_LANGUAGES,
.discrete = 1,
},
},
@ -155,19 +155,19 @@ void videoOptionsAction(void* data, int selection, struct MenuAction* action) {
}
break;
case VideoOptionTextLanguage:
gSaveData.controls.subtitleLanguage = action->state.iSlider.value;
gVideoMenuParams[LANGUAGE_TEXT_INDEX].params.text.message = SubtitleLanguages[gSaveData.controls.subtitleLanguage];
translationsReload(gSaveData.controls.subtitleLanguage);
gSaveData.controls.textLanguage = action->state.iSlider.value;
gVideoMenuParams[LANGUAGE_TEXT_INDEX].params.text.message = StringLanguages[gSaveData.controls.textLanguage];
translationsReload(gSaveData.controls.textLanguage);
break;
}
}
void videoOptionsInit(struct VideoOptions* videoOptions) {
if (gSaveData.controls.subtitleLanguage < 0 || gSaveData.controls.subtitleLanguage >= NUM_SUBTITLE_LANGUAGES) {
gSaveData.controls.subtitleLanguage = 0;
if (gSaveData.controls.textLanguage < 0 || gSaveData.controls.textLanguage >= NUM_STRING_LANGUAGES) {
gSaveData.controls.textLanguage = 0;
}
gVideoMenuParams[LANGUAGE_TEXT_INDEX].params.text.message = SubtitleLanguages[gSaveData.controls.subtitleLanguage];
gVideoMenuParams[LANGUAGE_TEXT_INDEX].params.text.message = StringLanguages[gSaveData.controls.textLanguage];
menuBuilderInit(
&videoOptions->menuBuilder,
@ -184,7 +184,7 @@ void videoOptionsInit(struct VideoOptions* videoOptions) {
menuBuilderSetCheckbox(&videoOptions->menuBuilder.elements[CAPTIONS_INDEX], (gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) != 0);
menuBuilderSetCheckbox(&videoOptions->menuBuilder.elements[SUBTITLES_INDEX], (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0);
menuBuilderSetISlider(&videoOptions->menuBuilder.elements[LANGUAGE_SLIDER_INDEX], gSaveData.controls.subtitleLanguage);
menuBuilderSetISlider(&videoOptions->menuBuilder.elements[LANGUAGE_SLIDER_INDEX], gSaveData.controls.textLanguage);
}
void videoOptionsRebuildtext(struct VideoOptions* videoOptions) {

View File

@ -5,17 +5,10 @@
#include "system/controller.h"
#include "../controls/controller_actions.h"
#include "../build/src/audio/subtitles.h"
struct SaveData __attribute__((aligned(8))) gSaveData;
int gCurrentTestSubject = -1;
#ifdef DEBUG
#define UNLOCK_ALL 1
#else
#define UNLOCK_ALL 1
#endif
OSPiHandle gSramHandle;
extern OSMesgQueue dmaMessageQ;
@ -94,7 +87,7 @@ void savefileNew() {
gSaveData.controls.acceleration = 0x4000;
gSaveData.controls.deadzone = 0x4000;
gSaveData.controls.portalRenderDepth = 2;
gSaveData.controls.subtitleLanguage = 0;
gSaveData.controls.textLanguage = 0;
gSaveData.audio.soundVolume = 0xFFFF;
gSaveData.audio.musicVolume = 0x8000;

View File

@ -52,7 +52,7 @@ struct ControlSaveState {
unsigned short acceleration;
unsigned short deadzone;
unsigned char portalRenderDepth;
unsigned char subtitleLanguage;
unsigned char textLanguage;
};
struct AudioSettingsSaveState {

View File

@ -1,13 +1,14 @@
#include "hud.h"
#include "../../build/assets/materials/hud.h"
#include "../menu/controls.h"
#include "../graphics/graphics.h"
#include "graphics/graphics.h"
#include "levels/levels.h"
#include "menu/controls.h"
#include "savefile/savefile.h"
#include "scene.h"
#include "strings/translations.h"
#include "system/time.h"
#include "../levels/levels.h"
#include "./scene.h"
#include "../savefile/savefile.h"
#include "../menu/translations.h"
#include "../../build/assets/materials/hud.h"
#define HUD_CENTER_WIDTH 6
#define HUD_CENTER_HEIGHT 8
@ -41,8 +42,8 @@
void hudInit(struct Hud* hud) {
hud->promptType = CutscenePromptTypeNone;
hud->subtitleKey = SubtitleKeyNone;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->subtitleId = StringIdNone;
hud->queuedSubtitleId = StringIdNone;
hud->subtitleType = SubtitleTypeNone;
hud->queuedSubtitleType = SubtitleTypeNone;
hud->promptOpacity = 0.0f;
@ -94,9 +95,9 @@ void hudUpdate(struct Hud* hud) {
if (!((hud->subtitleType == SubtitleTypeCaption) && (hud->queuedSubtitleType == SubtitleTypeCaption) && (hud->subtitleExpireTimer > 0.0))){
hud->flags &= ~HudFlagsSubtitleQueued;
hud->flags |= HudFlagsShowingSubtitle;
hud->subtitleKey = hud->queuedSubtitleKey;
hud->subtitleType= hud->queuedSubtitleType;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->subtitleId = hud->queuedSubtitleId;
hud->subtitleType = hud->queuedSubtitleType;
hud->queuedSubtitleId = StringIdNone;
hud->queuedSubtitleType = SubtitleTypeNone;
if (hud->subtitleType == SubtitleTypeCaption){
hud->subtitleExpireTimer = CAPTION_EXPIRE_TIME;
@ -177,11 +178,11 @@ void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType) {
hud->promptType = promptType;
}
void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum SubtitleType subtitleType) {
void hudShowSubtitle(struct Hud* hud, enum StringId subtitleId, enum SubtitleType subtitleType) {
if (!(gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled)){
return;
}
if (subtitleKey == hud->subtitleKey){
if (subtitleId == hud->subtitleId) {
return;
}
@ -189,7 +190,7 @@ void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum Subtitl
hud->flags &= ~HudFlagsShowingSubtitle;
hud->flags &= ~HudFlagsSubtitleQueued;
hud->queuedSubtitleType = SubtitleTypeNone;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->queuedSubtitleId = StringIdNone;
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
return;
}
@ -202,16 +203,16 @@ void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum Subtitl
}
else if ((hud->flags & HudFlagsShowingSubtitle) && (hud->subtitleType <= subtitleType)){
hud->flags |= HudFlagsSubtitleQueued;
hud->queuedSubtitleKey = subtitleKey;
hud->queuedSubtitleId = subtitleId;
hud->queuedSubtitleType = subtitleType;
hud->subtitleFadeTime = SUBTITLE_FAST_FADE_TIME;
}
else{
hud->flags |= HudFlagsShowingSubtitle;
hud->subtitleKey = subtitleKey;
hud->subtitleId = subtitleId;
hud->subtitleType = subtitleType;
hud->queuedSubtitleType = SubtitleTypeNone;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->queuedSubtitleId = StringIdNone;
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
hud->subtitleExpireTimer = CAPTION_EXPIRE_TIME;
}
@ -220,17 +221,17 @@ void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum Subtitl
else if (subtitleType == SubtitleTypeCloseCaption) {
if (hud->flags & HudFlagsShowingSubtitle){
hud->flags |= HudFlagsSubtitleQueued;
hud->queuedSubtitleKey = subtitleKey;
hud->queuedSubtitleId = subtitleId;
hud->queuedSubtitleType = subtitleType;
hud->subtitleFadeTime = SUBTITLE_FAST_FADE_TIME;
}
else{
hud->flags |= HudFlagsShowingSubtitle;
hud->flags &= ~HudFlagsSubtitleQueued;
hud->subtitleKey = subtitleKey;
hud->subtitleId = subtitleId;
hud->subtitleType = subtitleType;
hud->queuedSubtitleType = SubtitleTypeNone;
hud->queuedSubtitleKey = SubtitleKeyNone;
hud->queuedSubtitleId = StringIdNone;
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
}
return;
@ -362,7 +363,7 @@ void hudRender(struct Hud* hud, struct Player* player, struct RenderState* rende
controlsRenderPrompt(gPromptActions[hud->promptType], translationsGet(gPromptText[hud->promptType]), hud->promptOpacity, renderState);
}
if (hud->subtitleOpacity > 0.0f && (gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) && hud->subtitleKey != SubtitleKeyNone) {
controlsRenderSubtitle(translationsGet(hud->subtitleKey), hud->subtitleOpacity, hud->backgroundOpacity, renderState, hud->subtitleType);
if (hud->subtitleOpacity > 0.0f && (gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) && hud->subtitleId != StringIdNone) {
controlsRenderSubtitle(translationsGet(hud->subtitleId), hud->subtitleOpacity, hud->backgroundOpacity, renderState, hud->subtitleType);
}
}

View File

@ -1,10 +1,11 @@
#ifndef __SCENE_HUD_H__
#define __SCENE_HUD_H__
#include "../graphics/renderstate.h"
#include "../player/player.h"
#include "../controls/controller_actions.h"
#include "../../build/src/audio/subtitles.h"
#include "controls/controller_actions.h"
#include "graphics/renderstate.h"
#include "player/player.h"
#include "../build/src/strings/strings.h"
#define INTRO_BLACK_TIME 3.0f
#define INTRO_FADE_TIME 1.0f
@ -26,8 +27,8 @@ enum HudFlags {
struct Hud {
enum CutscenePromptType promptType;
enum SubtitleKey subtitleKey;
enum SubtitleKey queuedSubtitleKey;
enum StringId subtitleId;
enum StringId queuedSubtitleId;
enum SubtitleType subtitleType;
enum SubtitleType queuedSubtitleType;
float promptOpacity;
@ -52,7 +53,7 @@ void hudUpdatePortalIndicators(struct Hud* hud, struct Ray* raycastRay, struct
void hudPortalFired(struct Hud* hud, int index);
void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType);
void hudResolvePrompt(struct Hud* hud, enum CutscenePromptType promptType);
void hudShowSubtitle(struct Hud* hud, enum SubtitleKey subtitleKey, enum SubtitleType subtitleType);
void hudShowSubtitle(struct Hud* hud, enum StringId subtitleId, enum SubtitleType subtitleType);
void hudResolveSubtitle(struct Hud* hud);
void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState);

View File

@ -2,39 +2,40 @@
#include "scene.h"
#include "defs.h"
#include "audio/clips.h"
#include "audio/soundplayer.h"
#include "controls/controller_actions.h"
#include "controls/rumble_pak.h"
#include "decor/decor_object_list.h"
#include "dynamic_scene.h"
#include "effects/effect_definitions.h"
#include "graphics/graphics.h"
#include "hud.h"
#include "levels/cutscene_runner.h"
#include "levels/levels.h"
#include "levels/static_render.h"
#include "materials/shadow_caster.h"
#include "materials/subject.h"
#include "materials/light.h"
#include "materials/point_light_rendered.h"
#include "system/time.h"
#include "sk64/skeletool_defs.h"
#include "shadow_map.h"
#include "../physics/point_constraint.h"
#include "../physics/debug_renderer.h"
#include "../system/controller.h"
#include "../controls/controller_actions.h"
#include "../physics/collision_scene.h"
#include "../levels/static_render.h"
#include "../levels/levels.h"
#include "../savefile/checkpoint.h"
#include "../scene/portal_surface.h"
#include "../math/mathf.h"
#include "./hud.h"
#include "dynamic_scene.h"
#include "../audio/soundplayer.h"
#include "../audio/clips.h"
#include "../levels/cutscene_runner.h"
#include "../util/memory.h"
#include "../decor/decor_object_list.h"
#include "signals.h"
#include "math/mathf.h"
#include "menu/game_menu.h"
#include "physics/collision_scene.h"
#include "physics/debug_renderer.h"
#include "physics/point_constraint.h"
#include "savefile/checkpoint.h"
#include "player/player_rumble_clips.h"
#include "render_plan.h"
#include "../menu/game_menu.h"
#include "../effects/effect_definitions.h"
#include "../controls/rumble_pak.h"
#include "../player/player_rumble_clips.h"
#include "scene/portal_surface.h"
#include "shadow_map.h"
#include "signals.h"
#include "sk64/skeletool_defs.h"
#include "system/controller.h"
#include "system/time.h"
#include "util/memory.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
#include "../build/src/audio/clips.h"
extern struct GameMenu gGameMenu;

View File

@ -173,7 +173,7 @@ void securityCamerasCheckPortal(struct SecurityCamera* securityCameras, int came
if (!cutsceneRunnerIsChannelPlaying(CH_GLADOS)) {
short clipIndex = randomInRange(0, sizeof(gCameraDestroyClips) / sizeof(*gCameraDestroyClips));
cutsceneQueueSoundInChannel(gCameraDestroyClips[clipIndex], 1.0f, CH_GLADOS, SubtitleKeyNone);
cutsceneQueueSoundInChannel(gCameraDestroyClips[clipIndex], 1.0f, CH_GLADOS, StringIdNone);
}
}
}

View File

@ -1,16 +1,16 @@
#include "translations.h"
#include "../util/memory.h"
#include "../util/rom.h"
#include "util/memory.h"
#include "util/rom.h"
#include "../build/src/audio/subtitles.h"
#include "../build/src/strings/strings.h"
char* gLoadedLanugageBlock = NULL;
char** gCurrentTranslations = NULL;
int gCurrentLoadedLanguage = 0;
void translationsLoad(int language) {
if (NUM_SUBTITLE_LANGUAGES == 0) {
if (NUM_STRING_LANGUAGES == 0) {
gCurrentTranslations = NULL;
return;
}
@ -19,11 +19,11 @@ void translationsLoad(int language) {
language = 0;
}
if (language >= NUM_SUBTITLE_LANGUAGES) {
language = NUM_SUBTITLE_LANGUAGES - 1;
if (language >= NUM_STRING_LANGUAGES) {
language = NUM_STRING_LANGUAGES - 1;
}
struct SubtitleBlock* block = &SubtitleLanguageBlocks[language];
struct StringBlock* block = &StringLanguageBlocks[language];
int blockSize = (int)block->romEnd - (int)block->romStart;
gLoadedLanugageBlock = malloc(blockSize);
@ -32,7 +32,7 @@ void translationsLoad(int language) {
gCurrentTranslations = CALC_RAM_POINTER(block->values, gLoadedLanugageBlock);
gCurrentLoadedLanguage = language;
for (int i = 0; i < NUM_SUBTITLE_MESSAGES; ++i) {
for (int i = 0; i < NUM_TRANSLATED_STRINGS; ++i) {
gCurrentTranslations[i] = CALC_RAM_POINTER(gCurrentTranslations[i], gLoadedLanugageBlock);
}
}
@ -51,7 +51,7 @@ int translationsCurrentLanguage() {
}
char* translationsGet(int message) {
if (message < 0 || message >= NUM_SUBTITLE_MESSAGES || !gCurrentTranslations) {
if (message < 0 || message >= NUM_TRANSLATED_STRINGS || !gCurrentTranslations) {
return "";
}

View File

@ -10,7 +10,7 @@ local animation = require('tools.level_scripts.animation')
local signals = require('tools.level_scripts.signals')
sk_definition_writer.add_header('"../build/assets/materials/static.h"')
sk_definition_writer.add_header('"../build/src/audio/subtitles.h"')
sk_definition_writer.add_header('"../build/src/strings/strings.h"')
sk_definition_writer.add_header('"levels/level_definition.h"')
local portalable_surfaces = {

View File

@ -99,12 +99,12 @@ local function generate_cutscene_step(cutscene_name, step, step_index, label_loc
tonumber(step.args[2] or "1") * 255,
math.floor(tonumber(step.args[3] or "1") * 64 + 0.5),
}
elseif step.command == "q_sound" and #step.args >= 3 then
elseif step.command == "q_sound" and #step.args >= 2 then
result.type = sk_definition_writer.raw('CutsceneStepTypeQueueSound')
result.queueSound = {
sk_definition_writer.raw(string_starts_with(step.args[1], "SOUNDS_") and step.args[1] or ("SOUNDS_" .. step.args[1])),
sk_definition_writer.raw(step.args[2]),
sk_definition_writer.raw(step.args[3]),
sk_definition_writer.raw(step.args[3] or "StringIdNone"),
tonumber(step.args[4] or "1") * 255,
}
elseif step.command == "wait_for_channel" and #step.args >= 1 then

View File

@ -28,14 +28,9 @@ function getSoundName(soundFile, stripPrefix) {
return `SOUNDS_${sanitize(name).toUpperCase()}`;
}
function getSoundLanguage(soundFile, makefileHack) {
function getSoundLanguage(soundFile) {
const { name } = path.parse(soundFile);
// HACK: remove when makefile is no longer in use
if (makefileHack && soundFile.includes('assets/sound/vo/aperture_ai/')) {
return 'english';
}
return Object.keys(SUPPORTED_LANGUAGES).find(lang => {
return name.toLowerCase().startsWith(`${lang}_`);
});
@ -45,11 +40,11 @@ function getSoundNameWithoutLanguage(soundFile, language) {
return getSoundName(soundFile, language && `${language}_`);
}
function getProvidedLanguages(soundFiles, makefileHack) {
function getProvidedLanguages(soundFiles) {
const languageNames = new Set();
for (const soundFile of soundFiles) {
const language = getSoundLanguage(soundFile, makefileHack);
const language = getSoundLanguage(soundFile);
if (language) {
languageNames.add(language);
}
@ -75,8 +70,8 @@ function validateLocalizedSounds(languages) {
}
}
function parseSounds(soundFiles, makefileHack) {
const languageNames = getProvidedLanguages(soundFiles, makefileHack);
function parseSounds(soundFiles) {
const languageNames = getProvidedLanguages(soundFiles);
const defaultLanguage = languageNames[0];
// Initialize in language order so output order is consistent
@ -89,7 +84,7 @@ function parseSounds(soundFiles, makefileHack) {
const unlocalized = new Map();
for (const [i, soundFile] of soundFiles.entries()) {
const language = getSoundLanguage(soundFile, makefileHack);
const language = getSoundLanguage(soundFile);
const canonicalName = getSoundNameWithoutLanguage(soundFile, language);
const sound = {
// The game references sounds by canonical name
@ -217,24 +212,19 @@ const { values, positionals } = util.parseArgs({
options: {
'out-dir': {
type: 'string'
},
// HACK: remove when makefile is no longer in use
'makefile-hack': {
type: 'boolean'
}
},
allowPositionals: true
});
const outDir = values['out-dir'];
const makefileHack = values['makefile-hack'];
const soundFiles = positionals;
if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir, { recursive: true });
}
const soundInfo = parseSounds(soundFiles, makefileHack);
const soundInfo = parseSounds(soundFiles);
fs.writeFileSync(
path.join(outDir, 'clips.h'),

View File

@ -1,5 +1,3 @@
# TODO: rename file -> generate_strings.py
#!/usr/bin/env python3
import argparse
import json
@ -154,27 +152,27 @@ def generate_header(language_strings):
)
return (
f"#ifndef __SUBTITLES_H__\n"
f"#define __SUBTITLES_H__\n"
f"#ifndef __STRINGS_H__\n"
f"#define __STRINGS_H__\n"
f"\n"
f"#define NUM_SUBTITLE_LANGUAGES {len(language_strings)}\n"
f"#define NUM_SUBTITLE_MESSAGES {len(language_strings[first_language].values()) + 1}\n"
f"#define MAX_SUBTITLE_LENGTH {max_message_length}\n"
f"#define NUM_STRING_LANGUAGES {len(language_strings)}\n"
f"#define NUM_TRANSLATED_STRINGS {len(language_strings[first_language].values()) + 1}\n"
f"#define MAX_STRING_LENGTH {max_message_length}\n"
f"\n"
f"struct SubtitleBlock {{\n"
f"struct StringBlock {{\n"
f" char* romStart;\n"
f" char* romEnd;\n"
f" char** values;\n"
f"}};\n"
f"\n"
f"extern char* SubtitleLanguages[];\n"
f"extern struct SubtitleBlock SubtitleLanguageBlocks[];\n"
f"extern char* StringLanguages[];\n"
f"extern struct StringBlock StringLanguageBlocks[];\n"
f"\n"
f"{language_defines}\n"
f"\n"
f"enum SubtitleKey\n"
f"enum StringId\n"
f"{{\n"
f" SubtitleKeyNone,\n"
f" StringIdNone,\n"
f"{string_enum_entries}\n"
f"}};\n"
f"\n"
@ -188,9 +186,9 @@ def generate_main_source_file(language_strings):
)
output = (
f'#include "subtitles.h"\n'
f'#include "strings.h"\n'
f"\n"
f"char* SubtitleLanguages[] =\n"
f"char* StringLanguages[] =\n"
f"{{\n"
f"{language_name_entries}\n"
f"}};\n"
@ -199,20 +197,20 @@ def generate_main_source_file(language_strings):
for language in language_strings:
output += (
f"extern char _subtitles_{language}SegmentRomStart[];\n"
f"extern char _subtitles_{language}SegmentRomEnd[];\n"
f"extern char* gSubtitle{capitalize(language)}[NUM_SUBTITLE_MESSAGES];\n"
f"extern char _strings_{language}SegmentRomStart[];\n"
f"extern char _strings_{language}SegmentRomEnd[];\n"
f"extern char* gStrings{capitalize(language)}[NUM_TRANSLATED_STRINGS];\n"
f"\n"
)
output += f"struct SubtitleBlock SubtitleLanguageBlocks[] = {{\n"
output += f"struct StringBlock StringLanguageBlocks[] = {{\n"
for language in language_strings:
output += (
f" {{\n"
f" _subtitles_{language}SegmentRomStart,\n"
f" _subtitles_{language}SegmentRomEnd,\n"
f" gSubtitle{capitalize(language)},\n"
f" _strings_{language}SegmentRomStart,\n"
f" _strings_{language}SegmentRomEnd,\n"
f" gStrings{capitalize(language)},\n"
f" }},\n"
)
@ -230,12 +228,12 @@ def generate_language_source_file(language, strings, default_strings):
)
return (
f'#include "subtitles.h"\n'
f'#include "strings.h"\n'
f"\n"
f"{string_declarations}\n"
f"\n"
f"char* gSubtitle{capitalize(language)}[NUM_SUBTITLE_MESSAGES] = {{\n"
f' "",\n' # SubtitleKeyNone
f"char* gStrings{capitalize(language)}[NUM_TRANSLATED_STRINGS] = {{\n"
f' "",\n' # StringIdNone
f"{string_table_entries}\n"
f"}};"
)
@ -399,18 +397,17 @@ if font_data:
output_dir = args.output_dir
write_string(
os.path.join(output_dir, "subtitles.h"),
os.path.join(output_dir, "strings.h"),
generate_header(language_strings)
)
write_string(
os.path.join(output_dir, "subtitles.c"),
os.path.join(output_dir, "strings.c"),
generate_main_source_file(language_strings)
)
# TODO: strings_*.c
default_strings = language_strings[list(language_strings)[0]]
for language, strings in language_strings.items():
write_string(
os.path.join(output_dir, f"subtitles_{language}.c"),
os.path.join(output_dir, f"strings_{language}.c"),
generate_language_source_file(language, strings, default_strings)
)