Added IciclePyramidBananas example

This commit is contained in:
David
2024-04-10 15:02:22 -04:00
parent aa3623095b
commit d1e2261ea7
13 changed files with 3920 additions and 69 deletions
-3
View File
@@ -6139,8 +6139,6 @@ glabel ASSET_TEX2D_MENU_ICONTTAMULET4_0
.incbin "./build/us_1.0/assets/textures/2d/menu/icon_tt_amulet4_0.bin"
glabel ASSET_TEX2D_MENU_ICONTTAMULET4_1
.incbin "./build/us_1.0/assets/textures/2d/menu/icon_tt_amulet4_1.bin"
glabel ASSET_TEX2D_COMICFANS
.incbin "./build/us_1.0/assets/textures/2d/font/comicfans/comicfans.bin"
glabel ASSET_TEXTURES_2D_END
/********** ASSET_TEXTURES_2D_TABLE **********/
@@ -7053,7 +7051,6 @@ glabel ASSET_TEXTURES_2D_TABLE
.word ASSET_TEX2D_MENU_ICONTTAMULET3_1 - ASSET_TEXTURES_2D
.word ASSET_TEX2D_MENU_ICONTTAMULET4_0 - ASSET_TEXTURES_2D
.word ASSET_TEX2D_MENU_ICONTTAMULET4_1 - ASSET_TEXTURES_2D
.word ASSET_TEX2D_COMICFANS - ASSET_TEXTURES_2D
.word ASSET_TEXTURES_2D_END - ASSET_TEXTURES_2D
.word 0xFFFFFFFF
glabel ASSET_TEXTURES_2D_TABLE_END
+2 -4
View File
@@ -2387,8 +2387,7 @@ typedef enum AssetTextures2dEnum {
ASSET_TEX2D_MENU_ICONTTAMULET3_0,
ASSET_TEX2D_MENU_ICONTTAMULET3_1,
ASSET_TEX2D_MENU_ICONTTAMULET4_0,
ASSET_TEX2D_MENU_ICONTTAMULET4_1,
ASSET_TEX2D_COMICFANS
ASSET_TEX2D_MENU_ICONTTAMULET4_1
} AssetTextures2dEnum;
/********** ASSET_GAME_TEXT **********/
@@ -4823,8 +4822,7 @@ typedef enum AssetFontsEnum {
ASSET_FONTS_FUNFONT,
ASSET_FONTS_SMALLFONT,
ASSET_FONTS_BIGFONT,
ASSET_FONTS_SUBTITLEFONT,
ASSET_FONTS_COMICFANS
ASSET_FONTS_SUBTITLEFONT
} AssetFontsEnum;
/********** ASSET_TTGHOSTS **********/
+2 -2
View File
@@ -87,10 +87,10 @@ typedef enum RaceType {
RACETYPE_CUTSCENE_1 = 6, // Not sure what the difference between these two are.
RACETYPE_CUTSCENE_2 = 7,
RACETYPE_BOSS = 8,
RACETYPE_CHALLENGE = 64, // For masking
RACETYPE_CHALLENGE_BATTLE = 64,
RACETYPE_CHALLENGE_BANANAS = 65,
RACETYPE_CHALLENGE_EGGS = 66
RACETYPE_CHALLENGE_EGGS = 66,
RACETYPE_CHALLENGE = 0x40 // For masking
} RaceType;
typedef enum ObjectModelType {
@@ -0,0 +1,181 @@
{
"ai-levels": {
"adv1": {
"base": 0,
"completed": 0,
"silver-coins": 0,
"tracks-mode": 0,
"trophy-race": 0
},
"adv2": {
"base": 0,
"completed": 0,
"silver-coins": 0,
"tracks-mode": 0,
"trophy-race": 0
}
},
"avaliable-vehicles": [
"VEHICLE_CAR"
],
"background": {
"colour": {
"blue": 0,
"green": 0,
"red": 0
},
"multiplayer": {
"gradient-colour": {
"bottom": {
"blue": 255,
"green": 128,
"red": 128
},
"top": {
"blue": 255,
"green": 0,
"red": 0
}
}
},
"skybox": {
"id": "ASSET_OBJECT_DOME8"
}
},
"course-height": 450.0,
"default-vehicle": "VEHICLE_CAR",
"fog": {
"colour": {
"blue": 0,
"green": 0,
"red": 0
},
"far": 0,
"near": 0
},
"fov": 60,
"instruments": 65535,
"map-2": "ASSET_LEVEL_OBJECT_MAPS_28",
"map-collectables": "ASSET_LEVEL_OBJECT_MAPS_97",
"model": "ASSET_LEVELMODEL_ICICLEPYRAMID",
"music": 34,
"name": {
"LANGUAGE_ENGLISH": "Icicle Pyramid",
"LANGUAGE_FRENCH": "PYRAMIDE POLAIRE",
"LANGUAGE_GERMAN": "Bibberpyramide",
"LANGUAGE_JAPANESE": "Japanese"
},
"race-type": "RACETYPE_CHALLENGE_BATTLE",
"type": "LevelHeader",
"unknown": {
"unk1": 0,
"unk16": [
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
],
"unk2": 0,
"unk2A": 85,
"unk2B": [
90,
85,
100,
100,
20,
100,
0,
0,
0
],
"unk3": 1,
"unk4": [
3,
4,
4,
4
],
"unk44": [
0,
0,
0,
0,
12
],
"unk4F": [
0,
0,
0
],
"unk53": 180,
"unk56": 4,
"unk57": 16,
"unk58": 1,
"unk59": 0,
"unk5A": 1536,
"unk5C": 2,
"unk5D": 0,
"unk5E": 768,
"unk60": 120,
"unk62": 256,
"unk64": 153,
"unk66": 1024,
"unk68": 62,
"unk6A": 1,
"unk6B": 1,
"unk6C": 1,
"unk6D": 1,
"unk6E": 5,
"unk70": 1,
"unk71": 1,
"unk72": 66,
"unk73": 224,
"unkA0": 257,
"unkA2": 0,
"unkA3": 0,
"unkA8": 0,
"unkAA": 5,
"unkB0": 3600,
"unkB2": 3,
"unkB3": 18,
"unkB4": 0,
"unkB5": 83,
"unkB6": 133,
"unkB7": 1,
"unkB8": 0,
"unkB9": 66,
"unkBC": 0,
"unkBD": 0,
"unkC": [
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
],
"unkC4": -1475936256
},
"weather": {
"enable": 0,
"intensity": 0,
"opacity": 0,
"type": 0,
"velocity": {
"x": 0,
"y": 0,
"z": 0
}
},
"world": "WORLD_SNOWFLAKE_MOUNTAIN"
}
@@ -0,0 +1,5 @@
{
"name": "Icicle Pyramid (with bananas)",
"authors" : ["Example"],
"description": "Adds some bananas to the Icicle Pyramid battle map. NOTE: This example was also supposed to change the gamemode to the smokey castle one, but it crashes due to the A.I. nodes. Need to figure that out."
}
@@ -8,6 +8,10 @@
#include "helpers/c/cStructGltfHelper.h"
void search_for_objects_node() {
}
BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _settings(settings), _info(info) {
_preload_c_context();
@@ -23,8 +27,14 @@ BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _
GltfFile gltf(gltfPath);
int objectsNodeIndex;
DebugHelper::assert_(gltf.search_for_node_by_name("objects", objectsNodeIndex),
"(BuildObjectMap::BuildObjectMap) .glTF file does not contain a node named \"objects\"!");
GltfFileNode *objectsNode = gltf.get_node(objectsNodeIndex);
// _calculate_size() also fills the `_objectIdToStructCache` map.
size_t dataSize = _calculate_size(gltf);
size_t dataSize = _calculate_size(objectsNode);
size_t outSize = DataHelper::align8(dataSize + sizeof(LevelObjectMapHeader));
@@ -36,11 +46,15 @@ BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _
objectMap->header.fileSize = dataSize;
uint8_t *bytes = &objectMap->entriesData[0];
int numberOfNodes = gltf.get_node_count();
int numberOfChildNodes = objectsNode->get_child_count();
// Node 0 is the root node, so we want to start at node 1.
for(int i = 1; i < numberOfNodes; i++) {
std::string objectBuildId = gltf.get_node_extra<std::string>(i, "id", "");
for(int i = 0; i < numberOfChildNodes; i++) {
GltfFileNode *objNode = objectsNode->get_child_node_by_index(i);
std::string objectBuildId = objNode->get_extra<std::string>("id", "");
DebugHelper::assert_(!objectBuildId.empty(), "(BuildObjectMap::BuildObjectMap) Node", i,
" does not have id defined!");
int id = _transTable->get_index_of_elem_in_array<std::string>("/table", objectBuildId);
@@ -64,12 +78,12 @@ BuildObjectMap::BuildObjectMap(DkrAssetsSettings &settings, BuildInfo &info) : _
entryCommon = _c_context.get_struct("LevelObjectEntryCommon");
}
_set_obj_position(gltf, bytes, entryCommon, i);
_set_obj_position(objNode, bytes, entryCommon, i);
if(entryCommon != entryStruct) {
for(size_t entry = 0; entry < entryStruct->entry_count(); entry++) {
CStructEntry *structMember = entryStruct->get_entry(entry);
CStructGltfHelper::put_gltf_node_extra_into_struct_entry(_settings, structMember, gltf, i, bytes);
CStructGltfHelper::put_gltf_node_extra_into_struct_entry(_settings, structMember, objNode, bytes);
}
}
@@ -92,13 +106,13 @@ BuildObjectMap::~BuildObjectMap() {
}
void BuildObjectMap::_set_obj_position(GltfFile &gltf, uint8_t *bytes, CStruct *entryCommon, int nodeIndex) {
void BuildObjectMap::_set_obj_position(GltfFileNode *objNode, uint8_t *bytes, CStruct *entryCommon, int nodeIndex) {
CStructEntry *memberX = entryCommon->get_entry(2);
CStructEntry *memberY = entryCommon->get_entry(3);
CStructEntry *memberZ = entryCommon->get_entry(4);
double scaledX, scaledY, scaledZ;
gltf.get_node_position(nodeIndex, scaledX, scaledY, scaledZ);
objNode->get_position(scaledX, scaledY, scaledZ);
int xPos = _settings.adjust_from_model_scale(scaledX);
int yPos = _settings.adjust_from_model_scale(scaledY);
@@ -109,18 +123,17 @@ void BuildObjectMap::_set_obj_position(GltfFile &gltf, uint8_t *bytes, CStruct *
memberZ->set_integer_to_data(bytes, zPos);
}
size_t BuildObjectMap::_calculate_size(GltfFile &gltf) {
size_t BuildObjectMap::_calculate_size(GltfFileNode *objectsNode) {
size_t out = 0;
int numberOfNodes = gltf.get_node_count();
int numberOfChildNodes = objectsNode->get_child_count();
// Node 0 is the root node, so we want to start at node 1.
for(int i = 1; i < numberOfNodes; i++) {
std::string objectBuildId = gltf.get_node_extra<std::string>(i, "id", "");
for(int i = 0; i < numberOfChildNodes; i++) {
GltfFileNode *objNode = objectsNode->get_child_node_by_index(i);
std::string objectBuildId = objNode->get_extra<std::string>("id", "");
DebugHelper::assert_(!objectBuildId.empty(), "(BuildObjectMap::_calculate_size) id was not defined in node ", i);
DebugHelper::assert_(!objectBuildId.empty(),
"(BuildObjectMap::_calculate_size) id was not defined in node: ", objNode->get_name());
// First check if we have already calcuated the size of this object build id.
if(_objectIdStructSizeCache.find(objectBuildId) != _objectIdStructSizeCache.end()) {
@@ -30,8 +30,8 @@ private:
JsonFile *_transTable;
JsonFile *_objBehaviorToEntryTable;
void _set_obj_position(GltfFile &gltf, uint8_t *bytes, CStruct *entryCommon, int nodeIndex);
void _set_obj_position(GltfFileNode *objNode, uint8_t *bytes, CStruct *entryCommon, int nodeIndex);
size_t _calculate_size(GltfFile &gltf);
size_t _calculate_size(GltfFileNode *objectsNode);
void _preload_c_context();
};
@@ -302,9 +302,10 @@ void CStructGltfHelper::put_struct_entry_into_gltf_node_extra(DkrAssetsSettings
}
}
void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFile &gltfFile, int gltfNode, uint8_t *bytes) {
void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFileNode *objNode, uint8_t *bytes) {
CStructEntry::InternalType internalType = structMember->get_internal_type();
StructHintType hintType = StructHintType::NO_HINT;
if(structMember->has_hint()) {
hintType = hintTypes[structMember->get_hint_type()];
}
@@ -315,17 +316,17 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
int value = 0;
switch(hintType) {
case StructHintType::NO_HINT:
value = gltfFile.get_node_extra<int>(gltfNode, structMember->name, 0);
value = objNode->get_extra<int>(structMember->name, 0);
break;
case StructHintType::ENUM:
{
std::string enumValue = gltfFile.get_node_extra<std::string>(gltfNode, structMember->name, "");
std::string enumValue = objNode->get_extra<std::string>(structMember->name, "");
value = get_value_from_hint_enum(structMember, enumValue);
break;
}
case StructHintType::ASSET_ID:
{
std::string buildId = gltfFile.get_node_extra<std::string>(gltfNode, structMember->name, "");
std::string buildId = objNode->get_extra<std::string>(structMember->name, "");
if(buildId.empty()) {
value = -1;
} else {
@@ -335,19 +336,19 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
}
case StructHintType::ANGLE:
{
double angle = gltfFile.get_node_extra<double>(gltfNode, structMember->name, 0.0);
double angle = objNode->get_extra<double>(structMember->name, 0.0);
value = get_value_from_hint_angle(structMember, angle);
break;
}
case StructHintType::SCALE:
{
double scale = gltfFile.get_node_extra<double>(gltfNode, structMember->name, 0.0);
double scale = objNode->get_extra<double>(structMember->name, 0.0);
value = get_value_from_hint_scale(structMember, scale);
break;
}
case StructHintType::OBJECT:
{
std::string buildId = gltfFile.get_node_extra<std::string>(gltfNode, structMember->name, "");
std::string buildId = objNode->get_extra<std::string>(structMember->name, "");
if(buildId.empty()) {
value = -1;
} else {
@@ -357,7 +358,7 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
}
case StructHintType::TIME:
{
double timeSeconds = gltfFile.get_node_extra<double>(gltfNode, structMember->name, -1.0);
double timeSeconds = objNode->get_extra<double>(structMember->name, -1.0);
if(timeSeconds == -1.0) {
value = -1;
break;
@@ -374,7 +375,7 @@ void CStructGltfHelper::put_gltf_node_extra_into_struct_entry(DkrAssetsSettings
}
case CStructEntry::InternalType::ARRAY_INTEGER:
{
tinygltf::Value::Array arrayOfValues = gltfFile.get_node_extra<tinygltf::Value::Array>(gltfNode, structMember->name, {});
tinygltf::Value::Array arrayOfValues = objNode->get_extra<tinygltf::Value::Array>(structMember->name, {});
std::vector<int64_t> values;
for(tinygltf::Value &val : arrayOfValues) {
switch(hintType) {
@@ -11,6 +11,5 @@ public:
int gltfNode, uint8_t *bytes);
// gltf node extra -> struct entry
static void put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFile &gltfFile,
int gltfNode, uint8_t *bytes);
static void put_gltf_node_extra_into_struct_entry(DkrAssetsSettings &settings, CStructEntry *structMember, GltfFileNode *objNode, uint8_t *bytes);
};
@@ -5,6 +5,30 @@
#define TINYGLTF_USE_CPP14
#include "libs/tiny_gltf.h"
GltfFileNode::GltfFileNode(GltfFile *file, tinygltf::Node *node) : _file(file), _node(node) {
}
GltfFileNode::~GltfFileNode(){
}
size_t GltfFileNode::get_child_count() {
return _node->children.size();
}
GltfFileNode *GltfFileNode::get_child_node_by_index(int nodeIndex) {
return _file->get_node(_node->children[nodeIndex]);
}
void GltfFileNode::get_position(double &outX, double &outY, double &outZ) {
outX = _node->translation[0];
outY = _node->translation[1];
outZ = _node->translation[2];
}
std::string GltfFileNode::get_name() {
return _node->name;
}
GltfFile::GltfFile(const fs::path &filepath) {
std::string err;
std::string warn;
@@ -24,20 +48,44 @@ GltfFile::GltfFile(const fs::path &filepath) {
}
GltfFile::~GltfFile() {
// Free node cache memory.
for (auto &pair : _nodeCache) {
if(pair.second == nullptr) {
continue;
}
delete pair.second;
}
}
int GltfFile::get_node_count() {
size_t GltfFile::get_node_count() {
return _model.nodes.size();
}
std::string GltfFile::get_node_name(int node) {
return _model.nodes[node].name;
GltfFileNode *GltfFile::get_node(int nodeIndex) {
DebugHelper::assert_(nodeIndex < (int)_model.nodes.size(),
"(GltfFile::get_node) Node index ", nodeIndex, " is out of range!");
tinygltf::Node *tinygltfNode = &_model.nodes[nodeIndex];
if(_nodeCache.find(tinygltfNode) == _nodeCache.end()) {
_nodeCache[tinygltfNode] = new GltfFileNode(this, tinygltfNode);
}
return _nodeCache[tinygltfNode];
}
void GltfFile::get_node_position(int node, double &x, double &y, double &z) {
x = _model.nodes[node].translation[0];
y = _model.nodes[node].translation[1];
z = _model.nodes[node].translation[2];
bool GltfFile::search_for_node_by_name(const std::string nodeName, int &outIndex) {
size_t numNodes = get_node_count();
for(size_t i = 0; i < numNodes; i++) {
if(_model.nodes[i].name == nodeName) {
outIndex = i;
return true;
}
}
// No node with the name was found.
outIndex = -1;
return false;
}
WriteableGltfFile::WriteableGltfFile(std::string rootName) {
@@ -5,39 +5,56 @@
#include <string>
#include "libs/tiny_gltf.h"
class GltfFile;
// Represents a node in the gltf file.
class GltfFileNode {
public:
GltfFileNode(GltfFile *file, tinygltf::Node *node);
~GltfFileNode();
size_t get_child_count();
GltfFileNode *get_child_node_by_index(int nodeIndex);
void get_position(double &outX, double &outY, double &outZ);
std::string get_name();
template <typename T>
T get_extra(std::string key, T defaultValue) {
if(!_node->extras.IsObject()) {
// This node does not have any extras, just return the default value.
return defaultValue;
}
if(!_node->extras.Has(key)) {
// Return default value if the key is not in the map.
return defaultValue;
}
tinygltf::Value val = _node->extras.Get(key);
return val.Get<T>();
}
private:
GltfFile *_file;
tinygltf::Node *_node;
};
// Read-Only .gltf file
class GltfFile {
public:
GltfFile(const fs::path &filepath);
~GltfFile();
// Node stuff
int get_node_count();
std::string get_node_name(int node);
void get_node_position(int node, double &x, double &y, double &z);
template <typename T>
T get_node_extra(int node, std::string key, T defaultValue) {
tinygltf::Node &gltfNode = _model.nodes[node];
if(!gltfNode.extras.IsObject()) {
// This node does not have any extras, just return the default value.
return defaultValue;
}
if(!gltfNode.extras.Has(key)) {
// Return default value if the key is not in the map.
return defaultValue;
}
tinygltf::Value val = gltfNode.extras.Get(key);
return val.Get<T>();
}
size_t get_node_count();
GltfFileNode *get_node(int nodeIndex);
bool search_for_node_by_name(const std::string nodeName, int &outIndex);
private:
tinygltf::Model _model;
tinygltf::TinyGLTF _tinygltf;
std::unordered_map<tinygltf::Node *, GltfFileNode *> _nodeCache;
};
// Write-Only .gltf file