data: add high quality loading screens and images (#1176)

Resolves #358.

Co-authored-by: Marcin Kurczewski <dash@wind.garden>
Co-authored-by: Alberto Tudela <ajtudela@gmail.com>
This commit is contained in:
walkawayy 2024-03-22 11:11:57 -04:00 committed by GitHub
parent 4de8c65c0d
commit 169bfeace1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 176 additions and 18 deletions

View file

@ -3,6 +3,8 @@
- added three targeting lock options: full lock always keeps target lock (OG), semi lock loses target lock if the enemy dies, and no lock loses target lock if the enemey goes out of sight or dies (TR4+) (#1146)
- added an option to the installer to install from a CD drive (#1144)
- added stack traces to logs for better crash debugging (#1165)
- added an option to use PS1 loading screens (#358)
- added high quality images for the Eidos, Unfinished Business title, Unfinished Business credit, and final statistics screens
- changed the way music timestamps are internally handled resets music position in existing saves
- fixed a missing translation for the Spanish config tool for the Eidos logo skip option (#1151)

View file

@ -582,6 +582,24 @@ default gameflow for examples.
</td>
<td>Double</td>
</tr>
<tr valign="top">
<td rowspan="2">
<code>loading_screen</code>
</td>
<td>
<code>picture_path</code>
</td>
<td>String</td>
<td rowspan="2">
Displays the specified picture for the given number of seconds. Functions identically to display_picture except these pictures can be enabled/disabled by the user with the loading screen option in the config tool.
</td>
</tr>
<tr valign="top">
<td>
<code>display_time</code>
</td>
<td>Double</td>
</tr>
<tr valign="top">
<td>
<code>exit_to_cine</code>

View file

@ -234,6 +234,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- added enemy health bars
- added PS1 style UI
- added fade effects to displayed images
- added an option to use PS1 loading screens
- improved support for windowed mode
#### Gameplay
@ -483,4 +484,5 @@ This project is licensed under the GNU General Public License - see the
(c) 2021 Marcin Kurczewski. All rights reserved. Original game is created by
Core Design Ltd. in 1996. Lara Croft and Tomb Raider are trademarks of Square
Enix Ltd. Title image by Kidd Bowyer.
Enix Ltd. Title image by Kidd Bowyer. Loading screens and high quality images
by goblan_oldnewpixel and Posix.

View file

@ -4,7 +4,7 @@
// Refer to https://github.com/LostArtefacts/TR1X/blob/stable/GAMEFLOW.md
// for usage.
"main_menu_picture": "data/titleh.png",
"main_menu_picture": "data/images/title.webp",
"savegame_fmt_legacy": "saveati.%d",
"savegame_fmt_bson": "save_tr1_%02d.dat",
"force_game_modes": null,
@ -40,6 +40,7 @@
],
"sequence": [
{"type": "play_fmv", "fmv_path": "fmv/mansion.avi"},
{"type": "loading_screen", "picture_path": "data/images/gym.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -62,6 +63,7 @@
],
"sequence": [
{"type": "play_fmv", "fmv_path": "fmv/snow.avi"},
{"type": "loading_screen", "picture_path": "data/images/peru.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -82,6 +84,7 @@
"data/vilcabamba_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/peru.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -106,6 +109,7 @@
"data/valley_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/peru.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -131,6 +135,7 @@
"data/qualopec_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/peru.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -152,6 +157,7 @@
],
"sequence": [
{"type": "play_fmv", "fmv_path": "fmv/lift.avi"},
{"type": "loading_screen", "picture_path": "data/images/greece.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -178,6 +184,7 @@
"data/colosseum_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/greece.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -200,6 +207,7 @@
"data/midas_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/greece.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -224,6 +232,7 @@
"data/cistern_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/greece.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -252,6 +261,7 @@
{"enemy_num": 82, "object_ids": [86, 144, 129]},
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/greece.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -277,6 +287,7 @@
],
"sequence": [
{"type": "play_fmv", "fmv_path": "fmv/vision.avi"},
{"type": "loading_screen", "picture_path": "data/images/egypt.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -299,6 +310,7 @@
"data/obelisk_itemrots.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/egypt.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -326,6 +338,7 @@
"data/sanctuary_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/egypt.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
@ -360,6 +373,7 @@
],
"sequence": [
{"type": "play_fmv", "fmv_path": "fmv/canyon.avi"},
{"type": "loading_screen", "picture_path": "data/images/atlantis.webp", "display_time": 5},
{"type": "remove_guns"},
{"type": "remove_scions"},
{"type": "start_game"},
@ -386,6 +400,7 @@
],
"sequence": [
{"type": "play_fmv", "fmv_path": "fmv/pyramid.avi"},
{"type": "loading_screen", "picture_path": "data/images/atlantis.webp", "display_time": 5},
{"type": "start_game"},
{"type": "give_item", "object_id": 84, "quantity": 1},
{"type": "setup_bacon_lara", "anchor_room": 10},
@ -409,17 +424,18 @@
"data/pyramid_textures.bin",
],
"sequence": [
{"type": "loading_screen", "picture_path": "data/images/atlantis.webp", "display_time": 5},
{"type": "start_game"},
{"type": "loop_game"},
{"type": "stop_game"},
{"type": "level_stats", "level_id": 15},
{"type": "play_fmv", "fmv_path": "fmv/end.avi"},
{"type": "play_synced_audio", "audio_id": 19},
{"type": "display_picture", "picture_path": "data/end.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred1.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred2.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred3.pcx", "display_time": 7.5},
{"type": "total_stats", "picture_path": "data/install.pcx"},
{"type": "display_picture", "picture_path": "data/images/end.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_1.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_2.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_3.webp", "display_time": 7.5},
{"type": "total_stats", "picture_path": "data/images/install.webp"},
{"type": "exit_to_title"},
],
"strings": {},
@ -531,7 +547,7 @@
"music": 2,
"inherit_injections": false,
"sequence": [
{"type": "display_picture", "picture_path": "data/eidospc.png", "display_time": 1},
{"type": "display_picture", "picture_path": "data/images/eidos.webp", "display_time": 1},
{"type": "play_fmv", "fmv_path": "fmv/core.avi"},
{"type": "play_fmv", "fmv_path": "fmv/escape.avi"},
{"type": "play_fmv", "fmv_path": "fmv/cafe.avi"},

View file

@ -4,7 +4,7 @@
// Refer to https://github.com/LostArtefacts/TR1X/blob/stable/GAMEFLOW.md
// for usage.
"main_menu_picture": "data/titleh_ub.png",
"main_menu_picture": "data/images/title_ub.webp",
"savegame_fmt_legacy": "saveuba.%d",
"savegame_fmt_bson": "save_trub_%02d.dat",
"force_game_modes": null,
@ -105,12 +105,12 @@
{"type": "stop_game"},
{"type": "level_stats", "level_id": 3},
{"type": "play_synced_audio", "audio_id": 19},
{"type": "display_picture", "picture_path": "data/end.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred0.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred1.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred2.pcx", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/cred3.pcx", "display_time": 7.5},
{"type": "total_stats", "picture_path": "data/install.pcx"},
{"type": "display_picture", "picture_path": "data/images/end.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_ub.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_1.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_2.webp", "display_time": 7.5},
{"type": "display_picture", "picture_path": "data/images/credits_3.webp", "display_time": 7.5},
{"type": "total_stats", "picture_path": "data/images/install.webp"},
{"type": "exit_to_title"},
],
"strings": {},
@ -124,7 +124,7 @@
"music": 2,
"inherit_injections": false,
"sequence": [
{"type": "display_picture", "picture_path": "data/eidospc.png", "display_time": 1},
{"type": "display_picture", "picture_path": "data/images/eidos.webp", "display_time": 1},
{"type": "play_fmv", "fmv_path": "fmv/core.avi"},
{"type": "play_fmv", "fmv_path": "fmv/escape.avi"},
{"type": "exit_to_title"},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 KiB

BIN
bin/data/images/egypt.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

BIN
bin/data/images/eidos.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
bin/data/images/end.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
bin/data/images/greece.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

BIN
bin/data/images/gym.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

BIN
bin/data/images/peru.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 KiB

BIN
bin/data/images/title.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 KiB

View file

@ -135,6 +135,7 @@ typedef struct {
bool enable_lean_jumping;
bool enable_target_change;
TARGET_LOCK_MODE target_mode;
bool enable_loading_screens;
struct {
int32_t layout;

View file

@ -96,6 +96,7 @@ const CONFIG_OPTION g_ConfigOptionMap[] = {
{ .name = "enable_demo", .type = COT_BOOL, .target = &g_Config.enable_demo, .default_value = &(bool){true}, 0},
{ .name = "enable_fmv", .type = COT_BOOL, .target = &g_Config.enable_fmv, .default_value = &(bool){true}, 0},
{ .name = "enable_eidos_logo", .type = COT_BOOL, .target = &g_Config.enable_eidos_logo, .default_value = &(bool){true}, 0},
{ .name = "enable_loading_screens", .type = COT_BOOL, .target = &g_Config.enable_loading_screens, .default_value = &(bool){false}, 0},
{ .name = "enable_cine", .type = COT_BOOL, .target = &g_Config.enable_cine, .default_value = &(bool){true}, 0},
{ .name = "enable_music_in_menu", .type = COT_BOOL, .target = &g_Config.enable_music_in_menu, .default_value = &(bool){true}, 0},
{ .name = "enable_music_in_inventory", .type = COT_BOOL, .target = &g_Config.enable_music_in_inventory, .default_value = &(bool){true}, 0},

View file

@ -426,8 +426,14 @@ static bool GameFlow_LoadLevelSequence(
}
seq->data = Memory_DupStr(tmp_s);
} else if (!strcmp(type_str, "display_picture")) {
seq->type = GFS_DISPLAY_PICTURE;
} else if (
!strcmp(type_str, "display_picture")
|| !strcmp(type_str, "loading_screen")) {
if (!strcmp(type_str, "loading_screen")) {
seq->type = GFS_LOADING_SCREEN;
} else {
seq->type = GFS_DISPLAY_PICTURE;
}
GAMEFLOW_DISPLAY_PICTURE_DATA *data =
Memory_Alloc(sizeof(GAMEFLOW_DISPLAY_PICTURE_DATA));
@ -1113,6 +1119,7 @@ void GameFlow_Shutdown(void)
if (seq) {
while (seq->type != GFS_END) {
switch (seq->type) {
case GFS_LOADING_SCREEN:
case GFS_DISPLAY_PICTURE:
case GFS_TOTAL_STATS: {
GAMEFLOW_DISPLAY_PICTURE_DATA *data = seq->data;
@ -1326,7 +1333,13 @@ GameFlow_InterpretSequence(int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type)
}
break;
case GFS_LOADING_SCREEN:
case GFS_DISPLAY_PICTURE:
if (seq->type == GFS_LOADING_SCREEN
&& !g_Config.enable_loading_screens) {
break;
}
if (level_type == GFL_SAVED) {
break;
}
@ -1482,6 +1495,7 @@ GameFlow_StorySoFar(int32_t level_num, int32_t savegame_level)
case GFS_STOP_GAME:
case GFS_LEVEL_STATS:
case GFS_TOTAL_STATS:
case GFS_LOADING_SCREEN:
case GFS_DISPLAY_PICTURE:
case GFS_GIVE_ITEM:
case GFS_REMOVE_GUNS:

View file

@ -987,6 +987,7 @@ typedef enum GAMEFLOW_SEQUENCE_TYPE {
GFS_PLAY_FMV,
GFS_LEVEL_STATS,
GFS_TOTAL_STATS,
GFS_LOADING_SCREEN,
GFS_DISPLAY_PICTURE,
GFS_EXIT_TO_TITLE,
GFS_EXIT_TO_LEVEL,

View file

@ -248,6 +248,10 @@
"Title": "Enable EIDOS logo",
"Description": "Enables EIDOS logo at the game start."
},
"enable_loading_screens": {
"Title": "Enable loading screens",
"Description": "Enables PS1 style loading screens before each level."
},
"enable_buffering": {
"Title": "Enable buffering",
"Description": "Enables F-key (1-frame) and inventory (2-frame) buffering to achieve precise control of Lara's movement."

View file

@ -196,6 +196,10 @@
"Title": "Habilitar el logo de EIDOS",
"Description": "Habilita el logo de EIDOS al comienzo del juego."
},
"enable_loading_screens": {
"Title": "Habilitar pantallas de carga",
"Description": "Habilita las pantallas de carga con el estilo de PS1 antes de cada nivel."
},
"enable_jump_twists": {
"Title": "Giros al saltar",
"Description": "Habilita giros y saltos mortales al estilo TR2+, es decir, presiona rodar durante las animaciones de salto y salto del cisne."

View file

@ -248,6 +248,10 @@
"Title": "Activer le logo EIDOS",
"Description": "Active le logo EIDOS au début du jeu."
},
"enable_loading_screens": {
"Title": "Activer les écrans de chargement",
"Description": "Active les écrans de chargements avant chaque début des niveaux, comme sur PlayStation 1."
},
"enable_buffering": {
"Title": "Activer la mise en mémoire tampon",
"Description": "Permet la mise en mémoire tampon d'une saisie de mouvement grâce au passage dans l'inventaire (inventory buffering) ou image par image (frame buffering) pour obtenir un contrôle précis des mouvements de Lara."

View file

@ -275,6 +275,11 @@
"DataType": "Bool",
"DefaultValue": true
},
{
"Field": "enable_loading_screens",
"DataType": "Bool",
"DefaultValue": false
},
{
"Field": "enable_buffering",
"DataType": "Bool",

86
tools/generate_images Executable file
View file

@ -0,0 +1,86 @@
#!/usr/bin/env python3
import argparse
from pathlib import Path
from subprocess import check_call
TOOLS_DIR = Path(__file__).parent
REPO_DIR = TOOLS_DIR.parent
SOURCE_DIR = TOOLS_DIR / "resources/images"
TARGET_DIR = REPO_DIR / "bin/data/images"
def format_size(size: int) -> str:
return f"{size/1024/1024:.02f} MB"
def format_size_change(source_size: int, target_size: int) -> str:
ratio = target_size / source_size if target_size > 0 else 1.0
return (
f"{format_size(source_size)} → {format_size(target_size)}"
f" ({ratio:.02%})"
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Converts image assets to WEBP format for better file sizes"
)
parser.add_argument(
"quality",
type=int,
default=100,
nargs="?",
help="output quality (100 for lossless)",
)
parser.add_argument(
"-f",
"--force",
action="store_true",
help="force overwrite existing files",
)
return parser.parse_args()
def main() -> None:
args = parse_args()
TARGET_DIR.mkdir(parents=True, exist_ok=True)
total_source_size = 0
total_target_size = 0
for source_path in SOURCE_DIR.rglob("*.png"):
target_path = TARGET_DIR / f"{source_path.stem}.webp"
print(
f"Converting {source_path.relative_to(SOURCE_DIR)} "
f"to {target_path.relative_to(TARGET_DIR)}..."
)
if target_path.exists() and not args.force:
print(" target already exists, skipping")
continue
check_call(
[
"convert",
str(source_path),
"-quality",
str(args.quality),
str(target_path),
]
)
source_size = source_path.stat().st_size
target_size = target_path.stat().st_size
total_source_size += source_size
total_target_size += target_size
print(" " + format_size_change(source_size, target_size))
print()
print("Total:")
print(" " + format_size_change(total_source_size, total_target_size))
if __name__ == "__main__":
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View file

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB