From 8449b1c7bf0db00e1cf9128c024e56c5a5e95f7a Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:53:05 +0000 Subject: [PATCH] level: handle texture and palette reading in TRX This makes the palette and texture page readers for both games common in TRX. --- src/libtrx/game/level/common.c | 105 ++++++++++++++++++ src/libtrx/include/libtrx/game/level/common.h | 2 + src/tr1/game/level.c | 46 +------- src/tr2/game/level.c | 59 +--------- src/tr2/game/render/common.c | 1 - src/tr2/game/render/hwr.c | 1 - src/tr2/game/render/util.c | 23 ---- src/tr2/game/render/util.h | 5 - src/tr2/meson.build | 1 - 9 files changed, 112 insertions(+), 131 deletions(-) delete mode 100644 src/tr2/game/render/util.c delete mode 100644 src/tr2/game/render/util.h diff --git a/src/libtrx/game/level/common.c b/src/libtrx/game/level/common.c index a4b28943a..b88205520 100644 --- a/src/libtrx/game/level/common.c +++ b/src/libtrx/game/level/common.c @@ -1,5 +1,6 @@ #include "game/level/common.h" +#include "benchmark.h" #include "debug.h" #include "game/anims.h" #include "game/const.h" @@ -16,12 +17,35 @@ static int16_t *m_AnimCommands = nullptr; +static RGBA_8888 M_ARGB1555To8888(uint16_t argb1555); static void M_ReadVertex(XYZ_16 *vertex, VFILE *file); static void M_ReadFace4(FACE4 *face, VFILE *file); static void M_ReadFace3(FACE3 *face, VFILE *file); static void M_ReadObjectMesh(OBJECT_MESH *mesh, VFILE *file); static void M_ReadBounds16(BOUNDS_16 *bounds, VFILE *file); +static RGBA_8888 M_ARGB1555To8888(const uint16_t argb1555) +{ + // Extract 5-bit values for each ARGB component + uint8_t a1 = (argb1555 >> 15) & 0x01; + uint8_t r5 = (argb1555 >> 10) & 0x1F; + uint8_t g5 = (argb1555 >> 5) & 0x1F; + uint8_t b5 = argb1555 & 0x1F; + + // Expand 5-bit color components to 8-bit + uint8_t a8 = a1 * 255; // 1-bit alpha (either 0 or 255) + uint8_t r8 = (r5 << 3) | (r5 >> 2); + uint8_t g8 = (g5 << 3) | (g5 >> 2); + uint8_t b8 = (b5 << 3) | (b5 >> 2); + + return (RGBA_8888) { + .r = r8, + .g = g8, + .b = b8, + .a = a8, + }; +} + static void M_ReadVertex(XYZ_16 *const vertex, VFILE *const file) { vertex->x = VFile_ReadS16(file); @@ -128,6 +152,87 @@ static void M_ReadBounds16(BOUNDS_16 *const bounds, VFILE *const file) bounds->max.z = VFile_ReadS16(file); } +void Level_ReadPalette(LEVEL_INFO *const info, VFILE *const file) +{ + BENCHMARK *const benchmark = Benchmark_Start(); + + const int32_t palette_size = 256; + info->palette.size = palette_size; + + info->palette.data_24 = Memory_Alloc(sizeof(RGB_888) * palette_size); + VFile_Read(file, info->palette.data_24, sizeof(RGB_888) * palette_size); + info->palette.data_24[0].r = 0; + info->palette.data_24[0].g = 0; + info->palette.data_24[0].b = 0; + for (int32_t i = 1; i < palette_size; i++) { + RGB_888 *const col = &info->palette.data_24[i]; + col->r = (col->r << 2) | (col->r >> 4); + col->g = (col->g << 2) | (col->g >> 4); + col->b = (col->b << 2) | (col->b >> 4); + } + +#if TR_VERSION == 1 + info->palette.data_32 = nullptr; +#else + RGBA_8888 palette_16[palette_size]; + info->palette.data_32 = Memory_Alloc(sizeof(RGB_888) * palette_size); + VFile_Read(file, palette_16, sizeof(RGBA_8888) * palette_size); + for (int32_t i = 0; i < palette_size; i++) { + info->palette.data_32[i].r = palette_16[i].r; + info->palette.data_32[i].g = palette_16[i].g; + info->palette.data_32[i].b = palette_16[i].b; + } +#endif + + Benchmark_End(benchmark, nullptr); +} + +// TODO: replace extra_pages with value from injection interface +void Level_ReadTexturePages( + LEVEL_INFO *const info, const int32_t extra_pages, VFILE *const file) +{ + BENCHMARK *const benchmark = Benchmark_Start(); + + const int32_t num_pages = VFile_ReadS32(file); + info->textures.page_count = num_pages; + LOG_INFO("texture pages: %d", num_pages); + + const int32_t texture_size_8_bit = + num_pages * TEXTURE_PAGE_SIZE * sizeof(uint8_t); + const int32_t texture_size_32_bit = + (num_pages + extra_pages) * TEXTURE_PAGE_SIZE * sizeof(RGBA_8888); + + info->textures.pages_24 = Memory_Alloc(texture_size_8_bit); + VFile_Read(file, info->textures.pages_24, texture_size_8_bit); + + info->textures.pages_32 = Memory_Alloc(texture_size_32_bit); + RGBA_8888 *output = info->textures.pages_32; + +#if TR_VERSION == 1 + const uint8_t *input = info->textures.pages_24; + for (int32_t i = 0; i < texture_size_8_bit; i++) { + const uint8_t index = *input++; + const RGB_888 pix = info->palette.data_24[index]; + output->r = pix.r; + output->g = pix.g; + output->b = pix.b; + output->a = index == 0 ? 0 : 0xFF; + output++; + } +#else + const int32_t texture_size_16_bit = + num_pages * TEXTURE_PAGE_SIZE * sizeof(uint16_t); + uint16_t *input = Memory_Alloc(texture_size_16_bit); + VFile_Read(file, input, texture_size_16_bit); + for (int32_t i = 0; i < num_pages * TEXTURE_PAGE_SIZE; i++) { + *output++ = M_ARGB1555To8888(*input++); + } + Memory_FreePointer(&input); +#endif + + Benchmark_End(benchmark, NULL); +} + void Level_ReadRoomMesh(const int32_t room_num, VFILE *const file) { ROOM *const room = Room_Get(room_num); diff --git a/src/libtrx/include/libtrx/game/level/common.h b/src/libtrx/include/libtrx/game/level/common.h index 3b2486a69..bdb07f5bc 100644 --- a/src/libtrx/include/libtrx/game/level/common.h +++ b/src/libtrx/include/libtrx/game/level/common.h @@ -5,6 +5,8 @@ #define ANIM_BONE_SIZE 4 +void Level_ReadPalette(LEVEL_INFO *info, VFILE *file); +void Level_ReadTexturePages(LEVEL_INFO *info, int32_t extra_pages, VFILE *file); void Level_ReadRoomMesh(int32_t room_num, VFILE *file); void Level_ReadFloorData(VFILE *file); void Level_ReadObjectMeshes( diff --git a/src/tr1/game/level.c b/src/tr1/game/level.c index b0d50c4d7..95b2232b0 100644 --- a/src/tr1/game/level.c +++ b/src/tr1/game/level.c @@ -261,33 +261,8 @@ static void M_LoadFromFile(const GF_LEVEL *const level) static void M_LoadTexturePages(VFILE *file) { - BENCHMARK *const benchmark = Benchmark_Start(); - const int32_t num_pages = VFile_ReadS32(file); - m_LevelInfo.textures.page_count = num_pages; - LOG_INFO("%d texture pages", num_pages); - - const int32_t texture_size_8_bit = - num_pages * TEXTURE_PAGE_SIZE * sizeof(uint8_t); - m_LevelInfo.textures.pages_24 = Memory_Alloc(texture_size_8_bit); - VFile_Read(file, m_LevelInfo.textures.pages_24, texture_size_8_bit); - - const int32_t texture_size_32_bit = - (num_pages + m_InjectionInfo->texture_page_count) * TEXTURE_PAGE_SIZE - * sizeof(RGBA_8888); - m_LevelInfo.textures.pages_32 = Memory_Alloc(texture_size_32_bit); - RGBA_8888 *output = m_LevelInfo.textures.pages_32; - const uint8_t *input = m_LevelInfo.textures.pages_24; - for (int32_t i = 0; i < texture_size_8_bit; i++) { - const uint8_t index = *input++; - const RGB_888 pix = m_LevelInfo.palette.data_24[index]; - output->r = pix.r; - output->g = pix.g; - output->b = pix.b; - output->a = index == 0 ? 0 : 0xFF; - output++; - } - - Benchmark_End(benchmark, nullptr); + Level_ReadTexturePages( + &m_LevelInfo, m_InjectionInfo->texture_page_count, file); } static void M_LoadRooms(VFILE *file) @@ -705,22 +680,7 @@ static void M_LoadLightTable(VFILE *file) static void M_LoadPalette(VFILE *file) { - BENCHMARK *const benchmark = Benchmark_Start(); - LOG_INFO(""); - m_LevelInfo.palette.size = 256; - m_LevelInfo.palette.data_24 = - Memory_Alloc(sizeof(RGB_888) * m_LevelInfo.palette.size); - for (int32_t i = 0; i < 256; i++) { - m_LevelInfo.palette.data_24[i].r = VFile_ReadU8(file) * 4; - m_LevelInfo.palette.data_24[i].g = VFile_ReadU8(file) * 4; - m_LevelInfo.palette.data_24[i].b = VFile_ReadU8(file) * 4; - } - m_LevelInfo.palette.data_24[0].r = 0; - m_LevelInfo.palette.data_24[0].g = 0; - m_LevelInfo.palette.data_24[0].b = 0; - - m_LevelInfo.palette.data_32 = nullptr; - Benchmark_End(benchmark, nullptr); + Level_ReadPalette(&m_LevelInfo, file); } static void M_LoadCinematic(VFILE *file) diff --git a/src/tr2/game/level.c b/src/tr2/game/level.c index 2d845ce45..3944697d9 100644 --- a/src/tr2/game/level.c +++ b/src/tr2/game/level.c @@ -15,7 +15,6 @@ #include "game/output.h" #include "game/overlay.h" #include "game/render/common.h" -#include "game/render/util.h" #include "game/room.h" #include "game/shell.h" #include "game/sound.h" @@ -60,34 +59,7 @@ static void M_CompleteSetup(void); static void M_LoadTexturePages(VFILE *const file) { - BENCHMARK *const benchmark = Benchmark_Start(); - - const int32_t num_pages = VFile_ReadS32(file); - m_LevelInfo.textures.page_count = num_pages; - LOG_INFO("texture pages: %d", num_pages); - - const int32_t texture_size_8_bit = - num_pages * TEXTURE_PAGE_SIZE * sizeof(uint8_t); - const int32_t texture_size_16_bit = - num_pages * TEXTURE_PAGE_SIZE * sizeof(uint16_t); - const int32_t texture_size_32_bit = - num_pages * TEXTURE_PAGE_SIZE * sizeof(RGBA_8888); - - m_LevelInfo.textures.pages_24 = Memory_Alloc(texture_size_8_bit); - VFile_Read(file, m_LevelInfo.textures.pages_24, texture_size_8_bit); - - m_LevelInfo.textures.pages_32 = Memory_Alloc(texture_size_32_bit); - - uint16_t *input = Memory_Alloc(texture_size_16_bit); - VFile_Read(file, input, texture_size_16_bit); - RGBA_8888 *output = m_LevelInfo.textures.pages_32; - for (int32_t i = 0; i < num_pages * TEXTURE_PAGE_SIZE; i++) { - *output++ = Render_ARGB1555To8888(*input++); - } - - Memory_FreePointer(&input); - - Benchmark_End(benchmark, NULL); + Level_ReadTexturePages(&m_LevelInfo, 0, file); } static void M_LoadRooms(VFILE *const file) @@ -395,34 +367,7 @@ static void M_LoadDepthQ(VFILE *const file) static void M_LoadPalettes(VFILE *const file) { - BENCHMARK *const benchmark = Benchmark_Start(); - - const int32_t palette_size = 256; - m_LevelInfo.palette.size = palette_size; - m_LevelInfo.palette.data_24 = Memory_Alloc(sizeof(RGB_888) * palette_size); - m_LevelInfo.palette.data_32 = Memory_Alloc(sizeof(RGB_888) * palette_size); - - VFile_Read( - file, m_LevelInfo.palette.data_24, sizeof(RGB_888) * palette_size); - m_LevelInfo.palette.data_24[0].r = 0; - m_LevelInfo.palette.data_24[0].g = 0; - m_LevelInfo.palette.data_24[0].b = 0; - for (int32_t i = 1; i < palette_size; i++) { - RGB_888 *const col = &m_LevelInfo.palette.data_24[i]; - col->r = (col->r << 2) | (col->r >> 4); - col->g = (col->g << 2) | (col->g >> 4); - col->b = (col->b << 2) | (col->b >> 4); - } - - RGBA_8888 palette_16[palette_size]; - VFile_Read(file, palette_16, sizeof(RGBA_8888) * palette_size); - for (int32_t i = 0; i < palette_size; i++) { - m_LevelInfo.palette.data_32[i].r = palette_16[i].r; - m_LevelInfo.palette.data_32[i].g = palette_16[i].g; - m_LevelInfo.palette.data_32[i].b = palette_16[i].b; - } - - Benchmark_End(benchmark, nullptr); + Level_ReadPalette(&m_LevelInfo, file); } static void M_LoadCameras(VFILE *const file) diff --git a/src/tr2/game/render/common.c b/src/tr2/game/render/common.c index b3a5ee62f..e50a0f4a5 100644 --- a/src/tr2/game/render/common.c +++ b/src/tr2/game/render/common.c @@ -4,7 +4,6 @@ #include "game/render/hwr.h" #include "game/render/priv.h" #include "game/render/swr.h" -#include "game/render/util.h" #include "game/shell.h" #include "global/vars.h" diff --git a/src/tr2/game/render/hwr.c b/src/tr2/game/render/hwr.c index c41b6f987..e368be8a0 100644 --- a/src/tr2/game/render/hwr.c +++ b/src/tr2/game/render/hwr.c @@ -3,7 +3,6 @@ #include "decomp/decomp.h" #include "game/output.h" #include "game/render/priv.h" -#include "game/render/util.h" #include "game/shell.h" #include "global/vars.h" diff --git a/src/tr2/game/render/util.c b/src/tr2/game/render/util.c deleted file mode 100644 index 18341cb09..000000000 --- a/src/tr2/game/render/util.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "game/render/util.h" - -RGBA_8888 Render_ARGB1555To8888(const uint16_t argb1555) -{ - // Extract 5-bit values for each ARGB component - uint8_t a1 = (argb1555 >> 15) & 0x01; - uint8_t r5 = (argb1555 >> 10) & 0x1F; - uint8_t g5 = (argb1555 >> 5) & 0x1F; - uint8_t b5 = argb1555 & 0x1F; - - // Expand 5-bit color components to 8-bit - uint8_t a8 = a1 * 255; // 1-bit alpha (either 0 or 255) - uint8_t r8 = (r5 << 3) | (r5 >> 2); - uint8_t g8 = (g5 << 3) | (g5 >> 2); - uint8_t b8 = (b5 << 3) | (b5 >> 2); - - return (RGBA_8888) { - .r = r8, - .g = g8, - .b = b8, - .a = a8, - }; -} diff --git a/src/tr2/game/render/util.h b/src/tr2/game/render/util.h deleted file mode 100644 index b1bb4e0b6..000000000 --- a/src/tr2/game/render/util.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "global/types.h" - -RGBA_8888 Render_ARGB1555To8888(uint16_t argb1555); diff --git a/src/tr2/meson.build b/src/tr2/meson.build index 647b673c0..abe5bfd3d 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -264,7 +264,6 @@ sources = [ 'game/render/hwr.c', 'game/render/priv.c', 'game/render/swr.c', - 'game/render/util.c', 'game/requester.c', 'game/room.c', 'game/room_draw.c',