Merge pull request 'Added MSVC support and cleaned degug infos' (#8) from develop into master
Some checks failed
JCS-Prod/RSE-Model/pipeline/head There was a failure building this commit
Some checks failed
JCS-Prod/RSE-Model/pipeline/head There was a failure building this commit
Reviewed-on: #8
This commit is contained in:
commit
8a9a6a4e25
@ -42,10 +42,10 @@ add_executable(rse-model ${RSE_MOD_SRCS} ${RSE_MOD_HRDS})
|
|||||||
set_target_properties(rse-model PROPERTIES OUTPUT_NAME ${RSE_MOD_NAME})
|
set_target_properties(rse-model PROPERTIES OUTPUT_NAME ${RSE_MOD_NAME})
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# msvc does not append 'lib' - do it here to have consistent name
|
# msvc does not append 'lib' - do it here to have consistent name
|
||||||
set_target_properties(rse-model PROPERTIES PREFIX "lib")
|
#set_target_properties(rse-model PROPERTIES PREFIX "lib")
|
||||||
set_target_properties(rse-model PROPERTIES IMPORT_PREFIX "lib")
|
set_target_properties(rse-model PROPERTIES IMPORT_PREFIX "lib")
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(rse-model m)
|
target_link_libraries(rse-model)
|
||||||
|
|
||||||
# add GPG signature command
|
# add GPG signature command
|
||||||
#add_custom_command(
|
#add_custom_command(
|
||||||
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -5,7 +5,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
CI_OUTPUT_NAME = "RSE_Model"
|
CI_OUTPUT_NAME = "RSE_Model"
|
||||||
CI_VERSION = "1.0.0"
|
CI_VERSION = "1.0.1"
|
||||||
CI_BUILD_NUMBER = "$BUILD_NUMBER"
|
CI_BUILD_NUMBER = "$BUILD_NUMBER"
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
|
@ -46,7 +46,7 @@ Due to issue with copyrights, I can't provide samples... You need to extract HOB
|
|||||||
|
|
||||||
You can compile on both Windows (MinGW) or native Linux system thanks to CMake.
|
You can compile on both Windows (MinGW) or native Linux system thanks to CMake.
|
||||||
|
|
||||||
To compile, just clone and launch cmake:
|
To compile, just clone (**don't forget git submodules**) and launch cmake:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
cmake .
|
cmake .
|
||||||
|
@ -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 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
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,35 +98,47 @@ static unsigned int mainProcess(int args_cnt, char *args_value[]) {
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkInputArgs(int arg_nbr, char *args[]) {
|
static unsigned char checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]) {
|
||||||
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], "-no-subdir") == 0) {
|
} else if (strcmp(p_args[i], "-vv") == 0) {
|
||||||
_o &= ~OUTPUT_DIR;
|
opt_ptr->debug_mode = 1;
|
||||||
|
printf("[OPTN] Debug enabled.\n");
|
||||||
|
} else if (strcmp(p_args[i], "-vvv") == 0) {
|
||||||
|
opt_ptr->god_mode = 1;
|
||||||
|
printf("[OPTN] God damn it!\n");
|
||||||
|
} else if (strcmp(p_args[i], "-no-subdir") == 0) {
|
||||||
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _o;
|
opt_ptr->input_files_cnt = i;
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_ARGS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createSubDir(char *dirName) {
|
static void createSubDir(char *dirName) {
|
||||||
@ -164,10 +171,10 @@ 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 Activate verbose console output\n");
|
printf(" -v -vv Activate verbose console output\n");
|
||||||
printf(" -no-subdir Export models inside current folder\n");
|
printf(" -no-subdir Export models inside current folder\n");
|
||||||
printf(" -no-mtl Disable materials datas export with model\n");
|
printf(" -no-mtl Disable materials datas export with model\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -5,12 +5,15 @@
|
|||||||
* Author: JackCarterSmith
|
* Author: JackCarterSmith
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "error.h" //TODO: use it as base for error ID
|
//#include "error.h" //TODO: use it as base for error ID
|
||||||
|
|
||||||
|
|
||||||
#ifndef SRC_ERRORS_TYPES_H_
|
#ifndef SRC_ERRORS_TYPES_H_
|
||||||
#define SRC_ERRORS_TYPES_H_
|
#define SRC_ERRORS_TYPES_H_
|
||||||
|
|
||||||
|
#ifdef NO_ERROR
|
||||||
|
#undef NO_ERROR
|
||||||
|
#endif
|
||||||
#define NO_ERROR 0
|
#define NO_ERROR 0
|
||||||
#define ERROR_GENERIC 1
|
#define ERROR_GENERIC 1
|
||||||
#define ERROR_MEMORY 2
|
#define ERROR_MEMORY 2
|
||||||
|
120
src/hob_parser.c
120
src/hob_parser.c
@ -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,67 +49,74 @@ 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 (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_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_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_header2_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
|
// 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].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 group 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);
|
||||||
hob_struct->objects[i].face_group_count0 = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
|
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");
|
||||||
+ 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");
|
|
||||||
|
|
||||||
// Get facegroup datas
|
// Get facegroup datas
|
||||||
offset_index = calloc(hob_struct->objects[i].face_group_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].face_group_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].face_group_count; j++ ) {
|
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
|
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 & VERBOSE_ENABLED) printf("\n[DBG] > Next meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset);
|
if (p_opts->god_mode) printf("[DBG] > meshdef0 offset1: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset1);
|
||||||
if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Prev meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_offset);
|
if (p_opts->god_mode) printf("[DBG] > meshdef0 offset2: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset2);
|
||||||
hob_struct->objects[i].object_parts[j].id = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->object_id;
|
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("\n[DBG] > Facegroup/object ID: %d\n", hob_struct->objects[i].object_parts[j].id);
|
if (p_opts->verbose_mode) printf("[DBG] > Next meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset);
|
||||||
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;
|
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown3: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown3);
|
||||||
hob_struct->objects[i].object_parts[j].transform.z = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_z;
|
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown4: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown4);
|
||||||
if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Facegroup/object transform matrix: [%.8f %.8f %.8f]\n",
|
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown5: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown5);
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
// 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("[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 & VERBOSE_ENABLED) 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) {
|
||||||
@ -119,25 +127,27 @@ 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 & VERBOSE_ENABLED) 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 & VERBOSE_ENABLED) 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 (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
|
||||||
+ hob_struct->objects[i].object_parts[j].face_block_offset
|
+ hob_struct->objects[i].object_parts[j].face_block_offset
|
||||||
@ -172,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 & VERBOSE_ENABLED) 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
|
||||||
@ -288,8 +298,8 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_options & VERBOSE_ENABLED) {
|
if (p_opts->debug_mode) {
|
||||||
printf("[DBG] > Face %d details: 0x%X, %d, %d, %d, %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,
|
||||||
hob_struct->objects[i].object_parts[j].faces[k].b2,
|
hob_struct->objects[i].object_parts[j].faces[k].b2,
|
||||||
@ -337,6 +347,8 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
|
|||||||
);
|
);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_opts->debug_mode) printf("\n-----------------------End of FaceGroup part-----------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get vertex datas
|
// Get vertex datas
|
||||||
@ -358,14 +370,32 @@ 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 & VERBOSE_ENABLED) 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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
free(offset_index);
|
||||||
@ -380,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;
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
* car = 8bits
|
* car = 8bits
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define PACK
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define PACK __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// HOB file structure
|
// HOB file structure
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -80,10 +86,10 @@ typedef struct hob_object {
|
|||||||
char name[16];
|
char name[16];
|
||||||
unsigned int face_group_offset;
|
unsigned int face_group_offset;
|
||||||
unsigned int object_part_header_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_count;
|
||||||
unsigned int face_group_count0;
|
|
||||||
|
|
||||||
T_HOB_FACE_GROUP* object_parts;
|
T_HOB_FACE_GROUP* object_parts;
|
||||||
} T_HOB_OBJECT;
|
} T_HOB_OBJECT;
|
||||||
@ -102,14 +108,19 @@ typedef struct hob {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Declaration of Memory Mapped Structure
|
// Declaration of Memory Mapped Structure
|
||||||
|
// Caution: the place of variable is important for correct mapping!
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_header {
|
#if defined(_MSC_VER)
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct PACK hobfile_header {
|
||||||
unsigned int obj_count;
|
unsigned int obj_count;
|
||||||
unsigned int vertices_offset;
|
unsigned int vertices_offset;
|
||||||
} T_HOBFILE_HEADER;
|
} T_HOBFILE_HEADER;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_obj_descriptor {
|
typedef struct PACK hobfile_obj_descriptor {
|
||||||
unsigned char object_name[16];
|
unsigned char object_name[16];
|
||||||
unsigned int facegroup_offset;
|
unsigned int facegroup_offset;
|
||||||
unsigned int object_parts_offset;
|
unsigned int object_parts_offset;
|
||||||
@ -119,9 +130,9 @@ typedef struct __attribute__((packed)) hobfile_obj_descriptor {
|
|||||||
unsigned int reserved2;
|
unsigned int reserved2;
|
||||||
unsigned int reserved3;
|
unsigned int reserved3;
|
||||||
|
|
||||||
unsigned int unknown1;
|
unsigned int unknownOffset1;
|
||||||
unsigned int unknown2;
|
unsigned int unknownOffset2;
|
||||||
unsigned int unknown3;
|
unsigned int unknownOffset3;
|
||||||
float unknown4;
|
float unknown4;
|
||||||
|
|
||||||
unsigned int reserved4; // 12B of zeros
|
unsigned int reserved4; // 12B of zeros
|
||||||
@ -142,21 +153,21 @@ typedef struct __attribute__((packed)) hobfile_obj_descriptor {
|
|||||||
float reserved17;
|
float reserved17;
|
||||||
} T_HOBFILE_OBJ_DESCRIPTOR;
|
} T_HOBFILE_OBJ_DESCRIPTOR;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_facegroup_header {
|
typedef struct PACK hobfile_facegroup_header {
|
||||||
|
unsigned short object_part_count;
|
||||||
unsigned short facegroup_count;
|
unsigned short facegroup_count;
|
||||||
unsigned short facegroup_count0;
|
|
||||||
} T_HOBFILE_FACEGROUP_HEADER;
|
} T_HOBFILE_FACEGROUP_HEADER;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_facegroup_offset {
|
typedef struct PACK hobfile_facegroup_offset {
|
||||||
unsigned int unknown1;
|
unsigned int unknown1;
|
||||||
unsigned int facegroup_offset;
|
unsigned int facegroup_offset;
|
||||||
} T_HOBFILE_FACEGROUP_OFFSET;
|
} T_HOBFILE_FACEGROUP_OFFSET;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_meshdef0 {
|
typedef struct PACK hobfile_meshdef0 {
|
||||||
unsigned int next_meshdef0_offset;
|
unsigned int offset1;
|
||||||
unsigned int unknown1;
|
unsigned int offset2;
|
||||||
unsigned int unknown2;
|
|
||||||
unsigned int prev_meshdef0_offset;
|
unsigned int prev_meshdef0_offset;
|
||||||
|
unsigned int next_meshdef0_offset;
|
||||||
unsigned int meshdef1_offset_plus_4;
|
unsigned int meshdef1_offset_plus_4;
|
||||||
|
|
||||||
unsigned int reserved1; // 8B of zeros
|
unsigned int reserved1; // 8B of zeros
|
||||||
@ -200,7 +211,7 @@ typedef struct __attribute__((packed)) hobfile_meshdef0 {
|
|||||||
float transform_z;
|
float transform_z;
|
||||||
} T_HOBFILE_MESHDEF0;
|
} T_HOBFILE_MESHDEF0;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_meshdef1 {
|
typedef struct PACK hobfile_meshdef1 {
|
||||||
unsigned int facedef_end_offset;
|
unsigned int facedef_end_offset;
|
||||||
|
|
||||||
unsigned int reserved1; // 20B of zeros
|
unsigned int reserved1; // 20B of zeros
|
||||||
@ -230,7 +241,7 @@ typedef struct __attribute__((packed)) hobfile_meshdef1 {
|
|||||||
unsigned int reserved19;
|
unsigned int reserved19;
|
||||||
} T_HOBFILE_MESHDEF1;
|
} T_HOBFILE_MESHDEF1;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_faceblock {
|
typedef struct PACK hobfile_faceblock {
|
||||||
unsigned int reserved1; // 8B of zeros
|
unsigned int reserved1; // 8B of zeros
|
||||||
unsigned int reserved2;
|
unsigned int reserved2;
|
||||||
|
|
||||||
@ -238,7 +249,7 @@ typedef struct __attribute__((packed)) hobfile_faceblock {
|
|||||||
unsigned int faceCounts;
|
unsigned int faceCounts;
|
||||||
} T_HOBFILE_FACEBLOCK;
|
} T_HOBFILE_FACEBLOCK;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_faces_header {
|
typedef struct PACK hobfile_faces_header {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned char b1;
|
unsigned char b1;
|
||||||
unsigned char b2;
|
unsigned char b2;
|
||||||
@ -249,29 +260,33 @@ typedef struct __attribute__((packed)) hobfile_faces_header {
|
|||||||
unsigned short vertexIndices[4]; // Relative to facegroup, the last value is equal to 0 when it's triangle shape.
|
unsigned short vertexIndices[4]; // Relative to facegroup, the last value is equal to 0 when it's triangle shape.
|
||||||
} T_HOBFILE_FACES_HEADER;
|
} T_HOBFILE_FACES_HEADER;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_faces_extra_vertex_color {
|
typedef struct PACK hobfile_faces_extra_vertex_color {
|
||||||
T_RGBA v1_rgba;
|
T_RGBA v1_rgba;
|
||||||
T_RGBA v2_rgba;
|
T_RGBA v2_rgba;
|
||||||
T_RGBA v3_rgba;
|
T_RGBA v3_rgba;
|
||||||
T_RGBA v4_rgba; // Used with quad type face
|
T_RGBA v4_rgba; // Used with quad type face
|
||||||
} T_HOBFILE_FACES_VERTEX_COLOR;
|
} T_HOBFILE_FACES_VERTEX_COLOR;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_faces_extra_color {
|
typedef struct PACK hobfile_faces_extra_color {
|
||||||
T_RGBA rgba;
|
T_RGBA rgba;
|
||||||
} T_HOBFILE_FACES_COLOR;
|
} T_HOBFILE_FACES_COLOR;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_faces_extra_vertex_texture {
|
typedef struct PACK hobfile_faces_extra_vertex_texture {
|
||||||
T_TEXCOORD v1_texcoord; // Should be divided (no shifting) by 4096 to get 0...1 range
|
T_TEXCOORD v1_texcoord; // Should be divided (no shifting) by 4096 to get 0...1 range
|
||||||
T_TEXCOORD v2_texcoord;
|
T_TEXCOORD v2_texcoord;
|
||||||
T_TEXCOORD v3_texcoord;
|
T_TEXCOORD v3_texcoord;
|
||||||
T_TEXCOORD v4_texcoord; // Used with quad type face
|
T_TEXCOORD v4_texcoord; // Used with quad type face
|
||||||
} T_HOBFILE_FACES_VERTEX_TEXTURE;
|
} T_HOBFILE_FACES_VERTEX_TEXTURE;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) hobfile_vertex {
|
typedef struct PACK hobfile_vertex {
|
||||||
short x;
|
short x;
|
||||||
short y;
|
short y;
|
||||||
short z;
|
short z;
|
||||||
short w;
|
short w;
|
||||||
} T_HOBFILE_VERTEX;
|
} T_HOBFILE_VERTEX;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* SRC_HOB_STRUCT_H_ */
|
#endif /* SRC_HOB_STRUCT_H_ */
|
||||||
|
@ -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,9 +106,11 @@ 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 (_options & OUTPUT_DIR) mtlPathPatch(objExport_path, hob_objects->name);
|
#if defined(__GNUC__) //TODO: review MSVC file management or include and rewrite obj lib?
|
||||||
|
if (p_opts->output_dir) mtlPathPatch(objExport_path, hob_objects->name);
|
||||||
|
#endif
|
||||||
} else obj_write(objConstruct, objExport_path, NULL, 8);
|
} else obj_write(objConstruct, objExport_path, NULL, 8);
|
||||||
|
|
||||||
obj_delete(objConstruct);
|
obj_delete(objConstruct);
|
||||||
@ -150,7 +153,11 @@ static void mtlPathPatch(const char* out_file, const char* obj_name) {
|
|||||||
// Begin rewrite file
|
// Begin rewrite file
|
||||||
obj = fopen(out_file, "w");
|
obj = fopen(out_file, "w");
|
||||||
fprintf(obj, "mtllib %s", _path);
|
fprintf(obj, "mtllib %s", _path);
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
fwrite(memFile, fileSize - pos , 1, obj);
|
||||||
|
#elif defined(__GNUC__)
|
||||||
fwrite(memFile, fileSize - (pos + lines), 1, obj);
|
fwrite(memFile, fileSize - (pos + lines), 1, obj);
|
||||||
|
#endif
|
||||||
|
|
||||||
free(memFile);
|
free(memFile);
|
||||||
}
|
}
|
||||||
|
@ -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_ */
|
||||||
|
@ -1,10 +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
|
/// Options structure
|
||||||
#define OUTPUT_DIR 0x0002
|
typedef union u_prog_options {
|
||||||
#define EXPORT_MTL 0x0004
|
struct {
|
||||||
|
unsigned char verbose_mode:1; //!< Output simple details about ID and other "light" things.
|
||||||
|
|
||||||
extern 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_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user