Skip to content

Commit

Permalink
tr1/gameflow: add support for item descriptions
Browse files Browse the repository at this point in the history
This adds the ability to define descriptions for key, puzzle and
pickups items in the gameflow. Players can examine items that have a
description in the inventory. Indicators are shown to make this clear,
the idea being builders may want to use this feature to offer hints.

Description text is automatically wrapped to fit the screen, and very
long text will be paginated. New line and feed escape sequences are
supported in the text for manual layout.

This also removes the necessesity of having an empty strings object in
levels that don't have any key items.

Additionally, the update_gameflow tool has been adjusted to support the
use of curly braces inside strings (and indeed nested objects).

Resolves #1821.
  • Loading branch information
lahm86 committed Nov 11, 2024
1 parent d8f2a09 commit 33e4e9b
Show file tree
Hide file tree
Showing 33 changed files with 641 additions and 49 deletions.
14 changes: 3 additions & 11 deletions data/tr1/ship/cfg/TR1X_gameflow.json5
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
{"type": "level_stats", "level_id": 0},
{"type": "exit_to_title"},
],
"strings": {},
},

// Level 1
Expand All @@ -70,7 +69,6 @@
{"type": "level_stats", "level_id": 1},
{"type": "exit_to_level", "level_id": 2},
],
"strings": {},
},

// Level 2
Expand Down Expand Up @@ -143,7 +141,6 @@
{"type": "stop_game"},
{"type": "exit_to_cine", "level_id": 16},
],
"strings": {},
},

// Level 5
Expand Down Expand Up @@ -418,7 +415,6 @@
{"type": "play_fmv", "fmv_path": "fmv/prison.avi"},
{"type": "exit_to_cine", "level_id": 19},
],
"strings": {},
"unobtainable_pickups": 3,
},

Expand Down Expand Up @@ -448,7 +444,6 @@
{"type": "total_stats", "picture_path": "data/images/install.webp"},
{"type": "exit_to_title"},
],
"strings": {},
},

// Level 16
Expand All @@ -474,7 +469,6 @@
{"type": "level_stats", "level_id": 4},
{"type": "exit_to_level", "level_id": 5},
],
"strings": {},
},

// Level 17
Expand Down Expand Up @@ -502,7 +496,6 @@
{"type": "level_stats", "level_id": 9},
{"type": "exit_to_level", "level_id": 10},
],
"strings": {},
},

// Level 18
Expand All @@ -524,7 +517,6 @@
{"type": "loop_cine"},
{"type": "exit_to_level", "level_id": 14},
],
"strings": {},
},

// Level 19
Expand Down Expand Up @@ -553,7 +545,6 @@
{"type": "level_stats", "level_id": 14},
{"type": "exit_to_level", "level_id": 15},
],
"strings": {},
},

// Level 20
Expand All @@ -573,7 +564,6 @@
{"type": "play_fmv", "fmv_path": "fmv/cafe.avi"},
{"type": "exit_to_title"},
],
"strings": {},
},

// Level 21
Expand All @@ -586,7 +576,6 @@
"sequence": [
{"type": "exit_to_title"},
],
"strings": {},
},
],

Expand Down Expand Up @@ -656,6 +645,8 @@
"INV_ITEM_SOUND": "Sound",
"INV_ITEM_UZI": "Uzis",
"INV_ITEM_UZI_AMMO": "Uzi Clips",
"ITEM_EXAMINE_ROLE": "\\{button empty} %s: Examine",
"ITEM_USE_ROLE": "\\{button empty} %s: Use",
"KEYMAP_ACTION": "Action",
"KEYMAP_BACK": "Back",
"KEYMAP_BILINEAR": "Toggle Texture Filter",
Expand Down Expand Up @@ -766,6 +757,7 @@
"OSD_UI_OFF": "UI disabled",
"OSD_UI_ON": "UI enabled",
"OSD_UNKNOWN_COMMAND": "Unknown command: %s",
"PAGINATION_NAV": "%d / %d",
"PASSPORT_EXIT_GAME": "Exit Game",
"PASSPORT_EXIT_TO_TITLE": "Exit to Title",
"PASSPORT_LEGACY_SELECT_LEVEL_1": "Legacy saves do not",
Expand Down
5 changes: 3 additions & 2 deletions data/tr1/ship/cfg/TR1X_gameflow_demo_pc.json5
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
"sequence": [
{"type": "exit_to_title"},
],
"strings": {},
},

// Level 4
Expand All @@ -75,7 +74,6 @@
"sequence": [
{"type": "exit_to_title"},
],
"strings": {},
},
],

Expand Down Expand Up @@ -145,6 +143,8 @@
"INV_ITEM_SOUND": "Sound",
"INV_ITEM_UZI": "Uzis",
"INV_ITEM_UZI_AMMO": "Uzi Clips",
"ITEM_EXAMINE_ROLE": "\\{button empty} %s: Examine",
"ITEM_USE_ROLE": "\\{button empty} %s: Use",
"KEYMAP_ACTION": "Action",
"KEYMAP_BACK": "Back",
"KEYMAP_BILINEAR": "Toggle Texture Filter",
Expand Down Expand Up @@ -255,6 +255,7 @@
"OSD_UI_OFF": "UI disabled",
"OSD_UI_ON": "UI enabled",
"OSD_UNKNOWN_COMMAND": "Unknown command: %s",
"PAGINATION_NAV": "%d / %d",
"PASSPORT_EXIT_GAME": "Exit Game",
"PASSPORT_EXIT_TO_TITLE": "Exit to Title",
"PASSPORT_LEGACY_SELECT_LEVEL_1": "Legacy saves do not",
Expand Down
7 changes: 3 additions & 4 deletions data/tr1/ship/cfg/TR1X_gameflow_ub.json5
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
{"type": "level_stats", "level_id": 2},
{"type": "exit_to_level", "level_id": 3},
],
"strings": {},
"unobtainable_kills": 1,
},

Expand Down Expand Up @@ -116,7 +115,6 @@
{"type": "total_stats", "picture_path": "data/images/install.webp"},
{"type": "exit_to_title"},
],
"strings": {},
},

// Level 4
Expand All @@ -135,7 +133,6 @@
{"type": "play_fmv", "fmv_path": "fmv/escape.avi"},
{"type": "exit_to_title"},
],
"strings": {},
},

// Level 5
Expand All @@ -151,7 +148,6 @@
"music": 0,
"inherit_injections": false,
"sequence": [{"type": "exit_to_title"}],
"strings": {},
},
],

Expand Down Expand Up @@ -221,6 +217,8 @@
"INV_ITEM_SOUND": "Sound",
"INV_ITEM_UZI": "Uzis",
"INV_ITEM_UZI_AMMO": "Uzi Clips",
"ITEM_EXAMINE_ROLE": "\\{button empty} %s: Examine",
"ITEM_USE_ROLE": "\\{button empty} %s: Use",
"KEYMAP_ACTION": "Action",
"KEYMAP_BACK": "Back",
"KEYMAP_BILINEAR": "Toggle Texture Filter",
Expand Down Expand Up @@ -331,6 +329,7 @@
"OSD_UI_OFF": "UI disabled",
"OSD_UI_ON": "UI enabled",
"OSD_UNKNOWN_COMMAND": "Unknown command: %s",
"PAGINATION_NAV": "%d / %d",
"PASSPORT_EXIT_GAME": "Exit Game",
"PASSPORT_EXIT_TO_TITLE": "Exit to Title",
"PASSPORT_LEGACY_SELECT_LEVEL_1": "Legacy saves do not",
Expand Down
1 change: 1 addition & 0 deletions docs/tr1/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- added an option to enable responsive swim cancellation, similar to TR2+ (#1004)
- added a special target, "pickup", to item-based console commands
- added support for custom levels to enforce values for any config setting (#1846)
- added support for key/puzzle/pickup descriptions, allowing players to examine said items in the inventory (#1821)
- changed OpenGL backend to use version 3.3, with fallback to 2.1 if initialization fails (#1738)
- changed text backend to accept named sequences. Currently supported sequences (limited by the sprites available in OG):
- `\{umlaut}`
Expand Down
27 changes: 24 additions & 3 deletions docs/tr1/GAMEFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ Following are each of the properties available within a level.
"puzzle2": "Machine Cog",
// etc
},
"examine": {
"key1": "This shows when the player examines key1 in the inventory.",
"puzzle2": "You can use \n to make new lines and \f to make new pages.",
// etc
},
},
```
</details>
Expand Down Expand Up @@ -295,6 +300,21 @@ Following are each of the properties available within a level.
for details.
</td>
</tr>
<tr valign="top">
<td>
<code>examine</code>
</td>
<td>String-to-string map</td>
<td>No</td>
<td colspan="2">
Allows longer text descriptions to be defined for key and puzzle items,
over and above the names defined in <code>strings</code> (see below).
Players can examine items in the inventory when this text has been
defined. Use <code>\n</code> in the text to create new lines; you can also
use <code>\f</code> to force a page break. Long text will be automatically
wrapped and paginated as necessary.
</td>
</tr>
<tr valign="top">
<td>
<code>file</code>
Expand Down Expand Up @@ -372,10 +392,11 @@ Following are each of the properties available within a level.
<code>strings</code>
</td>
<td rowspan="12">String-to-string map</td>
<td rowspan="12">Yes</td>
<td rowspan="12">No</td>
<td colspan="2">
Key and puzzle item names. The possible types are as follows. An empty map
is permitted.
Key and puzzle item names. The possible types are as follows. If this map
is missing, or is missing an item's name, the game will use a suitable
default value.
</td>
</tr>
<tr valign="top">
Expand Down
17 changes: 17 additions & 0 deletions src/libtrx/game/objects/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

typedef struct {
char *name;
char *description;
} M_NAME_ENTRY;

static M_NAME_ENTRY m_NamesTable[O_NUMBER_OF] = { 0 };
Expand All @@ -21,6 +22,7 @@ static void M_ClearNames(void)
for (GAME_OBJECT_ID object_id = 0; object_id < O_NUMBER_OF; object_id++) {
M_NAME_ENTRY *const entry = &m_NamesTable[object_id];
Memory_FreePointer(&entry->name);
Memory_FreePointer(&entry->description);
}
}

Expand All @@ -32,12 +34,27 @@ void Object_SetName(const GAME_OBJECT_ID object_id, const char *const name)
entry->name = Memory_DupStr(name);
}

void Object_SetDescription(
const GAME_OBJECT_ID object_id, const char *const description)
{
M_NAME_ENTRY *const entry = &m_NamesTable[object_id];
Memory_FreePointer(&entry->description);
assert(description != NULL);
entry->description = Memory_DupStr(description);
}

const char *Object_GetName(const GAME_OBJECT_ID object_id)
{
M_NAME_ENTRY *const entry = &m_NamesTable[object_id];
return entry != NULL ? entry->name : NULL;
}

const char *Object_GetDescription(GAME_OBJECT_ID object_id)
{
M_NAME_ENTRY *const entry = &m_NamesTable[object_id];
return entry != NULL ? entry->description : NULL;
}

void Object_ResetNames(void)
{
M_ClearNames();
Expand Down
11 changes: 9 additions & 2 deletions src/libtrx/game/text.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "game/text.h"

#include "memory.h"
#include "utils.h"

#include <assert.h>
#include <string.h>
Expand Down Expand Up @@ -278,20 +279,26 @@ int32_t Text_GetWidth(const TEXTSTRING *const text)
return 0;
}

int32_t width = 0;
const GLYPH_INFO **glyph_ptr = text->glyphs;
if (text->glyphs == NULL) {
return 0;
}

int32_t width = 0;
int32_t max_width = 0;
const GLYPH_INFO **glyph_ptr = text->glyphs;
while (*glyph_ptr != NULL) {
if ((*glyph_ptr)->role == GLYPH_SPACE) {
width += text->word_spacing;
} else if ((*glyph_ptr)->role == GLYPH_NEWLINE) {
max_width = MAX(max_width, width);
width = 0;
} else {
width += (*glyph_ptr)->width + text->letter_spacing;
}
glyph_ptr++;
}

width = MAX(max_width, width);
width -= text->letter_spacing;
return width * text->scale.h / TEXT_BASE_SCALE;
}
Expand Down
12 changes: 12 additions & 0 deletions src/libtrx/game/ui/widgets/label.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ void UI_Label_SetSize(
self->height = height;
}

void UI_Label_SetVisible(UI_WIDGET *const widget, const bool visible)
{
UI_LABEL *const self = (UI_LABEL *)widget;
Text_Hide(self->text, !visible);
}

void UI_Label_AddFrame(UI_WIDGET *const widget)
{
UI_LABEL *const self = (UI_LABEL *)widget;
Expand Down Expand Up @@ -141,3 +147,9 @@ int32_t UI_Label_MeasureTextWidth(UI_WIDGET *const widget)
UI_LABEL *const self = (UI_LABEL *)widget;
return Text_GetWidth(self->text);
}

int32_t UI_Label_MeasureTextHeight(UI_WIDGET *const widget)
{
UI_LABEL *const self = (UI_LABEL *)widget;
return Text_GetHeight(self->text);
}
2 changes: 2 additions & 0 deletions src/libtrx/include/libtrx/game/objects/names.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
#include <stdint.h>

const char *Object_GetName(GAME_OBJECT_ID object_id);
const char *Object_GetDescription(GAME_OBJECT_ID object_id);

void Object_ResetNames(void);

void Object_SetName(GAME_OBJECT_ID object_id, const char *name);
void Object_SetDescription(GAME_OBJECT_ID object_id, const char *description);

// Return a list of object ids that match given string.
// out_match_count may be NULL.
Expand Down
2 changes: 2 additions & 0 deletions src/libtrx/include/libtrx/game/ui/widgets/label.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ extern UI_WIDGET *UI_Label_Create(
extern void UI_Label_ChangeText(UI_WIDGET *widget, const char *text);
extern const char *UI_Label_GetText(UI_WIDGET *widget);
extern void UI_Label_SetSize(UI_WIDGET *widget, int32_t width, int32_t height);
extern void UI_Label_SetVisible(UI_WIDGET *widget, bool visible);

extern void UI_Label_AddFrame(UI_WIDGET *widget);
extern void UI_Label_RemoveFrame(UI_WIDGET *widget);
extern void UI_Label_Flash(UI_WIDGET *widget, bool enable, int32_t rate);
extern void UI_Label_SetScale(UI_WIDGET *widget, float scale);
extern void UI_Label_SetZIndex(UI_WIDGET *widget, int32_t z_index);
extern int32_t UI_Label_MeasureTextWidth(UI_WIDGET *widget);
extern int32_t UI_Label_MeasureTextHeight(UI_WIDGET *widget);
5 changes: 5 additions & 0 deletions src/libtrx/include/libtrx/strings/common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "../vector.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Expand All @@ -15,4 +17,7 @@ bool String_ParseBool(const char *value, bool *target);
bool String_ParseInteger(const char *value, int32_t *target);
bool String_ParseDecimal(const char *value, float *target);

char *String_ToUpper(const char *text);

char *String_WordWrap(const char *text, size_t line_length);
VECTOR *String_Paginate(const char *text, int32_t max_lines);
Loading

0 comments on commit 33e4e9b

Please sign in to comment.