Some checks failed
JCS-Prod/RSE-Model/pipeline/pr-master There was a failure building this commit
> 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
214 lines
5.9 KiB
C
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");
|
|
}
|