Added more documentation

This commit is contained in:
JackCarterSmith 2022-08-19 18:03:47 +02:00
parent be31c972c4
commit 35ed66466b
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
7 changed files with 170 additions and 427 deletions

View File

@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
unsigned char p; unsigned char p;
// Hello world! // Hello world!
printf("\n*** RogueSquadron Extractor (RSE) - MODEL module - v%s ***\n", PRG_VERSION); printf("\n*** RogueSquadron Extractor (RSE) - MODEL module - v%s ***\n", RSPModel_getVersion());
// Check for arguments // Check for arguments
if (argc < 2) { if (argc < 2) {

View File

@ -122,7 +122,7 @@ unsigned char exportOBJModel(T_RSPMODEL_OBJECT* hob_objects, const char *out_pat
static void mtlPathPatch(const char* out_file, const char* obj_name) { static void mtlPathPatch(const char* out_file, const char* obj_name) {
FILE* obj = NULL; FILE* obj = NULL;
char* memFile = NULL; char* memFile = NULL;
long fileSize,i,pos = 0,lines; long fileSize,i,pos = 0,lines = 0;
char _path[128],b; char _path[128],b;
obj = fopen(out_file, "r"); obj = fopen(out_file, "r");

View File

@ -64,7 +64,9 @@ RSPMODEL_EXTERN char* RSPModel_getVersion( void );
* *
* @return Error status, return RSPLIB_SUCCESS in nominal case. * @return Error status, return RSPLIB_SUCCESS in nominal case.
*/ */
RSPMODEL_EXTERN unsigned short RSPModel_processHOBFile( T_RSPMODEL_HOB* hob, const char* const filePath ); RSPMODEL_EXTERN unsigned short RSPModel_processHOBFile(
T_RSPMODEL_HOB* hob, const char* const filePath
);
/** /**
* @brief Run model parser for the specified file in memory. * @brief Run model parser for the specified file in memory.
@ -78,7 +80,9 @@ RSPMODEL_EXTERN unsigned short RSPModel_processHOBFile( T_RSPMODEL_HOB* hob, con
* *
* @return Error status, return RSPLIB_SUCCESS in nominal case. * @return Error status, return RSPLIB_SUCCESS in nominal case.
*/ */
RSPMODEL_EXTERN unsigned short RSPModel_processHOBFileMemory( T_RSPMODEL_HOB* hob, const void* const memFilePtr, const long memFileSize ); RSPMODEL_EXTERN unsigned short RSPModel_processHOBFileMemory(
T_RSPMODEL_HOB* hob, const void* const memFilePtr, const long memFileSize
);
/** /**
* @brief Convert HOB's object datas to GL compatible format. * @brief Convert HOB's object datas to GL compatible format.
@ -89,7 +93,9 @@ RSPMODEL_EXTERN unsigned short RSPModel_processHOBFileMemory( T_RSPMODEL_HOB* ho
* *
* @return Error status, return RSPLIB_SUCCESS in nominal case. * @return Error status, return RSPLIB_SUCCESS in nominal case.
*/ */
RSPMODEL_EXTERN unsigned short RSPModel_objectToGL( const T_RSPMODEL_OBJECT* objStruct, void* glObj ); RSPMODEL_EXTERN unsigned short RSPModel_objectToGL(
const T_RSPMODEL_OBJECT* objStruct, void* glObj
);
/** /**
* @brief Convert HOB's object datas to Direct3D compatible format. * @brief Convert HOB's object datas to Direct3D compatible format.
@ -100,7 +106,9 @@ RSPMODEL_EXTERN unsigned short RSPModel_objectToGL( const T_RSPMODEL_OBJECT* obj
* *
* @return Error status, return RSPLIB_SUCCESS in nominal case. * @return Error status, return RSPLIB_SUCCESS in nominal case.
*/ */
RSPMODEL_EXTERN unsigned short RSPModel_objectToD3D( const T_RSPMODEL_OBJECT* objStruct, void* D3DObj ); RSPMODEL_EXTERN unsigned short RSPModel_objectToD3D(
const T_RSPMODEL_OBJECT* objStruct, void* D3DObj
);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -14,9 +14,11 @@
extern "C" { extern "C" {
#endif #endif
/////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Lib's structure definitions // Lib's structure definitions
/////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef char* MEMFILE;
typedef unsigned int T_RGBA; typedef unsigned int T_RGBA;

View File

@ -36,7 +36,11 @@ unsigned short RSPModel_processHOBFile( T_RSPMODEL_HOB* hob, const char* const f
unsigned short RSPModel_processHOBFileMemory( T_RSPMODEL_HOB* hob, const void* const memFilePtr, const long memFileSize ) { unsigned short RSPModel_processHOBFileMemory( T_RSPMODEL_HOB* hob, const void* const memFilePtr, const long memFileSize ) {
if ( hob == NULL || memFilePtr == NULL ) return RSPLIB_ERROR_ARGS_NULL; if ( hob == NULL || memFilePtr == NULL ) return RSPLIB_ERROR_ARGS_NULL;
T_PROG_OPTIONS canard;
canard.god_mode = 1;
canard.debug_mode = 1;
canard.verbose_mode = 1;
RSP_ModelLib_ParseHOBMemFile((MEMFILE)memFilePtr, hob, &canard);
return RSPLIB_SUCCESS; return RSPLIB_SUCCESS;
} }

View File

@ -1,9 +1,9 @@
/** /**
* @file hob_parser.c * @file hob_parser.c
* @date 26/07/2022 * @date 18/08/2022
* @author JackCarterSmith * @author JackCarterSmith
* @copyright GPL-v3.0 * @copyright GPL-v3.0
* @brief Decode HOB file structure. * @brief Process HOB file structure and extract its datas.
* *
*/ */
@ -17,14 +17,34 @@
#include "hob_parser.h" #include "hob_parser.h"
////////////////////////////////////////////////////////////////////////////////
// Private functions declarations
////////////////////////////////////////////////////////////////////////////////
static unsigned int ExtractObjects(T_RSPMODEL_HOB*, const MEMFILE, const unsigned char); static unsigned int ExtractObjects(T_RSPMODEL_HOB*, const MEMFILE, const unsigned char);
static unsigned int ExtractObjParts(T_RSPMODEL_OBJECT*, const MEMFILE, const unsigned char); static unsigned int ExtractObjParts(T_RSPMODEL_OBJECT*, const MEMFILE, const unsigned char);
static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS*, const MEMFILE, const unsigned char); static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS*, const MEMFILE, const unsigned char);
static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE*, const char*); static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE*, const char*);
static inline unsigned int ExtractObjpart_Face_UVMaps(T_RSPMODEL_FACE*, const char*); static inline unsigned int ExtractObjpart_Face_UVMaps(T_RSPMODEL_FACE*, const char*);
////////////////////////////////////////////////////////////////////////////////
// Public functions definition
////////////////////////////////////////////////////////////////////////////////
unsigned char RSP_ModelLib_ParseHOBMemFile(const MEMFILE pMemFile, T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts) {
unsigned char err = RSPLIB_SUCCESS;
if (hob_struct != NULL && pMemFile != NULL) {
// Do the magic!
err = ExtractObjects(hob_struct, pMemFile, p_opts->verbose_mode + p_opts->debug_mode + p_opts->god_mode);
} else err = RSPLIB_ERROR_ARGS_NULL;
return err;
}
unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts) { unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts) {
unsigned char err = NO_ERROR; unsigned char err = RSPLIB_SUCCESS;
long fileSize; long fileSize;
FILE* fStream = NULL; FILE* fStream = NULL;
MEMFILE memFile = NULL; MEMFILE memFile = NULL;
@ -47,352 +67,7 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
fclose(fStream); fclose(fStream);
// Do the magic! // Do the magic!
ExtractObjects(hob_struct, memFile, p_opts->verbose_mode + p_opts->debug_mode + p_opts->god_mode); err = ExtractObjects(hob_struct, memFile, p_opts->verbose_mode + p_opts->debug_mode + p_opts->god_mode);
/*
// Retrieve object count from the header
hob_struct->obj_count = ((T_HOBFILE_HEADER *)memFile)->obj_count;
printf("[INFO] - Object(s) quantity: %d\n", hob_struct->obj_count);
if (hob_struct->obj_count > 0) {
// Populate HOB structure with object descriptor
hob_struct->objects = calloc(hob_struct->obj_count, sizeof(T_RSPMODEL_OBJECT));
for ( i = 0; i < hob_struct->obj_count; i++ ) {
if (p_opts->debug_mode) printf("\n-=====================-Begin of Object part-======================-\n");
// Get object name
memcpy(hob_struct->objects[i].name, ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_name, 16);
if (p_opts->verbose_mode) printf("\n");
printf("[INFO] - Process %s object...\n", hob_struct->objects[i].name);
// Get offsets
hob_struct->objects[i].face_group_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset;
if (p_opts->verbose_mode) printf("[DBG] > Face group offset: 0x%X\n", hob_struct->objects[i].face_group_offset);
hob_struct->objects[i].object_part_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset;
if (p_opts->verbose_mode) printf("[DBG] > Face group header/object parts offset: 0x%X\n", hob_struct->objects[i].object_part_header_offset);
hob_struct->objects[i].face_group_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_header_2_offset;
if (p_opts->verbose_mode) printf("[DBG] > Face group header2 offset: 0x%X\n", hob_struct->objects[i].face_group_header_offset);
if (p_opts->god_mode) {
printf("[DBG] > Face group unknown1: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset1);
printf("[DBG] > Face group unknown2: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset2);
printf("[DBG] > Face group unknown3: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset3);
printf("[DBG] > Face group unknown4: %.8f\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknown4);
}
// Get count and offsets from the facegroup header
hob_struct->objects[i].object_part_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].object_part_header_offset))->object_part_count;
if (p_opts->verbose_mode) printf("[DBG] > Object parts count: %d\n", hob_struct->objects[i].object_part_count);
hob_struct->objects[i].face_group_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].object_part_header_offset))->facegroup_count;
if (p_opts->verbose_mode) printf("[DBG] > Face groups count: %d\n", hob_struct->objects[i].face_group_count);
if (hob_struct->objects[i].object_part_count != hob_struct->objects[i].face_group_count && (p_opts->verbose_mode))
printf("[DBG] > Object parts / facegroup count are different!\n");
// Get facegroup datas
offset_index = calloc(hob_struct->objects[i].object_part_count, sizeof(int));
hob_struct->objects[i].object_parts = calloc(hob_struct->objects[i].object_part_count, sizeof(T_HOB_FACE_GROUP));
for ( j = 0; j < hob_struct->objects[i].object_part_count; j++ ) {
if (p_opts->debug_mode) printf("\n-----------------------Begin of Mesh part-------------------------\n");
offset_index[j] = ((T_HOBFILE_FACEGROUP_OFFSET *)(memFile + hob_struct->objects[i].object_part_header_offset
+ sizeof(T_HOBFILE_FACEGROUP_HEADER)
+ sizeof(T_HOBFILE_FACEGROUP_OFFSET) * j))->facegroup_offset;
if (p_opts->verbose_mode) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]);
// Get meshdef0 datas
if (p_opts->god_mode) printf("[DBG] > meshdef0 offset1: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset1);
if (p_opts->god_mode) printf("[DBG] > meshdef0 offset2: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset2);
if (p_opts->verbose_mode) printf("[DBG] > Prev meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_offset);
if (p_opts->verbose_mode) printf("[DBG] > Next meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset);
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown3: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown3);
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown4: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown4);
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown5: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown5);
// Get meshdef1 (mesh descriptor) offset
hob_struct->objects[i].object_parts[j].meshdef1_offset = ((T_HOBFILE_MESHDEF0 *)(memFile
+ offset_index[j]))->meshdef1_offset_plus_4;
if (p_opts->verbose_mode) printf("\n[DBG] > Face group meshdef1 offset: 0x%X\n", hob_struct->objects[i].object_parts[j].meshdef1_offset);
if( ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved1 != 0 ||
((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved2 != 0 ) {
if (p_opts->god_mode) printf("[DBG] > Face group meshdef0: no 0!\n");
}
if (hob_struct->objects[i].object_parts[j].meshdef1_offset > 0) {
// Read meshdef1 datas
hob_struct->objects[i].object_parts[j].face_block_end_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->facedef_end_offset;
hob_struct->objects[i].object_parts[j].vertex_count = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertex_count;
hob_struct->objects[i].object_parts[j].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->faceblock_offset;
if (p_opts->verbose_mode) printf("[DBG] > Faces offset: 0x%X\n", hob_struct->objects[i].object_parts[j].face_block_offset);
hob_struct->objects[i].object_parts[j].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertexblocks_offset;
if (p_opts->verbose_mode) printf("[DBG] > Vertex offset: 0x%X\n\n", hob_struct->objects[i].object_parts[j].vertex_block_offset);
// Get face datas
if( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved1 != 0 ||
((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved2 != 0 ) {
if (p_opts->god_mode) printf("[DBG] > Face block: uncommon zero header!\n");
}
if ( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->facesOffset !=
hob_struct->objects[i].object_parts[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) {
if (p_opts->god_mode) printf("[DBG] > Face block: uncommon face data offset position!\n");
}
hob_struct->objects[i].object_parts[j].face_count = ((T_HOBFILE_FACEBLOCK *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset))->faceCounts;
hob_struct->objects[i].object_parts[j].faces = calloc(hob_struct->objects[i].object_parts[j].face_count, sizeof(T_HOB_FACE));
facesExtraOffset = 0;
for ( k = 0; k < hob_struct->objects[i].object_parts[j].face_count; k++ ) {
if (p_opts->debug_mode) printf("\n----------------------Begin of FaceGroup part----------------------\n");
// Get flags
hob_struct->objects[i].object_parts[j].faces[k].flags = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->flags;
// Get unknown bytes
hob_struct->objects[i].object_parts[j].faces[k].b1 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b1;
hob_struct->objects[i].object_parts[j].faces[k].b2 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b2;
hob_struct->objects[i].object_parts[j].faces[k].b3 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b3;
hob_struct->objects[i].object_parts[j].faces[k].bsize = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number
if (((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->headerSeparator != 0) {
if (p_opts->god_mode) printf("[DBG] > Face header: uncommon separator!\n");
}
// Get materials index
hob_struct->objects[i].object_parts[j].faces[k].material_index = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->materialIndex;
// Get vertex indices
memcpy(hob_struct->objects[i].object_parts[j].faces[k].indices,
((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->vertexIndices,
sizeof(unsigned short) * 4);
// Recalculate the dynamic extra bytes offset size - if present
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8;
// Get vertex color - if present
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasColor) {
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fSeparateColorVertex) {
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v1_rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v2_rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v3_rgba;
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad) {
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v4_rgba;
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR);
} else {
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR) - sizeof(T_RGBA);
}
} else {
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
facesExtraOffset += sizeof(T_HOBFILE_FACES_COLOR);
}
}
// Get UV map - if present
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasTexture) {
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v1_texcoord;
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v2_texcoord;
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v3_texcoord;
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad) {
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v4_texcoord;
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_TEXTURE);
} else {
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_TEXTURE) - sizeof(T_TEXCOORD);
}
}
if (p_opts->debug_mode) {
printf("[DBG] > Face %d details: flags:0x%X b1:%d b2:%d b3%d bsize:%d\n", k,
hob_struct->objects[i].object_parts[j].faces[k].flags,
hob_struct->objects[i].object_parts[j].faces[k].b1,
hob_struct->objects[i].object_parts[j].faces[k].b2,
hob_struct->objects[i].object_parts[j].faces[k].b3,
hob_struct->objects[i].object_parts[j].faces[k].bsize
);
printf("[DBG] - Type is Quad: %d\n", hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad);
printf("[DBG] - Material offset: 0x%X\n", hob_struct->objects[i].object_parts[j].faces[k].material_index);
printf("[DBG] - Vertex indices: %d, %d, %d, %d\n",
hob_struct->objects[i].object_parts[j].faces[k].indices[0],
hob_struct->objects[i].object_parts[j].faces[k].indices[1],
hob_struct->objects[i].object_parts[j].faces[k].indices[2],
hob_struct->objects[i].object_parts[j].faces[k].indices[3]
);
printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n",
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0],
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1],
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2],
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3]
);
printf("[DBG] - Vertex UV coord (divided by 4096):\n");
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].v
);
printf("\n");
}
if (p_opts->debug_mode) printf("\n-----------------------End of FaceGroup part-----------------------\n");
}
// Get vertex datas
ExtractObjpartVertices(&hob_struct->objects[i].object_parts[j], memFile, p_opts->debug_mode);
}
// Get object part ID, used by animation? bones?
hob_struct->objects[i].object_parts[j].id = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->object_id;
if (p_opts->verbose_mode) printf("\n[DBG] > Facegroup/object ID: %d\n", hob_struct->objects[i].object_parts[j].id);
// Get the transform matrix, used by at-st and at-at (at this time)
hob_struct->objects[i].object_parts[j].transform.x = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_x;
hob_struct->objects[i].object_parts[j].transform.y = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_y;
hob_struct->objects[i].object_parts[j].transform.z = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_z;
if (p_opts->god_mode) printf("\n[DBG] > Facegroup/object transform matrix: [%.8f %.8f %.8f]\n",
hob_struct->objects[i].object_parts[j].transform.x,
hob_struct->objects[i].object_parts[j].transform.y,
hob_struct->objects[i].object_parts[j].transform.z
);
if (p_opts->debug_mode) printf("\n-----------------------End of Mesh part---------------------------\n");
}
if (p_opts->debug_mode) printf("\n-=====================-End of Object part-========================-\n");
}
free(offset_index);
} else {
err = RSPLIB_ERROR_GENERIC;
printf("[INFO] Can't process empty file!\n");
}
*/
free(memFile); free(memFile);
@ -410,11 +85,16 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
return err; return err;
} }
////////////////////////////////////////////////////////////////////////////////
// Private functions definition
////////////////////////////////////////////////////////////////////////////////
/** /**
* Count objects and extract datas from them. * @brief Count objects and extract datas from them.
* *
* @param[in|out] pHobStruct Take root hob structure to get the T_RSPMODEL_OBJECT buffer and header datas. * @param[in|out] pHobStruct Take root hob structure to get the T_RSPMODEL_OBJECT buffer and header datas.
* @param[in] pMemfile * @param[in] pMemfile Pointer to an in-memory file location.
* @param[in] verbose * @param[in] verbose
* *
* @return Error code, RSPLIB_SUCCESS when no error. * @return Error code, RSPLIB_SUCCESS when no error.
@ -483,10 +163,10 @@ static unsigned int ExtractObjects(T_RSPMODEL_HOB* pHobStruct, const MEMFILE pMe
} }
/** /**
* Count object's sub-part and extract datas from them. * @brief Count object's sub-part and extract datas from them.
* *
* @param[in|out] pObject Take object structure to get the T_RSPMODEL_OBJ_PARTS buffer and object datas. * @param[in|out] pObject Take object structure to get the T_RSPMODEL_OBJ_PARTS buffer and object datas.
* @param[in] pMemfile * @param[in] pMemfile Pointer to an in-memory file location.
* @param[in] verbose * @param[in] verbose
* *
* @return Error code, RSPLIB_SUCCESS when no error. * @return Error code, RSPLIB_SUCCESS when no error.
@ -564,111 +244,111 @@ static unsigned int ExtractObjParts(T_RSPMODEL_OBJECT* pObject, const MEMFILE pM
} }
/** /**
* Extract datas from faces in object sub-part. * @brief Extract datas from faces from object sub-part.
* *
* @param[in|out] pObjParts * @param[in|out] pObjPart Take object sub-part structure to get the T_RSPMODEL_FACE buffer and object sub-part datas.
* @param[in] pMemfile * @param[in] pMemfile Pointer to an in-memory file location.
* @param[in] verbose * @param[in] verbose
* *
* @return Error code, RSPLIB_SUCCESS when no error. * @return Error code, RSPLIB_SUCCESS when no error.
*/ */
static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS* pObjParts, const MEMFILE pMemfile, const unsigned char verbose) { static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS* pObjPart, const MEMFILE pMemfile, const unsigned char verbose) {
unsigned int i, facesExtraOffset = 0; unsigned int i, facesExtraOffset = 0;
if (pObjParts == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL; if (pObjPart == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL;
if( ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->reserved1 != 0 || if( ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjPart->face_block_offset))->reserved1 != 0 ||
((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->reserved2 != 0 ) { ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjPart->face_block_offset))->reserved2 != 0 ) {
if (verbose == 3) printf("[DBG] > Face block: uncommon zero header!\n"); if (verbose == 3) printf("[DBG] > Face block: uncommon zero header!\n");
} }
if ( ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->facesOffset != if ( ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjPart->face_block_offset))->facesOffset !=
pObjParts->face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) { pObjPart->face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) {
if (verbose == 3) printf("[DBG] > Face block: uncommon face data offset position!\n"); if (verbose == 3) printf("[DBG] > Face block: uncommon face data offset position!\n");
} }
pObjParts->face_count = ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->faceCounts; pObjPart->face_count = ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjPart->face_block_offset))->faceCounts;
pObjParts->faces = calloc(pObjParts->face_count, sizeof(T_RSPMODEL_FACE)); pObjPart->faces = calloc(pObjPart->face_count, sizeof(T_RSPMODEL_FACE));
for ( i = 0; i < pObjParts->face_count; i++ ) { for ( i = 0; i < pObjPart->face_count; i++ ) {
if (verbose == 2) printf("\n----------------------Begin of FaceGroup part----------------------\n"); if (verbose == 2) printf("\n----------------------Begin of FaceGroup part----------------------\n");
// Get flags // Get flags
pObjParts->faces[i].flags = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset pObjPart->faces[i].flags = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->flags; + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->flags;
// Get unknown bytes // Get unknown bytes
pObjParts->faces[i].b1 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset pObjPart->faces[i].b1 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b1; + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b1;
pObjParts->faces[i].b2 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset pObjPart->faces[i].b2 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b2; + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b2;
pObjParts->faces[i].b3 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset pObjPart->faces[i].b3 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b3; + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b3;
pObjParts->faces[i].bsize = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset pObjPart->faces[i].bsize = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number
if (((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset + sizeof(T_HOBFILE_FACEBLOCK) if (((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->headerSeparator != 0) { + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->headerSeparator != 0) {
if (verbose == 3) printf("[DBG] > Face header: uncommon separator!\n"); if (verbose == 3) printf("[DBG] > Face header: uncommon separator!\n");
} }
// Get materials index // Get materials index
pObjParts->faces[i].material_index = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset pObjPart->faces[i].material_index = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->materialIndex; + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->materialIndex;
// Get vertex indices // Get vertex indices
memcpy(pObjParts->faces[i].indices, ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset memcpy(pObjPart->faces[i].indices, ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->vertexIndices, + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->vertexIndices,
sizeof(unsigned short) * 4); sizeof(unsigned short) * 4);
// Recalculate the dynamic extra bytes offset size - if present // Recalculate the dynamic extra bytes offset size - if present
if (pObjParts->faces[i].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8; if (pObjPart->faces[i].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8;
// Get vertex color - if present // Get vertex color - if present
if (pObjParts->faces[i].flags_bits.fHasColor) { if (pObjPart->faces[i].flags_bits.fHasColor) {
facesExtraOffset += ExtractObjpart_Face_Colors(&pObjParts->faces[i], pMemfile + pObjParts->face_block_offset facesExtraOffset += ExtractObjpart_Face_Colors(&pObjPart->faces[i], pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER) * i + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER) * i
+ facesExtraOffset); + facesExtraOffset);
} }
// Get UV map - if present // Get UV map - if present
if (pObjParts->faces[i].flags_bits.fHasTexture) { if (pObjPart->faces[i].flags_bits.fHasTexture) {
facesExtraOffset += ExtractObjpart_Face_UVMaps(&pObjParts->faces[i], pMemfile + pObjParts->face_block_offset facesExtraOffset += ExtractObjpart_Face_UVMaps(&pObjPart->faces[i], pMemfile + pObjPart->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER) * i + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER) * i
+ facesExtraOffset); + facesExtraOffset);
} }
if (verbose == 2) { if (verbose == 2) {
printf("[DBG] > Face %d details: flags:0x%X b1:%d b2:%d b3%d bsize:%d\n", i, pObjParts->faces[i].flags, printf("[DBG] > Face %d details: flags:0x%X b1:%d b2:%d b3%d bsize:%d\n", i, pObjPart->faces[i].flags,
pObjParts->faces[i].b1, pObjParts->faces[i].b2, pObjParts->faces[i].b3, pObjParts->faces[i].bsize); pObjPart->faces[i].b1, pObjPart->faces[i].b2, pObjPart->faces[i].b3, pObjPart->faces[i].bsize);
printf("[DBG] - Type is Quad: %d\n", pObjParts->faces[i].flags_bits.fIsQuad); printf("[DBG] - Type is Quad: %d\n", pObjPart->faces[i].flags_bits.fIsQuad);
printf("[DBG] - Material offset: 0x%X\n", pObjParts->faces[i].material_index); printf("[DBG] - Material offset: 0x%X\n", pObjPart->faces[i].material_index);
printf("[DBG] - Vertex indices: %d, %d, %d, %d\n", pObjParts->faces[i].indices[0], pObjParts->faces[i].indices[1], printf("[DBG] - Vertex indices: %d, %d, %d, %d\n", pObjPart->faces[i].indices[0], pObjPart->faces[i].indices[1],
pObjParts->faces[i].indices[2], pObjParts->faces[i].indices[3]); pObjPart->faces[i].indices[2], pObjPart->faces[i].indices[3]);
printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n", pObjParts->faces[i].vertex_colors[0], printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n", pObjPart->faces[i].vertex_colors[0],
pObjParts->faces[i].vertex_colors[1], pObjParts->faces[i].vertex_colors[2], pObjParts->faces[i].vertex_colors[3]); pObjPart->faces[i].vertex_colors[1], pObjPart->faces[i].vertex_colors[2], pObjPart->faces[i].vertex_colors[3]);
printf("[DBG] - Vertex UV coord (divided by 4096):\n"); printf("[DBG] - Vertex UV coord (divided by 4096):\n");
printf("[DBG] > %.8f(%d), %.8f(%d)\n", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[0].u, ((double) 1/4096) * pObjPart->faces[i].tex_coords[0].u,
pObjParts->faces[i].tex_coords[0].u, pObjPart->faces[i].tex_coords[0].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[0].v, ((double) 1/4096) * pObjPart->faces[i].tex_coords[0].v,
pObjParts->faces[i].tex_coords[0].v pObjPart->faces[i].tex_coords[0].v
); );
printf("[DBG] > %.8f(%d), %.8f(%d)\n", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[1].u, ((double) 1/4096) * pObjPart->faces[i].tex_coords[1].u,
pObjParts->faces[i].tex_coords[1].u, pObjPart->faces[i].tex_coords[1].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[1].v, ((double) 1/4096) * pObjPart->faces[i].tex_coords[1].v,
pObjParts->faces[i].tex_coords[1].v pObjPart->faces[i].tex_coords[1].v
); );
printf("[DBG] > %.8f(%d), %.8f(%d)\n", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[2].u, ((double) 1/4096) * pObjPart->faces[i].tex_coords[2].u,
pObjParts->faces[i].tex_coords[2].u, pObjPart->faces[i].tex_coords[2].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[2].v, ((double) 1/4096) * pObjPart->faces[i].tex_coords[2].v,
pObjParts->faces[i].tex_coords[2].v pObjPart->faces[i].tex_coords[2].v
); );
printf("[DBG] > %.8f(%d), %.8f(%d)\n", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[3].u, ((double) 1/4096) * pObjPart->faces[i].tex_coords[3].u,
pObjParts->faces[i].tex_coords[3].u, pObjPart->faces[i].tex_coords[3].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[3].v, ((double) 1/4096) * pObjPart->faces[i].tex_coords[3].v,
pObjParts->faces[i].tex_coords[3].v pObjPart->faces[i].tex_coords[3].v
); );
printf("\n"); printf("\n");
} }
@ -677,30 +357,39 @@ static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS* pObjParts, const
} }
// Get vertex datas // Get vertex datas
pObjParts->vertices = calloc(pObjParts->vertex_count, sizeof(T_VERTEX)); pObjPart->vertices = calloc(pObjPart->vertex_count, sizeof(T_VERTEX));
if (pObjParts->vertices == NULL) return RSPLIB_ERROR_MEMORY; if (pObjPart->vertices == NULL) return RSPLIB_ERROR_MEMORY;
for ( i = 0; i < pObjParts->vertex_count; i++ ) { for ( i = 0; i < pObjPart->vertex_count; i++ ) {
pObjParts->vertices[i].x = pObjPart->vertices[i].x =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->x; ((T_HOBFILE_VERTEX *)(pMemfile + pObjPart->vertex_block_offset + sizeof(T_VERTEX) * i))->x;
pObjParts->vertices[i].y = pObjPart->vertices[i].y =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->y; ((T_HOBFILE_VERTEX *)(pMemfile + pObjPart->vertex_block_offset + sizeof(T_VERTEX) * i))->y;
pObjParts->vertices[i].z = pObjPart->vertices[i].z =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->z; ((T_HOBFILE_VERTEX *)(pMemfile + pObjPart->vertex_block_offset + sizeof(T_VERTEX) * i))->z;
pObjParts->vertices[i].w = pObjPart->vertices[i].w =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->w; // Always 0??? ((T_HOBFILE_VERTEX *)(pMemfile + pObjPart->vertex_block_offset + sizeof(T_VERTEX) * i))->w; // Always 0???
if (verbose == 2) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", i, if (verbose == 2) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", i,
pObjParts->vertices[i].x, pObjParts->vertices[i].y, pObjParts->vertices[i].z pObjPart->vertices[i].x, pObjPart->vertices[i].y, pObjPart->vertices[i].z
); );
} }
return RSPLIB_SUCCESS; return RSPLIB_SUCCESS;
} }
/**
* @brief Extract colors from HOB's face to T_RSPMODEL_FACE instance.
*
* @param pFace[out] Pointer to an empty instance of T_RSPMODEL_FACE.
* @param pFaceMemFileOffset[in] Pointer to the in-memory location of face HOB datas.
* @warning Access to an unallocated memory location using this function result in an ACCESS_VIOLATION.
*
* @return The size of processed data. Used to count new offset between each face in object sub-part.
*/
static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE* pFace, const char* pFaceMemFileOffset) { static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE* pFace, const char* pFaceMemFileOffset) {
unsigned int dynOffset = 0; unsigned int dynOffset = 0;
@ -725,6 +414,15 @@ static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE* pFace, co
return dynOffset; return dynOffset;
} }
/**
* @brief Extract UV maps from HOB's face to T_RSPMODEL_FACE instance.
*
* @param pFace[out] Pointer to an empty instance of T_RSPMODEL_FACE.
* @param pFaceMemFileOffset[in] Pointer to the in-memory location of face HOB datas.
* @warning Access to an unallocated memory location using this function result in an ACCESS_VIOLATION.
*
* @return The size of processed data. Used to count new offset between each face in object sub-part.
*/
static inline unsigned int ExtractObjpart_Face_UVMaps(T_RSPMODEL_FACE* pFace, const char* pFaceMemFileOffset) { static inline unsigned int ExtractObjpart_Face_UVMaps(T_RSPMODEL_FACE* pFace, const char* pFaceMemFileOffset) {
unsigned int dynOffset = 0; unsigned int dynOffset = 0;

View File

@ -1,9 +1,9 @@
/** /**
* @file hob_parser.h * @file hob_parser.h
* @date 26/07/2022 * @date 18/08/2022
* @author JackCarterSmith * @author JackCarterSmith
* @copyright GPL-v3.0 * @copyright GPL-v3.0
* @brief Decode HOB file structure. * @brief Process HOB file structure and extract its datas.
* *
*/ */
@ -14,8 +14,39 @@
#ifndef SRC_HOB_PARSER_H_ #ifndef SRC_HOB_PARSER_H_
#define SRC_HOB_PARSER_H_ #define SRC_HOB_PARSER_H_
typedef char* MEMFILE; /**
* @brief Process HOB file stored in memory.
* @details Parser will directly extract objects count and information stored in
* HOB file and store them in T_RSPMODEL_HOB structure.
* @note Unmanaged mode
*
* @param[in] pMemFile Pointer to an in-memory HOB file location.
* @param[out] hob_struct Allocated empty T_RSPMODEL_HOB structure instance to
* be filled with HOB datas.
* @param[in] p_opts Parser options. DEPRECATED.
*
* @return Processing error code, RSPLIB_SUCCESS if no error.
*/
unsigned char RSP_ModelLib_ParseHOBMemFile(const MEMFILE pMemFile,
T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts);
unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts); /**
* @brief Process HOB file in file system.
* @details HOB file is dumped in memory before parsing in order to enhance
* performance during parser operation and in optic to protect data
* stored in the original file (read-only).
* Parser will extract objects count and information stored in HOB file
* and store them in T_RSPMODEL_HOB structure.
* @note Managed mode
*
* @param[in] fileName String value of file name/path.
* @param[out] hob_struct Allocated empty T_RSPMODEL_HOB structure instance to
* be filled with HOB datas.
* @param[in] p_opts Parser options. DEPRECATED.
*
* @return Processing error code, RSPLIB_SUCCESS if no error.
*/
unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName,
T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts);
#endif /* SRC_HOB_PARSER_H_ */ #endif /* SRC_HOB_PARSER_H_ */