mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
translate controls menu
This commit is contained in:
parent
44ab1ddfcd
commit
9d07965582
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ void optionsMenuInit(struct OptionsMenu* options) {
|
|||
}
|
||||
|
||||
void optionsMenuRebuildText(struct OptionsMenu* options) {
|
||||
controlsRebuildtext(&options->controlsMenu);
|
||||
audioOptionsRebuildtext(&options->audioOptions);
|
||||
tabsRebuildText(&options->tabs);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue