Build translations into separate files
This commit is contained in:
parent
bd45d91445
commit
93d99d6cb5
37
Makefile
37
Makefile
|
@ -494,10 +494,33 @@ build/src/decor/decor_object_list.o: build/src/audio/clips.h
|
||||||
## Subtitles
|
## Subtitles
|
||||||
####################
|
####################
|
||||||
|
|
||||||
# TODO pull translations from vpk/Portal/portal/resource once the translations are loaded dynamically
|
SUBTITLE_LANGUAGES = english \
|
||||||
|
brazilian \
|
||||||
|
bulgarian \
|
||||||
|
czech \
|
||||||
|
danish \
|
||||||
|
dutch \
|
||||||
|
finnish \
|
||||||
|
french \
|
||||||
|
german \
|
||||||
|
hungarian \
|
||||||
|
italian \
|
||||||
|
latam \
|
||||||
|
norwegian \
|
||||||
|
polish \
|
||||||
|
portuguese \
|
||||||
|
romanian \
|
||||||
|
russian \
|
||||||
|
spanish \
|
||||||
|
swedish \
|
||||||
|
thai \
|
||||||
|
turkish
|
||||||
|
|
||||||
build/src/audio/subtitles.h build/src/audio/subtitles.c: resource/closecaption_english.txt tools/level_scripts/subtitle_generate.py
|
SUBTITLE_SOURCES = $(SUBTITLE_LANGUAGES:%=build/src/audio/subtitles_%.c)
|
||||||
@python3 tools/level_scripts/subtitle_generate.py
|
SUBTITLE_OBJECTS = $(SUBTITLE_LANGUAGES:%=build/src/audio/subtitles_%.o)
|
||||||
|
|
||||||
|
build/src/audio/subtitles.h build/src/audio/subtitles.c build/subtitles.ld: tools/level_scripts/subtitle_generate.py
|
||||||
|
python3 tools/level_scripts/subtitle_generate.py $(SUBTITLE_LANGUAGES)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
## Linking
|
## Linking
|
||||||
|
@ -528,10 +551,10 @@ $(CODESEGMENT)_no_debug.o: $(CODEOBJECTS_NO_DEBUG)
|
||||||
$(LD) -o $(CODESEGMENT)_no_debug.o -r $(CODEOBJECTS_NO_DEBUG) $(LDFLAGS)
|
$(LD) -o $(CODESEGMENT)_no_debug.o -r $(CODEOBJECTS_NO_DEBUG) $(LDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
$(CP_LD_SCRIPT)_no_debug.ld: $(LD_SCRIPT) build/levels.ld build/dynamic_models.ld build/anims.ld
|
$(CP_LD_SCRIPT)_no_debug.ld: $(LD_SCRIPT) build/levels.ld build/dynamic_models.ld build/anims.ld build/subtitles.ld
|
||||||
cpp -P -Wno-trigraphs $(LCDEFS) -DCODE_SEGMENT=$(CODESEGMENT)_no_debug.o -o $@ $<
|
cpp -P -Wno-trigraphs $(LCDEFS) -DCODE_SEGMENT=$(CODESEGMENT)_no_debug.o -o $@ $<
|
||||||
|
|
||||||
$(BASE_TARGET_NAME).z64: $(CODESEGMENT)_no_debug.o $(OBJECTS) $(DATA_OBJECTS) $(CP_LD_SCRIPT)_no_debug.ld
|
$(BASE_TARGET_NAME).z64: $(CODESEGMENT)_no_debug.o $(OBJECTS) $(DATA_OBJECTS) $(SUBTITLE_OBJECTS) $(CP_LD_SCRIPT)_no_debug.ld
|
||||||
$(LD) -L. -T $(CP_LD_SCRIPT)_no_debug.ld -Map $(BASE_TARGET_NAME)_no_debug.map -o $(BASE_TARGET_NAME).elf
|
$(LD) -L. -T $(CP_LD_SCRIPT)_no_debug.ld -Map $(BASE_TARGET_NAME)_no_debug.map -o $(BASE_TARGET_NAME).elf
|
||||||
$(OBJCOPY) --pad-to=0x100000 --gap-fill=0xFF $(BASE_TARGET_NAME).elf $(BASE_TARGET_NAME).z64 -O binary
|
$(OBJCOPY) --pad-to=0x100000 --gap-fill=0xFF $(BASE_TARGET_NAME).elf $(BASE_TARGET_NAME).z64 -O binary
|
||||||
makemask $(BASE_TARGET_NAME).z64
|
makemask $(BASE_TARGET_NAME).z64
|
||||||
|
@ -546,10 +569,10 @@ endif
|
||||||
$(CODESEGMENT)_debug.o: $(CODEOBJECTS_DEBUG)
|
$(CODESEGMENT)_debug.o: $(CODEOBJECTS_DEBUG)
|
||||||
$(LD) -o $(CODESEGMENT)_debug.o -r $(CODEOBJECTS_DEBUG) $(LDFLAGS)
|
$(LD) -o $(CODESEGMENT)_debug.o -r $(CODEOBJECTS_DEBUG) $(LDFLAGS)
|
||||||
|
|
||||||
$(CP_LD_SCRIPT)_debug.ld: $(LD_SCRIPT) build/levels.ld build/dynamic_models.ld build/anims.ld
|
$(CP_LD_SCRIPT)_debug.ld: $(LD_SCRIPT) build/levels.ld build/dynamic_models.ld build/anims.ld build/subtitles.ld
|
||||||
cpp -P -Wno-trigraphs $(LCDEFS) -DCODE_SEGMENT=$(CODESEGMENT)_debug.o -o $@ $<
|
cpp -P -Wno-trigraphs $(LCDEFS) -DCODE_SEGMENT=$(CODESEGMENT)_debug.o -o $@ $<
|
||||||
|
|
||||||
$(BASE_TARGET_NAME)_debug.z64: $(CODESEGMENT)_debug.o $(OBJECTS) $(DATA_OBJECTS) $(CP_LD_SCRIPT)_debug.ld
|
$(BASE_TARGET_NAME)_debug.z64: $(CODESEGMENT)_debug.o $(OBJECTS) $(DATA_OBJECTS) $(SUBTITLE_OBJECTS) $(CP_LD_SCRIPT)_debug.ld
|
||||||
$(LD) -L. -T $(CP_LD_SCRIPT)_debug.ld -Map $(BASE_TARGET_NAME)_debug.map -o $(BASE_TARGET_NAME)_debug.elf
|
$(LD) -L. -T $(CP_LD_SCRIPT)_debug.ld -Map $(BASE_TARGET_NAME)_debug.map -o $(BASE_TARGET_NAME)_debug.elf
|
||||||
$(OBJCOPY) --pad-to=0x100000 --gap-fill=0xFF $(BASE_TARGET_NAME)_debug.elf $(BASE_TARGET_NAME)_debug.z64 -O binary
|
$(OBJCOPY) --pad-to=0x100000 --gap-fill=0xFF $(BASE_TARGET_NAME)_debug.elf $(BASE_TARGET_NAME)_debug.z64 -O binary
|
||||||
makemask $(BASE_TARGET_NAME)_debug.z64
|
makemask $(BASE_TARGET_NAME)_debug.z64
|
||||||
|
|
|
@ -80,6 +80,7 @@ SECTIONS
|
||||||
#include "build/levels.ld"
|
#include "build/levels.ld"
|
||||||
#include "build/dynamic_models.ld"
|
#include "build/dynamic_models.ld"
|
||||||
#include "build/anims.ld"
|
#include "build/anims.ld"
|
||||||
|
#include "build/subtitles.ld"
|
||||||
|
|
||||||
/* Discard everything not specifically mentioned above. */
|
/* Discard everything not specifically mentioned above. */
|
||||||
/DISCARD/ :
|
/DISCARD/ :
|
||||||
|
|
31
src/main.c
31
src/main.c
|
@ -1,28 +1,29 @@
|
||||||
#include <ultra64.h>
|
#include <ultra64.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include "audio/audio.h"
|
||||||
|
#include "audio/soundplayer.h"
|
||||||
|
#include "controls/controller_actions.h"
|
||||||
|
#include "controls/controller.h"
|
||||||
|
#include "controls/rumble_pak.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "graphics/graphics.h"
|
#include "graphics/graphics.h"
|
||||||
#include "util/rom.h"
|
|
||||||
#include "scene/scene.h"
|
|
||||||
#include "menu/main_menu.h"
|
|
||||||
#include "util/time.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "string.h"
|
|
||||||
#include "controls/controller.h"
|
|
||||||
#include "controls/controller_actions.h"
|
|
||||||
#include "scene/dynamic_scene.h"
|
|
||||||
#include "audio/soundplayer.h"
|
|
||||||
#include "audio/audio.h"
|
|
||||||
#include "scene/portal_surface.h"
|
|
||||||
#include "sk64/skelatool_defs.h"
|
|
||||||
#include "levels/cutscene_runner.h"
|
#include "levels/cutscene_runner.h"
|
||||||
#include "levels/intro.h"
|
#include "levels/intro.h"
|
||||||
|
#include "menu/main_menu.h"
|
||||||
|
#include "menu/translations.h"
|
||||||
#include "savefile/savefile.h"
|
#include "savefile/savefile.h"
|
||||||
|
#include "scene/dynamic_scene.h"
|
||||||
|
#include "scene/portal_surface.h"
|
||||||
|
#include "scene/scene.h"
|
||||||
#include "sk64/skelatool_animator.h"
|
#include "sk64/skelatool_animator.h"
|
||||||
|
#include "sk64/skelatool_defs.h"
|
||||||
|
#include "string.h"
|
||||||
#include "util/dynamic_asset_loader.h"
|
#include "util/dynamic_asset_loader.h"
|
||||||
|
#include "util/memory.h"
|
||||||
#include "util/profile.h"
|
#include "util/profile.h"
|
||||||
#include "controls/rumble_pak.h"
|
#include "util/rom.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
|
||||||
#include "levels/levels.h"
|
#include "levels/levels.h"
|
||||||
#include "savefile/checkpoint.h"
|
#include "savefile/checkpoint.h"
|
||||||
|
@ -240,6 +241,7 @@ static void gameProc(void* arg) {
|
||||||
rumblePakClipInit();
|
rumblePakClipInit();
|
||||||
initAudio(fps);
|
initAudio(fps);
|
||||||
soundPlayerInit();
|
soundPlayerInit();
|
||||||
|
translationsLoad(gSaveData.controls.subtitleLanguage);
|
||||||
skSetSegmentLocation(CHARACTER_ANIMATION_SEGMENT, (unsigned)_animation_segmentSegmentRomStart);
|
skSetSegmentLocation(CHARACTER_ANIMATION_SEGMENT, (unsigned)_animation_segmentSegmentRomStart);
|
||||||
gSceneCallbacks->initCallback(gSceneCallbacks->data);
|
gSceneCallbacks->initCallback(gSceneCallbacks->data);
|
||||||
|
|
||||||
|
@ -264,6 +266,7 @@ static void gameProc(void* arg) {
|
||||||
portalSurfaceRevert(0);
|
portalSurfaceRevert(0);
|
||||||
portalSurfaceCleanupQueueInit();
|
portalSurfaceCleanupQueueInit();
|
||||||
heapInit(_heapStart, memoryEnd);
|
heapInit(_heapStart, memoryEnd);
|
||||||
|
translationsLoad(gSaveData.controls.subtitleLanguage);
|
||||||
levelLoadWithCallbacks(levelGetQueued());
|
levelLoadWithCallbacks(levelGetQueued());
|
||||||
rumblePakClipInit();
|
rumblePakClipInit();
|
||||||
cutsceneRunnerReset();
|
cutsceneRunnerReset();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#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"
|
#include "../build/src/audio/languages.h"
|
||||||
|
#include "./translations.h"
|
||||||
|
|
||||||
#define GAMEPLAY_Y 54
|
#define GAMEPLAY_Y 54
|
||||||
#define GAMEPLAY_WIDTH 252
|
#define GAMEPLAY_WIDTH 252
|
||||||
|
@ -182,6 +183,7 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
|
||||||
int temp = (int)((audioOptions->subtitles_language_temp * (1.0f/0xFFFF) * NUM_SUBTITLE_LANGUAGES));
|
int temp = (int)((audioOptions->subtitles_language_temp * (1.0f/0xFFFF) * NUM_SUBTITLE_LANGUAGES));
|
||||||
temp = (int)minf(maxf(0.0, temp), NUM_SUBTITLE_LANGUAGES-1);
|
temp = (int)minf(maxf(0.0, temp), NUM_SUBTITLE_LANGUAGES-1);
|
||||||
gSaveData.controls.subtitleLanguage = temp;
|
gSaveData.controls.subtitleLanguage = temp;
|
||||||
|
translationsReload(temp);
|
||||||
audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 88);
|
audioOptions->subtitlesLanguageDynamicText = menuBuildText(&gDejaVuSansFont, SubtitleLanguages[gSaveData.controls.subtitleLanguage], GAMEPLAY_X + 125, GAMEPLAY_Y + 88);
|
||||||
break;
|
break;
|
||||||
case AudioOptionAudioLanguage:
|
case AudioOptionAudioLanguage:
|
||||||
|
|
48
src/menu/translations.c
Normal file
48
src/menu/translations.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#include "translations.h"
|
||||||
|
|
||||||
|
#include "../util/memory.h"
|
||||||
|
#include "../util/rom.h"
|
||||||
|
|
||||||
|
#include "../build/src/audio/subtitles.h"
|
||||||
|
|
||||||
|
char** gCurrentTranslations = NULL;
|
||||||
|
|
||||||
|
void translationsLoad(int language) {
|
||||||
|
if (NUM_SUBTITLE_LANGUAGES == 0) {
|
||||||
|
gCurrentTranslations = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language < 0) {
|
||||||
|
language = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language >= NUM_SUBTITLE_LANGUAGES) {
|
||||||
|
language = NUM_SUBTITLE_LANGUAGES - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SubtitleBlock* block = &SubtitleLanguageBlocks[language];
|
||||||
|
|
||||||
|
int blockSize = (int)block->romEnd - (int)block->romStart;
|
||||||
|
char* blockStart = malloc(blockSize);
|
||||||
|
romCopy(block->romStart, blockStart, blockSize);
|
||||||
|
|
||||||
|
gCurrentTranslations = CALC_RAM_POINTER(block->values, blockStart);
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_SUBTITLE_MESSAGES; ++i) {
|
||||||
|
gCurrentTranslations[i] = CALC_RAM_POINTER(gCurrentTranslations[i], blockStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translationsReload(int language) {
|
||||||
|
free(gCurrentTranslations);
|
||||||
|
translationsLoad(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* translationsGet(int message) {
|
||||||
|
if (message < 0 || message >= NUM_SUBTITLE_MESSAGES || !gCurrentTranslations) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return gCurrentTranslations[message];
|
||||||
|
}
|
9
src/menu/translations.h
Normal file
9
src/menu/translations.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __MENU_TRANSLATIONS_H__
|
||||||
|
#define __MENU_TRANSLATIONS_H__
|
||||||
|
|
||||||
|
void translationsLoad(int language);
|
||||||
|
void translationsReload(int language);
|
||||||
|
|
||||||
|
char* translationsGet(int message);
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../levels/levels.h"
|
#include "../levels/levels.h"
|
||||||
#include "./scene.h"
|
#include "./scene.h"
|
||||||
#include "../savefile/savefile.h"
|
#include "../savefile/savefile.h"
|
||||||
|
#include "../menu/translations.h"
|
||||||
|
|
||||||
#define HUD_CENTER_WIDTH 6
|
#define HUD_CENTER_WIDTH 6
|
||||||
#define HUD_CENTER_HEIGHT 8
|
#define HUD_CENTER_HEIGHT 8
|
||||||
|
@ -48,7 +49,6 @@ void hudInit(struct Hud* hud) {
|
||||||
hud->subtitleOpacity = 0.0f;
|
hud->subtitleOpacity = 0.0f;
|
||||||
hud->backgroundOpacity = 0.0f;
|
hud->backgroundOpacity = 0.0f;
|
||||||
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
|
hud->subtitleFadeTime = SUBTITLE_SLOW_FADE_TIME;
|
||||||
hud->chosenLanguage = gSaveData.controls.subtitleLanguage;
|
|
||||||
hud->flags = 0;
|
hud->flags = 0;
|
||||||
hud->resolvedPrompts = 0;
|
hud->resolvedPrompts = 0;
|
||||||
hud->lastPortalIndexShot = -1;
|
hud->lastPortalIndexShot = -1;
|
||||||
|
@ -78,8 +78,6 @@ void hudUpdate(struct Hud* hud) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hud->chosenLanguage = gSaveData.controls.subtitleLanguage;
|
|
||||||
|
|
||||||
float targetPromptOpacity = (hud->flags & HudFlagsShowingPrompt) ? 1.0 : 0.0f;
|
float targetPromptOpacity = (hud->flags & HudFlagsShowingPrompt) ? 1.0 : 0.0f;
|
||||||
float targetSubtitleOpacity = ((hud->flags & HudFlagsShowingSubtitle) && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.85: 0.0f;
|
float targetSubtitleOpacity = ((hud->flags & HudFlagsShowingSubtitle) && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.85: 0.0f;
|
||||||
float targetBackgroundOpacity = (hud->flags & HudFlagsShowingSubtitle && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.45: 0.0f;
|
float targetBackgroundOpacity = (hud->flags & HudFlagsShowingSubtitle && (!(hud->flags & HudFlagsSubtitleQueued) || (hud->subtitleExpireTimer > 0.0f))) ? 0.45: 0.0f;
|
||||||
|
@ -365,6 +363,6 @@ void hudRender(struct Hud* hud, struct Player* player, struct RenderState* rende
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hud->subtitleOpacity > 0.0f && (gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) && hud->subtitleKey != SubtitleKeyNone) {
|
if (hud->subtitleOpacity > 0.0f && (gSaveData.controls.flags & ControlSaveSubtitlesEnabled || gSaveData.controls.flags & ControlSaveAllSubtitlesEnabled) && hud->subtitleKey != SubtitleKeyNone) {
|
||||||
controlsRenderSubtitle(SubtitleLanguageValues[hud->chosenLanguage][hud->subtitleKey], hud->subtitleOpacity, hud->backgroundOpacity, renderState, hud->subtitleType);
|
controlsRenderSubtitle(translationsGet(hud->subtitleKey), hud->subtitleOpacity, hud->backgroundOpacity, renderState, hud->subtitleType);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,7 +25,6 @@ enum HudFlags {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Hud {
|
struct Hud {
|
||||||
int chosenLanguage;
|
|
||||||
enum CutscenePromptType promptType;
|
enum CutscenePromptType promptType;
|
||||||
enum SubtitleKey subtitleKey;
|
enum SubtitleKey subtitleKey;
|
||||||
enum SubtitleKey queuedSubtitleKey;
|
enum SubtitleKey queuedSubtitleKey;
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def dump_lines(sourcefile_path, lines):
|
||||||
|
if not os.path.exists(os.path.dirname(os.path.abspath(sourcefile_path))):
|
||||||
|
os.makedirs(os.path.dirname(os.path.abspath(sourcefile_path)))
|
||||||
|
|
||||||
|
with open(sourcefile_path, "w") as f:
|
||||||
|
f.writelines(lines)
|
||||||
|
|
||||||
def get_caption_keys_values_language(lines):
|
def get_caption_keys_values_language(lines):
|
||||||
language = "English"
|
language = "English"
|
||||||
|
@ -62,9 +70,16 @@ def make_overall_subtitles_header(all_header_lines, languages_list):
|
||||||
header_lines.append("#define __SUBTITLES_H__\n")
|
header_lines.append("#define __SUBTITLES_H__\n")
|
||||||
header_lines.append("\n")
|
header_lines.append("\n")
|
||||||
header_lines.append(f"#define NUM_SUBTITLE_LANGUAGES {len(languages_list)}\n")
|
header_lines.append(f"#define NUM_SUBTITLE_LANGUAGES {len(languages_list)}\n")
|
||||||
|
header_lines.append(f"#define NUM_SUBTITLE_MESSAGES 508\n")
|
||||||
|
header_lines.append("\n")
|
||||||
|
header_lines.append("struct SubtitleBlock {\n")
|
||||||
|
header_lines.append(" char* romStart;\n")
|
||||||
|
header_lines.append(" char* romEnd;\n")
|
||||||
|
header_lines.append(" char** values;\n")
|
||||||
|
header_lines.append("};\n")
|
||||||
header_lines.append("\n")
|
header_lines.append("\n")
|
||||||
header_lines.append("extern char* SubtitleLanguages[];\n")
|
header_lines.append("extern char* SubtitleLanguages[];\n")
|
||||||
header_lines.append("extern char* SubtitleLanguageValues[][508];\n")
|
header_lines.append("extern struct SubtitleBlock SubtitleLanguageBlocks[];\n")
|
||||||
header_lines.append("\n")
|
header_lines.append("\n")
|
||||||
if len(languages_list) > 0:
|
if len(languages_list) > 0:
|
||||||
header_lines.extend(all_header_lines)
|
header_lines.extend(all_header_lines)
|
||||||
|
@ -77,12 +92,7 @@ def make_overall_subtitles_header(all_header_lines, languages_list):
|
||||||
|
|
||||||
header_lines.append("#endif")
|
header_lines.append("#endif")
|
||||||
|
|
||||||
headerfile_path = "build/src/audio/subtitles.h"
|
dump_lines("build/src/audio/subtitles.h", header_lines)
|
||||||
if not os.path.exists(os.path.dirname(os.path.abspath(headerfile_path))):
|
|
||||||
os.makedirs(os.path.dirname(os.path.abspath(headerfile_path)))
|
|
||||||
|
|
||||||
with open(headerfile_path, "w") as f:
|
|
||||||
f.writelines(header_lines)
|
|
||||||
|
|
||||||
def make_SubtitleKey_headerlines(keys):
|
def make_SubtitleKey_headerlines(keys):
|
||||||
header_lines = []
|
header_lines = []
|
||||||
|
@ -96,33 +106,37 @@ def make_SubtitleKey_headerlines(keys):
|
||||||
header_lines.append("\n")
|
header_lines.append("\n")
|
||||||
return header_lines
|
return header_lines
|
||||||
|
|
||||||
def make_SubtitleLanguageValues(values_list):
|
def make_subtitle_for_language(lang_lines, lang_name):
|
||||||
sourcefile_lines = []
|
lines = []
|
||||||
if len(values_list) <= 0:
|
|
||||||
sourcefile_lines.append("\n")
|
|
||||||
sourcefile_lines.append("char* SubtitleLanguageValues[][508] =\n")
|
|
||||||
sourcefile_lines.append("{\n")
|
|
||||||
sourcefile_lines.append(" {\n")
|
|
||||||
for val in range(508):
|
|
||||||
sourcefile_lines.append(f' "",\n')
|
|
||||||
sourcefile_lines.append(" },\n")
|
|
||||||
sourcefile_lines.append("};\n")
|
|
||||||
sourcefile_lines.append("\n")
|
|
||||||
return sourcefile_lines
|
|
||||||
sourcefile_lines.append("\n")
|
|
||||||
sourcefile_lines.append("char* SubtitleLanguageValues[][508] =\n")
|
|
||||||
sourcefile_lines.append("{\n")
|
|
||||||
for lang in values_list:
|
|
||||||
sourcefile_lines.append(" {\n")
|
|
||||||
sourcefile_lines.append(' "",\n')
|
|
||||||
for value in lang:
|
|
||||||
sourcefile_lines.append(f' "{value}",\n')
|
|
||||||
sourcefile_lines.append(" },\n")
|
|
||||||
sourcefile_lines.append("};\n")
|
|
||||||
sourcefile_lines.append("\n")
|
|
||||||
return sourcefile_lines
|
|
||||||
|
|
||||||
def make_overall_subtitles_sourcefile(other_sourcefile_lines, language_list):
|
lines.append("\n")
|
||||||
|
lines.append(f"char* gSubtitle{lang_name}[508] = {'{'}\n")
|
||||||
|
|
||||||
|
for value in lang_lines:
|
||||||
|
lines.append(f' "{value}",\n')
|
||||||
|
|
||||||
|
lines.append("};\n")
|
||||||
|
|
||||||
|
dump_lines(f"build/src/audio/subtitles_{lang_name}.c", lines)
|
||||||
|
|
||||||
|
|
||||||
|
def make_subtitle_ld(languages):
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
for language in languages:
|
||||||
|
language_name = language['name']
|
||||||
|
|
||||||
|
lines.append(f" BEGIN_SEG(subtitles_{language_name}, 0x04000000)\n")
|
||||||
|
lines.append(" {\n")
|
||||||
|
lines.append(f" build/src/audio/subtitles_{language_name}.o(.data);\n")
|
||||||
|
lines.append(f" build/src/audio/subtitles_{language_name}.o(.bss);\n")
|
||||||
|
lines.append(" }\n")
|
||||||
|
lines.append(f" END_SEG(subtitles_{language_name})\n")
|
||||||
|
lines.append("\n")
|
||||||
|
|
||||||
|
dump_lines('build/subtitles.ld', lines)
|
||||||
|
|
||||||
|
def make_overall_subtitles_sourcefile(language_list):
|
||||||
sourcefile_lines = []
|
sourcefile_lines = []
|
||||||
sourcefile_lines.append('#include "subtitles.h"\n')
|
sourcefile_lines.append('#include "subtitles.h"\n')
|
||||||
|
|
||||||
|
@ -136,25 +150,38 @@ def make_overall_subtitles_sourcefile(other_sourcefile_lines, language_list):
|
||||||
sourcefile_lines.append(f' "{language.upper()}",\n')
|
sourcefile_lines.append(f' "{language.upper()}",\n')
|
||||||
sourcefile_lines.append("};\n")
|
sourcefile_lines.append("};\n")
|
||||||
sourcefile_lines.append("\n")
|
sourcefile_lines.append("\n")
|
||||||
sourcefile_lines.extend(other_sourcefile_lines)
|
|
||||||
sourcefile_path = "build/src/audio/subtitles.c"
|
|
||||||
if not os.path.exists(os.path.dirname(os.path.abspath(sourcefile_path))):
|
|
||||||
os.makedirs(os.path.dirname(os.path.abspath(sourcefile_path)))
|
|
||||||
|
|
||||||
with open(sourcefile_path, "w") as f:
|
for language in language_list:
|
||||||
f.writelines(sourcefile_lines)
|
sourcefile_lines.append(f"extern char _subtitles_{language}SegmentRomStart[];\n")
|
||||||
|
sourcefile_lines.append(f"extern char _subtitles_{language}SegmentRomEnd[];\n")
|
||||||
|
sourcefile_lines.append(f"extern char* gSubtitle{language}[508];\n")
|
||||||
|
sourcefile_lines.append("\n")
|
||||||
|
|
||||||
def process_all_closecaption_files(dir):
|
sourcefile_lines.append("struct SubtitleBlock SubtitleLanguageBlocks[] = {\n")
|
||||||
|
|
||||||
|
for language in language_list:
|
||||||
|
sourcefile_lines.append(" {\n")
|
||||||
|
sourcefile_lines.append(f" _subtitles_{language}SegmentRomStart,\n")
|
||||||
|
sourcefile_lines.append(f" _subtitles_{language}SegmentRomEnd,\n")
|
||||||
|
sourcefile_lines.append(f" gSubtitle{language},\n")
|
||||||
|
sourcefile_lines.append(" },\n")
|
||||||
|
|
||||||
|
sourcefile_lines.append("};\n")
|
||||||
|
sourcefile_lines.append("\n")
|
||||||
|
|
||||||
|
dump_lines("build/src/audio/subtitles.c", sourcefile_lines)
|
||||||
|
|
||||||
|
def process_all_closecaption_files(dir, language_names):
|
||||||
values_list = []
|
values_list = []
|
||||||
header_lines = []
|
header_lines = []
|
||||||
sourcefile_lines = []
|
sourcefile_lines = []
|
||||||
language_list = []
|
language_list = []
|
||||||
|
language_with_values_list = []
|
||||||
SubtitleKey_generated = False
|
SubtitleKey_generated = False
|
||||||
lst = os.listdir(dir)
|
|
||||||
lst.sort()
|
for langauge_name in language_names:
|
||||||
for filename in lst:
|
filename = f"closecaption_{langauge_name}.txt"
|
||||||
if "closecaption_" not in filename:
|
|
||||||
continue
|
|
||||||
try:
|
try:
|
||||||
filepath = os.path.join(dir, filename)
|
filepath = os.path.join(dir, filename)
|
||||||
lines = []
|
lines = []
|
||||||
|
@ -174,14 +201,23 @@ def process_all_closecaption_files(dir):
|
||||||
header_lines = make_SubtitleKey_headerlines(k)
|
header_lines = make_SubtitleKey_headerlines(k)
|
||||||
SubtitleKey_generated = True
|
SubtitleKey_generated = True
|
||||||
language_list.append(l)
|
language_list.append(l)
|
||||||
|
|
||||||
|
language_with_values_list.append({
|
||||||
|
'value': v,
|
||||||
|
'name': l,
|
||||||
|
})
|
||||||
print(filename, " - PASSED")
|
print(filename, " - PASSED")
|
||||||
except:
|
except:
|
||||||
print(filename, " - FAILED")
|
print(filename, " - FAILED")
|
||||||
continue
|
continue
|
||||||
sourcefile_lines = make_SubtitleLanguageValues(values_list)
|
|
||||||
|
for language in language_with_values_list:
|
||||||
|
make_subtitle_for_language(language['value'], language['name'])
|
||||||
|
make_subtitle_ld(language_with_values_list)
|
||||||
|
|
||||||
make_overall_subtitles_header(header_lines, language_list)
|
make_overall_subtitles_header(header_lines, language_list)
|
||||||
make_overall_subtitles_sourcefile(sourcefile_lines, language_list)
|
make_overall_subtitles_sourcefile(language_list)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
process_all_closecaption_files("resource/")
|
process_all_closecaption_files("vpk/Portal/portal/resource", sys.argv[1:])
|
Loading…
Reference in a new issue