From c4cf8f532b9e43918eb5fc1b08a3da7b0de9479a Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 6 Oct 2025 16:35:22 +0100 Subject: [PATCH] feat: World loading that's broken --- code/first.c | 128 ++++++++++++++++++++++------------------- code/game/impl/world.c | 96 ++++++++++++++++++++++++++----- code/game/world.h | 26 +++++---- code/world.sgdat | Bin 0 -> 120960 bytes 4 files changed, 169 insertions(+), 81 deletions(-) create mode 100644 code/world.sgdat diff --git a/code/first.c b/code/first.c index 6272ef7..990619a 100644 --- a/code/first.c +++ b/code/first.c @@ -95,7 +95,8 @@ int main(int argc, char **argv) camera->farp = 1000.0f; game->draw.camera = camera; - World *world = M_ArenaPush(arena, World);//LoadWorld(arena); + World *world = M_ArenaPush(arena, World); + //LoadWorld(arena, world); game->world = world; world->arena = arena; world->navMesh = &TestNavMesh; @@ -135,88 +136,90 @@ int main(int argc, char **argv) world->player.bulletsLoaded = PLAYER_BULLET_COUNT; world->player.reloadTimer = 0; world->player.currentArea = WORLD_AREA_OUTSIDE; - for(int i =0; i< 4200; i++) { - world->map[i] = map[i]; - } + world->map = map; + world->tileTypes = M_ArenaPush(arena, World_Tile, .count=WORLD_TILE_TYPE_MAX); world->tileTypes[0].rotation=0; - world->tileTypes[0].collision=false; - world->tileTypes[0].tile=D_ImageHandle(&game->draw, S("tile_dirt_0")); + world->tileTypes[0].tag=S("tile_dirt_0"); world->tileTypes[1].rotation=0, - world->tileTypes[1].collision=false, - world->tileTypes[1].tile=D_ImageHandle(&game->draw, S("path_middle")); + world->tileTypes[1].tag=S("path_middle"); world->tileTypes[2].rotation=0; - world->tileTypes[2].collision=false; - world->tileTypes[2].tile=D_ImageHandle(&game->draw, S("path_middle_edge")); + world->tileTypes[2].tag=S("path_middle_edge"); world->tileTypes[3].rotation=PI_F32/2; - world->tileTypes[3].collision=false; - world->tileTypes[3].tile=D_ImageHandle(&game->draw, S("path_middle_edge")); + world->tileTypes[3].tag=S("path_middle_edge"); world->tileTypes[4].rotation=PI_F32; - world->tileTypes[4].collision=false; - world->tileTypes[4].tile=D_ImageHandle(&game->draw, S("path_middle_edge")); + world->tileTypes[4].tag=S("path_middle_edge"); world->tileTypes[5].rotation=-PI_F32/2; - world->tileTypes[5].collision=false; - world->tileTypes[5].tile=D_ImageHandle(&game->draw, S("path_middle_edge")); + world->tileTypes[5].tag=S("path_middle_edge"); world->tileTypes[6].rotation=0; - world->tileTypes[6].collision=false; - world->tileTypes[6].tile=D_ImageHandle(&game->draw, S("path_middle")); + world->tileTypes[6].tag=S("path_middle"); world->tileTypes[7].rotation=PI_F32/2; - world->tileTypes[7].collision=false; - world->tileTypes[7].tile=D_ImageHandle(&game->draw, S("path_middle")); + world->tileTypes[7].tag=S("path_middle"); world->tileTypes[8].rotation=-PI_F32; - world->tileTypes[8].collision=false; - world->tileTypes[8].tile=D_ImageHandle(&game->draw, S("path_middle")); + world->tileTypes[8].tag=S("path_middle"); world->tileTypes[9].rotation=-PI_F32/2; - world->tileTypes[9].collision=false; - world->tileTypes[9].tile=D_ImageHandle(&game->draw, S("path_middle")); + world->tileTypes[9].tag=S("path_middle"); world->tileTypes[10].rotation=0; - world->tileTypes[10].collision=false; - world->tileTypes[10].tile=D_ImageHandle(&game->draw, S("path_corner")); + world->tileTypes[10].tag=S("path_corner"); world->tileTypes[11].rotation=PI_F32/2; - world->tileTypes[11].collision=false; - world->tileTypes[11].tile=D_ImageHandle(&game->draw, S("path_corner")); + world->tileTypes[11].tag=S("path_corner"); world->tileTypes[12].rotation=-PI_F32/2; - world->tileTypes[12].collision=false; - world->tileTypes[12].tile=D_ImageHandle(&game->draw, S("path_corner")); + world->tileTypes[12].tag=S("path_corner"); world->tileTypes[13].rotation=PI_F32; - world->tileTypes[13].collision=false; - world->tileTypes[13].tile=D_ImageHandle(&game->draw, S("path_corner")); + world->tileTypes[13].tag=S("path_corner"); world->tileTypes[14].rotation=0; - world->tileTypes[14].collision=false; - world->tileTypes[14].tile=D_ImageHandle(&game->draw, S("tile_dirt_1")); + world->tileTypes[14].tag=S("tile_dirt_1"); - world->propTypes[0].assetHandle=D_ImageHandle(&game->draw, S("rug0")); + world->propTypes = M_ArenaPush(arena, World_PropType, .count=WORLD_PROP_TYPE_MAX); + world->propTypes[0].tag=S("rug0"); world->propTypes[0].scale=1; - world->propTypes[1].assetHandle=D_ImageHandle(&game->draw, S("rug1")); + world->propTypes[1].tag=S("rug1"); world->propTypes[1].scale=1; - world->propTypes[2].assetHandle=D_ImageHandle(&game->draw, S("skull")); + world->propTypes[2].tag=S("skull"); world->propTypes[2].scale=1; - world->propTypes[3].assetHandle=D_ImageHandle(&game->draw, S("table")); - world->propTypes[3].scale=1; - world->propTypes[4].assetHandle=D_ImageHandle(&game->draw, S("barrel")); + world->propTypes[3].tag = S("table"); + world->propTypes[3].scale=2; + world->propTypes[4].tag = S("barrel"); world->propTypes[4].scale=1; - world->propTypes[5].assetHandle=D_ImageHandle(&game->draw, S("can")); + world->propTypes[5].tag = S("can"); world->propTypes[5].scale=1; - world->propTypes[6].assetHandle=D_ImageHandle(&game->draw, S("candle")); + world->propTypes[6].tag = S("candle"); world->propTypes[6].scale=1; - world->propTypes[7].assetHandle=D_ImageHandle(&game->draw, S("clock")); + world->propTypes[7].tag = S("clock"); world->propTypes[7].scale=1; - world->propTypes[8].assetHandle=D_ImageHandle(&game->draw, S("log_pile")); + world->propTypes[8].tag = S("log_pile"); world->propTypes[8].scale=1; - world->propTypes[9].assetHandle=D_ImageHandle(&game->draw, S("nightstand")); + world->propTypes[9].tag = S("nightstand"); world->propTypes[9].scale=1; - world->propTypes[10].assetHandle=D_ImageHandle(&game->draw, S("pool_table")); - world->propTypes[10].scale=1; - world->propTypes[11].assetHandle=D_ImageHandle(&game->draw, S("saloon_ext")); + world->propTypes[10].tag = S("pool_table"); + world->propTypes[10].scale=2; + world->propTypes[11].tag = S("saloon_ext"); world->propTypes[11].scale=6.875f; - world->propTypes[12].assetHandle=D_ImageHandle(&game->draw, S("saloon_int")); - world->propTypes[12].scale=6.875f; - world->propTypes[11].assetHandle=D_ImageHandle(&game->draw, S("house")); - world->propTypes[11].scale=6.875f; - world->propTypes[12].assetHandle=D_ImageHandle(&game->draw, S("house_int")); - world->propTypes[12].scale=6.875f; + world->propTypes[12].tag = S("saloon_int"); + world->propTypes[12].scale=2*6.875f; + world->propTypes[13].tag = S("house"); + world->propTypes[13].scale=6.875f; + world->propTypes[14].tag = S("house_int"); + world->propTypes[14].scale=6.875f; + world->propTypes[15].tag=S("tile_detail_0"); + world->propTypes[15].scale=1; + world->propTypes[16].tag = S("tile_detail_1"); + world->propTypes[16].scale=1; + world->propTypes[17].tag = S("tile_detail_2"); + world->propTypes[17].scale=1; + world->propTypes[18].tag= S("tile_detail_3"); + world->propTypes[18].scale=1; + world->propTypes[19].tag= S("tile_detail_4"); + world->propTypes[19].scale=1; + world->propTypes[20].tag=S("tile_detail_5"); + world->propTypes[20].scale=1; + world->propTypes[21].tag=S("tile_detail_6"); + world->propTypes[21].scale=1; + world->propCount = 0; + world->props = M_ArenaPush(arena, World_Prop, .count=WORLD_PROP_MAX); + world->hitboxes = M_ArenaPush(arena, AABB, .count=WORLD_HITBOX_MAX); } - game->editor.enabled = true; + game->editor.enabled = false; game->editor.mode = G_EDITOR_MODE_TILE; game->editor.currentLevel = WORLD_AREA_OUTSIDE; @@ -328,6 +331,7 @@ int main(int argc, char **argv) } case SDLK_SPACE: { game->editor.mode = (game->editor.mode + 1) % 4; + printf("EDITOR MODE %d\n", game->editor.mode); break; } case SDLK_U: { @@ -396,18 +400,26 @@ int main(int argc, char **argv) switch(game->editor.mode) { case G_EDITOR_MODE_TILE: { World_Tile asset = game->world->tileTypes[editor.currentAsset]; - D_Rect(&game->draw, tilex, tiley, .texture=asset.tile, .angle=asset.rotation); + D_Rect(&game->draw, tilex, tiley, .texture=D_ImageHandle(&game->draw, asset.tag), .angle=asset.rotation); break; } case G_EDITOR_MODE_PROP: { World_PropType prop = game->world->propTypes[editor.currentAsset]; - D_Rect(&game->draw, editor.cursor.x, editor.cursor.y, .texture=prop.assetHandle, .scale=prop.scale); + D_Rect(&game->draw, editor.cursor.x, editor.cursor.y, .texture=D_ImageHandle(&game->draw, prop.tag), .scale=prop.scale); break; } case G_EDITOR_MODE_HITBOX: { for(int i = 0; i < game->world->hitboxCount; i++) { V2f centre = AABB_Centre(game->world->hitboxes[i]); - D_Rect(&game->draw, centre.x, centre.y, .texture=0, .dim=game->world->hitboxes[i].size, .flags=D_RECT_IGNORE_ASPECT); + D_Rect( + &game->draw, + centre.x, + centre.y, + .texture=0, + .dim=game->world->hitboxes[i].size, + .flags=D_RECT_IGNORE_ASPECT, + .c=V4F(100,0,0,0.7), + ); } break; } diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 63757c3..e2d6638 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -34,6 +34,9 @@ void ProcessEvents(SDL_Event *event, World *world) if(event->type == SDL_EVENT_KEY_DOWN && event->key.key == SDLK_F5){ SaveWorld(world->arena, world); } + if(event->type == SDL_EVENT_KEY_DOWN && event->key.key == SDLK_F6){ + LoadWorld(world->arena, world); + } } void RenderWorld(World *world, D_Context *draw) { @@ -42,7 +45,7 @@ void RenderWorld(World *world, D_Context *draw) { D_Rect( draw, (F32) (i % 96), (F32) (i / 96), - .texture = world->tileTypes[world->map[i]].tile, + .texture = D_ImageHandle(draw,world->tileTypes[world->map[i]].tag), .angle = (F32) world->tileTypes[world->map[i]].rotation, ); } @@ -53,7 +56,7 @@ void RenderWorld(World *world, D_Context *draw) { draw, world->props[i].pos.x, world->props[i].pos.y, - .texture = world->propTypes[world->props[i].propType].assetHandle, + .texture = D_ImageHandle(draw,world->propTypes[world->props[i].propType].tag), .scale = world->propTypes[world->props[i].propType].scale, ); } @@ -75,23 +78,90 @@ void RenderWorld(World *world, D_Context *draw) { void SaveWorld(M_Arena *arena, World *world) { printf("Saving world\n"); OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_WRITE); - FS_FileWrite(file, world, sizeof(World)+sizeof(NavMesh), 0); - FS_FileWrite(file, world->navMesh, sizeof(World)+sizeof(NavMesh), sizeof(World)); + 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); + } + + FS_FileWrite(file, world->propTypes, sizeof(World_PropType)*WORLD_PROP_TYPE_MAX, offset); + offset += sizeof(World_PropType)*WORLD_PROP_TYPE_MAX; + + FS_FileWrite(file, &world->propCount, sizeof(U32), offset); + offset += sizeof(U32); + + FS_FileWrite(file, world->props, sizeof(World_Prop)*WORLD_PROP_MAX, offset); + offset += sizeof(World_Prop)*WORLD_PROP_MAX; + + FS_FileWrite(file, &world->hitboxCount, sizeof(U32), offset); + offset += sizeof(U32); + + FS_FileWrite(file, world->hitboxes, sizeof(AABB)*WORLD_HITBOX_MAX, offset); + offset += sizeof(AABB)*WORLD_HITBOX_MAX; + + FS_FileWrite(file, world->map, sizeof(U32)*WORLD_MAP_MAX, offset); + offset += sizeof(U32)*WORLD_MAP_MAX; + FS_FileClose(file); printf("Saved world :)\n"); } -World *LoadWorld(M_Arena *arena) { +void LoadWorld(M_Arena *arena, World *world) { printf("loading world\n"); OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_READ); - World *world = M_ArenaPush(arena, World); - NavMesh *navMesh = M_ArenaPush(arena, NavMesh); - FS_FileRead(file, world, sizeof(World), 0); - FS_FileRead(file, navMesh, sizeof(NavMesh), sizeof(World)); + U32 offset = 0; + + 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); + } + + FS_FileRead(file, &world->propCount, sizeof(U32), offset); + offset += sizeof(U32); + + 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->propCount; + + FS_FileRead(file, &world->hitboxCount, sizeof(U32), offset); + offset += sizeof(U32); + + 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->hitboxCount; + + 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; + FS_FileClose(file); - world->navMesh = navMesh; - world->arena = arena; - world->player.world = world; printf("loaded world\n"); - return world; } diff --git a/code/game/world.h b/code/game/world.h index a9969a9..5fda8ec 100644 --- a/code/game/world.h +++ b/code/game/world.h @@ -3,6 +3,12 @@ #include "../core/math.h" +#define WORLD_HITBOX_MAX 4096 +#define WORLD_PROP_MAX 2048 +#define WORLD_PROP_TYPE_MAX 64 +#define WORLD_TILE_TYPE_MAX 64 +#define WORLD_MAP_MAX 4800 + // Areas are which typedef U32 World_Area; enum World_Area @@ -13,14 +19,13 @@ enum World_Area typedef struct World_Tile World_Tile; struct World_Tile { - U32 tile; - double rotation; - bool collision; + Str8 tag; + F32 rotation; }; typedef struct World_PropType World_PropType; struct World_PropType { - U32 assetHandle; + Str8 tag; F32 scale; }; @@ -44,14 +49,15 @@ struct World { NavMesh *navMesh; Random random; V2f mouseProjected; - World_Tile tileTypes[64]; - U32 map[4800]; + //// Loaded from world file + World_Tile *tileTypes; + World_PropType *propTypes; + World_Prop *props; + AABB *hitboxes; + U32 *map; - World_PropType propTypes[64]; U32 propCount; - World_Prop props[256]; U32 hitboxCount; - AABB hitboxes[4096]; //// Player Player player; @@ -75,7 +81,7 @@ function void UpdateNPCs(F32 delta, World *world); function void UpdateNPC(F32 delta, NPC *npc, World *world); function void UpdateBandit(F32 delta, Bandit *bandit, World *world); -function World *LoadWorld(M_Arena *arena); +function void LoadWorld(M_Arena *arena, World *world); function void SaveWorld(M_Arena *arena, World *world); #endif // LD_GAME_WORLD_H_ diff --git a/code/world.sgdat b/code/world.sgdat new file mode 100644 index 0000000000000000000000000000000000000000..ec99a1f27b01e3a82ce4be280e2a2ac9293d8615 GIT binary patch literal 120960 zcmeI%y>25_6ae7B{$*LArQ!*;g94VHHr_H1kOFBX%bQq<6%$8}BO%d*j)IPgmY$w& zk*KzzqT7fk;0dUhvFCadujksA_3T`cFOn7IoHKXM`8;=IPabT|ekOxqzk4tkPr9F! zfd^Iiv^P2Gemyui81~D^2d{^_{e#13?&ZT5J9Wpse7M`G&%JnF)5el;d6uQ&-QSjm z7uMb%jZgaHa=L5Pv+!$c&%@Un4B_2QSmc%Jre@UJXoo&!(HXbGNE^)*Fxe(~?_NWWRS(9uW$PKd1Zu)uQ{u(f)B+vRxf9 z936H~i(5z;d#{R}3=WSbXOrUKtI^ZZXxN?i5NgkQ!_nxZ+y7>=wRPE9hz?GQ=+h@* zqNCCIS#hGv&i(2{(?EAxb=i5p3eL7(f6^Na%UjyT&a%W*YFXlO-4UPFB|fi9d{LM9 zvP@Ln`gOwu!gf9W=&QZGy>j^3wGiT`3-NIApV!2{oyWI20!`-OO@ z|6w5>&ims+JZ$`*7UE&+{#+CPWgegP8R~zX$1kV-hxqUF_|qrlT%n&o=J8p5xEK7n z5D%OCuX%jt5aNH=#Q&*@Z-0FK{R-=RSQCF#6MwuAFK6>ZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zV3oj~qTrq4b!%0jd?Nz<8)030QT}UFHB!jG5!SUA<-aynBZd4MVO@Js{%cb;Qpmp% z*0mRXoBr<>U3pzMxLcUKt?ysAi*u#C?pM8){r%rxIez~QdviPSeM@SdKI1+}lR*i$!vtG3Va+Z%Uxubyi(tWxlO@)2iOumD|kO!;JTe<(7Rm zFF&6y%WdZD@l`@^ZN2~T?lzMRGp2sV+sxVHtAyTef`5)P@{eDiO=tNxEgWB;f83|( zEdQp39-?VUieg1KurnCH;7LKpaKkn0XmVeX2@%8!7{y)&xvx%GJzw8-j z`8?F~&-fmF(`>lLJpX)C$^UkI@NerL6YDzX-eP^H5dP|uz*V-_n=RfVdL&4wkpLYG*y2r$(4%bGGy~X-Y$>ls_&b_4=$7*w) gG3VZ5rYX6cXUw^`6ysQJ&NJrRTg)^ix9J)G1(Ub{cK`qY literal 0 HcmV?d00001