translate controls menu

This commit is contained in:
James Lambert 2023-11-09 21:42:50 -07:00
parent 44ab1ddfcd
commit 9d07965582
9 changed files with 147 additions and 44 deletions

View file

@ -322,7 +322,7 @@ build/src/effects/portal_trail.o: build/assets/materials/static.h build/assets/m
build/src/levels/level_definition.o: build/src/audio/subtitles.h
build/src/levels/level_definition.h: 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/audio/subtitles.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/joystick_options.o: build/assets/materials/ui.h build/src/audio/clips.h

View file

@ -367,6 +367,69 @@ struct PrerenderedText* prerenderedTextNew(struct FontRenderer* renderer) {
return result;
}
struct PrerenderedText* prerenderedTextCopy(struct PrerenderedText* text) {
struct PrerenderedText* result = malloc(sizeof(struct PrerenderedText));
int imageIndex = 0;
int imageMask = text->usedImageIndices;
while (imageMask) {
imageMask >>= 1;
++imageIndex;
}
result->displayLists = malloc(sizeof(Gfx*) * imageIndex);
result->usedImageIndices = text->usedImageIndices;
result->x = text->x;
result->y = text->y;
result->width = text->width;
result->height = text->height;
imageIndex = 0;
imageMask = text->usedImageIndices;
while (imageMask) {
if (imageMask & 0x1) {
Gfx* src = text->displayLists[imageIndex];
src += 2;
while (_SHIFTR(src->words.w0, 24, 8) != G_ENDDL) {
// copy image
src += 3;
}
++src;
int size = (src - text->displayLists[imageIndex]) * sizeof(Gfx);
result->displayLists[imageIndex] = malloc(size);
Gfx* dest = result->displayLists[imageIndex];
src = text->displayLists[imageIndex];
// copy color
*dest++ = *src++;
*dest++ = *src++;
while (_SHIFTR(src->words.w0, 24, 8) != G_ENDDL) {
// copy image
*dest++ = *src++;
*dest++ = *src++;
*dest++ = *src++;
}
// copy end
*dest++ = *src++;
osWritebackDCache(result->displayLists[imageIndex], size);
} else {
result->displayLists[imageIndex] = NULL;
}
imageMask >>= 1;
++imageIndex;
}
return result;
}
void prerenderedTextCleanup(struct PrerenderedText* prerender) {
int imageIndex = 0;
int imageMask = prerender->usedImageIndices;

View file

@ -75,6 +75,7 @@ struct PrerenderedText {
void fontRendererInitPrerender(struct FontRenderer* renderer, struct PrerenderedText* prerender);
struct PrerenderedText* prerenderedTextNew(struct FontRenderer* renderer);
struct PrerenderedText* prerenderedTextCopy(struct PrerenderedText* text);
void prerenderedTextCleanup(struct PrerenderedText* prerender);
void prerenderedTextFree(struct PrerenderedText* prerender);
void prerenderedTextRelocate(struct PrerenderedText* prerender, int x, int y);

View file

@ -5,10 +5,12 @@
#include "../controls/controller.h"
#include "../audio/soundplayer.h"
#include "../util/memory.h"
#include "./translations.h"
#include "../build/assets/materials/ui.h"
#include "../build/src/audio/clips.h"
#include "../build/src/audio/subtitles.h"
#define CONTROL_ROW_HEIGHT 14
@ -111,25 +113,25 @@ char gControllerActionToDirectionIcon[] = {
};
struct ControlActionDataRow {
char* name;
short nameId;
short headerId;
enum ControllerAction action;
char* header;
};
struct ControlActionDataRow gControllerDataRows[] = {
{"Move", ControllerActionMove, "Movement"},
{"Look", ControllerActionRotate, NULL},
{"Jump", ControllerActionJump, NULL},
{"Duck", ControllerActionDuck, NULL},
{VALVE_MOVE, VALVE_MOVEMENT_TITLE, ControllerActionMove},
{VALVE_LOOK, -1, ControllerActionRotate},
{VALVE_JUMP, -1, ControllerActionJump},
{VALVE_DUCK, -1, ControllerActionDuck},
{"Fire blue portal", ControllerActionOpenPortal0, "Combat"},
{"Fire red portal", ControllerActionOpenPortal1, NULL},
{"Use item", ControllerActionUseItem, NULL},
{VALVE_PRIMARY_ATTACK, VALVE_COMBAT_TITLE, ControllerActionOpenPortal0},
{VALVE_SECONDARY_ATTACK, -1, ControllerActionOpenPortal1},
{VALVE_USE_ITEMS, -1, ControllerActionUseItem},
{"Pause", ControllerActionPause, "Misc"},
{VALVE_PAUSE_GAME, -1, ControllerActionPause},
{"Look forward", ControllerActionLookForward, "Misc Movement"},
{"Look backward", ControllerActionLookBackward, NULL},
{VALVE_LOOK_STRAIGHT_AHEAD, VALVE_MISCELLANEOUS_KEYBOARD_KEYS_TITLE, ControllerActionLookForward},
{VALVE_LOOK_STRAIGHT_BACK, -1, ControllerActionLookBackward},
};
int controlsMeasureIcons(enum ControllerAction action) {
@ -192,14 +194,24 @@ Gfx* controlsRenderIcons(Gfx* dl, enum ControllerAction action, int x, int y) {
}
void controlsLayoutRow(struct ControlsMenuRow* row, struct ControlActionDataRow* data, int x, int y) {
fontRender(&gDejaVuSansFont, data->name, x + ROW_PADDING, y, row->actionText);
struct PrerenderedText* copy = prerenderedTextCopy(row->actionText);
menuFreePrerenderedDeferred(row->actionText);
row->actionText = copy;
prerenderedTextRelocate(row->actionText, x + ROW_PADDING, y);
Gfx* dl = controlsRenderIcons(row->sourceIcons, data->action, CONTROLS_X + CONTROLS_WIDTH - ROW_PADDING * 2, y);
gSPEndDisplayList(dl++);
row->y = y;
}
void controlsLayoutHeader(struct ControlsMenuHeader* header, int x, int y) {
struct PrerenderedText* copy = prerenderedTextCopy(header->headerText);
menuFreePrerenderedDeferred(header->headerText);
header->headerText = copy;
prerenderedTextRelocate(header->headerText, x, y);
}
void controlsInitRow(struct ControlsMenuRow* row, struct ControlActionDataRow* data) {
row->actionText = menuBuildText(&gDejaVuSansFont, data->name, 0, 0);
row->actionText = menuBuildPrerenderedText(&gDejaVuSansFont, translationsGet(data->nameId), 0, 0, SCREEN_WD);
Gfx* dl = row->sourceIcons;
for (int i = 0; i < SOURCE_ICON_COUNT; ++i) {
@ -207,12 +219,8 @@ void controlsInitRow(struct ControlsMenuRow* row, struct ControlActionDataRow* d
}
}
void controlsLayoutHeader(struct ControlsMenuHeader* header, char* message, int x, int y) {
header->headerText = menuBuildText(&gDejaVuSansFont, message, x + HEADER_PADDING, y);
}
void controlsInitHeader(struct ControlsMenuHeader* header, char* message) {
header->headerText = menuBuildText(&gDejaVuSansFont, message, 0, 0);
void controlsInitHeader(struct ControlsMenuHeader* header, int message) {
header->headerText = menuBuildPrerenderedText(&gDejaVuSansFont, translationsGet(message), 0, 0, SCREEN_WD);
}
void controlsLayout(struct ControlsMenu* controlsMenu) {
@ -222,9 +230,9 @@ void controlsLayout(struct ControlsMenu* controlsMenu) {
Gfx* headerSeparators = controlsMenu->headerSeparators;
for (int i = 0; i < ControllerActionCount; ++i) {
if (gControllerDataRows[i].header && currentHeader < MAX_CONTROLS_SECTIONS) {
if (gControllerDataRows[i].headerId != -1 && currentHeader < MAX_CONTROLS_SECTIONS) {
y += TOP_PADDING;
controlsLayoutHeader(&controlsMenu->headers[currentHeader], gControllerDataRows[i].header, CONTROLS_X, y);
controlsLayoutHeader(&controlsMenu->headers[currentHeader], CONTROLS_X + 2, y);
y += CONTROL_ROW_HEIGHT;
if (y > CONTROLS_Y + 1 && y < CONTROLS_Y + CONTROLS_HEIGHT - 1) {
@ -242,14 +250,14 @@ void controlsLayout(struct ControlsMenu* controlsMenu) {
gSPEndDisplayList(headerSeparators++);
}
void controlsMenuInit(struct ControlsMenu* controlsMenu) {
void controlsMenuInitText(struct ControlsMenu* controlsMenu) {
int currentHeader = 0;
for (int i = 0; i < ControllerActionCount; ++i) {
controlsInitRow(&controlsMenu->actionRows[i], &gControllerDataRows[i]);
if (gControllerDataRows[i].header && currentHeader < MAX_CONTROLS_SECTIONS) {
controlsInitHeader(&controlsMenu->headers[currentHeader], gControllerDataRows[i].header);
if (gControllerDataRows[i].headerId != -1 && currentHeader < MAX_CONTROLS_SECTIONS) {
controlsInitHeader(&controlsMenu->headers[currentHeader], gControllerDataRows[i].headerId);
++currentHeader;
}
}
@ -257,6 +265,10 @@ void controlsMenuInit(struct ControlsMenu* controlsMenu) {
for (; currentHeader < MAX_CONTROLS_SECTIONS; ++currentHeader) {
controlsMenu->headers[currentHeader].headerText = NULL;
}
}
void controlsMenuInit(struct ControlsMenu* controlsMenu) {
controlsMenuInitText(controlsMenu);
controlsMenu->selectedRow = 0;
controlsMenu->scrollOffset = 0;
@ -274,6 +286,19 @@ void controlsMenuInit(struct ControlsMenu* controlsMenu) {
controlsMenu->scrollOutline = menuBuildOutline(CONTROLS_X, CONTROLS_Y, CONTROLS_WIDTH, CONTROLS_HEIGHT, 1);
}
void controlsRebuildtext(struct ControlsMenu* controlsMenu) {
for (int i = 0; i < ControllerActionCount; ++i) {
prerenderedTextFree(controlsMenu->actionRows[i].actionText);
}
for (int i = 0; i < MAX_CONTROLS_SECTIONS; ++i) {
prerenderedTextFree(controlsMenu->headers[i].headerText);
}
controlsMenuInitText(controlsMenu);
controlsLayout(controlsMenu);
}
enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu) {
if (controlsMenu->waitingForAction != ControllerActionNone) {
struct ControllerSourceWithController source = controllerReadAnySource();
@ -315,7 +340,7 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu) {
int topY = selectedAction->y;
int bottomY = topY + CONTROL_ROW_HEIGHT + TOP_PADDING;
if (gControllerDataRows[controlsMenu->selectedRow].header) {
if (gControllerDataRows[controlsMenu->selectedRow].headerId != -1) {
topY -= CONTROL_ROW_HEIGHT + TOP_PADDING + SEPARATOR_SPACE;
}
@ -418,26 +443,20 @@ void controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* r
gDPSetEnvColor(renderState->dl++, gColorWhite.r, gColorWhite.g, gColorWhite.b, gColorWhite.a);
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, CONTROLS_X, CONTROLS_Y, CONTROLS_X + CONTROLS_WIDTH, CONTROLS_Y + CONTROLS_HEIGHT);
struct PrerenderedTextBatch* batch = prerenderedBatchStart();
for (int i = 0; i < ControllerActionCount; ++i) {
if (controlsMenu->selectedRow == i) {
gDPPipeSync(renderState->dl++);
gDPSetEnvColor(renderState->dl++, 0, 0, 0, 255);
}
renderStateInlineBranch(renderState, controlsMenu->actionRows[i].actionText);
if (controlsMenu->selectedRow == i) {
gDPPipeSync(renderState->dl++);
gDPSetEnvColor(renderState->dl++, 255, 255, 255, 255);
}
prerenderedBatchAdd(batch, controlsMenu->actionRows[i].actionText, controlsMenu->selectedRow == i ? &gColorBlack : &gColorWhite);
}
for (int i = 0; i < MAX_CONTROLS_SECTIONS; ++i) {
if (!controlsMenu->headers[i].headerText) {
break;
}
renderStateInlineBranch(renderState, controlsMenu->headers[i].headerText);
prerenderedBatchAdd(batch, controlsMenu->headers[i].headerText, &gColorWhite);
}
renderState->dl = prerenderedBatchFinish(batch, gDejaVuSansImages, renderState->dl);
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_0_INDEX]);
gSPDisplayList(renderState->dl++, ui_material_list[BUTTON_ICONS_INDEX]);

View file

@ -5,6 +5,7 @@
#include "../controls/controller_actions.h"
#include "../graphics/graphics.h"
#include "../scene/hud.h"
#include "../font/font.h"
#define MAX_SOURCES_PER_ACTION 4
#define MAX_CONTROLS_SECTIONS 4
@ -14,13 +15,13 @@
#define SOURCE_ICON_COUNT MAX_SOURCES_PER_ACTION * GFX_ENTRIES_PER_IMAGE + GFX_ENTRIES_PER_END_DL
struct ControlsMenuRow {
Gfx* actionText;
struct PrerenderedText* actionText;
Gfx sourceIcons[SOURCE_ICON_COUNT];
short y;
};
struct ControlsMenuHeader {
Gfx* headerText;
struct PrerenderedText* headerText;
};
struct ControlsMenu {
@ -39,6 +40,7 @@ struct ControlsMenu {
};
void controlsMenuInit(struct ControlsMenu* controlsMenu);
void controlsRebuildtext(struct ControlsMenu* controlsMenu);
enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu);
void controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* renderState, struct GraphicsTask* task);

View file

@ -296,7 +296,7 @@ Gfx* menuSliderRender(struct MenuSlider* slider, Gfx* dl) {
return dl;
}
#define MAX_DEFERRED_RELEASE_SIZE 16
#define MAX_DEFERRED_RELEASE_SIZE 20
#define RELEASE_DEFER_COUNT 2
#define NEXT_ENTRY(curr) ((curr) + 1 == MAX_DEFERRED_RELEASE_SIZE ? 0 : (curr) + 1)

View file

@ -59,6 +59,7 @@ void optionsMenuInit(struct OptionsMenu* options) {
}
void optionsMenuRebuildText(struct OptionsMenu* options) {
controlsRebuildtext(&options->controlsMenu);
audioOptionsRebuildtext(&options->audioOptions);
tabsRebuildText(&options->tabs);
}

View file

@ -27,6 +27,20 @@ hl_gameui_whitelist = {
portal_whitelist = {
"PORTAL_CHAPTER1_TITLE",
"VALVE_PRIMARY_ATTACK",
"VALVE_SECONDARY_ATTACK",
}
valve_whitelist = {
"VALVE_JUMP",
"VALVE_DUCK",
"VALVE_USE_ITEMS",
"VALVE_COMBAT_TITLE",
"VALVE_MOVEMENT_TITLE",
"VALVE_MISCELLANEOUS_TITLE",
"VALVE_PAUSE_GAME",
"VALVE_LOOK_STRAIGHT_AHEAD",
"VALVE_MISCELLANEOUS_KEYBOARD_KEYS_TITLE",
}
language_translations = {
@ -306,10 +320,13 @@ def process_all_closecaption_files(dir, language_names):
portal_k, portal_v, _ = read_translation_file(f"vpk/Portal/portal/resource/portal_{language_name}.txt")
portal_k, portal_v = filter_whitelist(portal_k, portal_v, portal_whitelist)
valve_k, valve_v, _ = read_translation_file(f"vpk/Portal/hl2/resource/valve_{language_name}.txt")
valve_k, valve_v = filter_whitelist(valve_k, valve_v, valve_whitelist)
extra_k, extra_v, _ = read_translation_file(f"assets/translations/extra_{language_name}.txt")
k = k + gamepad_k + portal_k + extra_k
v = v + gamepad_v + portal_v + extra_v
k = k + gamepad_k + portal_k + valve_k + extra_k
v = v + gamepad_v + portal_v + valve_v + extra_v
if not key_order:
header_lines = make_SubtitleKey_headerlines(k)