RSE-Model/RSEModel/src/RSEModel.c
JackCarterSmith d40a9f921c
Some checks failed
JCS-Prod/RSE-Model/pipeline/pr-master There was a failure building this commit
Minor feature update
> New Load/Free mecanism for file memory management
> Added prototype of simple header parser for fast infos access
> Fix seg. fault when forcing mtl export without RSPTextureLib dll
> Added dependencies to Vulkan driver
2023-01-18 19:07:09 +01:00

214 lines
5.9 KiB
C

/**
* @file RSEModel.c
* @date 19/08/2022
* @author JackCarterSmith
* @copyright GPL-v3.0
* @brief HOB model parser and export to Waveform OBJ format.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#include <io.h>
#define F_OK 0
#define access _access
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#include "options.h"
#include <RSPModel.h>
#include <RSPModel_errordefs.h>
#include "model_export.h"
#include "lib_interface.h"
#define MAX_STR_VAR 1024
/*
* Internal functions declarations
*/
static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* opt_ptr);
static void createSubDir(char *dirName);
static unsigned short checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]);
static void dispHelp();
/*
* - MAIN -
*/
int main(int argc, char *argv[]) {
T_PROG_OPTIONS _opts = {0};
unsigned char p;
unsigned int status = RSPLIB_SUCCESS;
// Hello world!
printf("\n*~[ Rogue Squadron Extractor (RSE) - RSPModelLib v%s ]~*\n\n", RSPModel_getVersion());
// Try linking to externals modules
linkTextureLib(&_opts);
// Check for arguments
if (argc < 2) {
printf("[ERR] No input file/commands specified!\n");
dispHelp();
return RSPLIB_ERROR_ARGS_NULL;
}
// Create options for programs according to user's arguments.
p = checkInputArgs(&_opts, argc, argv);
if ( p == RSPLIB_ERROR_GENERIC ) return RSPLIB_SUCCESS;
else if ( p != RSPLIB_SUCCESS ) return p;
status = mainProcess(argc, argv, &_opts);
unlinkTextureLib();
return status;
}
/*
* Private functions definition
*/
static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* p_opts) {
unsigned short file_index;
RSPMODEL_PARAMETERS libParams;
T_RSPMODEL_HOB* hobStruct = NULL;
char hmt_filename[MAX_STR_VAR] = {0};
void* hmtStruct = NULL;
unsigned int i;
libParams.raw = p_opts->raw & 0x7;
// Manage multiple inputs files
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]);
// Allocate T_RSPMODEL_HOB structure to store extracted datas.
hobStruct = calloc(1, sizeof(T_RSPMODEL_HOB));
if (hobStruct) {
// Parse data from HOB file and put in T_RSPMODEL_HOB structure.
if (RSPModel_processHOBFile(hobStruct, args_value[file_index], libParams) != RSPLIB_SUCCESS) {
printf("[ERR] Failed to parse datas from %s\n", args_value[file_index]);
RSPModel_freeHOB(hobStruct);
return RSPLIB_ERROR_PROCESS;
}
// If Texture module loaded, process HMT file for mtl naming (doesn't extract texture!)
if (p_opts->texture_module) {
if (strlen(args_value[file_index]) >= MAX_STR_VAR) return RSPLIB_ERROR_GENERIC;
strncpy(hmt_filename, args_value[file_index], strlen(args_value[file_index]) - 3);
hmt_filename[strlen(args_value[file_index]) - 1] = 0; //C6053 fix
strncat(hmt_filename, "HMT", strlen(args_value[file_index]));
if (access(hmt_filename, F_OK) == 0) {
hmtStruct = RSPTexture_createHMT();
RSPTexture_processHMTFile(hmtStruct, hmt_filename, 0);
} else {
printf("[ERR] HMT file '%s' not found for mtl processing!\n", hmt_filename);
return RSPLIB_ERROR_GENERIC;
}
}
} else return RSPLIB_ERROR_MEMORY;
if (hobStruct->obj_count > 0) {
// Create output folders structure.
if (p_opts->output_dir) createSubDir(args_value[file_index]);
for ( i = 0; i < hobStruct->obj_count; i++ ) {
if (exportOBJModel(&(hobStruct->objects[i]), args_value[file_index], hmtStruct, p_opts) == RSPLIB_SUCCESS)
printf("[INFO] Successfully exported %s object in OBJ format.\n", hobStruct->objects[i].name);
else
printf("[ERR] Failed to export %s object in OBJ format!\n", hobStruct->objects[i].name);
}
}
if (p_opts->texture_module) RSPTexture_freeHMT(hmtStruct);
}
RSPModel_freeHOB(hobStruct);
return RSPLIB_SUCCESS;
}
static unsigned short checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]) {
char test[256];
int i;
// Set default options
opt_ptr->output_dir = 1;
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();
return RSPLIB_ERROR_GENERIC;
} else if (strcmp(p_args[i], "-v") == 0) {
opt_ptr->verbose_mode = 1;
printf("[OPTN] Verbose enabled.\n");
} else if (strcmp(p_args[i], "-vv") == 0) {
opt_ptr->verbose_mode = 1;
opt_ptr->debug_mode = 1;
printf("[OPTN] Debug enabled.\n");
} else if (strcmp(p_args[i], "-vvv") == 0) {
opt_ptr->verbose_mode = 1;
opt_ptr->debug_mode = 1;
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");
} else if (strcmp(p_args[i], "-mtl") == 0) {
if (opt_ptr->texture_module) {
opt_ptr->export_mtl = 1;
printf("[OPTN] Export materials datas.\n");
} else {
printf("[OPTN] Can't export materials datas, RSPTextureLib not found or incorrect version!\n");
}
} else {
printf("[ERR] Unknown option: %s\n", p_args[i]);
}
}
opt_ptr->input_files_cnt = i;
return RSPLIB_SUCCESS;
}
return RSPLIB_ERROR_ARGS_NULL;
}
static void createSubDir(char *dirName) {
if (dirName == NULL) return;
char _dir[1024];
snprintf(_dir, 1024, "%s-out", dirName);
#ifdef _WIN32
CreateDirectory(_dir, NULL);
#else
mkdir(_dir, 0755);
#endif
}
static void dispHelp() {
printf("\n");
printf("Options:\n -h Print this message\n");
printf(" -v -vv Activate verbose console output\n");
printf(" -no-subdir Export models inside current folder\n");
printf(" -mtl Export materials datas with model\n");
printf("\n");
printf("Usage: RSEModel [options] <hob files...>\n");
printf("\n");
}