diff --git a/src/libtrx/game/level/common.c b/src/libtrx/game/level/common.c index 0edc1bb2d..845d99403 100644 --- a/src/libtrx/game/level/common.c +++ b/src/libtrx/game/level/common.c @@ -439,3 +439,22 @@ void Level_ReadSpriteSequences(const int32_t num_sequences, VFILE *const file) } } } + +void Level_ReadAnimatedTextureRanges( + const int32_t num_ranges, VFILE *const file) +{ + for (int32_t i = 0; i < num_ranges; i++) { + ANIMATED_TEXTURE_RANGE *const range = &g_AnimTextureRanges[i]; + range->next_range = + i == num_ranges - 1 ? NULL : &g_AnimTextureRanges[i + 1]; + + // Level data is tied to the original logic in Output_AnimateTextures + // and hence stores one less than the actual count here. + range->num_textures = VFile_ReadS16(file) + 1; + range->textures = GameBuf_Alloc( + sizeof(int16_t) * range->num_textures, + GBUF_ANIMATED_TEXTURE_RANGES); + VFile_Read( + file, range->textures, sizeof(int16_t) * range->num_textures); + } +} diff --git a/src/libtrx/game/output.c b/src/libtrx/game/output.c index ba2c8f49f..ecc8eca58 100644 --- a/src/libtrx/game/output.c +++ b/src/libtrx/game/output.c @@ -1,6 +1,7 @@ #include "game/output.h" #include "game/const.h" +#include "game/game_buf.h" #include "game/matrix.h" #include "utils.h" @@ -295,3 +296,12 @@ void Output_AddDynamicLight( light->shade.value_1 = intensity; light->falloff.value_1 = falloff; } + +void Output_InitialiseAnimatedTextures(const int32_t num_ranges) +{ + g_AnimTextureRanges = num_ranges == 0 + ? NULL + : GameBuf_Alloc( + sizeof(ANIMATED_TEXTURE_RANGE) * num_ranges, + GBUF_ANIMATED_TEXTURE_RANGES); +} diff --git a/src/libtrx/include/libtrx/game/enum_map.def b/src/libtrx/include/libtrx/game/enum_map.def index 15f6a458b..94aa1a8b6 100644 --- a/src/libtrx/include/libtrx/game/enum_map.def +++ b/src/libtrx/include/libtrx/game/enum_map.def @@ -40,7 +40,7 @@ ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_BOXES, "Boxes") ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_OVERLAPS, "Overlaps") ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_GROUND_ZONE, "Ground zones") ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_FLY_ZONE, "Fly zones") -ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_ANIMATING_TEXTURE_RANGES, "Animating texture ranges") +ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_ANIMATED_TEXTURE_RANGES, "Animated texture ranges") ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_CINEMATIC_FRAMES, "Cinematic frames") ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_DEMO_BUFFER, "Demo buffer") ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_CREATURE_DATA, "Creature data") diff --git a/src/libtrx/include/libtrx/game/game_buf.h b/src/libtrx/include/libtrx/game/game_buf.h index 2076ef510..011ca8189 100644 --- a/src/libtrx/include/libtrx/game/game_buf.h +++ b/src/libtrx/include/libtrx/game/game_buf.h @@ -36,7 +36,7 @@ typedef enum { GBUF_OVERLAPS, GBUF_GROUND_ZONE, GBUF_FLY_ZONE, - GBUF_ANIMATING_TEXTURE_RANGES, + GBUF_ANIMATED_TEXTURE_RANGES, GBUF_CINEMATIC_FRAMES, GBUF_CREATURE_DATA, GBUF_CREATURE_LOT, diff --git a/src/libtrx/include/libtrx/game/level/common.h b/src/libtrx/include/libtrx/game/level/common.h index 72df382f0..3e363297e 100644 --- a/src/libtrx/include/libtrx/game/level/common.h +++ b/src/libtrx/include/libtrx/game/level/common.h @@ -22,3 +22,4 @@ void Level_ReadObjectTextures( void Level_ReadSpriteTextures( int32_t base_idx, int16_t base_page_idx, int32_t num_textures, VFILE *file); void Level_ReadSpriteSequences(int32_t num_sequences, VFILE *file); +void Level_ReadAnimatedTextureRanges(int32_t num_ranges, VFILE *file); diff --git a/src/libtrx/include/libtrx/game/output.h b/src/libtrx/include/libtrx/game/output.h index e24be199e..d0ece2ee1 100644 --- a/src/libtrx/include/libtrx/game/output.h +++ b/src/libtrx/include/libtrx/game/output.h @@ -44,3 +44,5 @@ void Output_LightRoom(ROOM *room); void Output_ResetDynamicLights(void); void Output_AddDynamicLight(XYZ_32 pos, int32_t intensity, int32_t falloff); + +void Output_InitialiseAnimatedTextures(int32_t num_ranges); diff --git a/src/libtrx/include/libtrx/game/output/types.h b/src/libtrx/include/libtrx/game/output/types.h index 043f6883a..1fdbc1143 100644 --- a/src/libtrx/include/libtrx/game/output/types.h +++ b/src/libtrx/include/libtrx/game/output/types.h @@ -37,6 +37,12 @@ typedef struct { int16_t y1; } SPRITE_TEXTURE; +typedef struct ANIMATED_TEXTURE_RANGE { + int16_t num_textures; + int16_t *textures; + struct ANIMATED_TEXTURE_RANGE *next_range; +} ANIMATED_TEXTURE_RANGE; + typedef struct { float r; float g; diff --git a/src/libtrx/include/libtrx/game/output/vars.h b/src/libtrx/include/libtrx/game/output/vars.h index ceaa2075c..2fc657069 100644 --- a/src/libtrx/include/libtrx/game/output/vars.h +++ b/src/libtrx/include/libtrx/game/output/vars.h @@ -3,5 +3,7 @@ #include "./const.h" #include "./types.h" +// TODO: change to output.c module scope extern OBJECT_TEXTURE g_ObjectTextures[MAX_OBJECT_TEXTURES]; extern SPRITE_TEXTURE g_SpriteTextures[MAX_SPRITE_TEXTURES]; +extern ANIMATED_TEXTURE_RANGE *g_AnimTextureRanges; diff --git a/src/tr1/game/level.c b/src/tr1/game/level.c index f672c7eb3..fa33a2a6c 100644 --- a/src/tr1/game/level.c +++ b/src/tr1/game/level.c @@ -610,46 +610,17 @@ static void M_LoadBoxes(VFILE *file) static void M_LoadAnimatedTextures(VFILE *file) { BENCHMARK *const benchmark = Benchmark_Start(); - m_LevelInfo.anim_texture_range_count = VFile_ReadS32(file); - size_t end_position = VFile_GetPos(file) - + m_LevelInfo.anim_texture_range_count * sizeof(int16_t); + const int32_t data_size = VFile_ReadS32(file); + size_t end_position = VFile_GetPos(file) + data_size * sizeof(int16_t); const int16_t num_ranges = VFile_ReadS16(file); LOG_INFO("%d animated texture ranges", num_ranges); - if (!num_ranges) { - g_AnimTextureRanges = NULL; - goto cleanup; - } - - g_AnimTextureRanges = GameBuf_Alloc( - sizeof(TEXTURE_RANGE) * num_ranges, GBUF_ANIMATING_TEXTURE_RANGES); - for (int32_t i = 0; i < num_ranges; i++) { - TEXTURE_RANGE *range = &g_AnimTextureRanges[i]; - range->next_range = - i == num_ranges - 1 ? NULL : &g_AnimTextureRanges[i + 1]; - - // Level data is tied to the original logic in Output_AnimateTextures - // and hence stores one less than the actual count here. - range->num_textures = VFile_ReadS16(file); - range->num_textures++; - - range->textures = GameBuf_Alloc( - sizeof(int16_t) * range->num_textures, - GBUF_ANIMATING_TEXTURE_RANGES); - VFile_Read( - file, range->textures, sizeof(int16_t) * range->num_textures); - } + Output_InitialiseAnimatedTextures(num_ranges); + Level_ReadAnimatedTextureRanges(num_ranges, file); -cleanup: { - // Ensure to read everything intended by the level compiler, even if it - // does not wholly contain accurate texture data. - const int32_t skip_length = end_position - VFile_GetPos(file); - if (skip_length > 0) { - VFile_Skip(file, skip_length); - } + VFile_SetPos(file, end_position); Benchmark_End(benchmark, NULL); } -} static void M_LoadItems(VFILE *file) { diff --git a/src/tr1/game/output.c b/src/tr1/game/output.c index 9b34fe982..8ff6d54fd 100644 --- a/src/tr1/game/output.c +++ b/src/tr1/game/output.c @@ -1081,8 +1081,8 @@ void Output_AnimateTextures(const int32_t num_frames) m_WibbleOffset = (m_WibbleOffset + num_frames) % WIBBLE_SIZE; m_AnimatedTexturesOffset += num_frames; while (m_AnimatedTexturesOffset > 5) { - const TEXTURE_RANGE *range = g_AnimTextureRanges; - while (range) { + const ANIMATED_TEXTURE_RANGE *range = g_AnimTextureRanges; + while (range != NULL) { int32_t i = 0; const OBJECT_TEXTURE temp = g_ObjectTextures[range->textures[i]]; for (; i < range->num_textures - 1; i++) { diff --git a/src/tr1/global/types.h b/src/tr1/global/types.h index 334005450..617914f0e 100644 --- a/src/tr1/global/types.h +++ b/src/tr1/global/types.h @@ -166,12 +166,6 @@ typedef struct { int16_t v; } PHD_VBUF; -typedef struct TEXTURE_RANGE { - int16_t num_textures; - int16_t *textures; - struct TEXTURE_RANGE *next_range; -} TEXTURE_RANGE; - typedef struct { SECTOR *sector; SECTOR old_sector; diff --git a/src/tr1/global/vars.c b/src/tr1/global/vars.c index 8430c10d2..05bbf29d9 100644 --- a/src/tr1/global/vars.c +++ b/src/tr1/global/vars.c @@ -46,7 +46,7 @@ uint16_t *g_Overlap = NULL; int16_t *g_GroundZone[2] = { NULL }; int16_t *g_GroundZone2[2] = { NULL }; int16_t *g_FlyZone[2] = { NULL }; -TEXTURE_RANGE *g_AnimTextureRanges = NULL; +ANIMATED_TEXTURE_RANGE *g_AnimTextureRanges = NULL; int16_t g_NumCineFrames = 0; int16_t g_CineFrame = -1; CINE_CAMERA *g_CineCamera = NULL; diff --git a/src/tr1/global/vars.h b/src/tr1/global/vars.h index e170dc58b..e6811e539 100644 --- a/src/tr1/global/vars.h +++ b/src/tr1/global/vars.h @@ -52,7 +52,6 @@ extern uint16_t *g_Overlap; extern int16_t *g_GroundZone[2]; extern int16_t *g_GroundZone2[2]; extern int16_t *g_FlyZone[2]; -extern TEXTURE_RANGE *g_AnimTextureRanges; extern int16_t g_NumCineFrames; extern int16_t g_CineFrame; extern CINE_CAMERA *g_CineCamera; diff --git a/src/tr2/game/level.c b/src/tr2/game/level.c index 998144264..ddfc499f5 100644 --- a/src/tr2/game/level.c +++ b/src/tr2/game/level.c @@ -541,10 +541,15 @@ static void M_LoadBoxes(VFILE *const file) static void M_LoadAnimatedTextures(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); - const int32_t num_ranges = VFile_ReadS32(file); - g_AnimTextureRanges = GameBuf_Alloc( - sizeof(int16_t) * num_ranges, GBUF_ANIMATING_TEXTURE_RANGES); - VFile_Read(file, g_AnimTextureRanges, sizeof(int16_t) * num_ranges); + const int32_t data_size = VFile_ReadS32(file); + size_t end_position = VFile_GetPos(file) + data_size * sizeof(int16_t); + + const int16_t num_ranges = VFile_ReadS16(file); + LOG_INFO("%d animated texture ranges", num_ranges); + Output_InitialiseAnimatedTextures(num_ranges); + Level_ReadAnimatedTextureRanges(num_ranges, file); + + VFile_SetPos(file, end_position); Benchmark_End(benchmark, NULL); } diff --git a/src/tr2/game/output.c b/src/tr2/game/output.c index 044850c4c..79ac4a4ec 100644 --- a/src/tr2/game/output.c +++ b/src/tr2/game/output.c @@ -746,15 +746,16 @@ void Output_DoAnimateTextures(const int32_t ticks) { m_TickComp += ticks; while (m_TickComp > TICKS_PER_FRAME * 5) { - const int16_t *ptr = g_AnimTextureRanges; - int16_t i = *(ptr++); - for (; i > 0; --i, ++ptr) { - int16_t j = *(ptr++); - const OBJECT_TEXTURE temp = g_ObjectTextures[*ptr]; - for (; j > 0; --j, ++ptr) { - g_ObjectTextures[ptr[0]] = g_ObjectTextures[ptr[1]]; + const ANIMATED_TEXTURE_RANGE *range = g_AnimTextureRanges; + while (range != NULL) { + int32_t i = 0; + const OBJECT_TEXTURE temp = g_ObjectTextures[range->textures[i]]; + for (; i < range->num_textures - 1; i++) { + g_ObjectTextures[range->textures[i]] = + g_ObjectTextures[range->textures[i + 1]]; } - g_ObjectTextures[*ptr] = temp; + g_ObjectTextures[range->textures[i]] = temp; + range = range->next_range; } m_TickComp -= TICKS_PER_FRAME * 5; } diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c index 732d1bde6..6c36b2a5d 100644 --- a/src/tr2/global/vars.c +++ b/src/tr2/global/vars.c @@ -117,7 +117,7 @@ int32_t g_TexturePageCount; int32_t g_ObjectTextureCount; uint8_t g_LabTextureUVFlag[MAX_OBJECT_TEXTURES]; int32_t g_NumCameras; -int16_t *g_AnimTextureRanges = NULL; +ANIMATED_TEXTURE_RANGE *g_AnimTextureRanges = NULL; uint32_t *g_DemoData = NULL; char g_LevelFileName[256]; uint16_t g_MusicTrackFlags[64]; diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h index 7ba797026..b1d065e4d 100644 --- a/src/tr2/global/vars.h +++ b/src/tr2/global/vars.h @@ -114,7 +114,6 @@ extern int32_t g_TexturePageCount; extern int32_t g_ObjectTextureCount; extern uint8_t g_LabTextureUVFlag[MAX_OBJECT_TEXTURES]; extern int32_t g_NumCameras; -extern int16_t *g_AnimTextureRanges; extern uint32_t *g_DemoData; extern char g_LevelFileName[256]; extern uint16_t g_MusicTrackFlags[64];