Compare commits

..

3 Commits

Author SHA1 Message Date
87d3c9087e Merge branch 'debug'
Fixed some warnings
2025-10-06 19:52:28 +01:00
0c33944721 Merge branch 'debug/world_change' of yibble.dev:bulmanator/ld58 into debug 2025-10-06 19:38:14 +01:00
c1fb705f68 Fixed level saving and loading 2025-10-06 19:36:41 +01:00
3 changed files with 132 additions and 81 deletions

View File

@@ -398,6 +398,7 @@ int main(int argc, char **argv)
G_Editor editor = game->editor;
F32 tilex = cast(F32) floor(editor.cursor.x+TILE_SIZE/2);
F32 tiley = cast(F32) floor(editor.cursor.y+TILE_SIZE/2);
switch(game->editor.mode) {
case G_EDITOR_MODE_TILE: {
World_Tile asset = game->world->tileTypes[editor.currentAsset];
@@ -419,7 +420,7 @@ int main(int argc, char **argv)
.texture=0,
.dim=game->world->hitboxes[i].size,
.flags=D_RECT_IGNORE_ASPECT,
.c=V4F(100,0,0,0.7),
.c=V4F(100,0,0,0.7f),
);
}
break;

View File

@@ -35,7 +35,7 @@ void ProcessEvents(SDL_Event *event, World *world)
{
PlayerInput(event, &world->player);
if(event->type == SDL_EVENT_KEY_DOWN && event->key.key == SDLK_F5){
SaveWorld(world->arena, world);
SaveWorld(world);
}
if(event->type == SDL_EVENT_KEY_DOWN && event->key.key == SDLK_F6){
LoadWorld(world->arena, world);
@@ -64,7 +64,7 @@ void RenderWorld(World *world, D_Context *draw) {
);
}
}
for (int i = 0; i < world->navMesh->nodeCount; i++) {
for (U32 i = 0; i < world->navMesh->nodeCount; i++) {
NavNode n = world->navMesh->nodes[i];
D_Rect(
draw,
@@ -89,94 +89,144 @@ void RenderWorld(World *world, D_Context *draw) {
PlayerDraw(draw, &world->player);
}
void SaveWorld(M_Arena *arena, World *world) {
(void) arena;
#define WRITE(v) FS_FileWrite(file, &(v), sizeof(v), offset); offset += sizeof(v)
#define WRITEN(v, n) FS_FileWrite(file, v, (n) * sizeof(*(v)), offset); offset += ((n) * sizeof(*(v)))
void SaveWorld(World *world) {
printf("--- Saving World ---\n");
printf(" - %d props\n", world->propCount);
printf(" - %d hitboxes\n", world->hitboxCount);
printf("Saving world\n");
OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_WRITE);
U32 offset = 0;
for(int i = 0; i < WORLD_TILE_TYPE_MAX; i++) {
FS_FileWrite(file, &world->tileTypes[i].tag.count, sizeof(S64), offset);
offset += sizeof(S64);
FS_FileWrite(file, world->tileTypes[i].tag.data, world->tileTypes[i].tag.count, offset);
offset += sizeof(U8) * world->tileTypes[i].tag.count;
FS_FileWrite(file, &world->tileTypes[i].rotation, sizeof(F32), offset);
offset += sizeof(F32);
}
for(int i = 0; i < WORLD_PROP_TYPE_MAX; i++) {
FS_FileWrite(file, &world->propTypes[i].tag.count, sizeof(S64), offset);
offset += sizeof(S64);
FS_FileWrite(file, world->propTypes[i].tag.data, world->propTypes[i].tag.count, offset);
offset += sizeof(U8) * world->propTypes[i].tag.count;
FS_FileWrite(file, &world->propTypes[i].scale, sizeof(F32), offset);
offset += sizeof(F32);
U64 offset = 0;
for (U32 i = 0; i < WORLD_TILE_TYPE_MAX; i++) {
World_Tile *tile = &world->tileTypes[i];
WRITE(tile->tag.count);
WRITEN(tile->tag.data, tile->tag.count);
WRITE(tile->rotation);
}
FS_FileWrite(file, &world->propCount, sizeof(U32), offset);
offset += sizeof(U32);
for (U32 i = 0; i < WORLD_PROP_TYPE_MAX; i++) {
World_PropType *type = &world->propTypes[i];
FS_FileWrite(file, world->props, sizeof(World_Prop)*WORLD_PROP_MAX, offset);
offset += sizeof(World_Prop)*WORLD_PROP_MAX;
WRITE(type->tag.count);
WRITEN(type->tag.data, type->tag.count);
WRITE(type->scale);
}
FS_FileWrite(file, &world->hitboxCount, sizeof(U32), offset);
offset += sizeof(U32);
WRITE(world->propCount);
WRITEN(world->props, WORLD_PROP_MAX);
FS_FileWrite(file, world->hitboxes, sizeof(AABB)*WORLD_HITBOX_MAX, offset);
offset += sizeof(AABB)*WORLD_HITBOX_MAX;
WRITE(world->hitboxCount);
WRITEN(world->hitboxes, WORLD_HITBOX_MAX);
FS_FileWrite(file, world->map, sizeof(U32)*WORLD_MAP_MAX, offset);
offset += sizeof(U32)*WORLD_MAP_MAX;
WRITEN(world->map, WORLD_MAP_MAX);
FS_FileClose(file);
printf("Saved world :)\n");
printf("--- World Saved ---\n");
}
void LoadWorld(M_Arena *arena, World *world) {
printf("loading world\n");
OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_READ);
U32 offset = 0;
printf("--- Loading World ---\n");
world->tileTypes = M_ArenaPush(arena, World_Tile, .count=WORLD_TILE_TYPE_MAX);
for(int i = 0; i < WORLD_TILE_TYPE_MAX; i++) {
FS_FileRead(file, &world->tileTypes[i].tag.count, sizeof(S64), offset);
offset += sizeof(S64);
world->tileTypes[i].tag.data = M_ArenaPush(arena, U8, .count=world->tileTypes[i].tag.count);
FS_FileRead(file, world->tileTypes[i].tag.data, world->tileTypes[i].tag.count, offset);
offset += sizeof(U8) * world->tileTypes[i].tag.count;
FS_FileRead(file, &world->tileTypes[i].rotation, sizeof(F32), offset);
offset += sizeof(F32);
}
world->propTypes = M_ArenaPush(arena, World_PropType, .count=WORLD_PROP_TYPE_MAX);
for(int i = 0; i < WORLD_PROP_TYPE_MAX; i++) {
FS_FileRead(file, &world->propTypes[i].tag.count, sizeof(S64), offset);
offset += sizeof(S64);
world->propTypes[i].tag.data = M_ArenaPush(arena, U8, .count=world->propTypes[i].tag.count);
FS_FileRead(file, world->propTypes[i].tag.data, world->propTypes[i].tag.count, offset);
offset += sizeof(U8) * world->propTypes[i].tag.count;
FS_FileRead(file, &world->propTypes[i].scale, sizeof(F32), offset);
offset += sizeof(F32);
M_TempScope(0, 0) {
Str8 data = FS_ReadEntireFile(temp.arena, S("world.sgdat"));
U8 *base = data.data;
// Load tile types
//
world->tileTypes = M_ArenaPush(arena, World_Tile, .count = WORLD_TILE_TYPE_MAX);
for (U32 it = 0; it < WORLD_TILE_TYPE_MAX; ++it) {
World_Tile *type = &world->tileTypes[it];
Str8 name;
name.count = *(S64 *) base;
name.data = base + 8;
base += 8;
base += name.count;
if (name.count != 0) {
// Means we likely got a vaild tag
type->tag = Str8_Copy(arena, name);
type->rotation = *(F32 *) base;
}
FS_FileRead(file, &world->propCount, sizeof(U32), offset);
offset += sizeof(U32);
base += 4;
}
world->props = M_ArenaPush(arena, World_Prop, .count=WORLD_PROP_MAX);
FS_FileRead(file, world->props, sizeof(World_Prop)*WORLD_PROP_MAX, offset);
offset += sizeof(World_Prop)*WORLD_PROP_MAX;
// Load prop types
//
world->propTypes = M_ArenaPush(arena, World_PropType, .count = WORLD_PROP_TYPE_MAX);
for (U32 it = 0; it < WORLD_PROP_TYPE_MAX; ++it) {
World_PropType *type = &world->propTypes[it];
FS_FileRead(file, &world->hitboxCount, sizeof(U32), offset);
offset += sizeof(U32);
Str8 name;
name.count = *(S64 *) base;
name.data = base + 8;
world->hitboxes = M_ArenaPush(arena, AABB, .count=WORLD_HITBOX_MAX);
FS_FileRead(file, world->hitboxes, sizeof(AABB)*WORLD_HITBOX_MAX, offset);
offset += sizeof(AABB)*WORLD_HITBOX_MAX;
base += 8;
base += name.count;
world->map = M_ArenaPush(arena, U32, .count=WORLD_MAP_MAX);
FS_FileRead(file, world->map, sizeof(U32)*WORLD_MAP_MAX, offset);
offset += sizeof(U32)*WORLD_MAP_MAX;
if (name.count != 0) {
type->tag = Str8_Copy(arena, name);
type->scale = *(F32 *) base;
}
FS_FileClose(file);
printf("loaded world\n");
base += 4;
}
// Prop locations
{
U32 n_props = *(U32 *) base; base += 4;
World_Prop *props = (World_Prop *) base;
world->propCount = n_props;
world->props = M_ArenaPush(arena, World_Prop, .count = WORLD_PROP_MAX);
M_CopySize(world->props, props, n_props * sizeof(World_Prop));
base += (WORLD_PROP_MAX * sizeof(World_Prop));
}
// Hitboxes
//
{
U32 n_hitbox = *(U32 *) base; base += 4;
AABB *boxes = (AABB *) base;
world->hitboxCount = n_hitbox;
world->hitboxes = M_ArenaPush(arena, AABB, .count = WORLD_HITBOX_MAX);
M_CopySize(world->hitboxes, boxes, n_hitbox * sizeof(AABB));
base += (WORLD_HITBOX_MAX * sizeof(AABB));
}
// Map
//
{
U32 *__map = (U32 *) base;
world->map = M_ArenaPush(arena, U32, .count = WORLD_MAP_MAX);
M_CopySize(world->map, __map, WORLD_MAP_MAX * sizeof(U32));
base += (WORLD_MAP_MAX * sizeof(U32));
}
if (base != (data.data + data.count)) {
printf("--- OFFSET MISMATCH ---\n");
}
printf(" - %d props\n", world->propCount);
printf(" - %d hitboxes\n", world->hitboxCount);
printf("--- Loaded World ---\n");
}
}
void GenerateNavMesh(M_Arena *arena, World *world) {
@@ -186,15 +236,15 @@ void GenerateNavMesh(M_Arena *arena, World *world) {
U32 x = (i % 96);
U32 y = (i / 96);
bool skip = false;
for(int hi = 0; hi < world->hitboxCount; hi++) {
if(AABB_Point(world->hitboxes[hi], V2F(x, y))) {
for(U32 hi = 0; hi < world->hitboxCount; hi++) {
if(AABB_Point(world->hitboxes[hi], V2F((F32) x, (F32) y))) {
skip = true;
break;
}
}
if(skip) {continue;}
world->navMesh->nodes[world->navMesh->nodeCount].pos.x = x;
world->navMesh->nodes[world->navMesh->nodeCount].pos.y = y;
world->navMesh->nodes[world->navMesh->nodeCount].pos.x = cast(F32) x;
world->navMesh->nodes[world->navMesh->nodeCount].pos.y = cast(F32) y;
U32 cost = 20;
if(Str8_Equal(world->tileTypes[world->map[i]].tag, S("path_middle"), STR8_EQUAL_IGNORE_CASE)) {
cost = 10;
@@ -210,8 +260,8 @@ void GenerateNavMesh(M_Arena *arena, World *world) {
continue;
}
// It's quad for loop time :D
for(int hi = 0; hi < world->hitboxCount; hi++) {
if(AABB_Point(world->hitboxes[hi], V2F(x+nx, y+ny))) {
for(U32 hi = 0; hi < world->hitboxCount; hi++) {
if(AABB_Point(world->hitboxes[hi], V2F((F32) (x + nx), (F32) (y + ny)))) {
skip = true;
break;
}
@@ -220,7 +270,7 @@ void GenerateNavMesh(M_Arena *arena, World *world) {
U32 index = x+nx + (y+ny)*96;
U32 nCount = world->navMesh->nodeCount;
world->navMesh->nodes[nCount].connections[world->navMesh->nodes[nCount].connectionCount].NodeIndex = index;
world->navMesh->nodes[nCount].connections[world->navMesh->nodes[nCount].connectionCount].Cost = cost;
world->navMesh->nodes[nCount].connections[world->navMesh->nodes[nCount].connectionCount].Cost = cast(F32) cost;
world->navMesh->nodes[nCount].connectionCount++;
}
}

View File

@@ -82,7 +82,7 @@ function void UpdateNPC(F32 delta, NPC *npc, World *world);
function void UpdateBandit(F32 delta, Bandit *bandit, World *world);
function void LoadWorld(M_Arena *arena, World *world);
function void SaveWorld(M_Arena *arena, World *world);
function void SaveWorld(World *world);
function void GenerateNavMesh(M_Arena *arena, World *world);
#endif // LD_GAME_WORLD_H_