diff --git a/code/first.c b/code/first.c index cbdc4b4..20adab5 100644 --- a/code/first.c +++ b/code/first.c @@ -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; diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 2b96290..bacdbb9 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); @@ -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")); - 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_FileClose(file); - printf("loaded world\n"); + base += 4; + } + + // 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]; + + 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)); + } + + 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++; } } diff --git a/code/game/world.h b/code/game/world.h index e86c95d..3cc1e3d 100644 --- a/code/game/world.h +++ b/code/game/world.h @@ -52,8 +52,8 @@ struct World { //// Loaded from world file World_Tile *tileTypes; World_PropType *propTypes; - World_Prop *props; - AABB *hitboxes; + World_Prop *props; + AABB *hitboxes; U32 *map; U32 propCount; @@ -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_