mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 12:47:58 +03:00
output: animate room sprites (#1282)
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 #449.
This commit is contained in:
parent
32e61c581b
commit
ca32163133
16 changed files with 97 additions and 32 deletions
|
@ -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
|
||||
|
|
|
@ -1371,6 +1371,15 @@ provided with the game achieves.
|
|||
<code>braid_cut2_cut4.bin</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<code>cistern_plants.bin</code>
|
||||
</td>
|
||||
<td>
|
||||
This disables the animation on sprite ID 193 in The Cistern and Tomb of
|
||||
Tihocan.
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<code>khamoon_mummy.bin</code>
|
||||
|
|
|
@ -369,6 +369,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
|
||||
|
|
|
@ -229,6 +229,7 @@
|
|||
"injections": [
|
||||
"data/cistern_fd.bin",
|
||||
"data/cistern_itemrots.bin",
|
||||
"data/cistern_plants.bin",
|
||||
"data/cistern_textures.bin",
|
||||
],
|
||||
"sequence": [
|
||||
|
@ -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",
|
||||
|
|
BIN
data/ship/data/cistern_plants.bin
Normal file
BIN
data/ship/data/cistern_plants.bin
Normal file
Binary file not shown.
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
|
|
@ -924,16 +924,16 @@ void Output_AnimateTextures(void)
|
|||
{
|
||||
m_WibbleOffset = Clock_GetLogicalFrame() % WIBBLE_SIZE;
|
||||
|
||||
if (!g_AnimTextureRanges) {
|
||||
if (!Clock_IsAtLogicalFrame(5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Clock_IsAtLogicalFrame(5)) {
|
||||
int16_t *ptr = g_AnimTextureRanges;
|
||||
if (g_AnimTextureRanges) {
|
||||
const int16_t *ptr = g_AnimTextureRanges;
|
||||
int16_t i = *ptr++;
|
||||
while (i > 0) {
|
||||
int16_t j = *ptr++;
|
||||
PHD_TEXTURE temp = g_PhdTextureInfo[*ptr];
|
||||
const PHD_TEXTURE temp = g_PhdTextureInfo[*ptr];
|
||||
while (j > 0) {
|
||||
g_PhdTextureInfo[ptr[0]] = g_PhdTextureInfo[ptr[1]];
|
||||
j--;
|
||||
|
@ -944,6 +944,21 @@ void Output_AnimateTextures(void)
|
|||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < STATIC_NUMBER_OF; i++) {
|
||||
const STATIC_INFO *const static_info = &g_StaticObjects[i];
|
||||
if (!static_info->loaded || static_info->nmeshes >= -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int32_t num_meshes = -static_info->nmeshes;
|
||||
const 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;
|
||||
}
|
||||
}
|
||||
|
||||
void Output_RotateLight(int16_t pitch, int16_t yaw)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -151,6 +151,11 @@
|
|||
"DataType": "Bool",
|
||||
"DefaultValue": true
|
||||
},
|
||||
{
|
||||
"Field": "fix_animated_sprites",
|
||||
"DataType": "Bool",
|
||||
"DefaultValue": true
|
||||
},
|
||||
{
|
||||
"Field": "fix_qwop_glitch",
|
||||
"DataType": "Bool",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue