Skip to content

Commit

Permalink
inject: allow mixing solid mesh palettes
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Sep 14, 2024
1 parent 735de24 commit 44e4582
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 78 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- improved crash debug information on Windows
- improved vertex movement when looking through water portals (#1493)
- improved anisotropic filter rendering (#902, #1507)
- improved skybox appearance (#1520)

## [4.3](https://github.com/LostArtefacts/TR1X/compare/4.2...4.3) - 2024-08-15
- added deadly water feature from TR2+ for custom levels (#1404)
Expand Down
70 changes: 35 additions & 35 deletions src/game/inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,29 +113,30 @@ static INJECTION_INFO *m_Aggregate = NULL;

static void Inject_LoadFromFile(INJECTION *injection, const char *filename);

static uint8_t Inject_RemapRGB(RGB_888 rgb);
static uint16_t Inject_RemapRGB(LEVEL_INFO *level_info, RGB_888 rgb);
static void Inject_AlignTextureReferences(
OBJECT_INFO *object, uint8_t *palette_map, int32_t page_base);
OBJECT_INFO *object, uint16_t *palette_map, int32_t page_base);

static void Inject_LoadTexturePages(
INJECTION *injection, uint8_t *palette_map, RGBA_8888 *page_ptr);
INJECTION *injection, LEVEL_INFO *level_info, uint16_t *palette_map,
RGBA_8888 *page_ptr);
static void Inject_TextureData(
INJECTION *injection, LEVEL_INFO *level_info, int32_t page_base);
static void Inject_MeshData(INJECTION *injection, LEVEL_INFO *level_info);
static void Inject_AnimData(INJECTION *injection, LEVEL_INFO *level_info);
static void Inject_AnimRangeEdits(INJECTION *injection);
static void Inject_ObjectData(
INJECTION *injection, LEVEL_INFO *level_info, uint8_t *palette_map);
INJECTION *injection, LEVEL_INFO *level_info, uint16_t *palette_map);
static void Inject_SFXData(INJECTION *injection, LEVEL_INFO *level_info);

static int16_t *Inject_GetMeshTexture(FACE_EDIT *face_edit);

static void Inject_ApplyFaceEdit(
FACE_EDIT *face_edit, int16_t *data_ptr, int16_t texture);
static void Inject_ApplyMeshEdit(MESH_EDIT *mesh_edit, uint8_t *palette_map);
static void Inject_MeshEdits(INJECTION *injection, uint8_t *palette_map);
static void Inject_ApplyMeshEdit(MESH_EDIT *mesh_edit, uint16_t *palette_map);
static void Inject_MeshEdits(INJECTION *injection, uint16_t *palette_map);
static void Inject_TextureOverwrites(
INJECTION *injection, LEVEL_INFO *level_info, uint8_t *palette_map);
INJECTION *injection, LEVEL_INFO *level_info, uint16_t *palette_map);

static void Inject_FloorDataEdits(INJECTION *injection, LEVEL_INFO *level_info);
static void Inject_TriggerParameterChange(
Expand Down Expand Up @@ -382,7 +383,7 @@ void Inject_AllInjections(LEVEL_INFO *level_info)

BENCHMARK *const benchmark = Benchmark_Start();

uint8_t palette_map[256];
uint16_t palette_map[256];
RGBA_8888 *source_pages = Memory_Alloc(
m_Aggregate->texture_page_count * PAGE_SIZE * sizeof(RGBA_8888));
int32_t source_page_count = 0;
Expand All @@ -395,7 +396,7 @@ void Inject_AllInjections(LEVEL_INFO *level_info)
}

Inject_LoadTexturePages(
injection, palette_map,
injection, level_info, palette_map,
source_pages + (source_page_count * PAGE_SIZE));

Inject_TextureData(injection, level_info, tpage_base);
Expand Down Expand Up @@ -450,7 +451,8 @@ void Inject_AllInjections(LEVEL_INFO *level_info)
}

static void Inject_LoadTexturePages(
INJECTION *injection, uint8_t *palette_map, RGBA_8888 *page_ptr)
INJECTION *injection, LEVEL_INFO *level_info, uint16_t *palette_map,
RGBA_8888 *page_ptr)
{
BENCHMARK *const benchmark = Benchmark_Start();

Expand All @@ -468,8 +470,9 @@ static void Inject_LoadTexturePages(
source_palette[i].r *= 4;
source_palette[i].g *= 4;
source_palette[i].b *= 4;

palette_map[i] = Inject_RemapRGB(source_palette[i]);
}
for (int32_t i = 0; i < 256; i++) {
palette_map[i] = Inject_RemapRGB(level_info, source_palette[i]);
}

// Read in each page for this injection and realign the pixels
Expand Down Expand Up @@ -749,7 +752,7 @@ static void Inject_AnimRangeEdits(INJECTION *injection)
}

static void Inject_ObjectData(
INJECTION *injection, LEVEL_INFO *level_info, uint8_t *palette_map)
INJECTION *injection, LEVEL_INFO *level_info, uint16_t *palette_map)
{
BENCHMARK *const benchmark = Benchmark_Start();

Expand Down Expand Up @@ -842,7 +845,7 @@ static void Inject_SFXData(INJECTION *injection, LEVEL_INFO *level_info)
}

static void Inject_AlignTextureReferences(
OBJECT_INFO *object, uint8_t *palette_map, int32_t page_base)
OBJECT_INFO *object, uint16_t *palette_map, int32_t page_base)
{
int16_t **mesh = &g_Meshes[object->mesh_index];
for (int32_t i = 0; i < object->nmeshes; i++) {
Expand Down Expand Up @@ -885,28 +888,25 @@ static void Inject_AlignTextureReferences(
}
}

static uint8_t Inject_RemapRGB(RGB_888 rgb)
static uint16_t Inject_RemapRGB(LEVEL_INFO *level_info, RGB_888 rgb)
{
// Find the index of the nearest match to the given RGB
int32_t best_match = 0x7fffffff;
int32_t test_match;
int32_t best_index = 0;
for (int32_t i = 1; i < 256; i++) {
const RGB_888 test_rgb = Output_GetPaletteColor(i);
const int32_t r = rgb.r - test_rgb.r;
const int32_t g = rgb.g - test_rgb.g;
const int32_t b = rgb.b - test_rgb.b;
test_match = SQUARE(r) + SQUARE(g) + SQUARE(b);

if (test_match < best_match) {
best_match = test_match;
best_index = i;
// Find the index of the exact match to the given RGB
for (int32_t i = 0; i < level_info->palette_size; i++) {
const RGB_888 test_rgb = level_info->palette[i];
if (rgb.r == test_rgb.r && rgb.g == test_rgb.g && rgb.b == test_rgb.b) {
return i;
}
}
return best_index;

// Match not found - expand the game palette
level_info->palette_size++;
level_info->palette = Memory_Realloc(
level_info->palette, level_info->palette_size * sizeof(RGB_888));
level_info->palette[level_info->palette_size - 1] = rgb;
return level_info->palette_size - 1;
}

static void Inject_MeshEdits(INJECTION *injection, uint8_t *palette_map)
static void Inject_MeshEdits(INJECTION *injection, uint16_t *palette_map)
{
INJECTION_INFO *inj_info = injection->info;
VFILE *const fp = injection->fp;
Expand Down Expand Up @@ -976,7 +976,7 @@ static void Inject_MeshEdits(INJECTION *injection, uint8_t *palette_map)
Benchmark_End(benchmark, NULL);
}

static void Inject_ApplyMeshEdit(MESH_EDIT *mesh_edit, uint8_t *palette_map)
static void Inject_ApplyMeshEdit(MESH_EDIT *mesh_edit, uint16_t *palette_map)
{
OBJECT_INFO object = g_Objects[mesh_edit->object_id];
if (!object.loaded) {
Expand Down Expand Up @@ -1128,7 +1128,7 @@ static int16_t *Inject_GetMeshTexture(FACE_EDIT *face_edit)
}

static void Inject_TextureOverwrites(
INJECTION *injection, LEVEL_INFO *level_info, uint8_t *palette_map)
INJECTION *injection, LEVEL_INFO *level_info, uint16_t *palette_map)
{
BENCHMARK *const benchmark = Benchmark_Start();

Expand All @@ -1150,14 +1150,14 @@ static void Inject_TextureOverwrites(
level_info->texture_page_ptrs + target_page * PAGE_SIZE;
for (int32_t y = 0; y < source_height; y++) {
for (int32_t x = 0; x < source_width; x++) {
const int32_t pal_idx = source_img[y * source_width + x];
const uint8_t pal_idx = source_img[y * source_width + x];
const int32_t target_pixel =
(y + target_y) * PAGE_WIDTH + x + target_x;
if (pal_idx == 0) {
(*(page + target_pixel)).a = 0;
} else {
const RGB_888 pix =
Output_GetPaletteColor(palette_map[pal_idx]);
level_info->palette[palette_map[pal_idx]];
(*(page + target_pixel)).r = pix.r;
(*(page + target_pixel)).g = pix.g;
(*(page + target_pixel)).b = pix.b;
Expand Down
28 changes: 15 additions & 13 deletions src/game/level.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,21 +781,22 @@ static void Level_LoadPalette(VFILE *file)
{
BENCHMARK *const benchmark = Benchmark_Start();
LOG_INFO("");
RGB_888 palette[256];
m_LevelInfo.palette_size = 256;
m_LevelInfo.palette =
Memory_Alloc(sizeof(RGB_888) * m_LevelInfo.palette_size);
for (int32_t i = 0; i < 256; i++) {
palette[i].r = VFile_ReadU8(file);
palette[i].g = VFile_ReadU8(file);
palette[i].b = VFile_ReadU8(file);
m_LevelInfo.palette[i].r = VFile_ReadU8(file);
m_LevelInfo.palette[i].g = VFile_ReadU8(file);
m_LevelInfo.palette[i].b = VFile_ReadU8(file);
}
palette[0].r = 0;
palette[0].g = 0;
palette[0].b = 0;
m_LevelInfo.palette[0].r = 0;
m_LevelInfo.palette[0].g = 0;
m_LevelInfo.palette[0].b = 0;
for (int i = 1; i < 256; i++) {
palette[i].r *= 4;
palette[i].g *= 4;
palette[i].b *= 4;
m_LevelInfo.palette[i].r *= 4;
m_LevelInfo.palette[i].g *= 4;
m_LevelInfo.palette[i].b *= 4;
}
Output_SetPalette(palette);
Benchmark_End(benchmark, NULL);
}

Expand Down Expand Up @@ -902,7 +903,7 @@ static void Level_CompleteSetup(int32_t level_num)
m_LevelInfo.texture_page_count * PAGE_SIZE * sizeof(RGBA_8888));
RGBA_8888 *output = m_LevelInfo.texture_page_ptrs;
const uint8_t *input = m_LevelInfo.texture_old_page_ptrs;
for (int i = 0; i < m_LevelInfo.texture_page_count; i++) {
for (int32_t i = 0; i < m_LevelInfo.texture_page_count; i++) {
for (int32_t j = 0; j < PAGE_SIZE; j++) {
const uint8_t index = *input++;
if (index == 0) {
Expand All @@ -911,7 +912,7 @@ static void Level_CompleteSetup(int32_t level_num)
output->b = 0;
output->a = 0;
} else {
RGB_888 pix = Output_GetPaletteColor(index);
RGB_888 pix = m_LevelInfo.palette[index];
output->r = pix.r;
output->g = pix.g;
output->b = pix.b;
Expand Down Expand Up @@ -949,6 +950,7 @@ static void Level_CompleteSetup(int32_t level_num)
g_TexturePagePtrs[i] = &m_LevelInfo.texture_page_ptrs[i * PAGE_SIZE];
}
Output_DownloadTextures(m_LevelInfo.texture_page_count);
Output_SetPalette(m_LevelInfo.palette, m_LevelInfo.palette_size);

// Initialise the sound effects.
size_t *sample_sizes =
Expand Down
27 changes: 17 additions & 10 deletions src/game/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static int m_OverlayCurAlpha = 0;
static int m_OverlayDstAlpha = 0;
static int m_BackdropCurAlpha = 0;
static int m_BackdropDstAlpha = 0;
static RGB_888 *m_ColorPalette = NULL;

static int32_t m_WibbleOffset = 0;
static double m_WibbleOffsetDbl = 0.0;
Expand Down Expand Up @@ -530,6 +531,7 @@ void Output_Shutdown(void)
{
S_Output_Shutdown();
Memory_FreePointer(&m_BackdropImagePath);
Memory_FreePointer(&m_ColorPalette);
}

void Output_ReserveVertexBuffer(const size_t size)
Expand Down Expand Up @@ -562,16 +564,6 @@ RGBA_8888 Output_RGB2RGBA(const RGB_888 color)
return ret;
}

void Output_SetPalette(RGB_888 palette[256])
{
S_Output_SetPalette(palette);
}

RGB_888 Output_GetPaletteColor(uint8_t idx)
{
return S_Output_GetPaletteColor(idx);
}

void Output_DrawBlack(void)
{
Output_DrawBlackOverlay(255);
Expand Down Expand Up @@ -1398,3 +1390,18 @@ int Output_GetObjectBounds(const BOUNDS_16 *const bounds)

return 1; // fully on screen
}

void Output_SetPalette(const RGB_888 *palette, const size_t palette_size)
{
m_ColorPalette =
Memory_Realloc(m_ColorPalette, sizeof(RGB_888) * palette_size);
memcpy(m_ColorPalette, palette, sizeof(RGB_888) * palette_size);
}

RGB_888 Output_GetPaletteColor(uint16_t idx)
{
if (m_ColorPalette == NULL) {
return (RGB_888) { 0 };
}
return m_ColorPalette[idx];
}
4 changes: 2 additions & 2 deletions src/game/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ void Output_ApplyRenderSettings(void);
void Output_DownloadTextures(int page_count);

RGBA_8888 Output_RGB2RGBA(const RGB_888 color);
void Output_SetPalette(RGB_888 palette[256]);
RGB_888 Output_GetPaletteColor(uint8_t idx);
void Output_SetPalette(const RGB_888 *palette, size_t palette_size);
RGB_888 Output_GetPaletteColor(uint16_t idx);

int32_t Output_GetNearZ(void);
int32_t Output_GetFarZ(void);
Expand Down
2 changes: 2 additions & 0 deletions src/global/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,8 @@ typedef struct LEVEL_INFO {
int32_t *sample_offsets;
int32_t sample_data_size;
char *sample_data;
RGB_888 *palette;
int32_t palette_size;
} LEVEL_INFO;

typedef enum TRISTATE_BOOL {
Expand Down
15 changes: 0 additions & 15 deletions src/specific/s_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@

static int m_TextureMap[GFX_MAX_TEXTURES] = { GFX_NO_TEXTURE };
static int m_EnvMapTexture = GFX_NO_TEXTURE;
static RGB_888 m_ColorPalette[256];

static GFX_2D_Renderer *m_Renderer2D = NULL;
static GFX_3D_Renderer *m_Renderer3D = NULL;
static bool m_IsPaletteActive = false;
static bool m_IsTextureMode = false;
static int32_t m_SelectedTexture = -1;

Expand Down Expand Up @@ -455,19 +453,6 @@ void S_Output_RenderEnd(void)
GFX_3D_Renderer_RenderEnd(m_Renderer3D);
}

void S_Output_SetPalette(RGB_888 palette[256])
{
for (int i = 0; i < 256; i++) {
m_ColorPalette[i] = palette[i];
}
m_IsPaletteActive = true;
}

RGB_888 S_Output_GetPaletteColor(uint8_t idx)
{
return m_ColorPalette[idx];
}

void S_Output_FlipScreen(void)
{
S_Output_FlipPrimaryBuffer();
Expand Down
3 changes: 0 additions & 3 deletions src/specific/s_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ void S_Output_ClearDepthBuffer(void);
void S_Output_SetWindowSize(int width, int height);
void S_Output_ApplyRenderSettings(void);

void S_Output_SetPalette(RGB_888 palette[256]);
RGB_888 S_Output_GetPaletteColor(uint8_t idx);

void S_Output_DownloadTextures(int32_t pages);
void S_Output_SelectTexture(int32_t texture_num);
void S_Output_DownloadBackdropSurface(const IMAGE *image);
Expand Down

0 comments on commit 44e4582

Please sign in to comment.