All checks were successful
JCS-Prod/RSE-Terrain/pipeline/head This commit looks good
220 lines
6.5 KiB
C
220 lines
6.5 KiB
C
/**
|
|
* @file RSETerrain.c
|
|
* @date 23/08/2022
|
|
* @author JackCarterSmith
|
|
* @copyright GPL-v3.0
|
|
* @brief HMP terrain parser and export to Waveform OBJ format and grey-scale PNG heightmap.
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#if defined(_WIN32)
|
|
#include <windows.h>
|
|
#else
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#endif
|
|
#include "options.h"
|
|
#include <RSPTerrain.h>
|
|
#include <RSPTerrain_errordefs.h>
|
|
#include "terrain_export.h"
|
|
|
|
|
|
/*
|
|
* 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;
|
|
unsigned char p;
|
|
|
|
// Hello world!
|
|
printf("\n*~[ Rogue Squadron Extractor (RSE) - RSPTerrainLib v%s ]~*\n", RSPTerrain_getVersion());
|
|
|
|
// Check for arguments
|
|
if (argc < 2) {
|
|
printf("\n[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;
|
|
|
|
return mainProcess(argc, argv, &_opts);
|
|
}
|
|
|
|
|
|
/*
|
|
* Private functions definition
|
|
*/
|
|
|
|
static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* p_opts) {
|
|
unsigned short file_index;
|
|
RSPTERRAIN_PARAMETERS libParams;
|
|
T_RSPTERRAIN_HMP* hmpStruct = NULL;
|
|
T_RSPTERRAIN_HEIGHTMAP* terrainHM = NULL;
|
|
T_RSPTERRAIN_MESH* terrainMesh = NULL;
|
|
|
|
libParams.raw = p_opts->raw & 0x7;
|
|
libParams.negative = p_opts->negative_HM; // Invert it by default to correspond to in-game rendering
|
|
libParams.invertZ = !p_opts->inverted_Z; // Invert it by default to correspond to in-game rendering
|
|
|
|
// 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_RSPTERRAIN_HMP structure to store extracted datas.
|
|
hmpStruct = calloc(1, sizeof(T_RSPTERRAIN_HMP));
|
|
if (hmpStruct) {
|
|
// Parse data from HMP file and put in T_RSPTERRAIN_HMP structure.
|
|
if (RSPTerrain_processHMPFile(hmpStruct, args_value[file_index], libParams) != RSPLIB_SUCCESS) {
|
|
printf("[ERR] Failed to parse datas from %s\n", args_value[file_index]);
|
|
RSPTerrain_freeHMP(hmpStruct);
|
|
free(hmpStruct);
|
|
return RSPLIB_ERROR_PROCESS;
|
|
}
|
|
} else return RSPLIB_ERROR_MEMORY;
|
|
|
|
// Create output folders structure.
|
|
if (p_opts->output_dir) createSubDir(args_value[file_index]);
|
|
|
|
// Allocate terrain full heighmap format
|
|
terrainHM = calloc(1, sizeof(T_RSPTERRAIN_HEIGHTMAP));
|
|
if (terrainHM) {
|
|
if (RSPTerrain_terrainToHeightmap(terrainHM, hmpStruct) == RSPLIB_SUCCESS) {
|
|
// Export terrain as a PNG greyscale heightmap
|
|
if (exportHeightmapPNG(terrainHM, args_value[file_index], p_opts) == RSPLIB_SUCCESS)
|
|
printf("[INFO] Successfully exported heightmap to PNG format.\n");
|
|
else
|
|
printf("[ERR] Failed to export heightmap to PNG format!\n");
|
|
} else {
|
|
printf("[ERR] Failed to process tilesmap to heightmap!\n");
|
|
}
|
|
RSPTerrain_freeHeightmap(terrainHM);
|
|
} else {
|
|
RSPTerrain_freeHMP(hmpStruct);
|
|
free(hmpStruct);
|
|
return RSPLIB_ERROR_MEMORY;
|
|
}
|
|
|
|
// Allocate mesh object for 3D terrain generation
|
|
//#ifndef TEXTURE_MODULE TODO: Next version: detect presence of external library to manage texture handling...
|
|
terrainMesh = calloc(1, sizeof(T_RSPTERRAIN_MESH));
|
|
if (terrainMesh) {
|
|
if (RSPTerrain_terrainToMesh(terrainMesh, hmpStruct, TERRAIN_MESH_SCALE) == RSPLIB_SUCCESS) {
|
|
// Export terrain as a blank OBJ terrain
|
|
if (exportHeightmapOBJ(terrainMesh, args_value[file_index], p_opts) == RSPLIB_SUCCESS)
|
|
printf("[INFO] Successfully exported terrain in OBJ format.\n");
|
|
else
|
|
printf("[ERR] Failed to export terrain in OBJ format!\n");
|
|
} else {
|
|
printf("[ERR] Failed to process tilesmap to mesh!\n");
|
|
}
|
|
RSPTerrain_freeMesh(terrainMesh);
|
|
} else {
|
|
RSPTerrain_freeHMP(hmpStruct);
|
|
free(hmpStruct);
|
|
return RSPLIB_ERROR_MEMORY;
|
|
}
|
|
//#endif
|
|
|
|
RSPTerrain_freeHMP(hmpStruct);
|
|
free(hmpStruct);
|
|
}
|
|
|
|
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->raw = 0;
|
|
opt_ptr->output_dir = 1;
|
|
opt_ptr->export_mtl = 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], "-no-mtl") == 0) {
|
|
opt_ptr->export_mtl = 0;
|
|
printf("[OPTN] Export to current directory.\n");
|
|
} else if (strcmp(p_args[i], "-invZ") == 0) {
|
|
opt_ptr->inverted_Z = 1;
|
|
printf("[OPTN] Invert Z axis.\n");
|
|
} else if (strcmp(p_args[i], "-neg") == 0) {
|
|
opt_ptr->negative_HM = 1;
|
|
printf("[OPTN] Negative heightmap output mode.\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(" -no-mtl Disable texture exporting\n");
|
|
printf(" -invZ Invert Z axis when parsing\n");
|
|
printf(" -neg Negative heightmap output\n");
|
|
printf("\n");
|
|
printf("Usage: RSE-Terrain [options] <hmp_file>\n");
|
|
printf("\n");
|
|
}
|