v2.1 - Add material getter methods #9

Merged
JackCarterSmith merged 3 commits from external-lib into master 2022-09-08 11:23:37 +02:00
9 changed files with 120 additions and 43 deletions

4
.gitignore vendored
View File

@ -15,8 +15,8 @@
# Precompiled Headers
*.gch
*.pch
RSPTerrainLib/src/config.h
RSETerrain/src/config.h
RSPTextureLib/src/config.h
RSETexture/src/config.h
# Libraries
*.lib

View File

@ -20,7 +20,7 @@ if(DEFINED ENV{CI}) # Jenkins CI integration mode
project(rse-texture VERSION $ENV{CI_VERSION}.$ENV{CI_BUILD_NUMBER} DESCRIPTION "RogueSquadron Extractor - Texture" LANGUAGES C)
set(RSE_TEXTURE_NAME $ENV{CI_OUTPUT_NAME})
else() # Standalone project mode, should not be used for release.
project(rse-texture VERSION 2.0.0 DESCRIPTION "RogueSquadron Extractor - Texture" LANGUAGES C)
project(rse-texture VERSION 2.1.0 DESCRIPTION "RogueSquadron Extractor - Texture" LANGUAGES C)
set(RSE_TEXTURE_NAME RSETexture)
endif()
set(RSP_TEXTURE_LIB_NAME RSPTexture${PROJECT_VERSION_MAJOR}${PROJECT_VERSION_MINOR})

2
Jenkinsfile vendored
View File

@ -5,7 +5,7 @@ pipeline {
}
environment {
CI_OUTPUT_NAME = "RSETexture"
CI_VERSION = "2.0.1"
CI_VERSION = "2.1.0"
CI_BUILD_NUMBER = "$BUILD_NUMBER"
}
stages {

View File

@ -54,6 +54,8 @@ extern "C" {
*/
RSPTEXTURE_EXTERN char* RSPTexture_getVersion( void );
RSPTEXTURE_EXTERN T_RSPTEXTURE_HMT* RSPTexture_createHMT( void );
/**
* @brief Run texture parser for the specified file in file system.
* @details Texture library can process HMT file from file system. It's a easy
@ -88,6 +90,26 @@ 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.
*
* @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
);
RSPTEXTURE_EXTERN char* RSPTexture_getMaterialName( const T_RSPTEXTURE_MATERIAL* mat );
RSPTEXTURE_EXTERN float RSPTexture_getMaterialOpacity( const T_RSPTEXTURE_MATERIAL* mat );
RSPTEXTURE_EXTERN float RSPTexture_getMaterialAmbient( const T_RSPTEXTURE_MATERIAL* mat );
/**
* @brief Clean HMT object and it's childrens from memory.
* @param[in] hmtStruct Pointer to data to be cleaned up.

View File

@ -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,22 @@ 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;
float opacity; //TODO: temporary, need to be defined
float ambient; //TODO: temporary, need to be defined
T_RSPTEXTURE_TEXTURE* texture;
} T_RSPTEXTURE_MATERIAL;
typedef struct rsptexture_hmt {
unsigned int materials_count;
unsigned int textures_count;

View File

@ -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.
@ -17,10 +17,20 @@
#include "RSPTexture.h"
/*
* Libs interface
*/
inline char* RSPTexture_getVersion( void ) {
return PRG_VERSION;
}
/*
* HMT parser
*/
T_RSPTEXTURE_HMT* RSPTexture_createHMT( void ) {
return calloc(1, sizeof(T_RSPTEXTURE_HMT));
}
unsigned short RSPTexture_processHMTFile( T_RSPTEXTURE_HMT* hmtStruct, const char* const filePath,
const RSPTEXTURE_PARAMETERS params ) {
@ -37,7 +47,35 @@ unsigned short RSPTexture_processHMTFileMemory( T_RSPTEXTURE_HMT* hmtStruct, con
return RSP_TextureLib_ParseHMTMemFile((MEMFILE)memFilePtr, hmtStruct, &params);
}
void RSPTexture_freeHMT(T_RSPTEXTURE_HMT* hmtStruct) {
/*
* Material utilities
*/
T_RSPTEXTURE_MATERIAL* RSPTexture_getMaterialFromID( const T_RSPTEXTURE_HMT* pHmt, const unsigned short mat_id ) {
if ( pHmt == NULL ) return NULL;
if ( pHmt->materials == NULL ) return NULL;
return &(pHmt->materials[mat_id]);
}
char* RSPTexture_getMaterialName( const T_RSPTEXTURE_MATERIAL* mat ) {
if ( mat == NULL ) return NULL;
return (char*)mat->name;
}
float RSPTexture_getMaterialOpacity( const T_RSPTEXTURE_MATERIAL* mat ) {
if ( mat == NULL ) return 1.0;
return mat->opacity;
}
float RSPTexture_getMaterialAmbient( const T_RSPTEXTURE_MATERIAL* mat ) {
if ( mat == NULL ) return 1.0;
return mat->ambient;
}
void RSPTexture_freeHMT( T_RSPTEXTURE_HMT* hmtStruct ) {
unsigned int i;
if (hmtStruct == NULL) return;

View File

@ -1,6 +0,0 @@
#ifndef CONFIG_H_
#define CONFIG_H_
#define PRG_VERSION "2.0.0"
#endif /* CONFIG_H_ */

View File

@ -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,19 +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;
pHmt->materials[i].opacity = ((T_HMTFILE_MATERIAL *)(pMemfile +
sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved1;
pHmt->materials[i].ambient = ((T_HMTFILE_MATERIAL *)(pMemfile +
sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved0;
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 id: %d\n", pHmt->materials[i].id);
printf("[INFO] > Material text. index: %d\n", i);
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);
printf("[DBG] > Material reserved1: %.8f\n", ((T_HMTFILE_MATERIAL *)(pMemfile +
sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved1);
printf("[DBG] > Material reserved0: %.8f\n", pHmt->materials[i].ambient);
printf("[DBG] > Material reserved1: %.8f\n", pHmt->materials[i].opacity);
printf("[DBG] > Material reserved2 (zero): 0x%X\n", ((T_HMTFILE_MATERIAL *)(pMemfile +
sizeof(T_HMTFILE_HEADER1) + sizeof(T_HMTFILE_MATERIAL) * i))->reserved2);
printf("[DBG] > Material reserved3 (0xA): 0x%X\n", ((T_HMTFILE_MATERIAL *)(pMemfile +
@ -193,6 +210,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 +263,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 +286,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 +296,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 +307,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;

View File

@ -46,10 +46,10 @@ typedef struct PACK hmtfile_material {
unsigned short type; // 1 - Material with texture / 2 - Material without texture
unsigned short texture_index;
float reserved0; // misc.
float reserved1; // Always 1.0f
float reserved0; // misc. Diffuse? Transparent?
float reserved1; // Always 1.0f Ambient?
unsigned int reserved2; // Zero
unsigned int reserved2; // Zero Specular?
unsigned int reserved3; // 0x0A
unsigned char name[16];