diff --git a/Jenkinsfile b/Jenkinsfile index fe61954..c5a2d07 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { } environment { CI_OUTPUT_NAME = "RSE_Model" - CI_VERSION = "1.0.0" + CI_VERSION = "1.0.1" CI_BUILD_NUMBER = "$BUILD_NUMBER" } stages { diff --git a/src/Model-Extractor.c b/src/Model-Extractor.c index 2c70ea8..1475bc1 100644 --- a/src/Model-Extractor.c +++ b/src/Model-Extractor.c @@ -124,6 +124,12 @@ static int checkInputArgs(int arg_nbr, char *args[]) { } else if (strcmp(args[i], "-mtl") == 0) { _o &= ~EXPORT_MTL; printf("[OPTN] No materials datas.\n"); + } else if (strcmp(args[i], "-vv") == 0) { + _o |= DEBUG_MODE; + printf("[OPTN] Verbose enabled.\n"); + } else if (strcmp(args[i], "-vvv") == 0) { + _o |= GOD_MODE; + printf("[OPTN] Verbose enabled.\n"); } else { printf("[ERR] Unknown option: %s\n", args[i]); } @@ -167,7 +173,7 @@ static void cleanUpMemory(T_HOB* hobStruct) { static inline void dispHelp() { printf("\n"); printf("Options:\n -h Print this message\n"); - printf(" -v Activate verbose console output\n"); + printf(" -v -vv Activate verbose console output\n"); printf(" -no-subdir Export models inside current folder\n"); printf(" -no-mtl Disable materials datas export with model\n"); printf("\n"); diff --git a/src/hob_parser.c b/src/hob_parser.c index 0108257..606814c 100644 --- a/src/hob_parser.c +++ b/src/hob_parser.c @@ -48,6 +48,8 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { // Populate HOB structure with object descriptor hob_struct->objects = calloc(hob_struct->obj_count, sizeof(T_HOB_OBJECT)); for ( i = 0; i < hob_struct->obj_count; i++ ) { + if (_options & 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) @@ -64,51 +66,56 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset; if (_options & VERBOSE_ENABLED) 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_header2_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + 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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face group header2 offset: 0x%X\n", hob_struct->objects[i].face_group_header2_offset); + if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group header2 offset: 0x%X\n", hob_struct->objects[i].face_group_header_offset); + + if (_options & 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 (_options & VERBOSE_ENABLED) 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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face group count: %d\n", hob_struct->objects[i].face_group_count); - hob_struct->objects[i].face_group_count0 = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile - + hob_struct->objects[i].object_part_header_offset))->facegroup_count0; - if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group count0: %d\n", hob_struct->objects[i].face_group_count0); - if (hob_struct->objects[i].face_group_count != hob_struct->objects[i].face_group_count0 && (_options & VERBOSE_ENABLED)) printf("[DBG] > Facegroup count are different!\n"); + if (_options & VERBOSE_ENABLED) 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 && (_options & VERBOSE_ENABLED)) printf("[DBG] > Object parts / facegroup count are different!\n"); // Get facegroup datas - offset_index = calloc(hob_struct->objects[i].face_group_count, sizeof(int)); - hob_struct->objects[i].object_parts = calloc(hob_struct->objects[i].face_group_count, sizeof(T_HOB_FACE_GROUP)); - for ( j = 0; j < hob_struct->objects[i].face_group_count; j++ ) { + 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 (_options & 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 (_options & VERBOSE_ENABLED) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]); // Get meshdef0 datas - if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Next meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset); - if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Prev meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_offset); - hob_struct->objects[i].object_parts[j].id = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->object_id; - if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Facegroup/object ID: %d\n", hob_struct->objects[i].object_parts[j].id); - 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 (_options & VERBOSE_ENABLED) 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 (_options & GOD_MODE) printf("[DBG] > meshdef0 offset1: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset1); + if (_options & GOD_MODE) printf("[DBG] > meshdef0 offset2: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset2); + if (_options & VERBOSE_ENABLED) printf("[DBG] > Prev meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_offset); + if (_options & VERBOSE_ENABLED) printf("[DBG] > Next meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset); + + if (_options & GOD_MODE) printf("[DBG] > meshdef0 unknown3: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown3); + if (_options & GOD_MODE) printf("[DBG] > meshdef0 unknown4: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown4); + if (_options & 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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face group meshdef1 offset: 0x%X\n", hob_struct->objects[i].object_parts[j].meshdef1_offset); + if (_options & VERBOSE_ENABLED) 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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face group meshdef0: no 0!\n"); + if (_options & GOD_MODE) printf("[DBG] > Face group meshdef0: no 0!\n"); } if (hob_struct->objects[i].object_parts[j].meshdef1_offset > 0) { @@ -127,17 +134,19 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { // 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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face block: uncommon zero header!\n"); + if (_options & 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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face block: uncommon face data offset position!\n"); + if (_options & 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 (_options & 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 @@ -172,7 +181,7 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * k + facesExtraOffset))->headerSeparator != 0) { - if (_options & VERBOSE_ENABLED) printf("[DBG] > Face header: uncommon separator!\n"); + if (_options & GOD_MODE) printf("[DBG] > Face header: uncommon separator!\n"); } // Get materials index @@ -288,8 +297,8 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { } } - if (_options & VERBOSE_ENABLED) { - printf("[DBG] > Face %d details: 0x%X, %d, %d, %d, %d\n", k, + if (_options & 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, @@ -337,6 +346,8 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { ); printf("\n"); } + + if (_options & DEBUG_MODE) printf("\n-----------------------End of FaceGroup part-----------------------\n"); } // Get vertex datas @@ -358,14 +369,32 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { + hob_struct->objects[i].object_parts[j].vertex_block_offset + sizeof(T_VERTEX) * k))->w; // Always 0??? - if (_options & VERBOSE_ENABLED) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", k, + if (_options & DEBUG_MODE) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", k, hob_struct->objects[i].object_parts[j].vertices[k].x, hob_struct->objects[i].object_parts[j].vertices[k].y, hob_struct->objects[i].object_parts[j].vertices[k].z ); } } + + // 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 (_options & VERBOSE_ENABLED) 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 (_options & 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 (_options & DEBUG_MODE) printf("\n-----------------------End of Mesh part---------------------------\n"); } + + if (_options & DEBUG_MODE) printf("\n-=====================-End of Object part-========================-\n"); } free(offset_index); diff --git a/src/hob_struct.h b/src/hob_struct.h index c3bc733..4b13fc2 100644 --- a/src/hob_struct.h +++ b/src/hob_struct.h @@ -80,10 +80,10 @@ typedef struct hob_object { char name[16]; unsigned int face_group_offset; unsigned int object_part_header_offset; - unsigned int face_group_header2_offset; + unsigned int face_group_header_offset; + unsigned int object_part_count; unsigned int face_group_count; - unsigned int face_group_count0; T_HOB_FACE_GROUP* object_parts; } T_HOB_OBJECT; @@ -102,6 +102,7 @@ typedef struct hob { /////////////////////////////////////////////////////////////////////////////// // Declaration of Memory Mapped Structure +// Caution: the place of variable is important for correct mapping! /////////////////////////////////////////////////////////////////////////////// typedef struct __attribute__((packed)) hobfile_header { @@ -119,9 +120,9 @@ typedef struct __attribute__((packed)) hobfile_obj_descriptor { unsigned int reserved2; unsigned int reserved3; - unsigned int unknown1; - unsigned int unknown2; - unsigned int unknown3; + unsigned int unknownOffset1; + unsigned int unknownOffset2; + unsigned int unknownOffset3; float unknown4; unsigned int reserved4; // 12B of zeros @@ -143,8 +144,8 @@ typedef struct __attribute__((packed)) hobfile_obj_descriptor { } T_HOBFILE_OBJ_DESCRIPTOR; typedef struct __attribute__((packed)) hobfile_facegroup_header { + unsigned short object_part_count; unsigned short facegroup_count; - unsigned short facegroup_count0; } T_HOBFILE_FACEGROUP_HEADER; typedef struct __attribute__((packed)) hobfile_facegroup_offset { @@ -153,10 +154,10 @@ typedef struct __attribute__((packed)) hobfile_facegroup_offset { } T_HOBFILE_FACEGROUP_OFFSET; typedef struct __attribute__((packed)) hobfile_meshdef0 { - unsigned int next_meshdef0_offset; - unsigned int unknown1; - unsigned int unknown2; + unsigned int offset1; + unsigned int offset2; unsigned int prev_meshdef0_offset; + unsigned int next_meshdef0_offset; unsigned int meshdef1_offset_plus_4; unsigned int reserved1; // 8B of zeros diff --git a/src/options.h b/src/options.h index 392e9a2..cef9fef 100644 --- a/src/options.h +++ b/src/options.h @@ -1,9 +1,11 @@ #ifndef OPTIONS_H_ #define OPTIONS_H_ -#define VERBOSE_ENABLED 0x0001 +#define VERBOSE_ENABLED 0x0001 // Simple details about ID and other "light" things #define OUTPUT_DIR 0x0002 #define EXPORT_MTL 0x0004 +#define DEBUG_MODE 0x0011 // Output all values of faces, indices and vertices and others "heavy" things +#define GOD_MODE 0x1111 // Dev only. Output experimental values. extern int _options;