diff --git a/CMakeLists.txt b/CMakeLists.txt index 15d5f43..455f52a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ if(DEFINED ENV{CI}) # Jenkins CI integration mode project(rse-terrain VERSION $ENV{CI_VERSION}.$ENV{CI_BUILD_NUMBER} DESCRIPTION "RogueSquadron Extractor - Terrain" LANGUAGES C) set(RSE_TERRAIN_NAME $ENV{CI_OUTPUT_NAME}) else() # Standalone project mode, should not be used for release. - project(rse-terrain VERSION 2.0.0 DESCRIPTION "RogueSquadron Extractor - Terrain" LANGUAGES C) + project(rse-terrain VERSION 2.1.0 DESCRIPTION "RogueSquadron Extractor - Terrain" LANGUAGES C) set(RSE_TERRAIN_NAME RSETerrain) endif() set(RSP_TERRAIN_LIB_NAME RSPTerrain${PROJECT_VERSION_MAJOR}${PROJECT_VERSION_MINOR}) diff --git a/Jenkinsfile b/Jenkinsfile index 632716a..b12b2b9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { } environment { CI_OUTPUT_NAME = "RSETerrain" - CI_VERSION = "2.0.4" + CI_VERSION = "2.1.0" CI_BUILD_NUMBER = "$BUILD_NUMBER" } stages { @@ -23,7 +23,7 @@ pipeline { checkout([$class: 'GitSCM', branches: [[name: '**']], browser: [$class: 'GiteaBrowser', repoUrl: 'https://git.jcsmith.fr/JCS-Prod/RSE-Terrain'], extensions: [], userRemoteConfigs: [[credentialsId: 'jenkins-ssh', url: 'ssh://git@git.jcsmith.fr:2322/JCS-Prod/RSE-Terrain.git']]]) sh 'git submodule update --init --recursive' dir("build") { - rtConanRun(clientId: "conan", command: "install .. --build=missing") + rtConanRun(clientId: "conan", command: "install .. -pr:b=default -pr:h=default --build=missing") } cmakeBuild buildDir: 'build', installation: 'latest', steps: [[args: 'all']] } diff --git a/RSPTerrainLib/include/RSPTerrain_datatypes.h b/RSPTerrainLib/include/RSPTerrain_datatypes.h index 9e1d262..9c4e12e 100644 --- a/RSPTerrainLib/include/RSPTerrain_datatypes.h +++ b/RSPTerrainLib/include/RSPTerrain_datatypes.h @@ -1,6 +1,6 @@ /** * @file RSPTerrain_datatypes.h - * @date 11/08/2022 + * @date 05/02/2023 * @author JackCarterSmith * @copyright GPL-v3.0 * @brief RSP Terrain workflow structures definitions @@ -51,20 +51,23 @@ typedef char* MEMFILE; #define MEMFILE_DEF #endif +#ifndef T_R8G8B8A8_DEF +typedef struct r8g8b8a8 { unsigned char r,g,b,a; } T_R8G8B8A8; +#define T_R8G8B8A8_DEF +#endif + +#ifndef T_R8G8B8_F_DEF +typedef struct r8g8b8_f { float r,g,b; } T_R8G8B8_F; +#define T_R8G8B8_F_DEF +#endif + #ifndef HEIGHTMAP_T_DEF typedef unsigned char** HEIGHTMAP_T; #define HEIGHTMAP_T_DEF #endif -#ifndef T_VECTOR3_DEF -typedef struct vector3 { float x,y,z; } T_VECTOR3; -#define T_VECTOR3_DEF -#endif - -#ifndef T_VERTEX_DEF -typedef T_VECTOR3 T_VERTEX; -#define T_VERTEX_DEF -#endif +typedef struct rspterrain_vector3 { float x,y,z; } T_RSPTERRAIN_VECTOR3; +typedef T_RSPTERRAIN_VECTOR3 T_RSPTERRAIN_VERTEX; typedef struct rspterrain_heightmap { unsigned short width; @@ -78,7 +81,7 @@ typedef struct rspterrain_mesh { unsigned short height; unsigned int vertices_count; - T_VERTEX* verticesmap; + T_RSPTERRAIN_VERTEX* verticesmap; } T_RSPTERRAIN_MESH ; typedef struct rspterrain_tile { @@ -97,6 +100,7 @@ typedef struct rspterrain_obj { float height_scale; unsigned short tiles_count; + unsigned short textures_count; T_RSPTERRAIN_TILE* tilesmap; } T_RSPTERRAIN_HMP ; diff --git a/RSPTerrainLib/src/RSPTerrain.c b/RSPTerrainLib/src/RSPTerrain.c index 5145140..d8d9d8e 100644 --- a/RSPTerrainLib/src/RSPTerrain.c +++ b/RSPTerrainLib/src/RSPTerrain.c @@ -1,6 +1,6 @@ /** * @file RSPTerrain.c - * @date 22/08/2022 + * @date 05/02/2023 * @author JackCarterSmith * @copyright GPL-v3.0 * @brief HMP terrain datas parser and export to Waveform OBJ format and greyscale PNG heightmap. diff --git a/RSPTerrainLib/src/hmp_parser.c b/RSPTerrainLib/src/hmp_parser.c index 0d137ff..3f4f2bb 100644 --- a/RSPTerrainLib/src/hmp_parser.c +++ b/RSPTerrainLib/src/hmp_parser.c @@ -1,6 +1,6 @@ /** * @file hmp_parser.c - * @date 22/08/2022 + * @date 05/02/2023 * @author JackCarterSmith * @copyright GPL-v3.0 * @brief Process HMP file structure and extract its datas. @@ -100,14 +100,17 @@ static unsigned short extractTerrainHMP(T_RSPTERRAIN_HMP* pHmpStruct, const MEMF unsigned short errorCode = RSPLIB_SUCCESS; T_TILE_INDICES* tiles_indices = NULL; T_HMPFILE_TILE* tiles = NULL; - unsigned int tiles_offset = 0; + unsigned int tiles_offset = 0, lso_offset = 0; if (pHmpStruct == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL; // Get header infos pHmpStruct->height_scale = ((T_HMPFILE_HEADER *)pMemfile)->height_scale; tiles_offset = ((T_HMPFILE_HEADER *)pMemfile)->tiles_start_offset; + lso_offset = ((T_HMPFILE_HEADER *)pMemfile)->lighting_datas_offset; pHmpStruct->tiles_count = ((T_HMPFILE_HEADER *)pMemfile)->tiles_count; + pHmpStruct->textures_count = ((T_HMPFILE_HEADER *)pMemfile)->textures_count; + pHmpStruct->width = ((T_HMPFILE_HEADER *)pMemfile)->width_BLK; pHmpStruct->height = ((T_HMPFILE_HEADER *)pMemfile)->height_BLK; @@ -115,26 +118,26 @@ static unsigned short extractTerrainHMP(T_RSPTERRAIN_HMP* pHmpStruct, const MEMF printf("[DBG] > Height scale: %.8f\n", pHmpStruct->height_scale); printf("[DBG] > Tiles count: %d\n", pHmpStruct->tiles_count); printf("[DBG] > Tiles offset: 0x%X\n", tiles_offset); + printf("[DBG] > LSO offset: 0x%X\n", lso_offset); printf("[DBG] > Terrain size: %dx%d\n", pHmpStruct->width, pHmpStruct->height); printf("\n"); } - if (pParams->god_mode) { - printf("[DBG] > Unknown0: %d\n", ((T_HMPFILE_HEADER *)pHmpStruct)->unknown0); - printf("[DBG] > Unknown1: %d\n", ((T_HMPFILE_HEADER *)pHmpStruct)->unknown1); - printf("\n"); - } // Get tiles indices tiles_indices = (T_TILE_INDICES *)malloc(pHmpStruct->width * pHmpStruct->height * sizeof(T_TILE_INDICES)); - memcpy(tiles_indices, - pMemfile + sizeof(T_HMPFILE_HEADER), - pHmpStruct->width * pHmpStruct->height * sizeof(unsigned short)); + if (tiles_indices) { + memcpy(tiles_indices, + pMemfile + sizeof(T_HMPFILE_HEADER), + pHmpStruct->width * pHmpStruct->height * sizeof(T_TILE_INDICES)); + } // Get tiles datas tiles = (T_HMPFILE_TILE *)malloc(pHmpStruct->tiles_count * sizeof(T_HMPFILE_TILE)); - memcpy(tiles, - pMemfile + tiles_offset, - ((T_HMPFILE_HEADER *)pMemfile)->tiles_count * sizeof(T_HMPFILE_TILE)); + if (tiles) { + memcpy(tiles, + pMemfile + tiles_offset, + pHmpStruct->tiles_count * sizeof(T_HMPFILE_TILE)); + } if (tiles && tiles_indices) { // Reconstruct tiles map from tiles datas and tiles indices diff --git a/RSPTerrainLib/src/hmp_struct.h b/RSPTerrainLib/src/hmp_struct.h index 88fb46a..298b493 100644 --- a/RSPTerrainLib/src/hmp_struct.h +++ b/RSPTerrainLib/src/hmp_struct.h @@ -1,6 +1,6 @@ /** * @file hmp_struct.h - * @date 22/08/2022 + * @date 05/02/2023 * @author JackCarterSmith * @copyright GPL-v3.0 * @brief HMP file mapping definition. @@ -33,6 +33,13 @@ #pragma pack(push, 1) #endif +/* + * - Global HMP file structure- + * +------------------+-----------------------------------------+----------------------+----------------------------+ + * | T_HMPFILE_HEADER | (width_BLK*height_BLK) * T_TILE_INDICES | T_HMPFILE_LIGHTDATAS | obj_count * T_HMPFILE_TILE | + * +------------------+-----------------------------------------+----------------------+----------------------------+ + * + */ typedef struct PACK hmpfile_header { unsigned int reserved0; //12B of zeros unsigned int reserved1; @@ -43,15 +50,58 @@ typedef struct PACK hmpfile_header { float reserved4; // Always 0x3F000000 unsigned short tiles_count; - unsigned short unknown0; + unsigned short textures_count; + /* + * #Thanaclara + * *textures_count* note - Some levels contain tiles with an animation for a texture. + * This animation consists of multiple textures, or "frames" for the animation. + * However each animation counts only as 1 towards the terrain texture count. + * An example of an animated terrain texture is a tile that is textured to look like water. + */ unsigned int tiles_start_offset; - unsigned int unknown1; // Offset to some datas? + unsigned int lighting_datas_offset; unsigned short width_BLK; unsigned short height_BLK; } T_HMPFILE_HEADER; +typedef struct PACK global_light_obj { + T_R8G8B8A8 shadow_color; + T_R8G8B8A8 world_light_color; + T_R8G8B8_F terrain_light_color; + unsigned int reserved0; // 4B of zeros + T_RSPTERRAIN_VECTOR3 terrain_light_normal; + unsigned int reserved1; // 4B of zeros +} T_HMPFILE_GLOBALLIGHT; + +typedef struct PACK light_shadow_obj { + /* + * In light mode higher values = brighter light + * Shadow mode is inverted, higher values = darker shadows + * but the inversion also extends to the shadow color (i.e if you + * want to make a blue shadow you would need to set the blue + * channel to 0.0f and the red and green channel to 255.0f + */ + T_R8G8B8_F light_color; + + unsigned char activated; + unsigned char shadow_mode; + unsigned char intensity_boost; + unsigned char unknown0; + + T_RSPTERRAIN_VECTOR3 light_position; + float light_scale; +} T_HMPFILE_LSO; + +typedef struct PACK lighting_datas { + // Lights and shadows object count + unsigned int ls_obj_count; + + T_HMPFILE_GLOBALLIGHT global_light; + T_HMPFILE_LSO* pLSO; // array size = (ls_obj_count - 1) because global_light count as a light element +} T_HMPFILE_LIGHTDATAS; + typedef unsigned short T_TILE_INDICES; typedef struct PACK hmpfile_tile {