summaryrefslogtreecommitdiff
path: root/src/level.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-21 20:54:14 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-03-21 21:40:21 -0400
commit677a3cbec2f7908ee0897b97d508a6bd66a0a344 (patch)
treefc88b21dd61dbb10dd8b5c8aef73702d15514f00 /src/level.cpp
parentcae76dd98e301a4560bb46ecb59b5952dff04149 (diff)
pke: first-pass level is a collection of scenes
Diffstat (limited to 'src/level.cpp')
-rw-r--r--src/level.cpp109
1 files changed, 60 insertions, 49 deletions
diff --git a/src/level.cpp b/src/level.cpp
index 047363b..57faf80 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -1,87 +1,98 @@
#include "level.hpp"
-#include "camera.hpp"
+#include "bucketed-array.hpp"
#include "ecs.hpp"
#include "pk.h"
-LevelHandle nextHandle = LevelHandle{0};
-long levelCount = 0;
-constexpr long LEVEL_NAME_LENGTH = 16;
-PkeLevel LEVELS[MAX_LEVEL_COUNT];
+struct level_mstr {
+ BucketContainer<PkeLevel, LevelHandle> bc;
+} level_mstr;
+void PkeLevel_Init() {
+ Buckets_Init(level_mstr.bc);
+}
+
+void PkeLevel_Teardown() {
+ Buckets_Destroy(level_mstr.bc);
+}
+
+/*
PkeLevel *PkeLevel_Get_Inner(LevelHandle handle) {
- for (long i = 0; i < MAX_LEVEL_COUNT; ++i) {
- if (LEVELS[i].levelHandle == handle) {
- return &LEVELS[i];
- }
+ if ( || handle.itemIndex >= level_mstr.bc.limits.itemIndex || (handle.bucketIndex == handle.bucketIndex) {
}
- return nullptr;
+ return &level_mstr.bc.buckets[handle.bucketIndex][handle.itemIndex];
}
+*/
-void PkeLevel_Init() {
- for (long i = 0; i < MAX_LEVEL_COUNT; ++i) {
- new (&LEVELS[i]) PkeLevel{};
- pk_arr_reset(&LEVELS[i].cameras);
+PkeLevel *PkeLevel_Create(const char *levelName) {
+ NULL_CHAR_ARR(safe_name, LEVEL_NAME_MAX_LEN + 1);
+
+ size_t len = strlen(levelName);
+ size_t start = len <= (LEVEL_NAME_MAX_LEN - 1) ? 0 : len - (LEVEL_NAME_MAX_LEN - 1);
+ sprintf(safe_name, pke_level_name_printf_format, levelName + start);
+
+ PkeLevel *lvl = PkeLevel_GetByName(levelName);
+ if (lvl != nullptr) {
+ fprintf(stderr, "[PkeLevel_Create] Failed to create new level: name already exists.");
+ return nullptr;
}
-}
-LevelHandle PkeLevel_Create(const char *levelName) {
- assert(levelCount < MAX_LEVEL_COUNT && "only MAX_LEVEL_COUNT levels can be loaded at once");
- levelCount += 1;
+ LevelHandle level_handle = Buckets_NewHandle(level_mstr.bc);
+ if (level_handle == LevelHandle_MAX) {
+ fprintf(stderr, "[PkeLevel_Create] Failed to create new level handle from BucketContainer");
+ return nullptr;
+ }
- PkeLevel *lvl = PkeLevel_Get_Inner(LevelHandle_MAX);
- assert(lvl != nullptr && "max level count not reached, but failed to find a valid level slot");
+ lvl = &level_mstr.bc[level_handle];
ECS_CreateEntity(lvl);
if (lvl->bkt == nullptr) {
lvl->bkt = pk_bucket_create(levelName, PK_DEFAULT_BUCKET_SIZE, false);
}
- lvl->levelHandle = nextHandle;
- ++nextHandle;
- auto len = strlen(levelName);
- auto start = len <= (LEVEL_NAME_LENGTH - 1) ? 0 : len - (LEVEL_NAME_LENGTH - 1);
- strncpy(lvl->name, levelName + start, LEVEL_NAME_LENGTH);
- return lvl->levelHandle;
+ return lvl;
}
PkeLevel *PkeLevel_Get(LevelHandle handle) {
- return PkeLevel_Get_Inner(handle);
+ return &level_mstr.bc[handle];
}
-LevelHandle PkeLevel_GetHandle(const char *levelName) {
- char safeName[LEVEL_NAME_LENGTH];
+PkeLevel *PkeLevel_GetByName(const char *levelName) {
+ NULL_CHAR_ARR(safe_name, LEVEL_NAME_MAX_LEN + 1);
auto len = strlen(levelName);
- auto start = len <= (LEVEL_NAME_LENGTH - 1) ? 0 : len - (LEVEL_NAME_LENGTH - 1);
- strncpy(safeName, levelName + start, LEVEL_NAME_LENGTH);
- for (long i = 0; i < MAX_LEVEL_COUNT; ++i) {
- if (LEVELS[i].levelHandle != LevelHandle_MAX) {
- if (strcmp(safeName, LEVELS[i].name)) {
- return LEVELS[i].levelHandle;
+ auto start = len <= (LEVEL_NAME_MAX_LEN - 1) ? 0 : len - (LEVEL_NAME_MAX_LEN - 1);
+ sprintf(safe_name, pke_level_name_printf_format, levelName + start);
+
+ pk_handle_bucket_index_T b;
+ pk_handle_item_index_T i, ii;
+ for (b = 0; b < level_mstr.bc.pkeHandle.bucketIndex; ++b) {
+ ii = level_mstr.bc.pkeHandle.bucketIndex == b ? level_mstr.bc.pkeHandle.itemIndex : level_mstr.bc.limits.itemIndex;
+ for (i = 0; i < ii; ++i) {
+ if (memcmp(safe_name, level_mstr.bc.buckets[b][i].name, LEVEL_NAME_MAX_LEN) == 0) {
+ return &level_mstr.bc.buckets[b][i];
}
}
}
- return LevelHandle_MAX;
+ return nullptr;
+}
+
+pk_handle_bucket_index_T pke_level_get_bucket_count() {
+ return level_mstr.bc.pkeHandle.bucketIndex + 1;
}
-void PkeLevel_RegisterCamera(LevelHandle levelHandle, CameraHandle cameraHandle) {
- assert(levelHandle != LevelHandle_MAX);
- assert(cameraHandle != CameraHandle_MAX);
- PkeLevel *lvl = PkeLevel_Get_Inner(levelHandle);
- assert(lvl != nullptr && "Failed to find level by requested LevelHandle");
- pk_arr_append(&lvl->cameras, &cameraHandle);
+struct PkeLevel *pke_level_get_levels(pk_handle_bucket_index_T bucket_index, pk_handle_item_index_T *item_count) {
+ assert(bucket_index <= level_mstr.bc.pkeHandle.bucketIndex);
+ assert(item_count != nullptr);
+ *item_count = bucket_index == level_mstr.bc.pkeHandle.bucketIndex ? level_mstr.bc.pkeHandle.itemIndex : level_mstr.bc.limits.itemIndex;
+ return level_mstr.bc.buckets[bucket_index];
}
void PkeLevel_Remove(LevelHandle handle) {
- PkeLevel *lvl = PkeLevel_Get_Inner(handle);
- assert(lvl != nullptr && "Failed to find level to remove by requested LevelHandle");
- levelCount -= 1;
+ PkeLevel *lvl = &level_mstr.bc[handle];
+ assert(lvl == nullptr && "Failed to find level to remove by requested LevelHandle");
+ // TODO mark bucket slot as open
ECS_MarkForRemoval(lvl);
- for (long i = 0; i < lvl->cameras.next; ++i) {
- PkeCamera_Destroy(lvl->cameras[i]);
- }
- pk_arr_reset(&lvl->cameras);
pk_bucket_reset(lvl->bkt);
lvl->levelHandle = LevelHandle_MAX;
}