summaryrefslogtreecommitdiff
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp172
1 files changed, 156 insertions, 16 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 071a2b3..6ce4847 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -4,6 +4,7 @@
#include "vendor/glm_include.hpp"
#include <cstring>
+#include <iomanip>
GameSettings pkeSettings{};
@@ -24,6 +25,7 @@ const char *PKE_FILE_END = ":PKFE:";
const char *PKE_FILE_VERSION = ":0:";
const char *PKE_FILE_OBJ_END = "";
const char *PKE_FILE_OBJ_ENTITY_TYPE = "EntityType:";
+const char *PKE_FILE_OBJ_INSTANCE = "Instance:";
const char *PKE_FILE_ENTITY_TYPE_MODELS_DIR = "ModelsDir: ";
const char *PKE_FILE_ENTITY_TYPE_MODEL_FILE = "ModelFile: ";
@@ -35,6 +37,12 @@ const char *PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL = "Importer
const char *PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV = "Importer_GLTF::AccessorIndexUV: ";
const char *PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX = "Importer_GLTF::AccessorIndexIndex: ";
+const char *PKE_FILE_INSTANCE_ENTITY_HANDLE = "EntityHandle: ";
+const char *PKE_FILE_INSTANCE_ENTITY_TYPE_CODE = "EntityTypeCode: ";
+const char *PKE_FILE_INSTANCE_POS_POS = "InstPos::Pos: ";
+const char *PKE_FILE_INSTANCE_POS_ROT = "InstPos::Rot: ";
+const char *PKE_FILE_INSTANCE_POS_SCALE = "InstPos::Scale: ";
+
char consoleBuffer[consoleBufferCount][consoleLineLength];
long consoleBufferIndex = 0;
EntityHandle selectedEntity = EntityHandle_MAX;
@@ -46,23 +54,56 @@ void SerializeEntityType(std::ofstream &stream, const EntityType &et) {
snprintf(handleStr, 19, "0x%016lX",static_cast<EntityHandle_T>(et.entityHandle));
EntityType e{};
if (et.modelsDir != e.modelsDir)
- stream << PKE_FILE_ENTITY_TYPE_MODELS_DIR << et.modelsDir << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_MODELS_DIR << et.modelsDir << std::endl;
if (et.modelFile != e.modelFile)
- stream << PKE_FILE_ENTITY_TYPE_MODEL_FILE << et.modelFile << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_MODEL_FILE << et.modelFile << std::endl;
if (et.entityTypeCode != e.entityTypeCode)
- stream << PKE_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode << std::endl;
if (et.entityHandle != e.entityHandle)
- stream << PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << std::endl;
if (et.startingInstanceCount != e.startingInstanceCount)
- stream << PKE_FILE_ENTITY_TYPE_STARTING_INSTANCE_COUNT << et.startingInstanceCount << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_STARTING_INSTANCE_COUNT << et.startingInstanceCount << std::endl;
if (et.Importer_GLTF.AccessorIndexVertex != e.Importer_GLTF.AccessorIndexVertex)
- stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_VERTEX << et.Importer_GLTF.AccessorIndexVertex << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_VERTEX << et.Importer_GLTF.AccessorIndexVertex << std::endl;
if (et.Importer_GLTF.AccessorIndexNormal != e.Importer_GLTF.AccessorIndexNormal)
- stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL << et.Importer_GLTF.AccessorIndexNormal << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL << et.Importer_GLTF.AccessorIndexNormal << std::endl;
if (et.Importer_GLTF.AccessorIndexUV != e.Importer_GLTF.AccessorIndexUV)
- stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV << et.Importer_GLTF.AccessorIndexUV << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV << et.Importer_GLTF.AccessorIndexUV << std::endl;
if (et.Importer_GLTF.AccessorIndexIndex != e.Importer_GLTF.AccessorIndexIndex)
- stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX << et.Importer_GLTF.AccessorIndexIndex << "\n";
+ stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX << et.Importer_GLTF.AccessorIndexIndex << std::endl;
+}
+
+void SerializeInstance(std::ofstream &stream, const CompInstance &comp) {
+ char handleStr[19] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
+ snprintf(handleStr, 19, "0x%016lX",static_cast<EntityHandle_T>(comp.entHandle));
+ EntityType *et = nullptr;
+ for (long i = 0; i < GlobalEntityTypes.Count(); ++i) {
+ if (GlobalEntityTypes[i].grBindsHandle == comp.grBindsHandle) {
+ et = &GlobalEntityTypes[i];
+ break;
+ }
+ }
+ assert(et != nullptr);
+ CompInstance c{};
+ if (comp.entHandle != c.entHandle)
+ stream << PKE_FILE_INSTANCE_ENTITY_HANDLE << handleStr << std::endl;
+ stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode << std::endl;
+ if (comp.instPos.pos != c.instPos.pos)
+ stream << PKE_FILE_INSTANCE_POS_POS << "["
+ << std::setw(10) << comp.instPos.pos[0] << ","
+ << std::setw(10) << comp.instPos.pos[1] << ","
+ << std::setw(10) << comp.instPos.pos[2] << "]" << std::endl;
+ if (comp.instPos.rot != c.instPos.rot)
+ stream << PKE_FILE_INSTANCE_POS_ROT << "["
+ << std::setw(10) << comp.instPos.rot[0] << ","
+ << std::setw(10) << comp.instPos.rot[1] << ","
+ << std::setw(10) << comp.instPos.rot[2] << ","
+ << std::setw(10) << comp.instPos.rot[3] << "]" << std::endl;
+ if (comp.instPos.scale != c.instPos.scale)
+ stream << PKE_FILE_INSTANCE_POS_SCALE << "["
+ << std::setw(10) << comp.instPos.scale[0] << ","
+ << std::setw(10) << comp.instPos.scale[1] << ","
+ << std::setw(10) << comp.instPos.scale[2] << "]" << std::endl;
}
void ParseEntityType(std::ifstream &stream) {
@@ -106,7 +147,6 @@ void ParseEntityType(std::ifstream &stream) {
continue;
}
if (strstr(readLine, PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE)) {
- // TODO parse from hex ?
uint64_t prefixLen = strlen(PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE);
EntityHandle_T handle_t;
STR2NUM_ERROR result = str2num(handle_t, readLine + prefixLen);
@@ -147,16 +187,99 @@ void ParseEntityType(std::ifstream &stream) {
}
}
+void ParseInstance(std::ifstream &stream) {
+ CompInstance comp{};
+ char entTypeCode[21];
+ memset(reinterpret_cast<void *>(entTypeCode), '\0', 21);
+ while (stream.getline(readLine, readLineLength)) {
+ if (strcmp(PKE_FILE_OBJ_END, readLine) == 0) {
+ if (entTypeCode[0] == '\0') {
+ printf("[Game::ParseInstance] Failed to create instance from save file. No EntTypeCode present.");
+ break;
+ }
+ int64_t existingEntityTypeIndex = EntityType_FindByTypeCode(entTypeCode);
+ if (existingEntityTypeIndex != -1) {
+ printf("[Game::ParseInstance] Failed to create instance from save file. Unknown EntityTypeCode: \"%s\"", entTypeCode);
+ break;
+ }
+ const auto &et = GlobalEntityTypes[existingEntityTypeIndex];
+ auto entityHandle = ECS_CreateEntity();
+ ECS_CreateInstance(entityHandle, et.entityHandle);
+ ECS_UpdateInstance(entityHandle, comp.instPos);
+ break;
+ }
+ if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) {
+ uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_HANDLE);
+ EntityHandle_T handle_t;
+ STR2NUM_ERROR result = str2num(handle_t, readLine + prefixLen);
+ assert(result == STR2NUM_ERROR::SUCCESS);
+ comp.entHandle = EntityHandle{handle_t};
+ continue;
+ }
+ if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_TYPE_CODE)) {
+ uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_TYPE_CODE);
+ uint64_t len = strlen(readLine + prefixLen);
+ memcpy(entTypeCode, readLine + prefixLen, len);
+ continue;
+ }
+ if (strstr(readLine, PKE_FILE_INSTANCE_POS_POS)) {
+ uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_POS_POS);
+ char *startingChar = strchr(readLine + prefixLen, '[') + 1;
+ assert(startingChar != nullptr);
+ char *pEnd = nullptr;
+ long index = 0;
+ do {
+ assert(index < 3);
+ STR2NUM_ERROR result = str2num(comp.instPos.scale[index], startingChar, pEnd);
+ assert(result == STR2NUM_ERROR::SUCCESS);
+ startingChar = pEnd + 1;
+ ++index;
+ } while (*pEnd != ']');
+ continue;
+ }
+ if (strstr(readLine, PKE_FILE_INSTANCE_POS_ROT)) {
+ uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_POS_ROT);
+ char *startingChar = strchr(readLine + prefixLen, '[') + 1;
+ assert(startingChar != nullptr);
+ char *pEnd = nullptr;
+ long index = 0;
+ do {
+ assert(index < 4);
+ STR2NUM_ERROR result = str2num(comp.instPos.scale[index], startingChar, pEnd);
+ assert(result == STR2NUM_ERROR::SUCCESS);
+ startingChar = pEnd + 1;
+ ++index;
+ } while (*pEnd != ']');
+ continue;
+ }
+ if (strstr(readLine, PKE_FILE_INSTANCE_POS_SCALE)) {
+ uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_POS_SCALE);
+ char *startingChar = strchr(readLine + prefixLen, '[') + 1;
+ assert(startingChar != nullptr);
+ char *pEnd = nullptr;
+ long index = 0;
+ do {
+ assert(index < 3);
+ STR2NUM_ERROR result = str2num(comp.instPos.scale[index], startingChar, pEnd);
+ assert(result == STR2NUM_ERROR::SUCCESS);
+ startingChar = pEnd + 1;
+ ++index;
+ } while (*pEnd != ']');
+ continue;
+ }
+ }
+}
+
void SaveSceneFile(const char *sceneFilePath) {
std::ofstream f(sceneFilePath);
assert(f.is_open());
- f << PKE_FILE_BEGIN << "\n";
- f << PKE_FILE_VERSION << "\n";
- f << "" << "\n";
+ f << PKE_FILE_BEGIN << std::endl;
+ f << PKE_FILE_VERSION << std::endl;
+ f << "" << std::endl;
for (long i = 0; i < GlobalEntityTypes.Count(); ++i) {
- f << PKE_FILE_OBJ_ENTITY_TYPE << "\n";
+ f << PKE_FILE_OBJ_ENTITY_TYPE << std::endl;
const auto &et = GlobalEntityTypes[i];
const CompGrBinds *grBinds = ECS_GetGrBinds(et.entityHandle);
// TODO ignore if no instances
@@ -164,10 +287,23 @@ void SaveSceneFile(const char *sceneFilePath) {
continue;
}
SerializeEntityType(f, et);
- f << PKE_FILE_OBJ_END << "\n";
+ f << PKE_FILE_OBJ_END << std::endl;
+ }
+
+ int64_t instanceBucketCount = ECS_GetInstances_BucketCount();
+ for (long b = 0; b < instanceBucketCount; ++b) {
+ uint64_t count;
+ auto *instances = ECS_GetInstances(b, count);
+ for (long i = 0; i < count; ++i) {
+ const auto &instance = instances[i];
+ if (instance.entHandle == EntityHandle_MAX)
+ continue;
+ SerializeInstance(f, instance);
+ f << PKE_FILE_OBJ_END << std::endl;
+ }
}
- f << PKE_FILE_END << "\n";
+ f << PKE_FILE_END << std::endl;
f.flush();
f.close();
@@ -184,6 +320,10 @@ void LoadSceneFile(const char *sceneFilePath) {
ParseEntityType(f);
continue;
}
+ if (strcmp(PKE_FILE_OBJ_INSTANCE, readLine) == 0) {
+ ParseInstance(f);
+ continue;
+ }
}
f.close();