ICB: ELDORADO: support newer texture format

This commit is contained in:
Joost Peters 2022-08-05 17:31:40 +02:00
parent 166e8fc5b4
commit c658a2e5d0
2 changed files with 71 additions and 21 deletions

View File

@ -30,14 +30,20 @@
namespace ICB {
#define REVTEX_API_ID "RTX"
#define REVTEX_API_SCHEMA 1
#define REVTEX_API_SCHEMA_ICB 1
#define REVTEX_API_SCHEMA_ELDORADO 2
#define MAX_PAL_ENTRIES (256)
typedef struct revtex_API_header {
char id[4];
uint32 schema;
} revtex_API_header;
// The level pointers within the RevTexture structure in this structure
// are relative addresses which get converted to absolute pointer by
// calling the Map function
typedef struct revtex_API {
typedef struct revtex_API_v1 {
char id[4];
uint32 schema;
@ -47,7 +53,20 @@ typedef struct revtex_API {
uint32 height; // must be power of 2
uint32 levelOffset[9]; // width/1 * height/1 -> width/256 * height/256
} revtex_API;
} revtex_API_v1;
typedef struct revtex_API_v2 {
char id[4];
uint32 schema;
uint32 transparent;
// RevTexture revtex;
uint32 palette[256]; // windows 32-bit RGB with 1 byte of padding
uint32 width; // must be power of 2
uint32 height; // must be power of 2
uint32 levelOffset[9]; // width/1 * height/1 -> width/256 * height/256
} revtex_API_v2;
} // End of namespace ICB

View File

@ -144,6 +144,7 @@ void DestoryRevRenderDevice() {
#define TEX 0
#define PAL 1
TextureHandle *texHans[MAX_NUM_TEX_HANS];
uint32 texTransparent[MAX_NUM_TEX_HANS];
uint32 texHanHashs[MAX_NUM_TEX_HANS][2];
uint32 texHanBaseHashs[MAX_NUM_TEX_HANS];
int32 numTexHans = 0;
@ -156,6 +157,7 @@ void ClearTextures() {
texHanHashs[i][TEX] = 0; // no hash so don't think we have this texture
texHanHashs[i][PAL] = 0; // no hash so don't think we have this texture
texHanBaseHashs[i] = 0; // ditto
texTransparent[i] = 0;
UnregisterTexture(texHans[i]);
}
@ -168,42 +170,71 @@ void ClearTextures() {
// open a new texture, add it to position numTexHans of texHans list...
void OpenTexture(const char *tex_name, uint32 tex_hash, const char *pal_name, uint32 pal_hash, const char *base, uint32 base_hash) {
// Load the texture
revtex_API *rTexAPI = (revtex_API *)rs_anims->Res_open(tex_name, tex_hash, base, base_hash);
revtex_API_header *rTexAPIHeader = (revtex_API_header *)rs_anims->Res_open(tex_name, tex_hash, base, base_hash);
// Check the texture file is correct ID & schema
if (READ_LE_UINT32((uint32 *)rTexAPI->id) != (*(uint32 *)const_cast<char *>(REVTEX_API_ID)))
Fatal_error("Invalid revtex_API id file %s API %s in file %s", rTexAPI->id, REVTEX_API_ID, tex_name);
if (READ_LE_UINT32((uint32 *)rTexAPIHeader->id) != (*(uint32 *)const_cast<char *>(REVTEX_API_ID)))
Fatal_error("Invalid revtex_API id file %s API %s in file %s", rTexAPIHeader->id, REVTEX_API_ID, tex_name);
if (FROM_LE_32(rTexAPI->schema) != REVTEX_API_SCHEMA)
Fatal_error("Invalid revtex_API file schema file %d API %d in file %s", FROM_LE_32(rTexAPI->schema), REVTEX_API_SCHEMA, tex_name);
if (FROM_LE_32(rTexAPIHeader->schema) != REVTEX_API_SCHEMA_ICB && FROM_LE_32(rTexAPIHeader->schema) != REVTEX_API_SCHEMA_ELDORADO)
Fatal_error("Invalid revtex_API file schema file %d in file %s", FROM_LE_32(rTexAPIHeader->schema), tex_name);
// Load the palette (it might be the same file !)
revtex_API *rPalAPI = (revtex_API *)rs_anims->Res_open(pal_name, pal_hash, base, base_hash);
revtex_API_header *rPalAPIHeader = (revtex_API_header *)rs_anims->Res_open(pal_name, pal_hash, base, base_hash);
// Is the palette different ?
if (rPalAPI != rTexAPI) {
if (rPalAPIHeader != rTexAPIHeader) {
// It's different !
if ((READ_LE_UINT32((uint32 *)rPalAPI->id)) != (*(uint32 *)const_cast<char *>(REVTEX_API_ID)))
Fatal_error("Invalid revtex_API id file %s API %s in file %s", rTexAPI->id, REVTEX_API_ID, pal_name);
if ((READ_LE_UINT32((uint32 *)rPalAPIHeader->id)) != (*(uint32 *)const_cast<char *>(REVTEX_API_ID)))
Fatal_error("Invalid revtex_API id file %s API %s in file %s", rPalAPIHeader->id, REVTEX_API_ID, pal_name);
if (FROM_LE_32(rPalAPI->schema) != REVTEX_API_SCHEMA)
Fatal_error("Invalid revtex_API file schema file %d API %d in file %s", FROM_LE_32(rTexAPI->schema), REVTEX_API_SCHEMA, pal_name);
if (FROM_LE_32(rPalAPIHeader->schema) != REVTEX_API_SCHEMA_ICB && FROM_LE_32(rPalAPIHeader->schema) != REVTEX_API_SCHEMA_ELDORADO)
Fatal_error("Invalid revtex_API file schema file %d in file %s", FROM_LE_32(rPalAPIHeader->schema), pal_name);
// Copy the palette into the texture
memcpy(rTexAPI->palette, rPalAPI->palette, 256 * sizeof(uint32));
if (FROM_LE_32(rTexAPIHeader->schema) != FROM_LE_32(rPalAPIHeader->schema))
Fatal_error("revtex_API file schema mismatch %d != %d", FROM_LE_32(rTexAPIHeader->schema), FROM_LE_32(rPalAPIHeader->schema));
if (FROM_LE_32(rTexAPIHeader->schema) == REVTEX_API_SCHEMA_ICB) {
revtex_API_v1 *rTexAPI = (revtex_API_v1 *)rTexAPIHeader;
revtex_API_v1 *rPalAPI = (revtex_API_v1 *)rPalAPIHeader;
// Copy the palette into the texture
memcpy(rTexAPI->palette, rPalAPI->palette, 256 * sizeof(uint32));
} else if (FROM_LE_32(rTexAPIHeader->schema) == REVTEX_API_SCHEMA_ELDORADO) {
revtex_API_v2 *rTexAPI = (revtex_API_v2 *)rTexAPIHeader;
revtex_API_v2 *rPalAPI = (revtex_API_v2 *)rPalAPIHeader;
// Copy the palette into the texture
memcpy(rTexAPI->palette, rPalAPI->palette, 256 * sizeof(uint32));
}
}
// Set up RevTexture structure
RevTexture revTex;
revTex.palette = rTexAPI->palette;
revTex.width = FROM_LE_32(rTexAPI->width);
revTex.height = FROM_LE_32(rTexAPI->height);
for (int32 i = 0; i < 9; i++) {
revTex.level[i] = (uint8 *)rTexAPI + FROM_LE_32(rTexAPI->levelOffset[i]);
uint32 transparent = 0;
if (FROM_LE_32(rTexAPIHeader->schema) == REVTEX_API_SCHEMA_ICB) {
revtex_API_v1 *rTexAPI = (revtex_API_v1 *)rTexAPIHeader;
revTex.palette = rTexAPI->palette;
revTex.width = FROM_LE_32(rTexAPI->width);
revTex.height = FROM_LE_32(rTexAPI->height);
for (int32 i = 0; i < 9; i++) {
revTex.level[i] = (uint8 *)rTexAPI + FROM_LE_32(rTexAPI->levelOffset[i]);
}
} else if (FROM_LE_32(rTexAPIHeader->schema) == REVTEX_API_SCHEMA_ELDORADO) {
revtex_API_v2 *rTexAPI = (revtex_API_v2 *)rTexAPIHeader;
revTex.palette = rTexAPI->palette;
revTex.width = FROM_LE_32(rTexAPI->width);
revTex.height = FROM_LE_32(rTexAPI->height);
for (int32 i = 0; i < 9; i++) {
revTex.level[i] = (uint8 *)rTexAPI + FROM_LE_32(rTexAPI->levelOffset[i]);
}
transparent = rTexAPI->transparent;
}
// Register the texture
texHans[numTexHans] = RegisterTexture(&revTex);
texTransparent[numTexHans] = transparent;
texHanHashs[numTexHans][TEX] = tex_hash;
texHanHashs[numTexHans][PAL] = pal_hash;
texHanBaseHashs[numTexHans] = base_hash;