Skip to content

Commit

Permalink
output: animate room sprites
Browse files Browse the repository at this point in the history
This allows room sprites that are part of a sequence with more than one
texture to be animated. This occurs at the same rate as regular
animated textures.

Resolves LostArtefacts#449.
  • Loading branch information
lahm86 committed Apr 7, 2024
1 parent 2510d83 commit 6c1fdbd
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- added Italian localization to the config tool
- added the ability to move the look camera while targeting an enemy in combat (#1187)
- added the ability to skip fade-out in stats screens
- added support for animated room sprites in custom levels and an option to animate plant sprites in The Cistern and Tomb of Tihocan (#449)
- changed stats no longer disappear during fade-out (#1211)
- changed the way music timestamps are internally handled – resets music position in existing saves
- changed vertex and fragment shaders into unified files that are runtime pre-processed for OpenGL versions 2.1 or 3.3
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- added optional fade effects
- added a vsync option
- added contextual arrows to menu options
- added support for animated room sprites, which also restores intended behavior in, for example, The Cistern room 0
- changed the Scion in The Great Pyramid from spawning blood when hit to a richochet effect
- fixed thin black lines between polygons
- fixed black screen flashing when navigating the inventory
Expand Down
2 changes: 2 additions & 0 deletions data/ship/cfg/TR1X_gameflow.json5
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@
"injections": [
"data/cistern_fd.bin",
"data/cistern_itemrots.bin",
"data/cistern_plants.bin",
"data/cistern_textures.bin",
],
"sequence": [
Expand All @@ -253,6 +254,7 @@
"type": "normal",
"music": 58,
"injections": [
"data/cistern_plants.bin",
"data/tihocan_fd.bin",
"data/tihocan_itemrots.bin",
"data/tihocan_textures.bin",
Expand Down
Binary file added data/ship/data/cistern_plants.bin
Binary file not shown.
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ typedef struct {
bool enable_target_change;
TARGET_LOCK_MODE target_mode;
bool enable_loading_screens;
bool fix_animated_sprites;

struct {
int32_t layout;
Expand Down
1 change: 1 addition & 0 deletions src/config_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ const CONFIG_OPTION g_ConfigOptionMap[] = {
{ .name = "text_scale", .type = COT_DOUBLE, .target = &g_Config.ui.text_scale, .default_value = &(double){DEFAULT_UI_SCALE}, 0},
{ .name = "bar_scale", .type = COT_DOUBLE, .target = &g_Config.ui.bar_scale, .default_value = &(double){DEFAULT_UI_SCALE}, 0},
{ .name = "new_game_plus_unlock", .type = COT_BOOL, .target = &g_Config.profile.new_game_plus_unlock, .default_value = &(bool){false}, 0},
{ .name = "fix_animated_sprites", .type = COT_BOOL, .target = &g_Config.fix_animated_sprites, .default_value = &(bool){true}, 0},
// clang-format on

// guard
Expand Down
34 changes: 19 additions & 15 deletions src/game/inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ typedef enum INJECTION_TYPE {
INJ_LARA_JUMPS = 6,
INJ_ITEM_POSITION = 7,
INJ_PS1_ENEMY = 8,
INJ_DISABLE_ANIM_SPRITE = 9,
} INJECTION_TYPE;

typedef struct INJECTION {
Expand Down Expand Up @@ -223,6 +224,9 @@ static void Inject_LoadFromFile(INJECTION *injection, const char *filename)
case INJ_PS1_ENEMY:
injection->relevant = g_Config.restore_ps1_enemies;
break;
case INJ_DISABLE_ANIM_SPRITE:
injection->relevant = !g_Config.fix_animated_sprites;
break;
default:
LOG_WARNING("%s is of unknown type %d", filename, injection->type);
break;
Expand Down Expand Up @@ -487,24 +491,24 @@ static void Inject_TextureData(

for (int i = 0; i < inj_info->sprite_count; i++) {
GAME_OBJECT_ID object_num;
int16_t num_meshes;
int16_t mesh_index;
File_Read(&object_num, sizeof(int32_t), 1, fp);
File_Read(&num_meshes, sizeof(int16_t), 1, fp);
File_Read(&mesh_index, sizeof(int16_t), 1, fp);

if (object_num < O_NUMBER_OF) {
File_Read(&g_Objects[object_num], sizeof(int16_t), 1, fp);
File_Read(
&g_Objects[object_num].mesh_index, sizeof(int16_t), 1, fp);
g_Objects[object_num].mesh_index += level_info->sprite_info_count;
level_info->sprite_info_count -= g_Objects[object_num].nmeshes;
g_Objects[object_num].loaded = 1;
} else {
int32_t static_num = object_num - O_NUMBER_OF;
File_Skip(fp, 2);
File_Read(
&g_StaticObjects[static_num].mesh_number, sizeof(int16_t), 1,
fp);
g_StaticObjects[static_num].mesh_number +=
level_info->sprite_info_count;
level_info->sprite_info_count++;
OBJECT_INFO *object = &g_Objects[object_num];
object->nmeshes = num_meshes;
object->mesh_index = mesh_index + level_info->sprite_info_count;
object->loaded = 1;
} else if (object_num - O_NUMBER_OF < STATIC_NUMBER_OF) {
STATIC_INFO *object = &g_StaticObjects[object_num - O_NUMBER_OF];
object->nmeshes = num_meshes;
object->mesh_number = mesh_index + level_info->sprite_info_count;
object->loaded = true;
}
level_info->sprite_info_count -= num_meshes;
level_info->sprite_count++;
}
}
Expand Down
34 changes: 21 additions & 13 deletions src/game/level.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ static bool Level_LoadObjects(MYFILE *fp)
File_Read(&object->c.min.z, sizeof(int16_t), 1, fp);
File_Read(&object->c.max.z, sizeof(int16_t), 1, fp);
File_Read(&object->flags, sizeof(int16_t), 1, fp);
object->loaded = true;
}

File_Read(&m_LevelInfo.texture_count, sizeof(int32_t), 1, fp);
Expand Down Expand Up @@ -528,18 +529,22 @@ static bool Level_LoadSprites(MYFILE *fp)
File_Read(&m_LevelInfo.sprite_count, sizeof(int32_t), 1, fp);
for (int i = 0; i < m_LevelInfo.sprite_count; i++) {
GAME_OBJECT_ID object_num;
int16_t num_meshes;
int16_t mesh_index;
File_Read(&object_num, sizeof(int32_t), 1, fp);
File_Read(&num_meshes, sizeof(int16_t), 1, fp);
File_Read(&mesh_index, sizeof(int16_t), 1, fp);

if (object_num < O_NUMBER_OF) {
File_Read(&g_Objects[object_num], sizeof(int16_t), 1, fp);
File_Read(
&g_Objects[object_num].mesh_index, sizeof(int16_t), 1, fp);
g_Objects[object_num].loaded = 1;
} else {
int32_t static_num = object_num - O_NUMBER_OF;
File_Skip(fp, 2);
File_Read(
&g_StaticObjects[static_num].mesh_number, sizeof(int16_t), 1,
fp);
OBJECT_INFO *object = &g_Objects[object_num];
object->nmeshes = num_meshes;
object->mesh_index = mesh_index;
object->loaded = 1;
} else if (object_num - O_NUMBER_OF < STATIC_NUMBER_OF) {
STATIC_INFO *object = &g_StaticObjects[object_num - O_NUMBER_OF];
object->nmeshes = num_meshes;
object->mesh_number = mesh_index;
object->loaded = true;
}
}
return true;
Expand Down Expand Up @@ -947,18 +952,21 @@ bool Level_Initialise(int32_t level_num)
Overlay_HideGameInfo();

g_FlipStatus = 0;
for (int i = 0; i < MAX_FLIP_MAPS; i++) {
for (int32_t i = 0; i < MAX_FLIP_MAPS; i++) {
g_FlipMapTable[i] = 0;
}

for (int i = 0; i < MAX_CD_TRACKS; i++) {
for (int32_t i = 0; i < MAX_CD_TRACKS; i++) {
g_MusicTrackFlags[i] = 0;
}

/* Clear Object Loaded flags */
for (int i = 0; i < O_NUMBER_OF; i++) {
for (int32_t i = 0; i < O_NUMBER_OF; i++) {
g_Objects[i].loaded = 0;
}
for (int32_t i = 0; i < STATIC_NUMBER_OF; i++) {
g_StaticObjects[i].loaded = false;
}

Camera_Reset();
Pierre_Reset();
Expand Down
15 changes: 15 additions & 0 deletions src/game/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,21 @@ void Output_AnimateTextures(void)
i--;
ptr++;
}

for (i = 0; i < STATIC_NUMBER_OF; i++) {
STATIC_INFO *static_info = &g_StaticObjects[i];
if (!static_info->loaded || static_info->nmeshes >= -1) {
continue;
}

int32_t num_meshes = -static_info->nmeshes;
PHD_SPRITE temp = g_PhdSpriteInfo[static_info->mesh_number];
for (int32_t j = 0; j < num_meshes - 1; j++) {
g_PhdSpriteInfo[static_info->mesh_number + j] =
g_PhdSpriteInfo[static_info->mesh_number + j + 1];
}
g_PhdSpriteInfo[static_info->mesh_number + num_meshes - 1] = temp;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/global/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1804,6 +1804,8 @@ typedef struct SHADOW_INFO {
} SHADOW_INFO;

typedef struct STATIC_INFO {
bool loaded;
int16_t nmeshes;
int16_t mesh_number;
int16_t flags;
BOUNDS_16 p;
Expand Down
4 changes: 4 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@
"Title": "Fix texture issues",
"Description": "Fixes original issues with missing or incorrect textures."
},
"fix_animated_sprites": {
"Title": "Fix sprite animations",
"Description": "Fixes original issues in The Cistern and Tomb of Tihocan where plant sprites in water areas do not animate."
},
"fix_item_rots": {
"Title": "Fix item rotation issues",
"Description": "Fixes original issues with some incorrectly rotated pickups when using the 3D pickups option."
Expand Down
4 changes: 4 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,10 @@
"Title": "Arreglar problemas de textura",
"Description": "Corrige los problemas originales con texturas faltantes o incorrectas."
},
"fix_animated_sprites": {
"Title": "Arreglar animaciones de sprites",
"Description": "Corrige los problemas originales en La Cisterna y La Tumba de Tihocan donde los duendes de las plantas en las áreas de agua no se animan."
},
"fix_item_rots": {
"Title": "Arreglar problemas de rotación de objetos",
"Description": "Corrige problemas originales con algunas recogidas giradas incorrectamente al usar la opción de recogidas en 3D."
Expand Down
4 changes: 4 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@
"Title": "Corrige les problèmes de texture",
"Description": "Corrige les bugs originaux connus de textures manquantes ou incorrectes."
},
"fix_animated_sprites": {
"Title": "Correction des animations des sprites",
"Description": "Corrige les problèmes originaux dans La Citerne et Le Tombe de Tihocan où les sprites végétaux dans les zones aquatiques ne s'animent pas."
},
"fix_item_rots": {
"Title": "Correction orientation des collectibles",
"Description": "Corrige des problèmes avec certains collectibles mal orientés, quand l'option des collectibles en 3D est utilisée."
Expand Down
4 changes: 4 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@
"Title": "Correggi i problemi delle texture",
"Description": "Risolve i problemi riguardanti texture mancanti o errate."
},
"fix_animated_sprites": {
"Title": "Correggi le animazioni degli sprite",
"Description": "Risolve i problemi originali nella Cisterna e nella Tomba di Tihocan per cui gli sprite delle piante nelle aree acquatiche non si animavano."
},
"fix_item_rots": {
"Title": "Correggi l'orientamento degli oggetti",
"Description": "Risolve i problemi relativi all'orientamento errato di alcuni oggetti quando viene utilizzata l'opzione Oggetti 3D."
Expand Down
5 changes: 5 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/specification.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@
"DataType": "Bool",
"DefaultValue": true
},
{
"Field": "fix_animated_sprites",
"DataType": "Bool",
"DefaultValue": true
},
{
"Field": "fix_qwop_glitch",
"DataType": "Bool",
Expand Down

0 comments on commit 6c1fdbd

Please sign in to comment.