Options structure rewrite

This commit is contained in:
JackCarterSmith 2022-07-29 18:04:09 +02:00
parent 52299176be
commit be8b7e9c50
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
6 changed files with 148 additions and 123 deletions

View File

@ -1,10 +1,9 @@
/* /**
================================================================================ * \file Model-Extractor.c
Name : Model-Extractor.c * \date 25/07/2022
Author : JackCarterSmith * \author JackCarterSmith
License : GPL-v3.0 * \copyright GPL-v3.0
Description : HOB model parser and export to Waveform OBJ format. * \brief HOB model parser and export to Waveform OBJ format.
================================================================================
*/ */
#include <stdio.h> #include <stdio.h>
@ -28,40 +27,36 @@
* Internal functions declarations * Internal functions declarations
*/ */
static unsigned int mainProcess(int args_cnt, char *args_value[]); static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* opt_ptr);
static void createSubDir(char *dirName); static void createSubDir(char *dirName);
static unsigned int checkInputArgs(int arg_nbr, char *args[]); static unsigned char checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]);
static void cleanUpMemory(T_HOB* hobStruct); static void cleanUpMemory(T_HOB* hobStruct);
//int exportTextures(HMT_FILE *hmt_f, char *filename); static void dispHelp();
static inline void dispHelp();
/*
* Global variables declaration
*/
unsigned int _options; // Global options settings variable
/* /*
* - MAIN - * - MAIN -
*/ */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Init buffer vars T_PROG_OPTIONS _opts;
unsigned char p;
// Hello world!
printf("\n*** RogueSquadron Extractor (RSE) - MODEL module - v%s ***\n", VERSION); printf("\n*** RogueSquadron Extractor (RSE) - MODEL module - v%s ***\n", VERSION);
// Check if filenames arguments exist // Check for arguments
if (argc < 2) { if (argc < 2) {
printf("\n[ERR] No input file/commands specified!\n"); printf("\n[ERR] No input file/commands specified!\n");
dispHelp(); dispHelp();
return ERROR_ARGS_NULL; return ERROR_ARGS_NULL;
} }
_options = checkInputArgs(argc, argv); // Analyse program arguments
if (_options == -1) return NO_ERROR;
return mainProcess(argc, argv); // Create options for programs according to user's arguments.
p = checkInputArgs(&_opts, argc, argv);
if ( p == ERROR_GENERIC ) return NO_ERROR;
else if ( p != NO_ERROR ) return p;
return mainProcess(argc, argv, &_opts);
} }
@ -69,28 +64,28 @@ int main(int argc, char *argv[]) {
* Private functions definition * Private functions definition
*/ */
static unsigned int mainProcess(int args_cnt, char *args_value[]) { static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* p_opts) {
unsigned short file_index; unsigned short file_index;
T_HOB* hobStruct = NULL; T_HOB* hobStruct = NULL;
int i; int i;
// Manage multiple inputs files // Manage multiple inputs files
for (file_index=(_options >> 8) & 0xFF; file_index < args_cnt; file_index++) for ( file_index = p_opts->input_files_cnt; file_index < args_cnt; file_index++)
{ {
printf("\n=============================================\n[INFO] - Parsing file: %s ...\n", args_value[file_index]); printf("\n=============================================\n[INFO] - Parsing file: %s ...\n", args_value[file_index]);
hobStruct = calloc(1, sizeof(T_HOB)); hobStruct = calloc(1, sizeof(T_HOB));
// Parse data from HOB file and put in T_HOB structure. // Parse data from HOB file and put in T_HOB structure.
if (parseHOBFile(args_value[file_index], hobStruct) != NO_ERROR) { if (parseHOBFile(args_value[file_index], hobStruct, p_opts) != NO_ERROR) {
printf("[ERR] Failed to parse datas from %s\n", args_value[file_index]); printf("[ERR] Failed to parse datas from %s\n", args_value[file_index]);
free(hobStruct); free(hobStruct);
return ERROR_PROCESS; return ERROR_PROCESS;
} }
if (hobStruct->obj_count > 0) { if (hobStruct->obj_count > 0) {
if (_options & OUTPUT_DIR) createSubDir(args_value[file_index]); if (p_opts->output_dir) createSubDir(args_value[file_index]);
for ( i = 0; i < hobStruct->obj_count; i++ ) { for ( i = 0; i < hobStruct->obj_count; i++ ) {
if (exportOBJModel(&(hobStruct->objects[i]), args_value[file_index]) != NO_ERROR) if (exportOBJModel(&(hobStruct->objects[i]), args_value[file_index], p_opts) != NO_ERROR)
printf("[ERR] Failed to export %s object in OBJ format!\n", hobStruct->objects[i].name); printf("[ERR] Failed to export %s object in OBJ format!\n", hobStruct->objects[i].name);
else else
printf("[INFO] Successfully exported %s object in OBJ format.\n", hobStruct->objects[i].name); printf("[INFO] Successfully exported %s object in OBJ format.\n", hobStruct->objects[i].name);
@ -103,41 +98,47 @@ static unsigned int mainProcess(int args_cnt, char *args_value[]) {
return NO_ERROR; return NO_ERROR;
} }
static unsigned int checkInputArgs(int arg_nbr, char *args[]) { static unsigned char checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]) {
unsigned int _o = (OUTPUT_DIR | EXPORT_MTL); // Default options parameters
char test[256]; char test[256];
int i; int i;
if (arg_nbr > 1) { // Set default options
for (i=1; i<arg_nbr; i++) { opt_ptr->raw = 0;
strcpy(test, args[i]); opt_ptr->output_dir = 1;
if (args[i][0] != '-') break; opt_ptr->export_mtl = 1;
if (strcmp(args[i], "-h") == 0) {
if (p_arg_nbr > 1) {
for ( i = 1; i < p_arg_nbr; i++) {
strcpy(test, p_args[i]);
if (p_args[i][0] != '-') break;
if (strcmp(p_args[i], "-h") == 0) {
dispHelp(); dispHelp();
return -1; return ERROR_GENERIC;
} else if (strcmp(args[i], "-v") == 0) { } else if (strcmp(p_args[i], "-v") == 0) {
_o |= VERBOSE_ENABLED; opt_ptr->verbose_mode = 1;
printf("[OPTN] Verbose enabled.\n"); printf("[OPTN] Verbose enabled.\n");
} else if (strcmp(args[i], "-vv") == 0) { } else if (strcmp(p_args[i], "-vv") == 0) {
_o |= DEBUG_MODE; opt_ptr->debug_mode = 1;
printf("[OPTN] Verbose enabled.\n"); printf("[OPTN] Debug enabled.\n");
} else if (strcmp(args[i], "-vvv") == 0) { } else if (strcmp(p_args[i], "-vvv") == 0) {
_o |= GOD_MODE; opt_ptr->god_mode = 1;
printf("[OPTN] Verbose enabled.\n"); printf("[OPTN] God damn it!\n");
} else if (strcmp(args[i], "-no-subdir") == 0) { } else if (strcmp(p_args[i], "-no-subdir") == 0) {
_o &= ~OUTPUT_DIR; opt_ptr->output_dir = 0;
printf("[OPTN] Export to current directory.\n"); printf("[OPTN] Export to current directory.\n");
} else if (strcmp(args[i], "-mtl") == 0) { } else if (strcmp(p_args[i], "-mtl") == 0) {
_o &= ~EXPORT_MTL; opt_ptr->export_mtl = 0;
printf("[OPTN] No materials datas.\n"); printf("[OPTN] No materials datas.\n");
} else { } else {
printf("[ERR] Unknown option: %s\n", args[i]); printf("[ERR] Unknown option: %s\n", p_args[i]);
} }
} }
_o = (i << 8) | (_o & 0x00FF);
opt_ptr->input_files_cnt = i;
return NO_ERROR;
} }
return _o; return ERROR_ARGS_NULL;
} }
static void createSubDir(char *dirName) { static void createSubDir(char *dirName) {
@ -170,7 +171,7 @@ static void cleanUpMemory(T_HOB* hobStruct) {
free(hobStruct); free(hobStruct);
} }
static inline void dispHelp() { static void dispHelp() {
printf("\n"); printf("\n");
printf("Options:\n -h Print this message\n"); printf("Options:\n -h Print this message\n");
printf(" -v -vv Activate verbose console output\n"); printf(" -v -vv Activate verbose console output\n");

View File

@ -1,8 +1,9 @@
/* /**
* hob_parser.c * \file hob_parser.c
* * \date 26/07/2022
* Created on: 26 juil. 2022 * \author JackCarterSmith
* Author: JackCarterSmith * \copyright GPL-v3.0
* \brief Decode HOB file structure.
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -14,7 +15,7 @@
#include "hob_parser.h" #include "hob_parser.h"
unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct, T_PROG_OPTIONS* p_opts) {
unsigned char err = NO_ERROR; unsigned char err = NO_ERROR;
long fileSize; long fileSize;
FILE* fStream = NULL; FILE* fStream = NULL;
@ -32,7 +33,7 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
fseek(fStream, 0, SEEK_END); fseek(fStream, 0, SEEK_END);
fileSize = ftell(fStream); fileSize = ftell(fStream);
fseek(fStream, 0, SEEK_SET); fseek(fStream, 0, SEEK_SET);
if (_options & VERBOSE_ENABLED) printf("[DBG] > Input file size: %ld bytes\n", fileSize); if (p_opts->verbose_mode) printf("[DBG] > Input file size: %ld bytes\n", fileSize);
memFile = malloc(fileSize + 1); memFile = malloc(fileSize + 1);
if (memFile != NULL) { if (memFile != NULL) {
@ -48,30 +49,30 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
// Populate HOB structure with object descriptor // Populate HOB structure with object descriptor
hob_struct->objects = calloc(hob_struct->obj_count, sizeof(T_HOB_OBJECT)); hob_struct->objects = calloc(hob_struct->obj_count, sizeof(T_HOB_OBJECT));
for ( i = 0; i < hob_struct->obj_count; i++ ) { for ( i = 0; i < hob_struct->obj_count; i++ ) {
if (_options & DEBUG_MODE) printf("\n-=====================-Begin of Object part-======================-\n"); if (p_opts->debug_mode) printf("\n-=====================-Begin of Object part-======================-\n");
// Get object name // Get object name
memcpy(hob_struct->objects[i].name, ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile memcpy(hob_struct->objects[i].name, ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_name, 16); + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_name, 16);
if (_options & VERBOSE_ENABLED) printf("\n"); if (p_opts->verbose_mode) printf("\n");
printf("[INFO] - Process %s object...\n", hob_struct->objects[i].name); printf("[INFO] - Process %s object...\n", hob_struct->objects[i].name);
// Get offsets // Get offsets
hob_struct->objects[i].face_group_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile hob_struct->objects[i].face_group_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset; + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group offset: 0x%X\n", hob_struct->objects[i].face_group_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 hob_struct->objects[i].object_part_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset; + 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); 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 hob_struct->objects[i].face_group_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_header_2_offset; + 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_header_offset); if (p_opts->verbose_mode) printf("[DBG] > Face group header2 offset: 0x%X\n", hob_struct->objects[i].face_group_header_offset);
if (_options & GOD_MODE) { 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 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 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 unknown3: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset3);
@ -81,41 +82,41 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
// Get count and offsets from the facegroup header // 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_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].object_part_header_offset))->object_part_count; + 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); 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].face_group_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].object_part_header_offset))->facegroup_count; + hob_struct->objects[i].object_part_header_offset))->facegroup_count;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face groups count: %d\n", hob_struct->objects[i].face_group_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 && (_options & VERBOSE_ENABLED)) printf("[DBG] > Object parts / facegroup count are different!\n"); 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 // Get facegroup datas
offset_index = calloc(hob_struct->objects[i].object_part_count, sizeof(int)); 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)); 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++ ) { for ( j = 0; j < hob_struct->objects[i].object_part_count; j++ ) {
if (_options & DEBUG_MODE) printf("\n-----------------------Begin of Mesh part-------------------------\n"); 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 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_HEADER)
+ sizeof(T_HOBFILE_FACEGROUP_OFFSET) * j))->facegroup_offset; + 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]); if (p_opts->verbose_mode) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]);
// Get meshdef0 datas // Get meshdef0 datas
if (_options & 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 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 (p_opts->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 (p_opts->verbose_mode) 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 (p_opts->verbose_mode) 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 (p_opts->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 (p_opts->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); if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown5: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown5);
// Get meshdef1 (mesh descriptor) offset // Get meshdef1 (mesh descriptor) offset
hob_struct->objects[i].object_parts[j].meshdef1_offset = ((T_HOBFILE_MESHDEF0 *)(memFile hob_struct->objects[i].object_parts[j].meshdef1_offset = ((T_HOBFILE_MESHDEF0 *)(memFile
+ offset_index[j]))->meshdef1_offset_plus_4; + offset_index[j]))->meshdef1_offset_plus_4;
if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Face group meshdef1 offset: 0x%X\n", hob_struct->objects[i].object_parts[j].meshdef1_offset); 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 || if( ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved1 != 0 ||
((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved2 != 0 ) { ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved2 != 0 ) {
if (_options & GOD_MODE) printf("[DBG] > Face group meshdef0: no 0!\n"); if (p_opts->god_mode) printf("[DBG] > Face group meshdef0: no 0!\n");
} }
if (hob_struct->objects[i].object_parts[j].meshdef1_offset > 0) { if (hob_struct->objects[i].object_parts[j].meshdef1_offset > 0) {
@ -126,26 +127,26 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertex_count; + 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].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->faceblock_offset; + hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->faceblock_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Faces offset: 0x%X\n", hob_struct->objects[i].object_parts[j].face_block_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].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertexblocks_offset; + hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertexblocks_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Vertex offset: 0x%X\n\n", hob_struct->objects[i].object_parts[j].vertex_block_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 // Get face datas
if( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved1 != 0 || 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 ) { ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved2 != 0 ) {
if (_options & GOD_MODE) printf("[DBG] > Face block: uncommon zero header!\n"); 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 != 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)) { hob_struct->objects[i].object_parts[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) {
if (_options & GOD_MODE) printf("[DBG] > Face block: uncommon face data offset position!\n"); 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_count = ((T_HOBFILE_FACEBLOCK *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset))->faceCounts; + 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)); hob_struct->objects[i].object_parts[j].faces = calloc(hob_struct->objects[i].object_parts[j].face_count, sizeof(T_HOB_FACE));
facesExtraOffset = 0; facesExtraOffset = 0;
for ( k = 0; k < hob_struct->objects[i].object_parts[j].face_count; k++ ) { 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"); if (p_opts->debug_mode) printf("\n----------------------Begin of FaceGroup part----------------------\n");
// Get flags // Get flags
hob_struct->objects[i].object_parts[j].faces[k].flags = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].flags = ((T_HOBFILE_FACES_HEADER *)(memFile
@ -181,7 +182,7 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->headerSeparator != 0) { + facesExtraOffset))->headerSeparator != 0) {
if (_options & GOD_MODE) printf("[DBG] > Face header: uncommon separator!\n"); if (p_opts->god_mode) printf("[DBG] > Face header: uncommon separator!\n");
} }
// Get materials index // Get materials index
@ -297,7 +298,7 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
} }
} }
if (_options & DEBUG_MODE) { if (p_opts->debug_mode) {
printf("[DBG] > Face %d details: flags:0x%X b1:%d b2:%d b3%d bsize:%d\n", k, 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].flags,
hob_struct->objects[i].object_parts[j].faces[k].b1, hob_struct->objects[i].object_parts[j].faces[k].b1,
@ -347,7 +348,7 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
printf("\n"); printf("\n");
} }
if (_options & DEBUG_MODE) printf("\n-----------------------End of FaceGroup part-----------------------\n"); if (p_opts->debug_mode) printf("\n-----------------------End of FaceGroup part-----------------------\n");
} }
// Get vertex datas // Get vertex datas
@ -369,7 +370,7 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
+ hob_struct->objects[i].object_parts[j].vertex_block_offset + hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->w; // Always 0??? + sizeof(T_VERTEX) * k))->w; // Always 0???
if (_options & DEBUG_MODE) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", k, if (p_opts->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].x,
hob_struct->objects[i].object_parts[j].vertices[k].y, hob_struct->objects[i].object_parts[j].vertices[k].y,
hob_struct->objects[i].object_parts[j].vertices[k].z hob_struct->objects[i].object_parts[j].vertices[k].z
@ -379,22 +380,22 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
// Get object part ID, used by animation? bones? // 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; 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); 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) // 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.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.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; 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", 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.x,
hob_struct->objects[i].object_parts[j].transform.y, hob_struct->objects[i].object_parts[j].transform.y,
hob_struct->objects[i].object_parts[j].transform.z hob_struct->objects[i].object_parts[j].transform.z
); );
if (_options & DEBUG_MODE) printf("\n-----------------------End of Mesh part---------------------------\n"); if (p_opts->debug_mode) printf("\n-----------------------End of Mesh part---------------------------\n");
} }
if (_options & DEBUG_MODE) printf("\n-=====================-End of Object part-========================-\n"); if (p_opts->debug_mode) printf("\n-=====================-End of Object part-========================-\n");
} }
free(offset_index); free(offset_index);
@ -409,11 +410,11 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
} else { } else {
fclose(fStream); fclose(fStream);
err = ERROR_MEMORY; err = ERROR_MEMORY;
if (_options & VERBOSE_ENABLED) printf("[ERR] Can't allocate enough memory for file processing!\n"); if (p_opts->verbose_mode) printf("[ERR] Can't allocate enough memory for file processing!\n");
} }
} else { } else {
err = ERROR_IO; err = ERROR_IO;
if (_options & VERBOSE_ENABLED) printf("[ERR] Input file %s not found!\n", fileName); if (p_opts->verbose_mode) printf("[ERR] Input file %s not found!\n", fileName);
} }
} else err = ERROR_ARGS_NULL; } else err = ERROR_ARGS_NULL;

View File

@ -1,14 +1,15 @@
/* /**
* hob_parser.h * \file hob_parser.h
* * \date 26/07/2022
* Created on: 26 juil. 2022 * \author JackCarterSmith
* Author: JackCarterSmith * \copyright GPL-v3.0
* \brief Decode HOB file structure.
*/ */
#ifndef SRC_HOB_PARSER_H_ #ifndef SRC_HOB_PARSER_H_
#define SRC_HOB_PARSER_H_ #define SRC_HOB_PARSER_H_
unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct); unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct, T_PROG_OPTIONS* p_opts);
#endif /* SRC_HOB_PARSER_H_ */ #endif /* SRC_HOB_PARSER_H_ */

View File

@ -1,8 +1,9 @@
/* /**
* obj_exporter.c * \file obj_exporter.c
* * \date 27/07/2022
* Created on: 27 juil. 2022 * \author JackCarterSmith
* Author: JackCarterSmith * \copyright GPL-v3.0
* \brief Export datas to Waveform OBJ format.
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -17,7 +18,7 @@
static void mtlPathPatch(const char* out_file, const char* obj_name) ; static void mtlPathPatch(const char* out_file, const char* obj_name) ;
unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) { unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path, T_PROG_OPTIONS* p_opts) {
char objExport_path[128]; char objExport_path[128];
char mtlExport_path[128]; char mtlExport_path[128];
obj* objConstruct = NULL; obj* objConstruct = NULL;
@ -30,7 +31,7 @@ unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) {
if (hob_objects == NULL || out_path == NULL) if (hob_objects == NULL || out_path == NULL)
return ERROR_ARGS_NULL; return ERROR_ARGS_NULL;
if (_options & OUTPUT_DIR) { if (p_opts->output_dir) {
strcpy(objExport_path, out_path); strcpy(objExport_path, out_path);
#ifdef _WIN32 #ifdef _WIN32
strcat(objExport_path, "-out\\"); strcat(objExport_path, "-out\\");
@ -105,10 +106,10 @@ unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) {
indexOffset = obj_num_vert(objConstruct); indexOffset = obj_num_vert(objConstruct);
} }
if (_options & EXPORT_MTL) { if (p_opts->export_mtl) {
obj_write(objConstruct, objExport_path, mtlExport_path, 8); obj_write(objConstruct, objExport_path, mtlExport_path, 8);
#if defined(__GNUC__) //TODO: review MSVC file management or include and rewrite obj lib? #if defined(__GNUC__) //TODO: review MSVC file management or include and rewrite obj lib?
if (_options & OUTPUT_DIR) mtlPathPatch(objExport_path, hob_objects->name); if (p_opts->output_dir) mtlPathPatch(objExport_path, hob_objects->name);
#endif #endif
} else obj_write(objConstruct, objExport_path, NULL, 8); } else obj_write(objConstruct, objExport_path, NULL, 8);

View File

@ -1,8 +1,9 @@
/* /**
* obj_exporter.h * \file obj_exporter.h
* * \date 27/07/2022
* Created on: 27 juil. 2022 * \author JackCarterSmith
* Author: JackCarterSmith * \copyright GPL-v3.0
* \brief Export datas to Waveform OBJ format.
*/ */
#ifndef SRC_OBJ_EXPORTER_H_ #ifndef SRC_OBJ_EXPORTER_H_
@ -15,6 +16,6 @@ typedef struct t_material {
unsigned int gl_tex_id; unsigned int gl_tex_id;
} T_MATERIAL; } T_MATERIAL;
unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path); unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path, T_PROG_OPTIONS* p_opts);
#endif /* SRC_OBJ_EXPORTER_H_ */ #endif /* SRC_OBJ_EXPORTER_H_ */

View File

@ -1,12 +1,32 @@
/**
* \file options.h
* \date 29/07/2022
* \author JackCarterSmith
* \copyright GPL-v3.0
* \brief Shared options structure definition and declaration.
*/
#ifndef OPTIONS_H_ #ifndef OPTIONS_H_
#define OPTIONS_H_ #define OPTIONS_H_
#define VERBOSE_ENABLED 0x0001 // Simple details about ID and other "light" things /// Options structure
#define OUTPUT_DIR 0x0002 typedef union u_prog_options {
#define EXPORT_MTL 0x0004 struct {
#define DEBUG_MODE 0x0010 // Output all values of faces, indices and vertices and others "heavy" things unsigned char verbose_mode:1; //!< Output simple details about ID and other "light" things.
#define GOD_MODE 0x0100 // Dev only. Output experimental values.
extern unsigned int _options; unsigned char output_dir:1; //!< Export extracted datas to a sub-directory.
unsigned char export_mtl:1; //!< Export materials datas with object.
#endif unsigned char reserved0:5; //!< For future use.
unsigned char debug_mode:1; //!< Output all values of faces, indices and vertices and others "heavy" things.
unsigned char god_mode:1; //!< Dev only. Output experimental values.
unsigned char reserved1:6; //!< For future use.
unsigned short input_files_cnt; //!< Internal files counters.
};
unsigned int raw; //!< Raw options access for bit-masking or memory copy/compare.
} T_PROG_OPTIONS ;
#endif /* OPTIONS_H_ */