From 6fa57199574023cb87b4d033e8abcb8661ac7ad4 Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Thu, 1 Sep 2022 18:47:50 +0200 Subject: [PATCH] Prototype of dll material interface --- RSPTextureLib/include/RSPTexture.h | 16 +++++++ RSPTextureLib/include/RSPTexture_datatypes.h | 24 +++++----- RSPTextureLib/src/RSPTexture.c | 29 +++++++++++- RSPTextureLib/src/hmt_parser.c | 48 +++++++++++++------- 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/RSPTextureLib/include/RSPTexture.h b/RSPTextureLib/include/RSPTexture.h index f208531..9bc50a7 100644 --- a/RSPTextureLib/include/RSPTexture.h +++ b/RSPTextureLib/include/RSPTexture.h @@ -88,6 +88,22 @@ RSPTEXTURE_EXTERN unsigned short RSPTexture_processHMTFileMemory( const RSPTEXTURE_PARAMETERS params ); +/** + * @brief Parse HMT materials for specific ID. + * @pre HMT structure should be processed with RSPTexture_processHMTFile() + * or RSPTexture_processHMTMemFile() before. + * + * @param[in] pHmt HMT texture structure to be analyzed. + * @param[in] mat_id ID of the material. + * @param[in] mat_type Type of the material. + * + * @return Pointer to T_RSPTEXTURE_MATERIAL if found or NULL otherwise. + */ +RSPTEXTURE_EXTERN T_RSPTEXTURE_MATERIAL* RSPTexture_getMaterialFromID( + const T_RSPTEXTURE_HMT* pHmt, const unsigned short mat_id, + const RSPTEX_MAT_TYPE mat_type + ); + /** * @brief Clean HMT object and it's childrens from memory. * @param[in] hmtStruct Pointer to data to be cleaned up. diff --git a/RSPTextureLib/include/RSPTexture_datatypes.h b/RSPTextureLib/include/RSPTexture_datatypes.h index 0c0dce7..daf9da3 100644 --- a/RSPTextureLib/include/RSPTexture_datatypes.h +++ b/RSPTextureLib/include/RSPTexture_datatypes.h @@ -44,15 +44,13 @@ typedef struct r8g8b8 { unsigned char r,g,b; } T_R8G8B8; typedef struct r8g8b8a8 { unsigned char r,g,b,a; } T_R8G8B8A8; #endif +typedef enum e_mat_type { + RSPTEX_MAT_TYPE_TEXTURED = 1, + RSPTEX_MAT_TYPE_SOLID = 2 +} RSPTEX_MAT_TYPE; + typedef unsigned char T_SAMPLE; -typedef struct rsptexture_material { - unsigned char name[17]; // 16 + 1 string ending \0 - unsigned short type; - - unsigned short texture_index; //TODO: pointer to a T_RSPTEXTURE_TEXTURE element? -} T_RSPTEXTURE_MATERIAL; - typedef struct rsptexture_texture { unsigned char name[17]; // 16 + 1 string ending \0 unsigned short width; @@ -61,15 +59,19 @@ typedef struct rsptexture_texture { unsigned char type; unsigned char sample_bits; unsigned int palette_entries; - T_R8G8B8A8 alpha_color; - unsigned int palette_offset; //TODO: useless? - unsigned int pixels_offset; //TODO: useless? - T_R8G8B8A8* pixels; } T_RSPTEXTURE_TEXTURE; +typedef struct rsptexture_material { + unsigned short id; + unsigned char name[17]; // 16 + 1 string ending \0 + RSPTEX_MAT_TYPE type; + + T_RSPTEXTURE_TEXTURE* texture; +} T_RSPTEXTURE_MATERIAL; + typedef struct rsptexture_hmt { unsigned int materials_count; unsigned int textures_count; diff --git a/RSPTextureLib/src/RSPTexture.c b/RSPTextureLib/src/RSPTexture.c index e32518e..2eea7d1 100644 --- a/RSPTextureLib/src/RSPTexture.c +++ b/RSPTextureLib/src/RSPTexture.c @@ -1,6 +1,6 @@ /** * @file RSPTexture.c - * @date 25/08/2022 + * @date 31/08/2022 * @author JackCarterSmith * @copyright GPL-v3.0 * @brief HMT textures datas parser and export to PNG format. @@ -37,7 +37,32 @@ unsigned short RSPTexture_processHMTFileMemory( T_RSPTEXTURE_HMT* hmtStruct, con return RSP_TextureLib_ParseHMTMemFile((MEMFILE)memFilePtr, hmtStruct, ¶ms); } -void RSPTexture_freeHMT(T_RSPTEXTURE_HMT* hmtStruct) { +T_RSPTEXTURE_MATERIAL* RSPTexture_getMaterialFromID( const T_RSPTEXTURE_HMT* pHmt, + const unsigned short mat_id, const RSPTEX_MAT_TYPE mat_type ) { + unsigned int i; + char mat_template_str[17]; + + if ( pHmt == NULL ) return NULL; + if ( pHmt->materials == NULL ) return NULL; + + if (mat_type == RSPTEX_MAT_TYPE_SOLID) { + snprintf(mat_template_str, 16, "mat_%d", mat_id); + + for ( i = 0; i < pHmt->materials_count; i++ ) { + if (strcmp((char *)pHmt->materials[i].name, mat_template_str) == 0) + return &(pHmt->materials[i]); + } + } else if (mat_type == RSPTEX_MAT_TYPE_TEXTURED) { + for ( i = 0; i < pHmt->materials_count; i++ ) { + if (pHmt->materials[i].id == mat_id && pHmt->materials[i].type == RSPTEX_MAT_TYPE_TEXTURED) + return &(pHmt->materials[i]); + } + } + + return NULL; +} + +void RSPTexture_freeHMT( T_RSPTEXTURE_HMT* hmtStruct ) { unsigned int i; if (hmtStruct == NULL) return; diff --git a/RSPTextureLib/src/hmt_parser.c b/RSPTextureLib/src/hmt_parser.c index 51f33cc..28b84b8 100644 --- a/RSPTextureLib/src/hmt_parser.c +++ b/RSPTextureLib/src/hmt_parser.c @@ -117,14 +117,15 @@ static unsigned short ExtractTextureHMT(T_RSPTEXTURE_HMT* pHmtStruct, const MEMF if (pParams->verbose_mode) printf("[DBG] > Texture offset: 0x%X\n", pHmtStruct->texture_offset); printf("\n"); - // Get materials if any - if (pHmtStruct->materials_count > 0) - errorCode |= ExtractMaterials(pHmtStruct, pMemfile, pParams); - // Get textures if any if (pHmtStruct->textures_count > 0) errorCode |= ExtractTextures(pHmtStruct, pMemfile, pParams); + // Get materials if any and link them to texture + if (pHmtStruct->materials_count > 0) + errorCode |= ExtractMaterials(pHmtStruct, pMemfile, pParams); + + return errorCode; } @@ -156,21 +157,35 @@ static unsigned short ExtractMaterials(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMe // Get material datas pHmt->materials[i].type = ((T_HMTFILE_MATERIAL *)(pMemfile + sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->type; - pHmt->materials[i].texture_index = ((T_HMTFILE_MATERIAL *)(pMemfile + - sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->texture_index; // Texture index is only for texture "type" (1) + pHmt->materials[i].id = ((T_HMTFILE_MATERIAL *)(pMemfile + + sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->texture_index; + + // If material is textured, the linked texture correspond to tex_index in textures array. + if (pHmt->materials[i].type == RSPTEX_MAT_TYPE_TEXTURED) pHmt->materials[i].texture = pHmt->textures + pHmt->materials[i].id; + else pHmt->materials[i].texture = NULL; if (pParams->verbose_mode) { printf("[INFO] > Material name: %s\n", pHmt->materials[i].name); printf("[INFO] > Material type: %d\n", pHmt->materials[i].type); - printf("[INFO] > Material text. index: %d (valid if type == 1)\n", pHmt->materials[i].texture_index); + printf("[INFO] > Material text. index: %d\n", pHmt->materials[i].id); + if (pHmt->materials[i].type == RSPTEX_MAT_TYPE_TEXTURED) + printf("[INFO] > Linked texture name: %s (should correspond to material name)\n", pHmt->materials[i].texture->name); } + + /* + * Unassigned generic material datas : + * - Transparent + * - Ambient (global) + * - Diffuse (environnement) + * - Specular (self) + */ if (pParams->debug_mode) { printf("[DBG] > Material reserved0: %.8f\n", ((T_HMTFILE_MATERIAL *)(pMemfile + - sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved0); + sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved0); // Diffuse? / Transparent? printf("[DBG] > Material reserved1: %.8f\n", ((T_HMTFILE_MATERIAL *)(pMemfile + - sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved1); + sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved1); // Ambient? printf("[DBG] > Material reserved2 (zero): 0x%X\n", ((T_HMTFILE_MATERIAL *)(pMemfile + - sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved2); + sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved2); // Specular? printf("[DBG] > Material reserved3 (0xA): 0x%X\n", ((T_HMTFILE_MATERIAL *)(pMemfile + sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved3); } @@ -193,6 +208,7 @@ static unsigned short ExtractMaterials(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMe static unsigned short ExtractTextures(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMemfile, const RSPTEXTURE_PARAMETERS* pParams) { T_R8G8B8* _palette = NULL; T_SAMPLE* _samples = NULL; + unsigned int palette_offset, pixels_offset; unsigned int i; if (pHmt == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL; @@ -245,9 +261,9 @@ static unsigned short ExtractTextures(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMem sizeof(T_HMTFILE_HEADER2) + sizeof(T_HMTFILE_TEXTURE_HEADER) * i))->tex_format.transparent_color, sizeof(T_R8G8B8A8)); // Get texture datas offsets - pHmt->textures[i].pixels_offset = ((T_HMTFILE_TEXTURE_HEADER *)(pMemfile + pHmt->texture_offset + + pixels_offset = ((T_HMTFILE_TEXTURE_HEADER *)(pMemfile + pHmt->texture_offset + sizeof(T_HMTFILE_HEADER2) + sizeof(T_HMTFILE_TEXTURE_HEADER) * i))->pixels_offset; - pHmt->textures[i].palette_offset = ((T_HMTFILE_TEXTURE_HEADER *)(pMemfile + pHmt->texture_offset + + palette_offset = ((T_HMTFILE_TEXTURE_HEADER *)(pMemfile + pHmt->texture_offset + sizeof(T_HMTFILE_HEADER2) + sizeof(T_HMTFILE_TEXTURE_HEADER) * i))->palette_offset; // Get texture name @@ -268,8 +284,8 @@ static unsigned short ExtractTextures(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMem printf("[DBG] > Texture unknown0: 0x%X\n", ((T_HMTFILE_TEXTURE_HEADER *)(pMemfile + pHmt->texture_offset + sizeof(T_HMTFILE_HEADER2) + sizeof(T_HMTFILE_TEXTURE_HEADER) * i))->tex_format.unknown0); if (((T_HMTFILE_TEXTURE_HEADER *)(pMemfile + pHmt->texture_offset + sizeof(T_HMTFILE_HEADER2) + sizeof(T_HMTFILE_TEXTURE_HEADER) * i))->tex_format.reserved0 != 1) printf("[DBG] > Texture: Always 1 different.\n"); - printf("[DBG] > Texture palette offset: 0x%X\n", pHmt->textures[i].palette_offset); - printf("[DBG] > Texture pixels offset: 0x%X\n", pHmt->textures[i].pixels_offset); + printf("[DBG] > Texture palette offset: 0x%X\n", palette_offset); + printf("[DBG] > Texture pixels offset: 0x%X\n", pixels_offset); } // Retrieve palette datas from HMT file @@ -278,7 +294,7 @@ static unsigned short ExtractTextures(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMem case 256: _palette = (T_R8G8B8 *)realloc(_palette, sizeof(T_R8G8B8) * pHmt->textures[i].palette_entries); if (_palette) - memcpy(_palette, pMemfile + pHmt->textures[i].palette_offset, sizeof(T_R8G8B8) * pHmt->textures[i].palette_entries); + memcpy(_palette, pMemfile + palette_offset, sizeof(T_R8G8B8) * pHmt->textures[i].palette_entries); else return RSPLIB_ERROR_MEMORY; break; default: @@ -289,7 +305,7 @@ static unsigned short ExtractTextures(T_RSPTEXTURE_HMT* pHmt, const MEMFILE pMem //TODO: better approach? _samples = (T_SAMPLE *)realloc(_samples, pHmt->textures[i].width * pHmt->textures[i].height * pHmt->textures[i].sample_bits / 8); if (_samples) { - memcpy(_samples, pMemfile + pHmt->textures[i].pixels_offset, pHmt->textures[i].width * pHmt->textures[i].height * pHmt->textures[i].sample_bits / 8); + memcpy(_samples, pMemfile + pixels_offset, pHmt->textures[i].width * pHmt->textures[i].height * pHmt->textures[i].sample_bits / 8); //if (pHmt->textures[i].type == 2) memcpy(pHmt->textures[i].samples, pMemfile + pHmt->textures[i].pixels_offset, pHmt->textures[i].width * pHmt->textures[i].height * pHmt->textures[i].sample_bits / (8 * 4)); //TODO: manage texture type 2 } else return RSPLIB_ERROR_MEMORY;