diff --git a/code/first.c b/code/first.c index 2bae5da..f4221eb 100644 --- a/code/first.c +++ b/code/first.c @@ -479,7 +479,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; diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 0f01f33..cebe920 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -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); @@ -79,105 +79,159 @@ 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; - - FS_FileWrite(file, &world->portalCount, sizeof(U32), offset); - offset += sizeof(U32); - - FS_FileWrite(file, world->hitboxes, sizeof(World_Portal)*WORLD_PORTAL_MAX, offset); + WRITEN(world->map, WORLD_MAP_MAX); + WRITE(world->portalCount); + WRITEN(world->portals, WORLD_PORTAL_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")); - FS_FileRead(file, &world->propCount, sizeof(U32), offset); - offset += sizeof(U32); + U8 *base = data.data; - 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 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]; - 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) { + // Means we likely got a vaild tag + type->tag = Str8_Copy(arena, name); + type->rotation = *(F32 *) base; + } - FS_FileRead(file, &world->portalCount, sizeof(U32), offset); - offset += sizeof(U32); + base += 4; + } - world->portals = M_ArenaPush(arena, World_Portal, .count=WORLD_PORTAL_MAX); - FS_FileRead(file, world->hitboxes, sizeof(World_Portal)*WORLD_PORTAL_MAX, offset); + // 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_FileClose(file); - printf("loaded world\n"); + Str8 name; + name.count = *(S64 *) base; + name.data = base + 8; + + base += 8; + base += name.count; + + if (name.count != 0) { + type->tag = Str8_Copy(arena, name); + type->scale = *(F32 *) base; + } + + 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)); + } + { + U32 n_portals = *(U32 *) base; base += 4; + World_Portal *portals = (World_Portal *) base; + + world->portalCount = n_portals; + world->portals = M_ArenaPush(arena, World_Portal, .count = WORLD_PORTAL_MAX); + + M_CopySize(world->portals, portals, n_portals * sizeof(World_Portal)); + + base += (WORLD_PORTAL_MAX * sizeof(World_Portal)); + } + + if (base != (data.data + data.count)) { + printf("--- OFFSET MISMATCH ---\n"); + } + + printf("loaded world\n"); + + printf(" - %d props\n", world->propCount); + printf(" - %d hitboxes\n", world->hitboxCount); + + printf("--- Loaded World ---\n"); + } } void GenerateNavMesh(M_Arena *arena, World *world) { @@ -187,8 +241,8 @@ 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; } @@ -207,8 +261,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; } diff --git a/code/game/world.h b/code/game/world.h index 03e5ba7..32cf62e 100644 --- a/code/game/world.h +++ b/code/game/world.h @@ -94,7 +94,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_ diff --git a/code/world.sgdat b/code/world.sgdat index 5788440..804a714 100644 Binary files a/code/world.sgdat and b/code/world.sgdat differ