summaryrefslogtreecommitdiff
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp537
1 files changed, 3 insertions, 534 deletions
diff --git a/src/game.cpp b/src/game.cpp
index f7b539b..5e5e1b0 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2,6 +2,7 @@
#include "game.hpp"
#include "camera.hpp"
+#include "serialization-component.hpp"
#include "components.hpp"
#include "ecs.hpp"
#include "entities.hpp"
@@ -13,11 +14,13 @@
#include "imgui.h"
#include "level-types.hpp"
#include "level.hpp"
+#include "math-helpers.hpp"
#include "physics.hpp"
#include "player-input.hpp"
#include "plugins.hpp"
#include "project.hpp"
#include "scene.hpp"
+#include "serialization.hpp"
#include "static-ui.hpp"
#include "thread-pool.hpp"
#include "window.hpp"
@@ -27,544 +30,10 @@
#include <BulletCollision/NarrowPhaseCollision/btRaycastCallback.h>
#include <GLFW/glfw3.h>
#include <cstring>
-#include <iomanip>
-#include <ostream>
-#include <fstream>
#include <thread>
-const long readLineLength = 128;
-char readLine[readLineLength];
-struct InstMapping {
- InstanceHandle origHandle = InstanceHandle_MAX;
- EntityHandle newEntHandle;
- InstanceHandle newInstHandle;
- InstPos newInstance{};
-};
-pk_arr_t<InstMapping> loadFileInstanceMappings{};
-
const char *levelName = "demo-level";
-const char *PKE_FILE_BEGIN = ":PKFB:";
-const char *PKE_FILE_END = ":PKFE:";
-const char *PKE_FILE_VERSION = ":0:";
-const char *PKE_FILE_OBJ_END = "";
-const char *PKE_FILE_OBJ_INSTANCE = "Instance:";
-const char *PKE_FILE_OBJ_CAMERA = "Camera:";
-
-const char *PKE_FILE_INSTANCE_HANDLE = "Inst::InstHandle: ";
-const char *PKE_FILE_INSTANCE_ENTITY_HANDLE = "EntityHandle: ";
-const char *PKE_FILE_INSTANCE_ENTITY_TYPE_CODE = "EntityTypeCode: ";
-const char *PKE_FILE_INSTANCE_UUID = "UUID: ";
-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: ";
-const char *PKE_FILE_INSTANCE_PHYSICS_MASS = "InstPos::Mass: ";
-const char *PKE_FILE_INSTANCE_PHYSICS_COLLISION_LAYER = "InstPos::CollisionLayer: ";
-const char *PKE_FILE_INSTANCE_PHYSICS_COLLISION_MASK = "InstPos::CollisionMask: ";
-const char *PKE_FILE_INSTANCE_COLLISION_CALLBACK_SIGNATURE = "Inst::CollisionCallbackSignature: ";
-
-const char PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA = 'C';
-
-const char *PKE_FILE_CAMERA_POS = "Cam::Pos: ";
-const char *PKE_FILE_CAMERA_ROT = "Cam::Rot: ";
-const char *PKE_FILE_CAMERA_TARGET = "Cam::Target: ";
-const char *PKE_FILE_CAMERA_TYPE = "Cam::Type: ";
-const char *PKE_FILE_CAMERA_UUID = "Cam::UUID: ";
-const char *PKE_FILE_CAMERA_ORIENTATION = "Cam::Orientation: ";
-const char *PKE_FILE_CAMERA_INSTANCE_HANDLE = "Cam::InstanceHandle: ";
-const char *PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE = "Cam::TargetInstanceHandle: ";
-const char *PKE_FILE_CAMERA_IS_PRIMARY = "Cam::IsPrimary: ";
-
-void SerializeCamera(std::ostream &stream, const PkeCamera &cam) {
- NULL_CHAR_ARR(handleStr, 23);
- PkeCamera c{};
- if (cam.uuid != pk_uuid_zed && cam.uuid != pk_uuid_max) {
- stream << PKE_FILE_CAMERA_UUID << cam.uuid << std::endl;
- }
- if (cam.type != c.type) {
- stream << PKE_FILE_CAMERA_TYPE << int(static_cast<PkeCameraType_T>(cam.type)) << std::endl;
- }
- if (cam.view != c.view) {
- stream << PKE_FILE_CAMERA_ORIENTATION << int(static_cast<PkeCameraView_T>(cam.view)) << std::endl;
- }
- if (cam.phys.instHandle != InstanceHandle_MAX) {
- snprintf(handleStr, 22, "0x%08X 0x%08X", cam.phys.instHandle.bucketIndex, cam.phys.instHandle.itemIndex);
- stream << PKE_FILE_CAMERA_INSTANCE_HANDLE << handleStr << std::endl;
- }
- if (cam.phys.targetInstHandle != InstanceHandle_MAX) {
- snprintf(handleStr, 22, "0x%08X 0x%08X", cam.phys.targetInstHandle.bucketIndex, cam.phys.targetInstHandle.itemIndex);
- stream << PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE << handleStr << std::endl;
- }
- if (cam.isPrimary != c.isPrimary) {
- stream << PKE_FILE_CAMERA_IS_PRIMARY << cam.isPrimary << std::endl;
- }
-
- CompInstance &comp = *ECS_GetInstance(cam.phys.instHandle);
- InstPos baseInst{};
- baseInst.posRot = btTransform{};
- baseInst.posRot.setIdentity();
- baseInst.scale = btVector3(1, 1, 1);
- btTransform trans;
- comp.bt.motionState->getWorldTransform(trans);
- btVector3 scale = comp.bt.rigidBody->getCollisionShape()->getLocalScaling();
- if (trans != baseInst.posRot) {
- btVector3 pos = trans.getOrigin();
- btQuaternion rot = trans.getRotation();
- stream << PKE_FILE_INSTANCE_POS_POS << "["
- << std::setw(10) << pos[0] << ","
- << std::setw(10) << pos[1] << ","
- << std::setw(10) << pos[2] << "]" << std::endl
- << PKE_FILE_INSTANCE_POS_ROT << "["
- << std::setw(10) << rot[0] << ","
- << std::setw(10) << rot[1] << ","
- << std::setw(10) << rot[2] << ","
- << std::setw(10) << rot[3] << "]" << std::endl;
- }
- if (scale != baseInst.scale)
- stream << PKE_FILE_INSTANCE_POS_SCALE << "["
- << std::setw(10) << scale[0] << ","
- << std::setw(10) << scale[1] << ","
- << std::setw(10) << scale[2] << "]" << std::endl;
-}
-
-void SerializeInstance(std::ostream &stream, const CompInstance &comp) {
- NULL_CHAR_ARR(handleStr, 23);
- EntityType *et = nullptr;
- if (comp.grBindsHandle != GrBindsHandle_MAX) {
- et = EntityType_FindByEntityHandle(ECS_GetGrBinds(comp.grBindsHandle)->entHandle);
- }
- CompInstance c{};
- InstPos baseInst{};
- baseInst.posRot = btTransform{};
- baseInst.posRot.setIdentity();
- baseInst.scale = btVector3(1, 1, 1);
- baseInst.mass = 1;
- if (comp.entHandle != InstanceHandle_MAX) {
- snprintf(handleStr, 22, "0x%08X 0x%08X", comp.entHandle.bucketIndex, comp.entHandle.itemIndex);
- stream << PKE_FILE_INSTANCE_ENTITY_HANDLE << handleStr << std::endl;
- }
- if (comp.instanceHandle != InstanceHandle_MAX) {
- snprintf(handleStr, 22, "0x%08X 0x%08X", comp.instanceHandle.bucketIndex, comp.instanceHandle.itemIndex);
- stream << PKE_FILE_INSTANCE_HANDLE << handleStr << std::endl;
- }
- if (comp.uuid != pk_uuid_zed && comp.uuid != pk_uuid_max) {
- stream << PKE_FILE_INSTANCE_UUID << comp.uuid << std::endl;
- }
- if (et != nullptr) {
- stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode.val << std::endl;
- } else if (PkeCamera_Get(comp.entHandle)) {
- stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA << std::endl;
- }
-
- btTransform trans;
- comp.bt.motionState->getWorldTransform(trans);
- btVector3 scale = comp.bt.rigidBody->getCollisionShape()->getLocalScaling();
- btScalar mass = comp.bt.rigidBody->getMass();
- PhysicsCollision collisionLayer{static_cast<PhysicsCollision_T>(comp.bt.rigidBody->getBroadphaseProxy()->m_collisionFilterGroup)};
- PhysicsCollision collisionMask{static_cast<PhysicsCollision_T>(comp.bt.rigidBody->getBroadphaseProxy()->m_collisionFilterMask)};
- if (trans != baseInst.posRot) {
- btVector3 pos = trans.getOrigin();
- btQuaternion rot = trans.getRotation();
- stream << PKE_FILE_INSTANCE_POS_POS << "["
- << std::setw(10) << pos[0] << ","
- << std::setw(10) << pos[1] << ","
- << std::setw(10) << pos[2] << "]" << std::endl
- << PKE_FILE_INSTANCE_POS_ROT << "["
- << std::setw(10) << rot[0] << ","
- << std::setw(10) << rot[1] << ","
- << std::setw(10) << rot[2] << ","
- << std::setw(10) << rot[3] << "]" << std::endl;
- }
- if (scale != baseInst.scale)
- stream << PKE_FILE_INSTANCE_POS_SCALE << "["
- << std::setw(10) << scale[0] << ","
- << std::setw(10) << scale[1] << ","
- << std::setw(10) << scale[2] << "]" << std::endl;
- if (mass != baseInst.mass) {
- stream << PKE_FILE_INSTANCE_PHYSICS_MASS << mass << std::endl;
- }
- if (collisionLayer != c.physicsLayer) {
- stream << PKE_FILE_INSTANCE_PHYSICS_COLLISION_LAYER << static_cast<PhysicsCollision_T>(collisionLayer) << std::endl;
- }
- if (collisionMask != c.physicsMask) {
- stream << PKE_FILE_INSTANCE_PHYSICS_COLLISION_MASK << static_cast<PhysicsCollision_T>(collisionMask) << std::endl;
- }
- if (comp.collisionCallback.name[0] != '\0') {
- stream << PKE_FILE_INSTANCE_COLLISION_CALLBACK_SIGNATURE << comp.collisionCallback.name << std::endl;
- }
-}
-
-bool FindFirstInstanceHandle(void *handle, void *mapping) {
- InstMapping *inst_mapping = reinterpret_cast<InstMapping *>(mapping);
- return inst_mapping->origHandle == *reinterpret_cast<InstanceHandle *>(handle);
-}
-void DeserializeCamera(pke_scene *scene, std::istream &stream) {
- PkeCamera cam{};
- InstanceHandle instanceHandle = InstanceHandle_MAX;
- InstanceHandle targetInstanceHandle = InstanceHandle_MAX;
- while (stream.getline(readLine, readLineLength)) {
- if (strcmp(readLine, PKE_FILE_OBJ_END) == 0) {
-
- int64_t instanceIndex = -1, targetInstanceIndex = -1;
-
- instanceIndex = pk_arr_find_first_index(&loadFileInstanceMappings, &instanceHandle, FindFirstInstanceHandle);
-
- if (targetInstanceHandle != InstanceHandle_MAX) {
- targetInstanceIndex = pk_arr_find_first_index(&loadFileInstanceMappings, &targetInstanceHandle, FindFirstInstanceHandle);
- }
-
- InstPos instPos;
- if (instanceIndex == -1) {
- instPos.mass = 1.f;
- instPos.posRot.setIdentity();
- instPos.scale = btVector3(1.f, 1.f, 1.f);
- fprintf(stdout, "[DeserializeCamera] Failed to find instance mapping. Is this an outdated parse?\n");
- } else {
- instPos = loadFileInstanceMappings[instanceIndex].newInstance;
- }
- auto &rCam = PkeCamera_Register(cam.uuid, instPos);
- rCam.type = cam.type;
- rCam.view = cam.view;
- rCam.isPrimary = cam.isPrimary;
- rCam.phys.targetInstHandle = targetInstanceHandle;
- pke_scene_register_camera(scene->scene_handle, rCam.camHandle);
- if (targetInstanceIndex > -1) {
- PkeCamera_TargetInstance(rCam.camHandle, ECS_GetInstance(loadFileInstanceMappings[targetInstanceIndex].newInstHandle));
- }
- if (rCam.isPrimary == true) {
- ActiveCamera = &rCam;
- }
- return;
- }
- if (strncmp(readLine, PKE_FILE_CAMERA_UUID, strlen(PKE_FILE_CAMERA_TYPE)) == 0) {
- uint64_t prefixLen = strlen(PKE_FILE_CAMERA_UUID);
- (readLine + prefixLen) >> cam.uuid;
- continue;
- }
- if (strncmp(readLine, PKE_FILE_CAMERA_TYPE, strlen(PKE_FILE_CAMERA_TYPE)) == 0) {
- uint64_t prefixLen = strlen(PKE_FILE_CAMERA_TYPE);
- PkeCameraType_T handle_t;
- STR2NUM_ERROR result = str2num(handle_t, readLine + prefixLen);
- assert(result == STR2NUM_ERROR::SUCCESS);
- cam.type = PkeCameraType{handle_t};
- continue;
- }
- if (strncmp(readLine, PKE_FILE_CAMERA_ORIENTATION, strlen(PKE_FILE_CAMERA_ORIENTATION)) == 0) {
- uint64_t prefixLen = strlen(PKE_FILE_CAMERA_ORIENTATION);
- PkeCameraView_T handle_t;
- STR2NUM_ERROR result = str2num(handle_t, readLine + prefixLen);
- assert(result == STR2NUM_ERROR::SUCCESS);
- cam.view = PkeCameraView{handle_t};
- continue;
- }
- if (strstr(readLine, PKE_FILE_CAMERA_INSTANCE_HANDLE)) {
- uint64_t prefixLen = strlen(PKE_FILE_CAMERA_INSTANCE_HANDLE);
- readLine[prefixLen + 10] = '\0';
- STR2NUM_ERROR result1 = str2num(instanceHandle.bucketIndex, readLine + prefixLen);
- STR2NUM_ERROR result2 = str2num(instanceHandle.itemIndex, readLine + prefixLen + 11);
- assert(result1 == STR2NUM_ERROR::SUCCESS);
- assert(result2 == STR2NUM_ERROR::SUCCESS);
- // TODO add to global list
- continue;
- }
- if (strstr(readLine, PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE)) {
- uint64_t prefixLen = strlen(PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE);
- readLine[prefixLen + 10] = '\0';
- STR2NUM_ERROR result1 = str2num(targetInstanceHandle.bucketIndex, readLine + prefixLen);
- STR2NUM_ERROR result2 = str2num(targetInstanceHandle.itemIndex, readLine + prefixLen + 11);
- assert(result1 == STR2NUM_ERROR::SUCCESS);
- assert(result2 == STR2NUM_ERROR::SUCCESS);
- // TODO find and set
- continue;
- }
- if (strncmp(readLine, PKE_FILE_CAMERA_IS_PRIMARY, strlen(PKE_FILE_CAMERA_IS_PRIMARY)) == 0) {
- uint64_t prefixLen = strlen(PKE_FILE_CAMERA_IS_PRIMARY);
- uint8_t isPrimary;
- STR2NUM_ERROR result = str2num(isPrimary, readLine + prefixLen);
- assert(result == STR2NUM_ERROR::SUCCESS);
- cam.isPrimary = bool(isPrimary);
- continue;
- }
- }
-}
-
-void DeserializeInstance(Entity_Base *parentEntity, std::istream &stream) {
- CompInstance comp{};
- InstMapping mapping {
- .origHandle = InstanceHandle_MAX,
- .newEntHandle = EntityHandle_MAX,
- .newInstHandle = InstanceHandle_MAX,
- .newInstance = {
- .posRot = {},
- .scale = btVector3(1.f, 1.f, 1.f),
- .mass = 1.f,
- },
- };
- mapping.newInstance.posRot.setIdentity();
- comp.collisionCallback.name[0] = '\0';
- NULL_CHAR_ARR(entTypeCode, 21);
- while (stream.getline(readLine, readLineLength)) {
- if (strstr(PKE_FILE_OBJ_END, readLine)) {
- EntityType *etPtr = nullptr;
- Entity_Base *entity = nullptr;
- bool skipEntCreate = false;
- if (strlen(entTypeCode) > 1) {
- etPtr = EntityType_FindByTypeCode(entTypeCode);
- if (etPtr == nullptr) {
- fprintf(stdout, "[Game::DeserializeInstance] Unknown EntityTypeCode: \"%s\"\n", entTypeCode);
- break;
- }
- } else if (strlen(entTypeCode) == 1) {
- // handle internally
- if (entTypeCode[0] == PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA) {
- skipEntCreate = true;
- }
- } else {
- fprintf(stdout, "[Game::DeserializeInstance] Failed to create instance from save file. No EntTypeCode present.\n");
- break;
- }
-
- if (skipEntCreate == false) {
- if (etPtr != nullptr && etPtr->createInstanceCallback.func != nullptr) {
- /* TODO 2025-03-27 JCB
- * We have not yet defined what the appropriate callback signature
- * for creating an entity instance is.
- * What should be passed as arguments? What would need to be passed
- * that couldn't be accessed globally?
- * Consider changing this callback to trigger after creating a
- * generic instance, rather than *creating* it.
- */
- // typedef Entity_Base *CreateInst();
- // entity = reinterpret_cast<CreateInst*>(etPtr->createInstanceCallback.func)();
- fprintf(stderr, "[%s] Attempted to call EntityType::createInstanceCallback and we have not yet defined a valid function signature", __FILE__);
- } else {
- entity = EntityType_CreateGenericInstance(etPtr, parentEntity, &comp, &mapping.newInstance);
- fprintf(stdout ,"[Game::DeserializeInstance] Debug: entTypeCode '%s' does not have a registered callback func to handle instance creation.\n", entTypeCode);
- }
- mapping.newEntHandle = entity->handle;
- }
- if (mapping.newEntHandle != EntityHandle_MAX) {
- // TODO this is messy
- pk_arr_t<CompInstance *> instances{};
- ECS_GetInstances(entity, instances);
- assert(instances.next > 0);
- mapping.newInstHandle = instances[0]->instanceHandle;
- }
- pk_arr_append(&loadFileInstanceMappings, &mapping);
- break;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_HANDLE);
- readLine[prefixLen + 10] = '\0';
- STR2NUM_ERROR result1 = str2num(comp.entHandle.bucketIndex, readLine + prefixLen);
- STR2NUM_ERROR result2 = str2num(comp.entHandle.itemIndex, readLine + prefixLen + 11);
- assert(result1 == STR2NUM_ERROR::SUCCESS);
- assert(result2 == STR2NUM_ERROR::SUCCESS);
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_HANDLE)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_HANDLE);
- readLine[prefixLen + 10] = '\0';
- STR2NUM_ERROR result1 = str2num(mapping.origHandle.bucketIndex, readLine + prefixLen);
- STR2NUM_ERROR result2 = str2num(mapping.origHandle.itemIndex, readLine + prefixLen + 11);
- assert(result1 == STR2NUM_ERROR::SUCCESS);
- assert(result2 == STR2NUM_ERROR::SUCCESS);
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_UUID)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_UUID);
- (readLine + prefixLen) >> comp.uuid ;
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_TYPE_CODE)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_TYPE_CODE);
- strncpy(entTypeCode, readLine + prefixLen, 21);
- 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;
- btVector3 pos;
- do {
- assert(index < 3);
- STR2NUM_ERROR result = str2num(pos[index], startingChar, pEnd);
- assert(result == STR2NUM_ERROR::SUCCESS);
- startingChar = pEnd + 1;
- ++index;
- } while (*pEnd != ']');
- mapping.newInstance.posRot.setOrigin(pos);
- 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;
- btQuaternion rot;
- do {
- assert(index < 4);
- STR2NUM_ERROR result = str2num(rot[index], startingChar, pEnd);
- assert(result == STR2NUM_ERROR::SUCCESS);
- startingChar = pEnd + 1;
- ++index;
- } while (*pEnd != ']');
- mapping.newInstance.posRot.setRotation(rot);
- 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(mapping.newInstance.scale[index], startingChar, pEnd);
- assert(result == STR2NUM_ERROR::SUCCESS);
- startingChar = pEnd + 1;
- ++index;
- } while (*pEnd != ']');
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_PHYSICS_MASS)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_PHYSICS_MASS);
- STR2NUM_ERROR result = str2num(mapping.newInstance.mass, readLine + prefixLen);
- assert(result == STR2NUM_ERROR::SUCCESS);
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_PHYSICS_COLLISION_LAYER)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_PHYSICS_COLLISION_LAYER);
- PhysicsCollision_T val = static_cast<PhysicsCollision_T>(comp.physicsLayer);
- STR2NUM_ERROR result = str2num(val, readLine + prefixLen);
- comp.physicsLayer = PhysicsCollision{val};
- assert(result == STR2NUM_ERROR::SUCCESS);
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_PHYSICS_COLLISION_MASK)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_PHYSICS_COLLISION_MASK);
- PhysicsCollision_T val = static_cast<PhysicsCollision_T>(comp.physicsMask);
- STR2NUM_ERROR result = str2num(val, readLine + prefixLen);
- comp.physicsMask = PhysicsCollision{val};
- assert(result == STR2NUM_ERROR::SUCCESS);
- continue;
- }
- if (strstr(readLine, PKE_FILE_INSTANCE_COLLISION_CALLBACK_SIGNATURE)) {
- uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_COLLISION_CALLBACK_SIGNATURE);
- strncpy(comp.collisionCallback.name, readLine + prefixLen, 16);
- continue;
- }
- }
-}
-
-void Game_SaveSceneFile(const char *sceneFilePath) {
- std::ostringstream stream{};
- bool failed = false;
-
- try {
- stream << PKE_FILE_BEGIN << std::endl;
- stream << PKE_FILE_VERSION << std::endl;
- stream << "" << std::endl;
-
- pk_handle_bucket_index_T instanceBucketCount = ECS_GetInstances_BucketCount();
- for (pk_handle_bucket_index_T b = 0; b < instanceBucketCount; ++b) {
- pk_handle_item_index_T count;
- auto *instances = ECS_GetInstances(b, count);
- for (pk_handle_item_index_T i = 0; i < count; ++i) {
- const auto &instance = instances[i];
- if (instance.entHandle == EntityHandle_MAX)
- continue;
- if (instance.flags & COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE) {
- continue;
- }
- stream << PKE_FILE_OBJ_INSTANCE << std::endl;
- SerializeInstance(stream, instance);
- stream << PKE_FILE_OBJ_END << std::endl;
- }
- }
-
- pk_handle_bucket_index_T cameraBucketCount = PkeCamera_GetBucketCount();
- for (pk_handle_bucket_index_T b = 0; b < cameraBucketCount; ++b) {
- pk_handle_item_index_T count;
- auto *cameras = PkeCamera_GetCameras(b, count);
- for (pk_handle_item_index_T i = 0; i < count; ++i) {
- const auto &cam = cameras[i];
- if (cam.handle == CameraHandle_MAX)
- continue;
- stream << PKE_FILE_OBJ_CAMERA << std::endl;
- SerializeCamera(stream, cam);
- stream << PKE_FILE_OBJ_END << std::endl;
- }
- }
-
- stream << PKE_FILE_END << std::endl;
- } catch (std::exception &e) {
- fprintf(stderr, "[%s][Game_SaveSceneFile] Failed to serialize scene file: %s\n", __FILE__, e.what());
- failed = false;
- } catch (...) {
- fprintf(stderr, "[%s][Game_SaveSceneFile] Failed to serialize scene file, uncaught exception.\n", __FILE__);
- failed = false;
- }
-
- if (failed == false) {
- std::ofstream f(sceneFilePath);
- if (!f.is_open()) {
- failed = true;
- } else {
- f << stream.str();
- }
- f.flush();
- f.close();
- }
-
- if (failed) {
- NULL_CHAR_ARR(errFileName, 256);
- strncpy(errFileName, sceneFilePath, 256);
- strncpy(errFileName + strlen(sceneFilePath), ".err", 256 - strlen(sceneFilePath));
- std::ofstream errF(sceneFilePath);
- if (errF.is_open()) {
- errF << stream.str();
- errF.flush();
- errF.close();
- fprintf(stderr, "Failed to save scene file '%s', partial output saved to '%s'\n", sceneFilePath, errFileName);
- } else {
- fprintf(stderr, "Failed to save scene file '%s' and also failed to write failed output\n", sceneFilePath);
- }
- }
-}
-
-void Game_LoadSceneFile(const char *sceneFilePath) {
- std::ifstream f(sceneFilePath);
- if (!f.is_open()) {
- fprintf(stderr, "Failed to load requested scene file: '%s'\n", sceneFilePath);
- return;
- }
- // TODO scene name is in the file?
- pke_scene *scn = pke_scene_get_by_name(sceneFilePath);
- if (scn == nullptr) {
- scn = pke_scene_create(sceneFilePath);
- }
-
- memset(readLine, '\0', readLineLength);
-
- while (f.getline(readLine, readLineLength)) {
- if (strcmp(PKE_FILE_OBJ_INSTANCE, readLine) == 0) {
- DeserializeInstance(scn, f);
- continue;
- }
- if (strcmp(PKE_FILE_OBJ_CAMERA, readLine) == 0) {
- DeserializeCamera(scn, f);
- continue;
- }
- }
-
- f.close();
- pk_arr_clear(&loadFileInstanceMappings);
-}
-
const int64_t consoleBufferCount = 30;
const int64_t consoleLineLength = 128;
char consoleBuffer[consoleBufferCount][consoleLineLength];