options UI: settle file terminology on the end-user term 'Profile' (D359)

'Game file' (the manual's term) reads, in modern PC usage, as the
program's own files, not the user's save. 'Profile' is the clearest
end-user term for what these files actually are -- a per-player
bundle of progress + per-file settings -- and '(per profile)'
expresses the tag's scope where '(save)' read as a verb.

Strings (both UIs: front options + F10 overlay):
- front top row: 'Save file' / 'File N'  ->  'Profile' / 'N'
- section annotation: '(File N)' / '(no file)'  ->  '(Profile N)' / '(none)'
- per-file row tag: '(game file)'  ->  '(per profile)'
- F10 unavailable value: 'Select game file'  ->  'Select a profile'

Display layer only: identifiers and ini keys (Bond.* rows,
watchSettings*, ini) are untouched. D357 plan section 4 is the
terminology record; new D359 finding + index row; manual
'game file' -> 'profile' sync noted as a TODO (port-owned doc,
not in this repo). Build + headless smoke clean.
This commit is contained in:
James Dansereau committed 2026-09-27 15:03:24 -04:00
1 parent 44d2b4353a
commit d8971fded0
5 files changed
+85 -44

No files matched your search

+14 -12
View File
@@ -495,16 +495,17 @@ Gfx *frontOptionsMenuDraw(Gfx *DL)
if (optionsRowIsSaveScoped(s_pageHdr[s_page])) {
int f = watchSettingsActiveFolder();
char note[16];
if (f < 0) snprintf(note, sizeof(note), "(no file)");
else snprintf(note, sizeof(note), "(File %d)", f + 1);
if (f < 0) snprintf(note, sizeof(note), "(none)");
else snprintf(note, sizeof(note), "(Profile %d)", f + 1);
DL = ink(DL, ROW_X + titleW + 8, TITLE_Y, note, INK_DIM);
}
/* D356: the top game-file row (item 0, not in the row table; the
* label reads "Game file", the instruction manual's term): the
* single file control of the front screen (F10 always targets the
* active file, so it has no file row). L/R (and A) cycle folders;
* (no file) is the unavailable state until one is created. */
/* D356: the top profile row (item 0, not in the row table; the label
* reads "Profile" -- the end-user term for a per-player game file,
* see D357 plan section 4): the single file control of the front
* screen (F10 always targets the active file, so it has no file
* row). L/R (and A) cycle folders; (none) is the unavailable state
* until one is created. */
{
int y = rowY(0);
char sv[32];
@@ -512,10 +513,10 @@ Gfx *frontOptionsMenuDraw(Gfx *DL)
DL = microcode_constructor_related_to_menus(DL, ROW_X - 2, y - 1,
ROW_X + 140, y + 0xE, HILITE);
}
DL = ink(DL, ROW_X, y, "Game file\n", INK);
DL = ink(DL, ROW_X, y, "Profile\n", INK);
int f = watchSettingsActiveFolder();
if (f < 0) snprintf(sv, sizeof(sv), "(no file)");
else snprintf(sv, sizeof(sv), "File %d\n", f + 1);
if (f < 0) snprintf(sv, sizeof(sv), "(none)");
else snprintf(sv, sizeof(sv), "%d\n", f + 1);
DL = inkR(DL, VAL_R, y, sv, INK);
}
@@ -534,9 +535,10 @@ Gfx *frontOptionsMenuDraw(Gfx *DL)
DL = ink(DL, ROW_X, y, label, INK);
/* D357: per-file rows in the mixed-scope section carry a dim
* "(game file)" tag (the section title already says which file). */
* "(per profile)" tag -- "stored separately in each profile";
* the section title says which one is active. */
if (optionsRowIsSaveScoped(i)) {
DL = ink(DL, ROW_X + measureW(label) + 4, y, "(game file)\n", INK_DIM);
DL = ink(DL, ROW_X + measureW(label) + 4, y, "(per profile)\n", INK_DIM);
}
if (optionsRowIsSlider(i)) {
+12 -11
View File
@@ -146,7 +146,7 @@ struct Row {
int dispDiv;
/* D356: 1 = this row's value lives in the selected save file (per-file
* watch rows). Carries the dim "(game file)" tag on the only section that
* watch rows). Carries the dim "(per profile)" tag on the only section that
* mixes scopes (GAMEPLAY); on headers the flag is recomputed at init to
* mean "this section contains per-file rows" (drives the "(File N)"
* title annotation in both UIs). */
@@ -158,7 +158,7 @@ static struct Row rows[] = {
* GAMEPLAY, GRAPHICS, AUDIO, VIDEO; docs/dev/D356-SETTINGS-REGROUP-PLAN.md).
* The D353 "BOND FILE" section -- the one named after WHERE a value is
* saved -- is gone: its surviving rows split into GAMEPLAY (the per-file
* watch toggles, dim "(game file)" tagged since the section mixes scopes) and
* watch toggles, dim "(per profile)" tagged since the section mixes scopes) and
* AUDIO (the per-file volume sliders, homogeneous so title annotation
* only), and the "Edit file" chooser row is retired in favour of the
* single top save-file row on the front options screen (frontoptions.c).
@@ -198,7 +198,7 @@ static struct Row rows[] = {
* Bond.AimControl collides with Input.AimMode (two rows fighting over
* the same N64-vs-PC aim model).
* The four surviving per-file toggles move here from the D353 BOND FILE
* section and carry .saveScoped (dim "(game file)" tag, the only mixed-scope
* section and carry .saveScoped (dim "(per profile)" tag, the only mixed-scope
* section). */
/* { .key="Bond.Look", .label="Look up/down (watch; stacks)", .kind=ROW_TOGGLE,
.names=kReverse, .found=1, .uiMax=1, .cfgMax=1 }, */
@@ -1231,12 +1231,12 @@ static void valueText(int i, char *out, int n)
double v = rowGet(r);
if (r->kind == ROW_BOND_FILE) {
int f = watchSettingsFolder();
if (f < 0) snprintf(out, n, "Select game file");
else snprintf(out, n, "File %d", f + 1);
if (f < 0) snprintf(out, n, "Select a profile");
else snprintf(out, n, "%d", f + 1);
return;
}
if (watchSettingsFieldForKey(r->key) >= 0 && !watchSettingsAvailable()) {
snprintf(out, n, "Select game file");
snprintf(out, n, "Select a profile");
return;
}
if (r->kind == ROW_RES) {
@@ -1428,8 +1428,8 @@ Gfx *optionsOverlayEmit(void)
if (r->saveScoped) {
int f = watchSettingsActiveFolder();
char note[16];
if (f < 0) snprintf(note, sizeof(note), "(no file)");
else snprintf(note, sizeof(note), "(File %d)", f + 1);
if (f < 0) snprintf(note, sizeof(note), "(none)");
else snprintf(note, sizeof(note), "(Profile %d)", f + 1);
gdl = drawText(gdl, OV_X0 + measureText(r->label) + 6, rowY, note, 0x909090ff);
}
continue;
@@ -1437,10 +1437,11 @@ Gfx *optionsOverlayEmit(void)
gdl = drawText(gdl, OV_LABEL_X, rowY, (char *)r->label,
r->found ? col : 0x808080ff);
/* D357: per-file rows in the mixed-scope section carry a dim
* "(game file)" tag (the section title already says which file). */
* "(per profile)" tag -- "stored separately in each profile";
* the section title says which one is active. */
if (r->saveScoped && r->kind != ROW_HEADER) {
gdl = drawText(gdl, OV_LABEL_X + measureText(r->label) + 5, rowY,
"(game file)", 0x909090ff);
"(per profile)", 0x909090ff);
}
if (!r->found) {
gdl = drawTextR(gdl, right, rowY, "(n/a)", 0x808080ff);
@@ -1520,7 +1521,7 @@ int optionsRowIsBondChooser(int i)
/* D356: content rows carry the literal per-file flag from the table; header
* rows were recomputed at init to "this section contains per-file rows".
* Both drive UI decoration (the "(game file)" tag, the "(File N)" annotation).
* Both drive UI decoration (the "(per profile)" tag, the "(Profile N)" annotation).
* The F10 overlay and the front options screen are the only consumers. */
int optionsRowIsSaveScoped(int i)
{