diff --git a/src/base/base_bitbuff.c b/src/base/base_bitbuff.c index 42996ad5..705db5d0 100644 --- a/src/base/base_bitbuff.c +++ b/src/base/base_bitbuff.c @@ -3,7 +3,7 @@ //////////////////////////////////////////////////////////// //~ Buff management -BB_Buff BB_AcquireBuff(u64 arena_reserve) +BB_Buff BB_AcquireDynamicBuff(u64 arena_reserve) { BB_Buff result = Zi; result.arena = AcquireArena(arena_reserve); @@ -11,7 +11,7 @@ BB_Buff BB_AcquireBuff(u64 arena_reserve) return result; } -void BB_ReleaseBuff(BB_Buff *bb) +void BB_ReleaseDynamicBuff(BB_Buff *bb) { // Only arena bitbuffs need to be released if (bb->is_backed_by_arena) @@ -151,7 +151,7 @@ void BB_WriteAlignBytes(BB_Writer *bw, u64 align) u64 new_pos = (bw->cur_bit >> 3); new_pos += (align - 1); new_pos -= new_pos % align; - if (BB_CheckWriterOverflowBits(bw, new_pos << 3)) + if (BB_CheckWriterOverflowBits(bw, (new_pos << 3) - bw->cur_bit)) { return; } @@ -484,7 +484,7 @@ void BB_ReadAlignBytes(BB_Reader *br, u64 align) u64 new_pos = (br->cur_bit >> 3); new_pos += (align - 1); new_pos -= new_pos % align; - if (BB_CheckReaderOverflowBits(br, new_pos << 3)) + if (BB_CheckReaderOverflowBits(br, (new_pos << 3) - br->cur_bit)) { return; } @@ -859,7 +859,7 @@ void BB_Test(void) String encoded = Zi; { - BB_Buff bb = BB_AcquireBuff(Gibi(64)); + BB_Buff bb = BB_AcquireDynamicBuff(Gibi(64)); BB_Writer bw = BB_WriterFromBuff(&bb); for (u64 i = 0; i < countof(cases); ++i) { diff --git a/src/base/base_bitbuff.h b/src/base/base_bitbuff.h index 5e5f1b91..9c75b409 100644 --- a/src/base/base_bitbuff.h +++ b/src/base/base_bitbuff.h @@ -62,8 +62,8 @@ Enum(BB_DebugMagicKind) //~ Buff management //- Growable-arena backed bitbuff -BB_Buff BB_AcquireBuff(u64 arena_reserve); -void BB_ReleaseBuff(BB_Buff *bitbuff); +BB_Buff BB_AcquireDynamicBuff(u64 arena_reserve); +void BB_ReleaseDynamicBuff(BB_Buff *bitbuff); //- Fixed-buffer backed bitbuff BB_Buff BB_BuffFromString(String s); diff --git a/src/base/base_controller.c b/src/base/base_controller.c index 9ef0c490..be1f8cea 100644 --- a/src/base/base_controller.c +++ b/src/base/base_controller.c @@ -3,7 +3,7 @@ String StringFromButton(Button button) { - PERSIST Readonly String names[Button_Count] = { + PERSIST Readonly String names[Button_COUNT] = { [Button_M1] = CompLit("Mouse 1"), [Button_M2] = CompLit("Mouse 2"), [Button_M3] = CompLit("Mouse 3"), diff --git a/src/base/base_controller.h b/src/base/base_controller.h index fb1c99a6..09701fd1 100644 --- a/src/base/base_controller.h +++ b/src/base/base_controller.h @@ -106,7 +106,7 @@ Enum(Button) Button_Insert, Button_Semicolon, - Button_Count + Button_COUNT }; //////////////////////////////////////////////////////////// @@ -126,7 +126,7 @@ Enum(ControllerEventKind) ControllerEventKind_Quit, - ControllerEventKind_Count + ControllerEventKind_COUNT }; Struct(ControllerEvent) diff --git a/src/base/base_log.h b/src/base/base_log.h index 3d3de600..e2aed782 100644 --- a/src/base/base_log.h +++ b/src/base/base_log.h @@ -42,7 +42,7 @@ Struct(LogEventsArray) #define LogLevel_Success 3 #define LogLevel_Info 4 #define LogLevel_Debug 5 -#define LogLevel_Count 6 +#define LogLevel_COUNT 6 //////////////////////////////////////////////////////////// //~ Log level types @@ -52,7 +52,7 @@ Struct(LogLevelSettings) String shorthand; }; -Global Readonly LogLevelSettings log_settings[LogLevel_Count] = { +Global Readonly LogLevelSettings log_settings[LogLevel_COUNT] = { [LogLevel_Critical] = { CompLit("CRITICAL"), }, diff --git a/src/base/base_math.h b/src/base/base_math.h index 75f5b5de..4df85b88 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -13,8 +13,8 @@ Enum(Axis) Axis_Y = 1, Axis_Z = 2, - Axis_CountXY = 2, - Axis_CountXYZ = 3 + Axis_COUNTXY = 2, + Axis_COUNTXYZ = 3 }; //////////////////////////////////////////////////////////// diff --git a/src/base/base_win32/base_win32.c b/src/base/base_win32/base_win32.c index 9ed1fa1b..2f32f76a 100644 --- a/src/base/base_win32/base_win32.c +++ b/src/base/base_win32/base_win32.c @@ -296,7 +296,7 @@ void W32_Log(i32 level, String msg) if (Atomic32Fetch(&W32.logs_initialized)) { LogLevelSettings settings = log_settings[level]; - if (level < 0 || level >= LogLevel_Count) + if (level < 0 || level >= LogLevel_COUNT) { Panic(Lit("Invalid log level")); } diff --git a/src/base/base_win32/base_win32.h b/src/base/base_win32/base_win32.h index 06ffd117..29d91cd6 100644 --- a/src/base/base_win32/base_win32.h +++ b/src/base/base_win32/base_win32.h @@ -90,7 +90,7 @@ Struct(W32_Ctx) Arena *logs_arena; u64 logs_count; - u64 log_level_counts[LogLevel_Count]; + u64 log_level_counts[LogLevel_COUNT]; LogEvent *readable_log_events; Atomic64 readable_logs_count; }; diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index 3e50db24..f35032bb 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -185,7 +185,7 @@ Enum(G_Format) G_Format_SamplerFeedbackMinMipOpaque = 189, G_Format_SamplerFeedbackMipRegionUsedOpaque = 190, G_Format_A4B4G4R4_Unorm = 191, - G_Format_Count = 192 + G_Format_COUNT = 192 }; //////////////////////////////////////////////////////////// diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 2434d3a4..d536b882 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -176,7 +176,7 @@ void G_Bootstrap(void) { Struct(Dx12HeapDesc) { D3D12_DESCRIPTOR_HEAP_TYPE type; D3D12_DESCRIPTOR_HEAP_FLAGS flags; u64 max; }; - Dx12HeapDesc descs[G_D12_DescriptorHeapKind_Count] = { + Dx12HeapDesc descs[G_D12_DescriptorHeapKind_COUNT] = { [G_D12_DescriptorHeapKind_CbvSrvUav] = { .type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, .flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index ecfc53cf..fbb158e3 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -106,7 +106,7 @@ Enum(G_D12_DescriptorHeapKind) G_D12_DescriptorHeapKind_Rtv, G_D12_DescriptorHeapKind_Sampler, - G_D12_DescriptorHeapKind_Count + G_D12_DescriptorHeapKind_COUNT }; Struct(G_D12_DescriptorHeap) @@ -158,7 +158,7 @@ Enum(G_D12_ResourceHeapKind) G_D12_ResourceHeapKind_Cpu, G_D12_ResourceHeapKind_CpuWriteCombined, - G_D12_ResourceHeapKind_Count, + G_D12_ResourceHeapKind_COUNT }; Struct(G_D12_ResourceHeap) @@ -183,11 +183,11 @@ Struct(G_D12_Arena) Arena *arena; G_D12_DescriptorList descriptors; - G_D12_DescriptorList reset_descriptors_by_heap[G_D12_DescriptorHeapKind_Count]; + G_D12_DescriptorList reset_descriptors_by_heap[G_D12_DescriptorHeapKind_COUNT]; G_D12_ResourceList free_resources; - G_D12_ResourceHeap resource_heaps[G_D12_ResourceHeapKind_Count]; + G_D12_ResourceHeap resource_heaps[G_D12_ResourceHeapKind_COUNT]; }; //////////////////////////////////////////////////////////// @@ -421,7 +421,7 @@ Struct(G_D12_Ctx) G_D12_Queue queues[G_NumQueues]; // Descriptor heaps - G_D12_DescriptorHeap descriptor_heaps[G_D12_DescriptorHeapKind_Count]; + G_D12_DescriptorHeap descriptor_heaps[G_D12_DescriptorHeapKind_COUNT]; // Rootsig ID3D12RootSignature *bindless_rootsig; diff --git a/src/meta/meta.c b/src/meta/meta.c index c7635396..e4466d14 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -153,7 +153,8 @@ EmbedObj Embed(String store_name, String dir_path) } } - BB_Buff bb = BB_AcquireBuff(Gibi(2)); + // TODO: Cache dynamic bitbuffs? + BB_Buff bb = BB_AcquireDynamicBuff(Gibi(2)); BB_Writer bw = BB_WriterFromBuff(&bb); // Write magic diff --git a/src/pp/pp_sim/pp_sim.lay b/src/pp/pp_sim/pp_sim.lay index 08b8457f..b25945a7 100644 --- a/src/pp/pp_sim/pp_sim.lay +++ b/src/pp/pp_sim/pp_sim.lay @@ -11,6 +11,7 @@ @IncludeC pp_sim_tiles.cgh @IncludeG pp_sim_tiles.cgh @IncludeC pp_sim_core.h +@IncludeC pp_sim_transcode.h @Bootstrap S_Bootstrap @@ -18,5 +19,6 @@ //- Impl @IncludeC pp_sim_core.c +@IncludeC pp_sim_transcode.c @IncludeC pp_sim_tiles.cg @IncludeG pp_sim_tiles.cg diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index 0d2ffb53..8b120fc0 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -23,14 +23,15 @@ void S_Bootstrap(void) output->arena = AcquireArena(Gibi(64)); } - // Dispatch sim wave + // Start simulating DispatchWave(Lit("Sim"), 1, S_TickForever, 0); + OnExit(S_Shutdown); } void S_Shutdown(void) { Atomic32Set(&S.shutdown, 1); - YieldOnFence(&S.worker_completion_fence, S.workers_count); + YieldOnFence(&S.shutdown_fence, 1); } //////////////////////////////////////////////////////////// @@ -86,6 +87,15 @@ Rng2I32 S_UpdateTilesInPlaceFromPlacement(u8 *tiles, S_TilePlacement placement) Rng2I32 dirty_rect = Zi; switch (placement.placement_kind) { + case S_TilePlacementKind_Raw: + { + CopyBytes(tiles, placement.raw_tiles, S_WorldSize * S_WorldSize * 4); + dirty_rect = RNG2I32( + VEC2I32(0, 0), + VEC2I32(S_WorldSize * 2, S_WorldSize * 2) + ); + } break; + case S_TilePlacementKind_Range: { S_TileKind tile = placement.tile_kind; @@ -247,6 +257,7 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot) CopyStructs(world->ents, snapshot->ents, snapshot->ents_count); world->ents_count = snapshot->ents_count; world->tick = snapshot->tick; + world->time_ns = snapshot->time_ns; return world; } @@ -280,16 +291,16 @@ void S_TickForever(WaveLaneCtx *lane) Arena *frame_arena = AcquireArena(Gibi(64)); Arena *perm = PermArena(); - const i32 world_size = S_WorldSize; - //- World data Arena *ents_arena = AcquireArena(Gibi(64)); S_World *world = PushStruct(perm, S_World); world->ents = ArenaFirst(ents_arena, S_Ent); i64 first_free_ent_num = 0; - i64 sim_time_ns = 0; - u8 *tiles = PushBytes(perm, world_size * world_size * 4, alignof(S_TileKind)); + u8 *tiles = PushBytes(perm, S_WorldSize * S_WorldSize * 4, alignof(S_TileKind)); + + // TODO: Real per-client deltas + b32 has_sent_initial_tick = 0; ////////////////////////////// //- Sim loop @@ -297,6 +308,8 @@ void S_TickForever(WaveLaneCtx *lane) b32 shutdown = 0; while (!shutdown) { + shutdown = Atomic32Fetch(&S.shutdown); + ResetArena(frame_arena); S_Iter iter = Zi; S_Lookup lookup = Zi; @@ -309,6 +322,44 @@ void S_TickForever(WaveLaneCtx *lane) f64 sim_dt = SecondsFromNs(sim_dt_ns); world->tick += 1; + ////////////////////////////// + //- Swap + + { + b32 swapin = world->tick == 1 && IsSwappedIn(); + b32 swapout = !swapin && shutdown && IsSwappingOut(); + + //- Swap out + if (swapout) + { + S_TranscodeResult tr = S_TranscodeLevel(frame_arena, 1, Zstr, world, tiles); + if (tr.ok) + { + WriteSwappedState(Lit("pp_sim.swp"), tr.packed); + } + } + + //- Swap in + if (swapin) + { + String packed = SwappedStateFromName(frame_arena, Lit("pp_sim.swp")); + S_TranscodeResult tr = S_TranscodeLevel(frame_arena, 0, packed, world, tiles); + if (tr.ok) + { + // Unpack tiles + CopyBytes(tiles, tr.unpacked.tiles, S_WorldSize * S_WorldSize * 4); + + // Unpack world + world->tick = tr.unpacked.world.tick; + world->time_ns = tr.unpacked.world.time_ns; + world->ents_count = tr.unpacked.world.ents_count; + ResetArena(ents_arena); + PushStructsNoZero(ents_arena, S_Ent, world->ents_count); + CopyStructs(world->ents, tr.unpacked.world.ents, world->ents_count); + } + } + } + lookup = S_LookupFromWorld(frame_arena, world); ////////////////////////////// @@ -431,23 +482,42 @@ void S_TickForever(WaveLaneCtx *lane) *dst = *src; } - // Forward tile placements - snapshot->tile_placements_count = tile_placements_count; - snapshot->tile_placements = PushStructs(output->arena, S_TilePlacement, tile_placements_count); + // Push tile map { - u64 tile_placement_idx = 0; - for (S_CmdNode *cmd_node = input->first_cmd_node; cmd_node && tile_placement_idx < tile_placements_count; cmd_node = cmd_node->next) + u64 dst_tile_placement_idx = 0; + snapshot->tile_placements_count = tile_placements_count; + snapshot->tile_placements = PushStructs(output->arena, S_TilePlacement, tile_placements_count + 1); + + // Send raw tile map + if (!has_sent_initial_tick) { - S_Cmd *cmd = &cmd_node->cmd; - if (cmd->kind == S_CmdKind_Tile) + snapshot->tile_placements_count += 1; { - S_TilePlacement *dst_placement = &snapshot->tile_placements[tile_placement_idx]; - *dst_placement = cmd->tile_placement; - tile_placement_idx += 1; + S_TilePlacement *dst = &snapshot->tile_placements[dst_tile_placement_idx]; + dst->placement_kind = S_TilePlacementKind_Raw; + dst->raw_tiles = PushStructsNoZero(output->arena, u8, S_WorldSize * S_WorldSize * 4); + CopyBytes(dst->raw_tiles, tiles, S_WorldSize * S_WorldSize * 4); + } + dst_tile_placement_idx += 1; + has_sent_initial_tick = 1; + } + + // Forward range tile placements + { + u64 src_tile_placement_idx = 0; + for (S_CmdNode *cmd_node = input->first_cmd_node; cmd_node && src_tile_placement_idx < tile_placements_count; cmd_node = cmd_node->next) + { + S_Cmd *cmd = &cmd_node->cmd; + if (cmd->kind == S_CmdKind_Tile) + { + S_TilePlacement *dst = &snapshot->tile_placements[src_tile_placement_idx]; + *dst = cmd->tile_placement; + dst_tile_placement_idx += 1; + src_tile_placement_idx += 1; + } } } } - } UnlockTicketMutex(&S.output_back_tm); @@ -462,18 +532,18 @@ void S_TickForever(WaveLaneCtx *lane) input->arena = arena; } - i64 frame_end_ns = TimeNs(); - sim_time_ns += sim_dt_ns; + world->time_ns += sim_dt_ns; ////////////////////////////// //- Sleep - if (!Atomic32Fetch(&S.shutdown)) + if (!shutdown) { i64 step_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND; P_SleepFrame(frame_begin_ns, step_dt_ns); } - shutdown = Atomic32Fetch(&S.shutdown); } + + FetchAddFence(&S.shutdown_fence, 1); } diff --git a/src/pp/pp_sim/pp_sim_core.h b/src/pp/pp_sim/pp_sim_core.h index 440c80f0..d2c89ac1 100644 --- a/src/pp/pp_sim/pp_sim_core.h +++ b/src/pp/pp_sim/pp_sim_core.h @@ -8,6 +8,25 @@ Struct(S_Key) U128 v; }; +//////////////////////////////////////////////////////////// +//~ Tile types + +Enum(S_TilePlacementKind) +{ + S_TilePlacementKind_Raw, + S_TilePlacementKind_Range, +}; + +Struct(S_TilePlacement) +{ + S_TilePlacementKind placement_kind; + + u8 *raw_tiles; + + S_TileKind tile_kind; + Rng2I32 range; +}; + //////////////////////////////////////////////////////////// //~ Shape types @@ -105,6 +124,7 @@ Struct(S_Lookup) Struct(S_World) { i64 tick; + i64 time_ns; S_Ent *ents; i64 ents_count; @@ -113,6 +133,7 @@ Struct(S_World) Struct(S_Snapshot) { i64 tick; + i64 time_ns; S_Ent *ents; i64 ents_count; @@ -191,8 +212,7 @@ Struct(S_OutputState) Struct(S_Ctx) { Atomic32 shutdown; - Fence worker_completion_fence; - i64 workers_count; + Fence shutdown_fence; //- Sim input TicketMutex input_back_tm; diff --git a/src/pp/pp_sim/pp_sim_tiles.cgh b/src/pp/pp_sim/pp_sim_tiles.cgh index 0c5aa004..07f11338 100644 --- a/src/pp/pp_sim/pp_sim_tiles.cgh +++ b/src/pp/pp_sim/pp_sim_tiles.cgh @@ -14,22 +14,10 @@ Enum(S_TileKind) { S_TilesXMacro(X) - S_TileKind_Count + S_TileKind_COUNT }; #undef X -Enum(S_TilePlacementKind) -{ - S_TilePlacementKind_Range -}; - -Struct(S_TilePlacement) -{ - S_TilePlacementKind placement_kind; - S_TileKind tile_kind; - Rng2I32 range; -}; - //////////////////////////////////////////////////////////// //~ Tile helpers diff --git a/src/pp/pp_sim/pp_sim_transcode.c b/src/pp/pp_sim/pp_sim_transcode.c new file mode 100644 index 00000000..eeb5fbd4 --- /dev/null +++ b/src/pp/pp_sim/pp_sim_transcode.c @@ -0,0 +1,143 @@ +//////////////////////////////////////////////////////////// +//~ Transcode + +S_TranscodeResult S_TranscodeLevel(Arena *arena, b32 pack, String packed, S_World *world, u8 *tiles) +{ + S_TranscodeResult result = Zi; + result.ok = 1; + result.version = S_Tv_Latest; + + ////////////////////////////// + //- Init bitbuff + + u32 level_magic = 0xa2bf209c; + + BB_Buff bb = Zi; + BB_Writer bw = Zi; + BB_Reader br = Zi; + if (pack) + { + bb = BB_AcquireDynamicBuff(Gibi(4)); + bw = BB_WriterFromBuff(&bb); + BB_WriteUBits(&bw, level_magic, 32); + BB_WriteUBits(&bw, result.version, 32); + } + else + { + bb = BB_BuffFromString(packed); + br = BB_ReaderFromBuff(&bb); + result.ok = BB_ReadUBits(&br, 32) == level_magic; + result.version = (S_Tv)BB_ReadUBits(&br, 32); + } + + ////////////////////////////// + //- Transcode world metadata + + if (result.ok) + { + if (pack) + { + BB_WriteIBits(&bw, world->tick, 64); + BB_WriteIBits(&bw, world->time_ns, 64); + } + else + { + result.unpacked.world.tick = BB_ReadIBits(&br, 64); + result.unpacked.world.time_ns = BB_ReadIBits(&br, 64); + } + } + + ////////////////////////////// + //- Transcode tiles + + // TODO: Compress tile data + + if (result.ok) + { + u64 tiles_count = S_WorldSize * S_WorldSize * 4; + if (pack) + { + String tiles_str = Zi; + tiles_str.len = tiles_count; + tiles_str.text = tiles; + BB_WriteBytes(&bw, tiles_str); + } + else + { + u8 *raw_tiles = BB_ReadBytesRaw(&br, tiles_count); + if (raw_tiles) + { + result.unpacked.tiles = PushStructsNoZero(arena, u8, S_WorldSize * S_WorldSize * 4); + CopyStructs(result.unpacked.tiles, raw_tiles, tiles_count); + } + else + { + result.ok = 0; + } + } + } + + ////////////////////////////// + //- Transcode entities + + // TODO: Compress entity data + + if (result.ok) + { + if (pack) + { + BB_WriteUBits(&bw, sizeof(S_Ent), 32); + BB_WriteUBits(&bw, alignof(S_Ent), 32); + } + else + { + u32 ent_size = BB_ReadUBits(&br, 32); + u32 ent_align = BB_ReadUBits(&br, 32); + result.ok = ent_size == sizeof(S_Ent) && ent_align == alignof(S_Ent); + } + } + + if (result.ok) + { + if (pack) + { + String ents_str = Zi; + ents_str.len = sizeof(S_Ent) * world->ents_count; + ents_str.text = (u8 *)world->ents; + + BB_WriteUBits(&bw, world->ents_count, 64); + BB_WriteAlignBytes(&bw, alignof(S_Ent)); + BB_WriteBytes(&bw, ents_str); + } + else + { + u64 ents_count = BB_ReadUBits(&br, 64); + BB_ReadAlignBytes(&br, alignof(S_Ent)); + S_Ent *ents_raw = (S_Ent *)BB_ReadBytesRaw(&br, ents_count * sizeof(S_Ent)); + if (ents_raw) + { + result.unpacked.world.ents_count = ents_count; + result.unpacked.world.ents = PushStructsNoZero(arena, S_Ent, ents_count); + CopyStructs(result.unpacked.world.ents, ents_raw, ents_count); + } + else + { + result.ok = 0; + } + } + } + + ////////////////////////////// + //- Finalize + + if (result.ok) + { + if (pack) + { + result.packed = BB_GetWritten(arena, &bw); + BB_ReleaseDynamicBuff(&bb); + } + } + + return result; +} diff --git a/src/pp/pp_sim/pp_sim_transcode.h b/src/pp/pp_sim/pp_sim_transcode.h new file mode 100644 index 00000000..a3663119 --- /dev/null +++ b/src/pp/pp_sim/pp_sim_transcode.h @@ -0,0 +1,28 @@ +//////////////////////////////////////////////////////////// +//~ Transcode types + +Enum(S_Tv) +{ + S_Tv_None = 0, + + S_Tv_COUNT +}; + +#define S_Tv_Latest (S_Tv_COUNT - 1) + +Struct(S_TranscodeResult) +{ + b32 ok; + S_Tv version; + String packed; + struct + { + S_World world; + u8 *tiles; + } unpacked; +}; + +//////////////////////////////////////////////////////////// +//~ Transcode + +S_TranscodeResult S_TranscodeLevel(Arena *arena, b32 pack, String packed, S_World *world, u8 *tiles); diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 714c8d2f..b3ebea1c 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -6,6 +6,7 @@ V_Ctx V = Zi; void V_Bootstrap(void) { DispatchWave(Lit("Vis"), 1, V_TickForever, 0); + OnExit(V_Shutdown); } void V_Shutdown(void) @@ -336,7 +337,6 @@ void V_TickForever(WaveLaneCtx *lane) V.world_arena = AcquireArena(Gibi(64)); V.world = PushStruct(V.world_arena, S_World); - V.player_key = S_RandKey(); Vec2I32 tiles_dims = VEC2I32(world_size * 2, world_size * 2); u8 *tiles = PushBytes(perm, tiles_dims.x * tiles_dims.y, alignof(S_TileKind)); @@ -403,32 +403,15 @@ void V_TickForever(WaveLaneCtx *lane) } } - ////////////////////////////// - //- Swap in - - // if (IsSwappedIn()) - // { - // TempArena scratch = BeginScratchNoConflict(); - // { - // String swap_encoded = SwappedStateFromName(scratch.arena, Lit("pp_vis")); - // BB_Buff bb = BB_BuffFromString(swap_encoded); - // BB_Reader br = BB_ReaderFromBuff(&bb); - // String swap_str = BB_ReadString(scratch.arena, &br); - // if (swap_str.len == sizeof(Persist)) - // { - // CopyBytes(&persist, swap_str.text, swap_str.len); - // } - // window_restore = BB_ReadString(perm, &br); - // } - // EndScratch(scratch); - // } - ////////////////////////////// //- Begin vis loop b32 shutdown = 0; while (!shutdown) { + shutdown = Atomic32Fetch(&V.shutdown); + S_Iter iter = Zi; + ////////////////////////////// //- Begin frame @@ -471,27 +454,65 @@ void V_TickForever(WaveLaneCtx *lane) frame->dt_ns = frame->time_ns - last_frame->time_ns; frame->dt = SecondsFromNs(frame->dt_ns); - S_Iter iter = Zi; + if (S_IsKeyNil(V.player_key)) + { + V.player_key = S_RandKey(); + } ////////////////////////////// - //- Spawn test ents + //- Swap - if (frame->tick == 1) { - S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Spawn); - S_Ent *ent = &cmd->ent; - ent->key = V.player_key; - ent->move_speed = 0.1; + b32 swapin = frame->tick == 1 && IsSwappedIn(); + b32 swapout = !swapin && shutdown && IsSwappingOut(); + if (swapin || swapout) { - ent->local_shape = S_ShapeFromDesc( - .mass = 10, - .count = 1, - .radius = 0.3, - ); + //- Init bitbuff + BB_Buff bb = Zi; + BB_Writer bw = Zi; + BB_Reader br = Zi; + if (swapout) + { + u64 max_size = Mebi(64); + u8 *bytes = PushStructsNoZero(frame->arena, u8, max_size); + bb = BB_BuffFromString(STRING(max_size, bytes)); + bw = BB_WriterFromBuff(&bb); + } + else + { + String swap_encoded = SwappedStateFromName(frame->arena, Lit("pp_vis.swp")); + bb = BB_BuffFromString(swap_encoded); + br = BB_ReaderFromBuff(&bb); + } + + //- Transcode swap state + if (swapout) + { + BB_WriteUBits(&bw, V.player_key.v.hi, 64); + BB_WriteUBits(&bw, V.player_key.v.lo, 64); + BB_WriteBit(&bw, last_frame->is_editing); + BB_WriteF32(&bw, last_frame->edit_camera_pos.x); + BB_WriteF32(&bw, last_frame->edit_camera_pos.y); + BB_WriteF32(&bw, last_frame->edit_camera_zoom); + BB_WriteString(&bw, last_frame->window_restore); + } + else + { + V.player_key.v.hi = BB_ReadUBits(&br, 64); + V.player_key.v.lo = BB_ReadUBits(&br, 64); + frame->is_editing = BB_ReadBit(&br); + frame->edit_camera_pos.x = BB_ReadF32(&br); + frame->edit_camera_pos.y = BB_ReadF32(&br); + frame->edit_camera_zoom = BB_ReadF32(&br); + frame->window_restore = BB_ReadString(frame->arena, &br); + } + + // Write swapout + if (swapout) + { + WriteSwappedState(Lit("pp_vis.swp"), STRING(BB_GetNumBytesWritten(&bw), BB_GetWrittenRaw(&bw))); + } } - // ent->local_xf = XformFromPos(VEC2(200, 200)); - ent->xf = XformFromPos(VEC2(0, 0)); - ent->has_weapon = 1; } ////////////////////////////// @@ -646,11 +667,6 @@ void V_TickForever(WaveLaneCtx *lane) b32 pan_button = Button_M3; frame->is_panning = frame->held_buttons[pan_button] != 0; frame->edit_camera_zoom *= PowF32(zoom_rate, -last_frame->zooms); - if (frame->edit_camera_zoom <= 0) - { - frame->edit_camera_pos = S_EntFromKey(&V.lookup, V.player_key)->xf.og; - frame->edit_camera_zoom = 3; - } frame->edit_camera_zoom = ClampF32(frame->edit_camera_zoom, min_zoom, max_zoom); // Offset edit camera based on cursor if panning / zooming b32 is_zooming = last_frame->zooms != 0 && (frame->edit_camera_zoom != last_frame->edit_camera_zoom); @@ -1048,7 +1064,7 @@ void V_TickForever(WaveLaneCtx *lane) UI_Push(Tag, window->key.hash); if (window->is_tile_window) { - for (S_TileKind tile_kind = 0; tile_kind < S_TileKind_Count; ++tile_kind) + for (S_TileKind tile_kind = 0; tile_kind < S_TileKind_COUNT; ++tile_kind) { String name = S_NameFromTileKind(tile_kind); UI_Key key = UI_KeyF("Tile %F", FmtString(name)); @@ -1276,7 +1292,7 @@ void V_TickForever(WaveLaneCtx *lane) // i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug; i32 console_level = LogLevel_Debug; - Vec4 colors[LogLevel_Count][2] = Zi; + Vec4 colors[LogLevel_COUNT][2] = Zi; SetBytes(colors, 0xFF, sizeof(colors)); // Debug colors colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4); @@ -1414,7 +1430,7 @@ void V_TickForever(WaveLaneCtx *lane) { String cmd_name = cmd_node->cmd.name; V_CmdKind kind = V_CmdKind_nop; - for (V_CmdKind tmp_kind = V_CmdKind_nop; tmp_kind < V_CmdKind_Count; ++tmp_kind) + for (V_CmdKind tmp_kind = V_CmdKind_nop; tmp_kind < V_CmdKind_COUNT; ++tmp_kind) { V_CmdDesc desc = V_cmd_descs[tmp_kind]; if (MatchString(desc.name, cmd_name)) @@ -1454,16 +1470,18 @@ void V_TickForever(WaveLaneCtx *lane) case V_CmdKind_toggle_editor: { - b32 new = !frame->is_editing; - if (new) + if (!last_frame->is_editing) { + frame->is_editing = 1; + frame->edit_camera_pos = frame->camera_pos; + frame->edit_camera_zoom = frame->camera_zoom; LogInfoF("Enabled editor"); } else { + frame->is_editing = 0; LogInfoF("Disabled editor"); } - frame->is_editing = new; } break; case V_CmdKind_toggle_ui_debug: @@ -1493,13 +1511,19 @@ void V_TickForever(WaveLaneCtx *lane) case V_CmdKind_spawn: { - // S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile); - // cmd->tile_placement.placement_kind = S_TilePlacementKind_Range; - // cmd->tile_placement.tile_kind = S_TileKind_Wall; - // cmd->tile_placement.range.p0 = VEC2I32(100, 100); - // cmd->tile_placement.range.p1 = VEC2I32(110, 110); - // cmd->tile_placement.range.p0 = VEC2I32(2, 2); - // cmd->tile_placement.range.p1 = VEC2I32(5, 5); + S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Spawn); + S_Ent *ent = &cmd->ent; + ent->key = V.player_key; + ent->move_speed = 0.1; + { + ent->local_shape = S_ShapeFromDesc( + .mass = 10, + .count = 1, + .radius = 0.3, + ); + } + ent->xf = XformFromPos(frame->world_cursor); + ent->has_weapon = 1; } break; } } @@ -1732,27 +1756,7 @@ void V_TickForever(WaveLaneCtx *lane) G_CommitCommandList(frame->cl); UI_EndFrame(ui_frame); - - shutdown = Atomic32Fetch(&V.shutdown); } - ////////////////////////////// - //- Swap out - - // if (IsSwappingOut()) - // { - // TempArena scratch = BeginScratchNoConflict(); - // u64 max_size = Mebi(64); - // u8 *bytes = PushStructsNoZero(scratch.arena, u8, max_size); - // BB_Buff bb = BB_BuffFromString(STRING(max_size, bytes)); - // { - // BB_Writer bw = BB_WriterFromBuff(&bb); - // BB_WriteString(&bw, StringFromStruct(&persist)); - // BB_WriteString(&bw, window_restore); - // WriteSwappedState(Lit("pp_vis"), STRING(BB_GetNumBytesWritten(&bw), BB_GetWrittenRaw(&bw))); - // } - // EndScratch(scratch); - // } - FetchAddFence(&V.shutdown_complete, 1); } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 0c9e8e00..872995d0 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -12,7 +12,7 @@ X(toggle_console, Toggle Developer Console, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent ), ) \ X(toggle_fullscreen, Toggle Fullscreen Mode, V_CmdDescFlag_None, V_HOTKEY( Button_Enter, .alt = 1 ) ) \ X(toggle_window_topmost, Toggle Window Topmost, V_CmdDescFlag_None, V_HOTKEY( Button_F4 ), ) \ - X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \ + X(spawn, Spawn/Teleport Player, V_CmdDescFlag_None, V_HOTKEY( Button_T ), ) \ // -------------------------------------------------------------------------------------------------------------------- //////////////////////////////////////////////////////////// @@ -56,7 +56,7 @@ Enum(V_CmdKind) V_CmdsTableXMacro(X) #undef X - V_CmdKind_Count, + V_CmdKind_COUNT, }; Struct(V_Shortcut) @@ -99,7 +99,7 @@ Struct(V_CmdNode) V_Cmd cmd; }; -Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_Count] = { +Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_COUNT] = { #define X(_name, _display_name, _flags, ...) { .name = CompLit(#_name), .display_name = CompLit(#_display_name), .flags = _flags, .default_hotkeys = { __VA_ARGS__ } }, V_CmdsTableXMacro(X) #undef X @@ -206,7 +206,7 @@ Struct(V_Frame) i64 dt_ns; f64 dt; - Button held_buttons[Button_Count]; + Button held_buttons[Button_COUNT]; V_CommandsWidget commands_widget; String window_restore; diff --git a/src/pp_old/pp.c b/src/pp_old/pp.c index 42e84fcd..c3a42d09 100644 --- a/src/pp_old/pp.c +++ b/src/pp_old/pp.c @@ -213,7 +213,7 @@ String PP_DebugStringFromEnt(Arena *arena, PP_Ent *ent) u64 chunk = ent->props[chunk_index]; for (u64 part_index = 8; part_index-- > 0;) { - if ((chunk_index != (countof(ent->props) - 1)) || ((chunk_index * 64) + (part_index * 8)) <= PP_Prop_Count) + if ((chunk_index != (countof(ent->props) - 1)) || ((chunk_index * 64) + (part_index * 8)) <= PP_Prop_COUNT) { u8 part = (chunk >> (part_index * 8)) & 0xFF; StringFromChar(arena, hex[(part >> 4) & 0x0F]); @@ -546,7 +546,7 @@ void PP_UpdateUser(void) if ((event->kind == ControllerEventKind_ButtonDown || event->kind == ControllerEventKind_ButtonUp)) { Btn button = event->button; - button = button >= Btn_Count ? Btn_None : button; + button = button >= Btn_COUNT ? Btn_None : button; PP_BindKind bind = g_binds[button]; if (bind) { diff --git a/src/pp_old/pp.h b/src/pp_old/pp.h index b85c3d50..d53f0402 100644 --- a/src/pp_old/pp.h +++ b/src/pp_old/pp.h @@ -48,13 +48,13 @@ Enum(PP_BindKind) PP_BindKind_DecrementDebugSteps, #endif - PP_BindKind_Count + PP_BindKind_COUNT }; //- Test bindings /* TODO: Remove this */ -Global Readonly PP_BindKind g_binds[Btn_Count] = { +Global Readonly PP_BindKind g_binds[Btn_COUNT] = { [Btn_W] = PP_BindKind_MoveUp, [Btn_S] = PP_BindKind_MoveDown, [Btn_A] = PP_BindKind_MoveLeft, @@ -195,7 +195,7 @@ Struct(PP_SharedUserState) i64 gpu_submit_fence_target; //- Bind state - PP_BindState bind_states[PP_BindKind_Count]; + PP_BindState bind_states[PP_BindKind_COUNT]; //- Window -> user Mutex sys_window_events_mutex; diff --git a/src/pp_old/pp_ent.h b/src/pp_old/pp_ent.h index c7ff1a7e..ebb06a01 100644 --- a/src/pp_old/pp_ent.h +++ b/src/pp_old/pp_ent.h @@ -58,7 +58,7 @@ Enum(PP_Prop) PP_Prop_SoundEmitterTest, PP_Prop_LightTest, - PP_Prop_Count + PP_Prop_COUNT }; //////////////////////////////////////////////////////////// @@ -72,7 +72,7 @@ Struct(PP_Ent) b32 valid; /* Is this ent allocated in memory that can be written to (can always be read) */ PP_EntKey key; - u64 props[(PP_Prop_Count + 63) / 64]; + u64 props[(PP_Prop_COUNT + 63) / 64]; u64 continuity_gen; /* Is this the root ent */ diff --git a/src/pp_old/pp_sim.h b/src/pp_old/pp_sim.h index 3a59c0db..792db1df 100644 --- a/src/pp_old/pp_sim.h +++ b/src/pp_old/pp_sim.h @@ -170,9 +170,9 @@ Enum(PP_TileKind) PP_TileKind_None, PP_TileKind_Wall, - PP_TileKind_Count + PP_TileKind_COUNT }; -StaticAssert(PP_TileKind_Count < 256); /* Tile kind must fit in 8 bits */ +StaticAssert(PP_TileKind_COUNT < 256); /* Tile kind must fit in 8 bits */ //////////////////////////////////////////////////////////// //~ Snapshot types diff --git a/src/pp_old/pp_widgets.c b/src/pp_old/pp_widgets.c index 8018cf8a..11455ea0 100644 --- a/src/pp_old/pp_widgets.c +++ b/src/pp_old/pp_widgets.c @@ -11,7 +11,7 @@ UI_Box *PP_BuildDebugConsole(b32 minimized) // i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug; i32 console_level = LogLevel_Debug; - u32 colors[LogLevel_Count][2] = ZI; + u32 colors[LogLevel_COUNT][2] = ZI; SetBytes(colors, 0xFF, sizeof(colors)); /* Debug colors */ colors[LogLevel_Debug][0] = Rgb32F(0.4, 0.1, 0.4); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 469d7e6d..b9b0a8d8 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -207,7 +207,7 @@ void UI_PopCP(UI_Checkpoint cp) { UI_Frame *frame = UI_CurrentFrame(); UI_Stack *stack = frame->top_stack; - for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) + for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_COUNT; ++kind) { UI_StyleNode *n = stack->style_tops[kind]; while (n && n->checkpoint.v >= cp.v) @@ -238,7 +238,7 @@ void UI_PushDefaults(void) UI_Stack *stack = frame->top_stack; UI_Checkpoint checkpoint = stack->top_checkpoint; { - for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) + for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_COUNT; ++kind) { UI_StyleDesc desc = Zi; desc.style.kind = kind; @@ -1002,7 +1002,7 @@ void UI_EndFrame(UI_Frame *frame) for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) { UI_Box *box = boxes_pre[pre_index]; - for (Axis axis = 0; axis < Axis_CountXY; ++axis) + for (Axis axis = 0; axis < Axis_COUNTXY; ++axis) { UI_Size pref_size = box->desc.pref_size[axis]; if (pref_size.kind == UI_SizeKind_Pixel) @@ -1057,7 +1057,7 @@ void UI_EndFrame(UI_Frame *frame) for (u64 post_index = 0; post_index < boxes_count; ++post_index) { UI_Box *box = boxes_post[post_index]; - for (Axis axis = 0; axis < Axis_CountXY; ++axis) + for (Axis axis = 0; axis < Axis_COUNTXY; ++axis) { UI_Size pref_size = box->desc.pref_size[axis]; if (pref_size.kind == UI_SizeKind_Shrink && !AnyBit(box->desc.flags, UI_BoxFlag_DrawText)) @@ -1101,7 +1101,7 @@ void UI_EndFrame(UI_Frame *frame) for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) { UI_Box *box = boxes_pre[pre_index]; - for (Axis axis = 0; axis < Axis_CountXY; ++axis) + for (Axis axis = 0; axis < Axis_COUNTXY; ++axis) { f32 box_size = box->layout.solved_dims[axis]; // Solve non-floating violations diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index e6b6560f..dc8f63ce 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -124,7 +124,7 @@ Enum(UI_StyleKind) #define X(name, type) UI_StyleKind_##name, UI_StyleKind_None, UI_StyleKindsXMacro(X) - UI_StyleKind_Count, + UI_StyleKind_COUNT, #undef X }; @@ -165,7 +165,7 @@ Struct(UI_StyleNode) Struct(UI_Stack) { - UI_StyleNode *style_tops[UI_StyleKind_Count]; + UI_StyleNode *style_tops[UI_StyleKind_COUNT]; UI_Checkpoint top_checkpoint; }; @@ -207,7 +207,7 @@ Struct(UI_BoxDesc) UI_Key key; UI_Key parent; - UI_Size pref_size[Axis_CountXY]; + UI_Size pref_size[Axis_COUNTXY]; UI_Round rounding; Vec4 background_color; Vec4 border_color; @@ -219,7 +219,7 @@ Struct(UI_BoxDesc) GC_FontKey font; f32 font_size; Axis child_layout_axis; - UI_AxisAlignment child_alignment[Axis_CountXY]; + UI_AxisAlignment child_alignment[Axis_COUNTXY]; }; Struct(UI_Cmd) @@ -278,8 +278,8 @@ Struct(UI_Box) struct { f32 cursor; - f32 solved_dims[Axis_CountXY]; - f32 final_children_size_accum[Axis_CountXY]; + f32 solved_dims[Axis_COUNTXY]; + f32 final_children_size_accum[Axis_COUNTXY]; } layout; //- Layout results diff --git a/src/window/window.h b/src/window/window.h index 2b8fb359..5f2d1551 100644 --- a/src/window/window.h +++ b/src/window/window.h @@ -21,7 +21,7 @@ Enum(WND_CursorKind) WND_CursorKind_TlBrResize, WND_CursorKind_TrBlResize, - WND_CursorKind_Count + WND_CursorKind_COUNT }; //////////////////////////////////////////////////////////// diff --git a/src/window/window_win32/window_win32.h b/src/window/window_win32/window_win32.h index a152ab1e..d4b9396d 100644 --- a/src/window/window_win32/window_win32.h +++ b/src/window/window_win32/window_win32.h @@ -71,7 +71,7 @@ Struct(WND_W32_Ctx) { Button vk_to_button[256]; - HCURSOR cursors[WND_CursorKind_Count]; + HCURSOR cursors[WND_CursorKind_COUNT]; WNDCLASSEXW window_class;