sim world swapping

This commit is contained in:
jacob 2025-12-28 16:11:37 -06:00
parent 75bedaecbb
commit 3d7f6eddfe
29 changed files with 417 additions and 161 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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"),

View File

@ -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)

View File

@ -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"),
},

View File

@ -13,8 +13,8 @@ Enum(Axis)
Axis_Y = 1,
Axis_Z = 2,
Axis_CountXY = 2,
Axis_CountXYZ = 3
Axis_COUNTXY = 2,
Axis_COUNTXYZ = 3
};
////////////////////////////////////////////////////////////

View File

@ -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"));
}

View File

@ -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;
};

View File

@ -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
};
////////////////////////////////////////////////////////////

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -21,7 +21,7 @@ Enum(WND_CursorKind)
WND_CursorKind_TlBrResize,
WND_CursorKind_TrBlResize,
WND_CursorKind_Count
WND_CursorKind_COUNT
};
////////////////////////////////////////////////////////////

View File

@ -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;