From 7f3312c12a83490d01d89d1bbb7f145b1ac409e5 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 3 Apr 2026 00:35:07 -0500 Subject: [PATCH] text box mouse selection & caret interpolation --- build.bat | 5 +- src/config.h | 2 +- src/gpu/gpu_core.h | 10 +- src/gpu/gpu_dx12/gpu_dx12_core.c | 66 ++-- src/gpu/gpu_dx12/gpu_dx12_core.h | 4 +- src/gpu/gpu_shared.cgh | 42 +-- src/meta/meta.c | 213 ++++++----- src/pp/pp.h | 10 + src/pp/pp_sim/pp_sim_core.c | 148 +++++++- src/pp/pp_sim/pp_sim_core.h | 53 +++ src/pp/pp_vis/pp_vis_core.c | 627 +++++++++++++++++++------------ src/pp/pp_vis/pp_vis_core.h | 29 +- src/pp/pp_vis/pp_vis_gpu.g | 42 +-- src/pp/pp_vis/pp_vis_shared.cgh | 12 +- src/proto/proto.c | 2 +- src/proto/proto_gpu.g | 4 +- src/proto/proto_shared.cgh | 4 +- src/ui/ui_core.c | 8 +- src/ui/ui_core.h | 2 +- src/ui/ui_gpu.g | 6 +- src/ui/ui_shared.cgh | 6 +- 21 files changed, 829 insertions(+), 466 deletions(-) diff --git a/build.bat b/build.bat index 524a281c..510e4495 100644 --- a/build.bat +++ b/build.bat @@ -44,7 +44,8 @@ where /Q cl.exe || ( ::- Build metaprogram :meta_build if not exist meta.exe ( - echo ====== Meta Build ===== + echo Metaprogram dirty since last run, rebuilding... + echo ======== Meta Build ======== %meta_build_cmd% set "rc=!errorlevel!" if !rc! NEQ 0 ( @@ -55,7 +56,7 @@ if not exist meta.exe ( ::- Run metaprogram if not "%--no_meta_run%"=="1" ( - echo ======== Build ======== + echo =========== Build ========== %program_build_cmd% set "rc=!errorlevel!" if !rc! NEQ 0 ( diff --git a/src/config.h b/src/config.h index 176a202d..247aad23 100644 --- a/src/config.h +++ b/src/config.h @@ -24,7 +24,7 @@ //~ Settings -#define PROFILING_ENABLED 1 +#define PROFILING_ENABLED 0 diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index 4f500892..45bdf615 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -537,14 +537,14 @@ void *G_CpuPointerFromBuffer(G_BufferRef buffer); G_CommandListHandle G_PrepareCommandList(G_QueueKind queue); i64 G_CommitCommandList(G_CommandListHandle cl); -//- Constant +//- Register -void G_SetConstantEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size); +void G_SetRegisterEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size); -#define G_SetConstant(cl, name, value) do { \ - CAT(__ShaderConstantType_,name) __src; \ +#define G_SetRegister(cl, name, value) do { \ + CAT(__ShaderRegisterType__,name) __src; \ __src.v = value; \ - G_SetConstantEx((cl), (name), &__src, sizeof(__src)); \ + G_SetRegisterEx((cl), (name), &__src, sizeof(__src)); \ } while (0) //- Sync diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 3cf6dec2..dfdae376 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -517,8 +517,8 @@ void G_Bootstrap(void) ID3D10Blob *blob = 0; if (SUCCEEDED(hr)) { - D3D12_ROOT_PARAMETER1 params[G_NumConstants] = Zi; - for (i32 slot = 0; slot < G_NumConstants; ++slot) + D3D12_ROOT_PARAMETER1 params[G_NumRegisters] = Zi; + for (i32 slot = 0; slot < G_NumRegisters; ++slot) { D3D12_ROOT_PARAMETER1 *param = ¶ms[slot]; param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; @@ -2498,7 +2498,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) if ( cmd_kind != G_D12_CmdKind_Barrier && - cmd_kind != G_D12_CmdKind_Constant && + cmd_kind != G_D12_CmdKind_Register && cmd_kind != G_D12_CmdKind_Zone ) { @@ -2659,24 +2659,24 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) b32 descriptor_heaps_set = 0; G_D12_Pipeline *bound_pipeline = 0; - // Constants state - u64 slotted_constants[G_NumConstants]; - u64 bound_compute_constants[G_NumConstants]; - u64 bound_graphics_constants[G_NumConstants]; - for (i32 slot = 0; slot < countof(slotted_constants); ++slot) { slotted_constants[slot] = 0; } // Zero-initialize all slots - for (i32 slot = 0; slot < countof(bound_compute_constants); ++slot) { bound_compute_constants[slot] = U64Max; } - for (i32 slot = 0; slot < countof(bound_graphics_constants); ++slot) { bound_graphics_constants[slot] = U64Max; } + // Registers state + u64 slotted_registers[G_NumRegisters]; + u64 bound_compute_registers[G_NumRegisters]; + u64 bound_graphics_registers[G_NumRegisters]; + for (i32 slot = 0; slot < countof(slotted_registers); ++slot) { slotted_registers[slot] = 0; } // Zero-initialize all slots + for (i32 slot = 0; slot < countof(bound_compute_registers); ++slot) { bound_compute_registers[slot] = U64Max; } + for (i32 slot = 0; slot < countof(bound_graphics_registers); ++slot) { bound_graphics_registers[slot] = U64Max; } - // Fill built-in constants + // Set per-command-list registers if (!G_IsRefNil(queue->print_buffer)) { - slotted_constants[G_ShaderConst_PrintBuffer] = queue->print_buffer.v; + slotted_registers[G_ShaderReg_PrintBuffer] = queue->print_buffer.v; } { b32 tweak_b32 = TweakBool("Shader tweak-bool", 1); f32 tweak_f32 = TweakFloat("Shader tweak-float", 1, 0, 1); - slotted_constants[G_ShaderConst_TweakB32] = tweak_b32; - CopyBytes(&slotted_constants[G_ShaderConst_TweakF32], &tweak_f32, sizeof(tweak_f32)); + slotted_registers[G_ShaderReg_TweakB32] = tweak_b32; + CopyBytes(&slotted_registers[G_ShaderReg_TweakF32], &tweak_f32, sizeof(tweak_f32)); } // Rasterizer state @@ -2812,15 +2812,15 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) G_D12_Cmd *cmd = bcn->cmd; switch (cmd->kind) { - //- Constant + //- Register - case G_D12_CmdKind_Constant: + case G_D12_CmdKind_Register: { - i32 slot = cmd->constant.slot; - u32 value = cmd->constant.value; - if (slot >= 0 && slot < countof(slotted_constants)) + i32 slot = cmd->reg.slot; + u32 value = cmd->reg.value; + if (slot >= 0 && slot < countof(slotted_registers)) { - slotted_constants[slot] = value; + slotted_registers[slot] = value; } } break; @@ -2929,12 +2929,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) } // Update root constants - for (i32 slot = 0; slot < countof(slotted_constants); ++slot) + for (i32 slot = 0; slot < countof(slotted_registers); ++slot) { - if (bound_compute_constants[slot] != slotted_constants[slot]) + if (bound_compute_registers[slot] != slotted_registers[slot]) { - ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(d3d_cl, slot, slotted_constants[slot], 0); - bound_compute_constants[slot] = slotted_constants[slot]; + ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(d3d_cl, slot, slotted_registers[slot], 0); + bound_compute_registers[slot] = slotted_registers[slot]; } } @@ -3040,12 +3040,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) } // Update root constants - for (i32 slot = 0; slot < countof(slotted_constants); ++slot) + for (i32 slot = 0; slot < countof(slotted_registers); ++slot) { - if (bound_graphics_constants[slot] != slotted_constants[slot]) + if (bound_graphics_registers[slot] != slotted_registers[slot]) { - ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(d3d_cl, slot, slotted_constants[slot], 0); - bound_graphics_constants[slot] = slotted_constants[slot]; + ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(d3d_cl, slot, slotted_registers[slot], 0); + bound_graphics_registers[slot] = slotted_registers[slot]; } } @@ -3248,15 +3248,15 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) return completion_target; } -//- Constant +//- Register -void G_SetConstantEx(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u32 size) +void G_SetRegisterEx(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u32 size) { G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_Cmd *cmd = G_D12_PushCmd(cl); - cmd->kind = G_D12_CmdKind_Constant; - cmd->constant.slot = slot; - CopyBytes(&cmd->constant.value, src_32bit, MinU32(size, 4)); + cmd->kind = G_D12_CmdKind_Register; + cmd->reg.slot = slot; + CopyBytes(&cmd->reg.value, src_32bit, MinU32(size, 4)); } //- Sync diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index 48f65f9c..c75374b3 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -310,7 +310,7 @@ Enum(G_D12_EventKind) Enum(G_D12_CmdKind) { G_D12_CmdKind_None, - G_D12_CmdKind_Constant, + G_D12_CmdKind_Register, G_D12_CmdKind_Barrier, G_D12_CmdKind_Zone, G_D12_CmdKind_CopyBytes, @@ -330,7 +330,7 @@ Struct(G_D12_Cmd) { i32 slot; u32 value; - } constant; + } reg; struct { diff --git a/src/gpu/gpu_shared.cgh b/src/gpu/gpu_shared.cgh index 2d32accc..b3cf1b57 100644 --- a/src/gpu/gpu_shared.cgh +++ b/src/gpu/gpu_shared.cgh @@ -18,44 +18,44 @@ Struct(G_SamplerRef) { G_BaseDescriptorIndex v; }; #define G_IsRefNil(r) ((r).v == 0) //////////////////////////////////////////////////////////// -//~ Constant types +//~ Register types // // D3D12 exposes 64 root constants and Vulkan exposes 32 push constants. // Supposedly AMD hardware will start spilling constants once more than // 12 are in use - https://gpuopen.com/learn/rdna-performance-guide/ // -#define G_NumGeneralPurposeConstants (24) // Constants available for any usage -#define G_NumReservedConstants (4) // Constants reserved for internal usage by the GPU layer -#define G_NumConstants (G_NumGeneralPurposeConstants + G_NumReservedConstants) +#define G_NumGeneralPurposeRegisters (24) // Registers available for any usage +#define G_NumReservedRegisters (4) // Registers reserved for internal usage by the GPU layer +#define G_NumRegisters (G_NumGeneralPurposeRegisters + G_NumReservedRegisters) #if IsCpu - #define G_ForceDeclConstant(type, name, slot) \ + #define G_ForceDeclRegister(type, name, slot) \ enum { name = slot }; \ - Struct(CAT(__ShaderConstantType_,name)) { type v; } - #define G_DeclConstant(type, name, slot) \ + Struct(CAT(__ShaderRegisterType__,name)) { type v; } + #define G_DeclRegister(type, name, slot) \ StaticAssert(sizeof(type) <= 4); \ - StaticAssert(slot < G_NumGeneralPurposeConstants); \ - G_ForceDeclConstant(type, name, slot) + StaticAssert(slot < G_NumGeneralPurposeRegisters); \ + G_ForceDeclRegister(type, name, slot) #else - #define G_ForceDeclConstant(type, name, slot) cbuffer name : register(CAT(b,slot)) { type name; } - #define G_DeclConstant(type, name, slot) G_ForceDeclConstant(type, name, slot) + #define G_ForceDeclRegister(type, name, slot) cbuffer name : register(CAT(b,slot)) { type name; } + #define G_DeclRegister(type, name, slot) G_ForceDeclRegister(type, name, slot) #endif //////////////////////////////////////////////////////////// -//~ Reserved constants +//~ Reserved registers -// The constants declared below assume this configuration is accurate for slot usage -StaticAssert(G_NumGeneralPurposeConstants == 24); -StaticAssert(G_NumReservedConstants >= 3); +// The registers declared below assume this configuration is accurate for slot usage +StaticAssert(G_NumGeneralPurposeRegisters == 24); +StaticAssert(G_NumReservedRegisters >= 3); -G_ForceDeclConstant(G_BufferRef, G_ShaderConst_PrintBuffer, 24); -G_ForceDeclConstant(b32, G_ShaderConst_TweakB32, 25); -G_ForceDeclConstant(f32, G_ShaderConst_TweakF32, 26); +G_ForceDeclRegister(G_BufferRef, G_ShaderReg_PrintBuffer, 24); +G_ForceDeclRegister(b32, G_ShaderReg_TweakB32, 25); +G_ForceDeclRegister(f32, G_ShaderReg_TweakF32, 26); #if IsGpu - #define G_TweakBool G_ShaderConst_TweakB32 - #define G_TweakFloat G_ShaderConst_TweakF32 + #define G_TweakBool G_ShaderReg_TweakB32 + #define G_TweakFloat G_ShaderReg_TweakF32 #endif //////////////////////////////////////////////////////////// @@ -223,7 +223,7 @@ Struct(G_FmtArg) void G_CommitPrint(G_TempPrintBuffer buff) { - RWByteAddressBuffer rw = G_Deref(G_ShaderConst_PrintBuffer, RWByteAddressBuffer); + RWByteAddressBuffer rw = G_Deref(G_ShaderReg_PrintBuffer, RWByteAddressBuffer); if (buff.overflowed) { diff --git a/src/meta/meta.c b/src/meta/meta.c index bd7bd2a2..f5a5945e 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -268,151 +268,163 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) // Return rebuild code if metaprogram is dirty if (lane->idx == 0) { - // Read old metahash - u64 old_metahash = 0; - if (F_IsFile(Lit("metahash.dat"))) + b32 is_metaprogram_dirty = 0; { - String hashes_str = F_DataFromFile(perm, Lit("metahash.dat")); - if (hashes_str.len == sizeof(old_metahash)) + // Read old metahash + u64 old_metahash = 0; + if (F_IsFile(Lit("metahash.dat"))) { - CopyBytes(&old_metahash, hashes_str.text, sizeof(old_metahash)); + String hashes_str = F_DataFromFile(perm, Lit("metahash.dat")); + if (hashes_str.len == sizeof(old_metahash)) + { + CopyBytes(&old_metahash, hashes_str.text, sizeof(old_metahash)); + } + OS_Rm(Lit("metahash.dat")); } - OS_Rm(Lit("metahash.dat")); - } - // Compute new metahash - u64 new_metahash = 0; - { - StringList check_files = Zi; - F_FilesFromDir(perm, &check_files, Lit("../src/base"), F_IterFlag_Recurse); - F_FilesFromDir(perm, &check_files, Lit("../src/meta"), F_IterFlag_Recurse); - PushStringToList(perm, &check_files, Lit("../src/config.h")); - for (StringListNode *n = check_files.first; n; n = n->next) + // Compute new metahash + u64 new_metahash = 0; { - String file = n->s; - new_metahash = MixU64s(new_metahash, OS_LastWriteTimestampFromPath(file)); - new_metahash = HashStringEx(new_metahash , file); + StringList check_files = Zi; + { + // If any of these files are dirty, then the metaprogram should be rebuilt + F_FilesFromDir(perm, &check_files, Lit("../src/base"), F_IterFlag_Recurse); + F_FilesFromDir(perm, &check_files, Lit("../src/meta"), F_IterFlag_Recurse); + PushStringToList(perm, &check_files, Lit("../src/config.h")); + PushStringToList(perm, &check_files, Lit("../build.bat")); + } + for (StringListNode *n = check_files.first; n; n = n->next) + { + String file = n->s; + new_metahash = MixU64s(new_metahash, OS_LastWriteTimestampFromPath(file)); + new_metahash = HashStringEx(new_metahash , file); + } + } + if (old_metahash == 0 || old_metahash == new_metahash) + { + F_ClearWrite(Lit("metahash.dat"), StringFromStruct(&new_metahash)); + } + else + { + is_metaprogram_dirty = 1; } } // Exit if metaprogram needs recompilation - if (old_metahash == 0 || old_metahash == new_metahash) + if (is_metaprogram_dirty) { - F_ClearWrite(Lit("metahash.dat"), StringFromStruct(&new_metahash)); - } - else - { - M_EchoLine(Lit("Metaprogram is dirty")); ExitNow(M_RebuildCode); } } ////////////////////////////// - //- Init command line + //- Init environment from command line - // Layer name { - CommandlineArg arg = CommandlineArgFromName(Lit("layer")); - String layer_name = Zi; - if (arg.name.len != 0) + //- Layer name { - layer_name = arg.value; - } - else - { - layer_name = StringFromCommandlineIdx(1); - } - if (layer_name.len == 0) - { - layer_name = Lit("pp"); - if (lane->idx == 0) + CommandlineArg arg = CommandlineArgFromName(Lit("layer")); + String layer_name = Zi; + if (arg.name.len != 0) { - M_EchoLine(Lit("No layer specified, assuming \"pp\" build")); + layer_name = arg.value; } + else + { + layer_name = StringFromCommandlineIdx(1); + } + if (layer_name.len == 0) + { + layer_name = Lit("pp"); + if (lane->idx == 0) + { + M_EchoLine(Lit("No target layer specified, assuming 'pp' build")); + } + } + M.cmdline.leaf_layer_name = layer_name; } - M.cmdline.leaf_layer_name = layer_name; - } - // Platform - { - CommandlineArg arg = CommandlineArgFromName(Lit("platform")); - if (MatchString(arg.value, Lit("windows"))) + //- Platform { - M.cmdline.target_platform = M_PlatformKind_Windows; - } - else if (MatchString(arg.value, Lit("macos"))) - { - M.cmdline.target_platform = M_PlatformKind_Mac; - } - else if (MatchString(arg.value, Lit("linux"))) - { - M.cmdline.target_platform = M_PlatformKind_Linux; - } - else - { - if (IsPlatformWindows) + CommandlineArg arg = CommandlineArgFromName(Lit("platform")); + if (MatchString(arg.value, Lit("windows"))) { M.cmdline.target_platform = M_PlatformKind_Windows; } - else if (IsPlatformMac) + else if (MatchString(arg.value, Lit("macos"))) { M.cmdline.target_platform = M_PlatformKind_Mac; } - else + else if (MatchString(arg.value, Lit("linux"))) { M.cmdline.target_platform = M_PlatformKind_Linux; } + else + { + if (IsPlatformWindows) + { + M.cmdline.target_platform = M_PlatformKind_Windows; + } + else if (IsPlatformMac) + { + M.cmdline.target_platform = M_PlatformKind_Mac; + } + else + { + M.cmdline.target_platform = M_PlatformKind_Linux; + } + } } - } - // Compiler - { - CommandlineArg arg = CommandlineArgFromName(Lit("compiler")); - if (MatchString(arg.value, Lit("msvc"))) + //- Compiler { - M.cmdline.target_compiler = M_CompilerKind_Msvc; - } - else if (MatchString(arg.value, Lit("clang"))) - { - M.cmdline.target_compiler = M_CompilerKind_Clang; - } - else - { - if (IsPlatformWindows) + CommandlineArg arg = CommandlineArgFromName(Lit("compiler")); + if (MatchString(arg.value, Lit("msvc"))) { M.cmdline.target_compiler = M_CompilerKind_Msvc; } - else + else if (MatchString(arg.value, Lit("clang"))) { M.cmdline.target_compiler = M_CompilerKind_Clang; } + else + { + if (IsPlatformWindows) + { + M.cmdline.target_compiler = M_CompilerKind_Msvc; + } + else + { + M.cmdline.target_compiler = M_CompilerKind_Clang; + } + } } - } - // Release/Debug - { - CommandlineArg arg = CommandlineArgFromName(Lit("release")); - if (arg.exists) + //- Release/Debug { - M.cmdline.release = 1; + CommandlineArg arg = CommandlineArgFromName(Lit("release")); + if (arg.exists) + { + M.cmdline.release = 1; + } } - } - // Subsystem - { - CommandlineArg arg = CommandlineArgFromName(Lit("console")); - if (arg.exists) + //- Subsystem { - M.cmdline.console = 1; + CommandlineArg arg = CommandlineArgFromName(Lit("console")); + if (arg.exists) + { + M.cmdline.console = 1; + } } - } - // Asan - { - CommandlineArg arg = CommandlineArgFromName(Lit("asan")); - if (arg.exists) + //- Asan { - M.cmdline.asan = 1; + CommandlineArg arg = CommandlineArgFromName(Lit("asan")); + if (arg.exists) + { + M.cmdline.asan = 1; + } } } @@ -441,7 +453,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) M_EchoLine(Lit("[ASAN]")); } - M_EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(M.cmdline.leaf_layer_name))); + M_EchoLine(StringF(perm, "[Target layer: '%F']", FmtString(M.cmdline.leaf_layer_name))); } ////////////////////////////// @@ -1425,7 +1437,11 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) if (lane->idx == 0) { - M_EchoLine(StringF(perm, "Runtime: %Fs", FmtFloat(SecondsFromNs(TimeNs()), .p = 3))); + M_EchoLine(Lit("----------------------------")); + M_EchoLine(StringF(perm, "Objects embedded %F", FmtUint(M.embed_objs.count))); + M_EchoLine(StringF(perm, "Shaders compiled %F", FmtUint(M.gpu_objs.count))); + M_EchoLine(StringF(perm, "Build time %Fs", FmtFloat(SecondsFromNs(TimeNs()), .p = 3))); + M_EchoLine(Lit("----------------------------")); ExitNow(M_GetBuildStatus()); } } @@ -1436,7 +1452,6 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) void BootstrapLayers(void) { OS_Bootstrap(); - CpuTopologyInfo cpu_info = GetCpuTopologyInfo(); - i32 meta_lanes_count = cpu_info.num_logical_cores - 1; + i32 meta_lanes_count = 32; DispatchWave(Lit("Meta"), MaxI32(meta_lanes_count, 1), M_BuildEntryPoint, 0); } diff --git a/src/pp/pp.h b/src/pp/pp.h index 1a1d78b4..b29b5547 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -459,6 +459,7 @@ Enum(P_MsgKind) // Server -> Client P_MsgKind_Tiles, + P_MsgKind_PublicState, P_MsgKind_COUNT }; @@ -552,6 +553,15 @@ Struct(P_RaycastResult) //////////////////////////////////////////////////////////// //~ State types +// NOTE: +// Public state is scanned and reflected dumbly to clients each frame, +// so absurdly large data should not go here. +// +Struct(P_PublicState) +{ + b32 is_recording_demo; +}; + Struct(P_SimStatistics) { NET_PipeStatistics pipe; diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index e5fb4179..4a3290c8 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -69,7 +69,7 @@ void S_TickForever(WaveLaneCtx *lane) BB_Buff packer_bb = BB_AcquireDynamicBuff(Gibi(64)); BB_Writer packer_bbw = BB_WriterFromBuff(&packer_bb); - + P_PublicState *public = &S.public_state; // FIXME: Header @@ -195,6 +195,11 @@ void S_TickForever(WaveLaneCtx *lane) } } + + + + + ////////////////////////////// //- Connect clients @@ -399,22 +404,141 @@ void S_TickForever(WaveLaneCtx *lane) } } + + + + + + + + + + + ////////////////////////////// + //- Apply demo controls + + + // FIXME: Remove this + PERSIST i64 current_demo_tick = 0; + PERSIST Demo *demo = 0; + PERSIST b32 is_playing_demo; + if (!demo) + { + demo = PushStruct(perm, Demo); + } + + { + // FIXME: Remove this + if (is_playing_demo) + { + // Init tracks + { + P_EntList ents_to_spawn = Zi; + for (DemoTrack *track = demo->first_track; track; track = track->next) + { + P_Ent *player = P_EntFromKey(world_frame, track->player); + if (!player->is_player) + { + player = P_PushTempEnt(frame_arena, &ents_to_spawn); + player->key = P_RandEntKey(); + player->is_player = 1; + } + for (DemoCmd *demo_cmd = track->first_cmd; demo_cmd; demo_cmd = demo_cmd->next) + { + P_Control control = demo_cmd->control; + } + } + P_SpawnEntsFromList(world_frame, ents_to_spawn); + } + + // FIXME: No linear search + for (DemoTrack *track = demo->first_track; track; track = track->next) + { + P_Ent *player = P_EntFromKey(world_frame, track->player); + for (DemoCmd *demo_cmd = track->first_cmd; demo_cmd; demo_cmd = demo_cmd->next) + { + if (demo_cmd->demo_tick == current_demo_tick) + { + P_Control control = demo_cmd->control; + player->control = demo_cmd->control; + break; + } + } + } + } + } + + + + + + + + + + + + + + + + + + ////////////////////////////// //- Apply client controls + + + + + + + + for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next) { P_Control *control = &client->controls[world_frame->tick % client->controls_cap]; if (control->tick == world_frame->tick) { P_Ent *player = P_EntFromKey(world_frame, client->player); - if (!P_IsEntNil(player)) + if (player->is_player) { player->control = *control; + + if (client->is_recording_demo) + { + // FIXME: No linear search + DemoTrack *track = 0; + { + { + for (track = demo->first_track; track; track = track->next) + { + if (P_MatchEntKey(track->player, player->key)) + { + break; + } + } + } + if (!track) + { + track = PushStruct(perm, DemoTrack); + track->player = player->key; + DllQueuePush(demo->first_track, demo->last_track, track); + } + } + DemoCmd *demo_cmd = PushStruct(perm, DemoCmd); + demo_cmd->demo_tick = current_demo_tick; + demo_cmd->control = player->control; + SllQueuePush(track->first_cmd, track->last_cmd, demo_cmd); + } } } } + + + ////////////////////////////// //- Apply bot controls @@ -712,6 +836,18 @@ void S_TickForever(WaveLaneCtx *lane) P_StepFrame(world_frame); } + ////////////////////////////// + //- Push public state messages + + // TODO: Don't network reliably + // TODO: Delta compress + + { + P_Msg *msg = P_PushMsg(P_MsgKind_PublicState, Zstr); + msg->kind = P_MsgKind_PublicState; + msg->data = StringFromStruct(public); + } + ////////////////////////////// //- Push tile messages @@ -910,10 +1046,6 @@ void S_TickForever(WaveLaneCtx *lane) { BB_ResetWriter(&packer_bbw); String packed = P_PackMessages(&packer_bbw, msgs); - - // String address_str = NET_StringFromKey(frame_arena, client->net_key); - // LogDebugF("Sending message to client \"%F\"", FmtString(address_str)); - NET_Send(net_pipe, client->net_key, packed, NET_SendFlag_None); ZeroStruct(&client->out_msgs); } @@ -924,9 +1056,9 @@ void S_TickForever(WaveLaneCtx *lane) } ////////////////////////////// - //- Publish Sim -> User data + //- Publish Sim -> Vis data - ProfZoneDF("Publish Sim -> User") + ProfZoneDF("Publish Sim -> Vis") { LockTicketMutex(&P.s2v_tm); { diff --git a/src/pp/pp_sim/pp_sim_core.h b/src/pp/pp_sim/pp_sim_core.h index 6c554b2f..8aa1c012 100644 --- a/src/pp/pp_sim/pp_sim_core.h +++ b/src/pp/pp_sim/pp_sim_core.h @@ -1,3 +1,51 @@ + + + + + + +//////////////////////////////////////////////////////////// +//~ Demo types + + + +// FIXME: Remove this + + + + +Struct(DemoCmd) +{ + DemoCmd *next; + + i64 demo_tick; + P_Control control; +}; + +Struct(DemoTrack) +{ + DemoTrack *next; + DemoTrack *prev; + + P_EntKey player; + + DemoCmd *first_cmd; + DemoCmd *last_cmd; +}; + +Struct(Demo) +{ + DemoTrack *first_track; + DemoTrack *last_track; +}; + + + + + + + + //////////////////////////////////////////////////////////// //~ Client types @@ -23,6 +71,9 @@ Struct(S_Client) i64 remote_ack; i64 ack; + i64 demo_record_tick_offset; + b32 is_recording_demo; + u64 remote_tiles_hash; }; @@ -45,6 +96,8 @@ Struct(S_Ctx) i64 client_bins_count; S_ClientBin *client_bins; + + P_PublicState public_state; }; extern S_Ctx S; diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index b4966bb7..6062e4f6 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -261,28 +261,33 @@ void V_DrawPoint(Vec2 p, Vec4 srgb) //////////////////////////////////////////////////////////// //~ Text box -void V_ApplyTextboxDelta(V_TextboxState *tb, V_TextboxDelta delta) +V_TextboxDeltaFlag V_ApplyTextboxDelta(V_TextboxState *tb, V_TextboxDelta delta) { V_TextboxDeltaNode tbd_node = { .delta = delta }; - V_ApplyTextboxDeltas(tb, (V_TextboxDeltaList) { .first = &tbd_node, .last = &tbd_node }); + return V_ApplyTextboxDeltas(tb, (V_TextboxDeltaList) { .first = &tbd_node, .last = &tbd_node }); } -void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas) +V_TextboxDeltaFlag V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas) { TempArena scratch = BeginScratchNoConflict(); + V_TextboxDeltaFlag applied_flags = 0; for (V_TextboxDeltaNode *tbd_node = deltas.first; tbd_node; tbd_node = tbd_node->next) { V_TextboxDelta delta = tbd_node->delta; + applied_flags |= delta.flags; // Navigate { b32 navigated = 0; if (!(delta.flags & V_TextboxDeltaFlag_OnlyNavIfSelectionEmpty) || tb->start == tb->end) { - if (delta.flags & V_TextboxDeltaFlag_NavDirect) + if (delta.flags & V_TextboxDeltaFlag_NavDirectStart) + { + tb->start = ClampI64(delta.direct_start, 0, tb->len); + } + if (delta.flags & V_TextboxDeltaFlag_NavDirectEnd) { navigated = 1; - tb->start = ClampI64(delta.direct_start, 0, tb->len); tb->end = ClampI64(delta.direct_end, 0, tb->len); } if (delta.flags & V_TextboxDeltaFlag_NavLeft) @@ -346,7 +351,7 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas) } } } - if (navigated && !(delta.flags & V_TextboxDeltaFlag_NavSelect)) + if (navigated && !(delta.flags & V_TextboxDeltaFlag_NavSelect) && !(delta.flags & V_TextboxDeltaFlag_NavDirectStart)) { tb->start = tb->end; } @@ -550,6 +555,7 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas) // } } EndScratch(scratch); + return applied_flags; } String V_StringFromTextbox(Arena *arena, V_TextboxState *tb) @@ -594,7 +600,7 @@ V_WidgetTheme V_GetWidgetTheme(void) V_WidgetTheme theme = Zi; theme.ui_font = GC_FontKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("font/seguisb.ttf"))); - // theme.chat_font = GC_FontKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("font/fixedsys.ttf"))); + theme.player_name_font = GC_FontKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("font/fixedsys.ttf"))); theme.chat_font = GC_FontKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("font/seguisb.ttf"))); theme.icon_font = UI_BuiltinIconFont(); @@ -688,6 +694,9 @@ void V_TickForever(WaveLaneCtx *lane) BB_Buff packer_bb = BB_AcquireDynamicBuff(Gibi(64)); BB_Writer packer_bbw = BB_WriterFromBuff(&packer_bb); + // TODO: Reset public state when connected to new server + P_PublicState *public = &V.public_state; + ////////////////////////////// //- Init vis state @@ -1256,7 +1265,7 @@ void V_TickForever(WaveLaneCtx *lane) } if (down && cev->button == Button_A && frame->real_held_buttons[Button_Ctrl]) { - delta.flags |= V_TextboxDeltaFlag_NavSelect | V_TextboxDeltaFlag_NavDirect; + delta.flags |= V_TextboxDeltaFlag_NavSelect | V_TextboxDeltaFlag_NavDirectStart | V_TextboxDeltaFlag_NavDirectEnd; delta.direct_start = 0; delta.direct_end = V_MaxTextboxLen; } @@ -1779,6 +1788,17 @@ void V_TickForever(WaveLaneCtx *lane) V_PushNotif(txt); } + //- Public state + if (msg->kind == P_MsgKind_PublicState) + { + String data = msg->data; + u64 safe_copy_len = sizeof(*public); + if (data.len == safe_copy_len) + { + CopyBytes(public, data.text, safe_copy_len); + } + } + //- Tiles if (msg->kind == P_MsgKind_Tiles && sim_world->tiles_hash != msg->tiles_hash) { @@ -3306,9 +3326,9 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Push test emitter - // if (frame->held_buttons[Button_F]) + if (frame->held_buttons[Button_F]) // if (frame->held_buttons[Button_F] && !prev_frame->held_buttons[Button_F]) - if (0) + // if (0) { { V_Emitter emitter = Zi; @@ -3372,9 +3392,9 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Push test explosion - // if (frame->held_buttons[Button_G]) + if (frame->held_buttons[Button_G]) // if (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G]) - if (0) + // if (0) { // Fire { @@ -3634,7 +3654,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Build panels - UI_SetDF(Parent, vis_game_box) + UI_PushDF(Parent, vis_game_box) // if (show_editor_ui && frame->is_editing) { Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; @@ -4324,7 +4344,7 @@ void V_TickForever(WaveLaneCtx *lane) //- Build command palette V_Palette *palette = &frame->palette; - UI_SetDF(Parent, UI_RootKey) + UI_PushDF(Parent, UI_RootKey) { UI_Push(Tag, HashF("developer command palette")); @@ -4542,8 +4562,31 @@ void V_TickForever(WaveLaneCtx *lane) //- Search box { UI_Key search_box = UI_KeyF("search box"); + UI_Key search_scroll_box = UI_KeyF("search scroll box"); V_TextboxState *search_state = &palette->search_state; + String search_text = V_StringFromTextbox(frame->arena, search_state); + search_pattern = LowerString(frame->arena, search_text); + is_searching = search_text.len != 0; + + String display_text = search_text; + Vec4 display_text_color = Color_White; + if (!is_searching) + { + display_text_color = theme.col.hint; + display_text = Lit(" Search..."); + } + + f32 font_size = UI_Top(FontSize); + GC_FontKey font = UI_Top(Font); + + // Vec4 search_color = Color_Black; + Vec4 search_color = Zi; + + // TODO: Cache run for UI + String32 codepoints = String32FromString(frame->arena, search_text); + GC_Run run = GC_RunFromString32(frame->arena, codepoints, font, font_size); + b32 has_focus = UI_MatchKey(search_box, prev_frame->text_input_focus); // FIXME: Remove this @@ -4566,123 +4609,94 @@ void V_TickForever(WaveLaneCtx *lane) WND_SetCursor(window_frame, WND_CursorKind_Text); } + V_TextboxDeltaFlag tb_applied_flags = 0; + b32 started_dragging_text = 0; + b32 is_dragging_text = 0; if (has_focus) { - frame->text_input_focus = search_box; - if (text_input_deltas.first) + // Apply text input deltas + { + frame->text_input_focus = search_box; + if (text_input_deltas.first) + { + V.text_input_ns = frame->time_ns; + tb_applied_flags |= V_ApplyTextboxDeltas(search_state, text_input_deltas); + } + } + + // Apply mouse select + if (UI_Held(search_box, Button_M1)) { V.text_input_ns = frame->time_ns; - V_ApplyTextboxDeltas(search_state, text_input_deltas); + is_dragging_text = 1; + f32 mouse_text_px = UI_CursorPos().x - UI_Anchor(search_scroll_box).x; + i64 rect_idx = 0; + for (; rect_idx < (i64)run.rects_count; ++rect_idx) + { + GC_RunRect rect = run.rects[rect_idx]; + if (rect.baseline_pos + rect.advance / 2 > mouse_text_px) + { + break; + } + } + { + V_TextboxDelta delta = Zi; + delta.flags |= V_TextboxDeltaFlag_NavDirectEnd; + delta.flags |= V_TextboxDeltaFlag_NavSelect; + delta.direct_end = rect_idx; + if (UI_Downs(search_box, Button_M1)) + { + delta.flags |= V_TextboxDeltaFlag_NavDirectStart; + delta.direct_start = delta.direct_end; + started_dragging_text = 1; + } + tb_applied_flags |= V_ApplyTextboxDelta(search_state, delta); + } } + + // // Apply mouse selection drag + // if (UI_Held(search_box)) + // { + // f32 drag_delta = UI_CursorPos().x - UI_DragCursorPos().x; + + // } } - // // FIXME: Remove this - // if (frame->held_buttons[Button_B] && !prev_frame->held_buttons[Button_B]) - // { - // V_TextboxDelta delta = Zi; - // // delta.kind = V_DeltaKind_ - // delta.text = Lit("Hi"); - // // delta.range = RNGI64(I64Max, I64Max); - - // // delta.start = search_state->start; - // // delta.end = search_state->end; - - // // delta.start = 0; - // // delta.end = 1; - - // delta.flags |= V_TextboxDeltaFlag_UpdateText; - - // V_ApplyTextboxDelta(search_state, delta); - // } - - String search_text = V_StringFromTextbox(frame->arena, search_state); - search_pattern = LowerString(frame->arena, search_text); - is_searching = search_text.len != 0; - - - String display_text = search_text; - Vec4 display_text_color = Color_White; - if (!is_searching) - { - display_text_color = theme.col.hint; - display_text = Lit(" Search..."); - } - - // Vec4 search_color = Color_Black; - Vec4 search_color = Zi; - UI_SetNext(Width, UI_Grow(1, 0)); UI_SetNext(Height, search_height); UI_SetNext(BackgroundColor, search_color); + UI_SetNext(ChildAlignment, UI_Region_Right); // UI_SetNext(BorderColor, item_border_color); - UI_SetNext(BorderSize, 0); + UI_PushDF(BorderSize, 0); // UI_SetNext(Rounding, UI_Rpx(5)); - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_SetNext(TextColor, display_text_color); - UI_SetNext(Text, display_text); - UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse); - UI_PushCp(UI_BuildRowEx(search_box)); + UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_Scissor); + UI_PushDF(Parent, UI_BuildRowEx(search_box)) { - f32 font_size = UI_Top(FontSize); - GC_FontKey font = UI_Top(Font); - - //- Text caret/selection - if (has_focus) + //- Compute caret / selection pos { - UI_Key caret_box = UI_KeyF("search caret"); - UI_Key selection_box = UI_KeyF("search selection"); - - - UI_Size caret_width = UI_Px(1, 1); - UI_Size caret_height = UI_Px(search_height.v, 1); - - - Vec4 selection_color = VEC4(0, 0.25, 0.75, 0.5); - - Vec4 caret_color = VEC4(1, 1, 1, 0.75); - // caret_color.a = AbsF32(SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 4)); - // caret_color.a = SinF32(SecondsFromNs(frame->time_ns - V.text_input_ns)) > 0.5 ? 1 : 0; - // caret_color.a = (CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 5) + 1) * 0.5; - caret_color.a *= AbsF32(CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 3)); - - f32 start_offset_px = 0; - f32 end_offset_px = 0; - - // caret_offset_px = TweakFloat("RAAAAAAAAAAAAAAAAAAAH", 0, 0, 100); - - // caret_offset_px = - - - - - // FIXME: Remove this, use UI computed run + // TODO: Cache result of caret search when textbox + f32 target_caret_start_px = 0; + f32 target_caret_end_px = 0; if (search_text.len > 0) { - String32 codepoints = String32FromString(frame->arena, search_text); - GC_Run run = GC_RunFromString32(frame->arena, codepoints, font, font_size); - - // FIXME: Don't use rect idx - // FIXME: Selection - // FIXME: Offset & scissor for (i64 rect_idx = 0; rect_idx < (i64)run.rects_count; ++rect_idx) { + GC_RunRect rect = run.rects[rect_idx]; if (rect_idx < search_state->start) { - GC_RunRect rect = run.rects[rect_idx]; - start_offset_px = rect.baseline_pos + rect.advance; + target_caret_start_px = rect.baseline_pos + rect.advance; } if (rect_idx < search_state->end) { - GC_RunRect rect = run.rects[rect_idx]; - end_offset_px = rect.baseline_pos + rect.advance; + target_caret_end_px = rect.baseline_pos + rect.advance; } if (rect_idx >= search_state->start && rect_idx >= search_state->end) { @@ -4691,21 +4705,74 @@ void V_TickForever(WaveLaneCtx *lane) } } - - - - - - - - // { - // i64 offset_ - // } - - // Selection + f32 caret_start_lerp_rate = 25 * frame->dt; + f32 caret_end_lerp_rate = 50 * frame->dt; { - f32 min = MinF32(start_offset_px, end_offset_px); - f32 max = MaxF32(start_offset_px, end_offset_px); + if (started_dragging_text) + { + caret_start_lerp_rate = 1; + caret_end_lerp_rate = 1; + } + if (is_dragging_text) + { + caret_end_lerp_rate *= 2; + } + caret_start_lerp_rate = SaturateF32(caret_start_lerp_rate); + caret_end_lerp_rate = SaturateF32(caret_end_lerp_rate); + } + palette->caret_start_px = LerpF32(palette->caret_start_px, target_caret_start_px, caret_start_lerp_rate); + palette->caret_end_px = LerpF32(palette->caret_end_px, target_caret_end_px, caret_end_lerp_rate); + } + + //- Determine text scroll pos + f32 search_box_width = DimsFromRng2(UI_Rect(search_box)).x; + { + { + f32 new_text_scroll_px = palette->caret_end_px - 10; + palette->text_scroll_px = MinF32( palette->text_scroll_px, new_text_scroll_px); + } + { + f32 new_text_scroll_px = palette->caret_end_px - search_box_width + 10; + palette->text_scroll_px = MaxF32(palette->text_scroll_px, new_text_scroll_px); + } + palette->text_scroll_px = MaxF32(palette->text_scroll_px, 0); + } + + UI_Size caret_width = UI_Px(1, 1); + UI_Size caret_height = UI_Px(search_height.v, 1); + f32 h = TweakFloat("Text selection hue", 200, 0, 360); + f32 s = TweakFloat("Text selection saturation", 1, 0, 1); + f32 v = TweakFloat("Text selection brightness", 1, 0, 1); + Vec4 selection_color = SrgbFromHsv(h, s, v); + selection_color.a = 0.25; + + Vec4 caret_color = VEC4(1, 1, 1, 0.75); + caret_color.a *= AbsF32(CosF32(SecondsFromNs(frame->time_ns - V.text_input_ns) * 3)); + + //- Text region + UI_SetNext(FloatingPos, VEC2(-palette->text_scroll_px, 0)); + UI_SetNext(Anchor, UI_Region_Left); + UI_SetNext(ChildAlignment, UI_Region_Left); + UI_SetNext(Width, UI_Shrink(0, 1)); + UI_SetNext(TextColor, display_text_color); + UI_SetNext(Text, display_text); + UI_SetNext(Parent, search_box); + UI_SetNext( + Flags, + UI_BoxFlag_DrawText | + UI_BoxFlag_DontTruncateText | + UI_BoxFlag_Floating | + UI_BoxFlag_DontClampFloatingX + ); + UI_PushDF(Parent, UI_BuildRowEx(search_scroll_box)) + { + UI_Key caret_box = UI_KeyF("search caret"); + UI_Key selection_box = UI_KeyF("search selection"); + + //- Selection + { + f32 min = MinF32(palette->caret_end_px, palette->caret_start_px); + f32 max = MaxF32(palette->caret_end_px, palette->caret_start_px); UI_SetNext(Width, UI_Px(max - min, 1)); UI_SetNext(Height, caret_height); @@ -4718,11 +4785,12 @@ void V_TickForever(WaveLaneCtx *lane) UI_BuildBoxEx(selection_box); } - // Caret + //- Caret + if (has_focus) { UI_SetNext(Width, caret_width); UI_SetNext(Height, caret_height); - UI_SetNext(FloatingPos, VEC2(end_offset_px, 0)); + UI_SetNext(FloatingPos, VEC2(palette->caret_end_px, 0)); UI_SetNext(Anchor, UI_Region_Left); UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); UI_SetNext(BorderSize, 0); @@ -4732,7 +4800,6 @@ void V_TickForever(WaveLaneCtx *lane) } } } - UI_PopCp(UI_TopCp()); } } UI_PopCp(UI_TopCp()); @@ -5518,7 +5585,7 @@ void V_TickForever(WaveLaneCtx *lane) profiler->ns_per_px = ClampF64(profiler->ns_per_px, min_profiler_ns_per_px, max_profiler_ns_per_px); UI_Key profiler_graph_box = UI_KeyF("graph"); - UI_SetDF(OmitFlags, UI_BoxFlag_CaptureMouse * !!(frame->is_looking)) + UI_PushDF(OmitFlags, UI_BoxFlag_CaptureMouse * !!(frame->is_looking)) if (profiler->is_showing) { @@ -5548,8 +5615,8 @@ void V_TickForever(WaveLaneCtx *lane) //- Build profiler UI_Key profiler_box = UI_KeyF("profiler"); ProfZoneDF("Build profiler") - UI_SetDF(Tag, profiler_box.v) - UI_SetDF(Parent, profiler_box) + UI_PushDF(Tag, profiler_box.v) + UI_PushDF(Parent, profiler_box) { UI_Key main_box = UI_KeyF("main"); @@ -5615,9 +5682,9 @@ void V_TickForever(WaveLaneCtx *lane) profiler->last_zoom_delta = profiler->target_ns_per_px - profiler->ns_per_px; profiler->last_view_delta = profiler->target_view_ns - profiler->view_ns; } - f64 overshoot_rate = 2 * frame->dt; - profiler->ns_per_px = LerpF64(profiler->ns_per_px, profiler->target_ns_per_px + profiler->last_zoom_delta * overshoot_rate, prof_lerp_rate); - profiler->view_ns = LerpF64(profiler->view_ns, profiler->target_view_ns + profiler->last_view_delta * overshoot_rate, prof_lerp_rate); + f64 overshoot_factor = 0.01; + profiler->ns_per_px = LerpF64(profiler->ns_per_px, profiler->target_ns_per_px + profiler->last_zoom_delta * overshoot_factor, prof_lerp_rate); + profiler->view_ns = LerpF64(profiler->view_ns, profiler->target_view_ns + profiler->last_view_delta * overshoot_factor, prof_lerp_rate); if (profiler->last_zoom_delta < 0) { @@ -5796,7 +5863,8 @@ void V_TickForever(WaveLaneCtx *lane) VisTrack *first_vis_track = 0; VisTrack *last_vis_track = 0; f32 zone_collapse_threshold_px = 10; - f32 min_zone_width_px = 5; + f32 zone_name_hide_threshold_px = UI_Top(FontSize) * 3; + f32 min_zone_width_px = 6; ProfZoneDF("Generate visible zones") { for (V_ZoneTrack *zone_track = V.first_zone_track; zone_track; zone_track = zone_track->next) @@ -5830,8 +5898,8 @@ void V_TickForever(WaveLaneCtx *lane) // Process child zones { - VisZone *left_vis = 0; b32 reached_end_of_view = 0; + VisZone *left_vis = 0; for (V_ZoneChunk *chunk = parent->first_chunk; chunk && !reached_end_of_view; chunk = chunk->next) { i64 chunk_start_ns = chunk->zones[0].start_ns; @@ -5841,7 +5909,7 @@ void V_TickForever(WaveLaneCtx *lane) if (chunk_start_ns <= view_end_ns && chunk_end_ns >= view_start_ns) { - // TODO: Binary search to find start + // TODO: Binary search to find start within chunk for (u64 chunk_zone_idx = 0; chunk_zone_idx < chunk->count && !reached_end_of_view; ++chunk_zone_idx) { V_Zone *zone = &chunk->zones[chunk_zone_idx]; @@ -5870,8 +5938,14 @@ void V_TickForever(WaveLaneCtx *lane) visual_zone_start_px = MaxF64(visual_zone_start_px, parent_vis->start_px); if (left_vis) { - visual_zone_start_px = MaxF64(visual_zone_start_px, left_vis->start_px); + // visual_zone_start_px = MaxF64(visual_zone_start_px, CeilF64(left_vis->end_px)); + visual_zone_start_px = MaxF64(visual_zone_start_px, left_vis->end_px); } + // visual_zone_start_px = MinF64(visual_zone_start_px, visual_zone_end_px - min_zone_width_px); + // visual_zone_start_px = MaxF64(visual_zone_start_px, parent_vis->start_px); + + // visual_zone_end_px = MaxF64(visual_zone_end_px, visual_zone_start_px + min_zone_width_px); + // visual_zone_end_px = MinF64(visual_zone_end_px, parent_vis->end_px); } // Push vis zone @@ -5946,7 +6020,7 @@ void V_TickForever(WaveLaneCtx *lane) f32 profiler_opacity = TweakFloat("Profiler opacity", 1, 0, 1); Vec4 timeline_cursor_color = theme.col.window_bd; - timeline_cursor_color.a = UI_Hot(main_box) * 0.5; + timeline_cursor_color.a = UI_Hot(main_box) * 0.75; UI_Size timeline_cursor_width = UI_Fnt(0.15, 1); UI_Key hovered_zone_box = Zi; @@ -5976,22 +6050,22 @@ void V_TickForever(WaveLaneCtx *lane) UI_SetNext(Height, profiler_height); UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); UI_SetNext(Opacity, profiler_opacity); - UI_SetDF(Width, UI_Grow(1, 0)) - UI_SetDF(Parent, UI_BuildColumnEx(profiler_box)) - UI_SetDF(Parent, UI_BuildRow()) + UI_PushDF(Width, UI_Grow(1, 0)) + UI_PushDF(Parent, UI_BuildColumnEx(profiler_box)) + UI_PushDF(Parent, UI_BuildRow()) { UI_BuildSpacer(window_padding, Axis_X); - UI_SetDF(Parent, UI_BuildColumn()) + UI_PushDF(Parent, UI_BuildColumn()) { //- Header - // UI_SetDF(BackgroundColor, Color_Red) + // UI_PushDF(BackgroundColor, Color_Red) // UI_SetNext(BorderColor, Color_Red); // UI_SetNext(BorderSize, 1); UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetDF(Height, header_height) - UI_SetDF(Parent, UI_BuildBoxEx(UI_KeyF("profiler header"))) + UI_PushDF(Height, header_height) + UI_PushDF(Parent, UI_BuildBoxEx(UI_KeyF("profiler header"))) { - UI_SetDF(TextColor, theme.col.hint) + UI_PushDF(TextColor, theme.col.hint) UI_BuildLabelF("Profiler"); } @@ -6002,7 +6076,7 @@ void V_TickForever(WaveLaneCtx *lane) //- Graph // UI_SetNext(BackgroundColor, Color_Cyan); UI_SetNext(Height, graph_height); - UI_SetDF(Parent, UI_BuildBoxEx(profiler_graph_box)) + UI_PushDF(Parent, UI_BuildBoxEx(profiler_graph_box)) { } // UI_BuildDivider(UI_Px(1, 1), theme.col.divider, Axis_Y); @@ -6018,10 +6092,10 @@ void V_TickForever(WaveLaneCtx *lane) // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_CaptureThroughChildren | UI_BoxFlag_Scissor); UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_CaptureThroughChildren); // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetDF(Parent, UI_BuildColumnEx(main_box)) + UI_PushDF(Parent, UI_BuildColumnEx(main_box)) { //- Active area background - UI_SetDF(Opacity, 0.75) + UI_PushDF(Opacity, 0.75) { f64 aabg_left_ns = MaxF64(0, profiler->view_ns); f64 aabg_right_ns = MinF64(frame->time_ns, view_end_ns); @@ -6055,8 +6129,8 @@ void V_TickForever(WaveLaneCtx *lane) for (VisTrack *vis_track = first_vis_track; vis_track; vis_track = vis_track->next) { UI_SetNext(Height, track_height); - UI_SetDF(Tag, HashF("vis track %F", FmtUint(vis_track->id))) - UI_SetDF(Parent, UI_BuildColumn()) + UI_PushDF(Tag, HashF("vis track %F", FmtUint(vis_track->id))) + UI_PushDF(Parent, UI_BuildColumn()) { //- Zone rows UI_Key *zone_row_boxes = PushStructs(frame->arena, UI_Key, vis_track->rows_count); @@ -6066,7 +6140,7 @@ void V_TickForever(WaveLaneCtx *lane) zone_row_boxes[zone_row_box_idx] = zone_row_box; // UI_SetNext(Height, zone_height); UI_SetNext(Height, zone_height); - UI_SetDF(Parent, UI_BuildRowEx(zone_row_box)) + UI_PushDF(Parent, UI_BuildRowEx(zone_row_box)) { } } @@ -6133,11 +6207,7 @@ void V_TickForever(WaveLaneCtx *lane) String zone_text = zone->name; if (is_collapsed) { - zone_text = Zstr; - if (zone->collapsed_count > 1) - { - zone_text = StringF(frame->arena, "%F", FmtUint(zone->collapsed_count)); - } + zone_text = StringF(frame->arena, "%F", FmtUint(zone->collapsed_count)); zone_text_color = collapsed_text_color; zone_line_color = collapsed_line_color; @@ -6168,6 +6238,11 @@ void V_TickForever(WaveLaneCtx *lane) } + if (zone_len_px < zone_name_hide_threshold_px) + { + zone_text.len = 0; + } + zone_color_bd = LerpSrgb(zone_color_bd, Color_White, zone_hovered * !is_collapsed); zone_text_color = LerpSrgb(zone_text_color, Color_White, zone_hovered); zone_line_color = LerpSrgb(zone_line_color, Color_White, zone_hovered); @@ -6179,7 +6254,9 @@ void V_TickForever(WaveLaneCtx *lane) // f32 top_zag_information_density = 10; f32 top_zag_information_density = zone_collapse_threshold_px; - f32 zag_intensity = SmoothstepF32(0, top_zag_information_density, collapsed_zones_per_px); + // f32 zag_intensity = SmoothstepF32(0, top_zag_information_density, collapsed_zones_per_px); + // f32 zag_intensity = 1; + f32 zag_intensity = 0.3; // f32 zag_intensity = TweakFloat("RAAAAAAAAAAAAAH", 1, 0, 1); f32 period_max = 20; @@ -6206,75 +6283,62 @@ void V_TickForever(WaveLaneCtx *lane) UI_BoxFlag_Scissor ); UI_SetNext(Parent, zone_row_box); - UI_SetDF(OrFlags, UI_Top(OrFlags) | (UI_BoxFlag_DontTruncateText * !!(is_collapsed))) - // UI_SetDF(OmitFlags, UI_Top(OmitFlags) | (UI_BoxFlag_Scissor * !!(is_collapsed))) - // UI_SetDF(ZagPeriod, UI_Top(FontSize) * 1) - // UI_SetDF(ZagPeriod, (collapsed_zones_per_px * UI_Top(FontSize)) * 0.1) - // UI_SetDF(ZagPeriod, collapsed_zones_per_px / (UI_Top(FontSize) * 1)) - UI_SetDF(ZagPeriod, zag_period) - UI_SetDF(ZagThickness, 1.5) - UI_SetDF(ZagRoundness, 0) - UI_SetDF(ZagAmplitude, zag_amplitude) - UI_SetDF(Parent, UI_BuildRowEx(zone_box)) + // UI_PushDF(OrFlags, UI_Top(OrFlags) | (UI_BoxFlag_DontTruncateText * !!(is_collapsed))) + // UI_PushDF(OmitFlags, UI_Top(OmitFlags) | (UI_BoxFlag_Scissor * !!(is_collapsed))) + // UI_PushDF(ZagPeriod, UI_Top(FontSize) * 1) + // UI_PushDF(ZagPeriod, (collapsed_zones_per_px * UI_Top(FontSize)) * 0.1) + // UI_PushDF(ZagPeriod, collapsed_zones_per_px / (UI_Top(FontSize) * 1)) + UI_PushDF(ZagPeriod, zag_period) + UI_PushDF(ZagThickness, 1.5) + UI_PushDF(ZagRoundness, 1) + UI_PushDF(ZagAmplitude, zag_amplitude) + UI_PushDF(Parent, UI_BuildRowEx(zone_box)) { - // Left collapsed lines if (is_collapsed) { - // // Vertical line - // { - // UI_SetDF(Opacity, 1.0 - zone_hovered) - // UI_SetNext(BackgroundColor, collapsed_line_color); - // UI_SetNext(Width, collapsed_line_size); - // UI_SetNext(Height, UI_Grow(1, 0)); - // UI_BuildBox(); - // } - - // Zag - { - UI_SetNext(Width, UI_Grow(1, 0)); - UI_SetNext(ZagColor, zone_line_color); - UI_BuildBox(); - } + // Left zag + UI_SetNext(Width, UI_Grow(1, 0)); + UI_SetNext(ZagColor, zone_line_color); + UI_BuildBox(); + } + else + { + UI_SetNext(Width, UI_Px(3, 1)); + UI_BuildBox(); } - // Zone name - // if (zone_len_px > zone_collapse_threshold_px * 3) + if (zone_text.len > 0) { + // Zone name + // if (zone_len_px > zone_collapse_threshold_px * 3) + { + if (is_collapsed) + { + UI_SetNext(Width, UI_Shrink(0, 1)); + UI_SetNext(ChildAlignment, UI_Region_Center); + } + else + { + UI_SetNext(ChildAlignment, UI_Region_Left); + UI_SetNext(Width, UI_Grow(1, 0)); + } + UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); + UI_SetNext(TextColor, zone_text_color); + UI_SetNext(Text, zone_text); + UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_DontTruncateText); + UI_BuildRow(); + } + + // Right collapsed lines if (is_collapsed) { - UI_SetNext(Width, UI_Shrink(0, 1)); + // Right zag + { + UI_SetNext(Width, UI_Grow(1, 0)); + UI_SetNext(ZagColor, zone_line_color); + UI_BuildBox(); + } } - else - { - UI_SetNext(Width, UI_Shrink(0, 0)); - } - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); - UI_SetNext(TextColor, zone_text_color); - UI_SetNext(Text, zone_text); - UI_SetNext(Flags, UI_BoxFlag_DrawText); - UI_BuildRow(); - } - - // Right collapsed lines - if (is_collapsed) - { - // Zag - { - UI_SetNext(Width, UI_Grow(1, 0)); - UI_SetNext(ZagColor, zone_line_color); - UI_BuildBox(); - } - - // // Vertical line - // { - // UI_SetDF(Opacity, 1.0 - zone_hovered) - // UI_SetNext(BackgroundColor, collapsed_line_color); - // UI_SetNext(Width, collapsed_line_size); - // UI_SetNext(Height, UI_Grow(1, 0)); - // UI_SetNext(Anchor, UI_Region_Right); - // UI_BuildBox(); - // } } } } @@ -6287,7 +6351,7 @@ void V_TickForever(WaveLaneCtx *lane) //- Ruler - UI_SetDF(Opacity, profiler->ruler_opacity) + UI_PushDF(Opacity, profiler->ruler_opacity) { { f64 ruler_left_ns = MinF64(profiler->ruler_start_ns, profiler->cursor_ns); @@ -6311,7 +6375,7 @@ void V_TickForever(WaveLaneCtx *lane) { // UI_SetNext(BorderSize, 1); // UI_SetNext(BorderColor, Color_White); - // UI_SetDF(Opacity, profiler->ruler_opacity) + // UI_PushDF(Opacity, profiler->ruler_opacity) UI_SetNext(Width, ruler_width); UI_SetNext(FloatingPos, ruler_pos); UI_SetNext(BackgroundColor, ruler_color); @@ -6365,15 +6429,15 @@ void V_TickForever(WaveLaneCtx *lane) UI_SetNext(Anchor, UI_Region_TopLeft); UI_SetNext(FloatingPos, tooltip_pos); UI_SetNext(Flags, UI_BoxFlag_Floating); - UI_SetDF(Width, UI_Shrink(0, 1)) - UI_SetDF(Height, UI_Shrink(0, 1)) - UI_SetDF(Parent, UI_BuildRowEx(tooltip_box)) + UI_PushDF(Width, UI_Shrink(0, 1)) + UI_PushDF(Height, UI_Shrink(0, 1)) + UI_PushDF(Parent, UI_BuildRowEx(tooltip_box)) { UI_BuildSpacer(window_padding, Axis_X); UI_SetNext(Width, UI_Shrink(0, 1)); UI_SetNext(Height, UI_Shrink(0, 1)); - UI_SetDF(Parent, UI_BuildColumn()) + UI_PushDF(Parent, UI_BuildColumn()) { UI_BuildSpacer(window_padding, Axis_Y); @@ -6400,22 +6464,44 @@ void V_TickForever(WaveLaneCtx *lane) if (show_hovered_zone) { VisZone *zone = hovered_zone; - UI_SetDF(Parent, UI_BuildRow()) + UI_PushDF(Parent, UI_BuildRow()) { i64 elapsed_ns = zone->end_ns - zone->start_ns; - UI_SetDF(Parent, UI_BuildColumn()) + UI_PushDF(Parent, UI_BuildColumn()) { UI_BuildLabelF("%F ", FmtTimeNs(elapsed_ns, .p = 2)); - if (zone->collapsed_count > 1) + if (zone->collapsed_count > 0) { - UI_SetDF(Parent, UI_BuildRow()) + UI_PushDF(Parent, UI_BuildRow()) { - UI_SetNext(TextColor, theme.col.hint); - UI_BuildLabelF("Zones too small to display"); + if (zone->collapsed_count == 1) + { + // // UI_BuildLabelF(" (%F)", FmtUint(zone->collapsed_count)); + // UI_SetNext(TextColor, theme.col.hint); + // UI_BuildLabelF("%F", FmtString(zone->name)); - UI_SetNext(TextColor, collapsed_text_color); - UI_BuildLabelF(" (%F)", FmtUint(zone->collapsed_count)); + // UI_SetNext(TextColor, collapsed_text_color); + // UI_BuildLabelF(" (Too small to display)"); + + UI_SetNext(TextColor, collapsed_text_color); + UI_BuildLabelF("1 zone too small to display: "); + UI_SetNext(TextColor, theme.col.hint); + UI_BuildLabelF("%F", FmtString(zone->name)); + } + else + { + // UI_SetNext(TextColor, theme.col.hint); + // UI_BuildLabelF("Zones too small to display"); + + // UI_SetNext(TextColor, collapsed_text_color); + // UI_BuildLabelF(" (%F)", FmtUint(zone->collapsed_count)); + + + // UI_SetNext(TextColor, theme.col.hint); + UI_SetNext(TextColor, collapsed_text_color); + UI_BuildLabelF("%F zones too small to display", FmtUint(zone->collapsed_count)); + } } } else @@ -6438,17 +6524,17 @@ void V_TickForever(WaveLaneCtx *lane) // UI_BuildSpacer(window_padding, Axis_Y); //- Footer - UI_SetDF(Height, footer_height) - UI_SetDF(ChildAlignment, UI_Region_Center) - UI_SetDF(Parent, UI_BuildRow()) + UI_PushDF(Height, footer_height) + UI_PushDF(ChildAlignment, UI_Region_Center) + UI_PushDF(Parent, UI_BuildRow()) { if (IsUnoptimized) { - UI_SetDF(Width, UI_Shrink(0, 1)) - UI_SetDF(Height, UI_Shrink(0, 1)) - UI_SetDF(ChildAlignment, UI_Region_Left) - UI_SetDF(TextColor, theme.col.warn) - UI_SetDF(Parent, UI_BuildRow()) + UI_PushDF(Width, UI_Shrink(0, 1)) + UI_PushDF(Height, UI_Shrink(0, 1)) + UI_PushDF(ChildAlignment, UI_Region_Left) + UI_PushDF(TextColor, theme.col.warn) + UI_PushDF(Parent, UI_BuildRow()) { UI_BuildIcon(theme.icon_font, UI_Icon_Warning); // UI_BuildIcon(theme.icon_font, UI_Icon_Info); @@ -7084,6 +7170,67 @@ void V_TickForever(WaveLaneCtx *lane) UI_PopCp(UI_TopCp()); } + ////////////////////////////// + //- Build player names UI + + { + UI_PushDF(Font, theme.player_name_font) + UI_PushDF(FontSize, 12) + UI_PushDF(Width, UI_Shrink(3, 1)) + UI_PushDF(Height, UI_Shrink(2, 1)) + UI_PushDF(BackgroundColor, Color_Black) + UI_PushDF(ChildAlignment, UI_Region_Center) + UI_PushDF(Opacity, 0.95) + UI_PushDF(Rounding, UI_Rgrow(0.25)) + // UI_PushDF(BackgroundColor, Color_Cyan) + UI_PushDF(FontSize, UI_Top(FontSize) * 1.5) + // UI_PushDF(TextColor, SrgbFromHsv(32, 1, 1)) + UI_PushDF(TextColor, SrgbFromHsv(32, 0.75, 1)) + UI_PushDF(Parent, vis_game_box) + UI_PushDF(Anchor, UI_Region_Bottom) + UI_PushDF(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DrawText | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY) + { + for (P_Ent *player = P_FirstEnt(local_frame); !P_IsEntNil(player); player = P_NextEnt(player)) + { + if (player->is_player) + { + P_Ent *guy = P_EntFromKey(local_frame, player->guy); + String name = P_StringFromEnt(player); + if (guy->is_guy && name.len > 0) + { + Vec2 guy_world_pos = guy->xf.t; + guy_world_pos.y -= UI_Top(FontSize) * 0.01; + + Vec2 guy_screen_pos = MulAffineVec2(frame->af.world_to_screen, guy_world_pos); + + Vec2 text_pos = Zi; + text_pos.x = guy_screen_pos.x; + text_pos.y = guy_screen_pos.y; + + UI_PushDF(Text, name) + { + // Name box + // UI_SetNext(TextColor, Color_Transparent); + UI_SetNext(FloatingPos, text_pos); + UI_PushDF(Text, name) + UI_PushDF(Parent, UI_BuildBox()) + { + // // Drop-shadow + // UI_SetNext(TextColor, Color_Black); + // UI_SetNext(FloatingPos, AddVec2(text_pos, VEC2(2, 2))); + // UI_BuildBox(); + + // Name text + // UI_BuildBox(); + } + + } + } + } + } + } + } + ////////////////////////////// //- Build console UI @@ -7621,11 +7768,11 @@ void V_TickForever(WaveLaneCtx *lane) .name = StringF(frame->arena, "Gpu frame [%F]", FmtSint(frame->tick)) ); - // Set initial constants + // Init registers V_GpuFlag gpu_flags = V_GpuFlag_None; - G_SetConstant(cl, V_GpuConst_Flags, gpu_flags); - G_SetConstant(cl, V_GpuConst_Frame, gpu_frame); - G_SetConstant(cl, V_GpuConst_NoiseTex, G_BasicNoise3D()); + G_SetRegister(cl, V_GpuReg_Flags, gpu_flags); + G_SetRegister(cl, V_GpuReg_Frame, gpu_frame); + G_SetRegister(cl, V_GpuReg_NoiseTex, G_BasicNoise3D()); } G_Sync(cl); @@ -7657,14 +7804,14 @@ void V_TickForever(WaveLaneCtx *lane) // Backdrop passes { i32 mips_count = G_CountMips(frame->backdrop_chain); - G_SetConstant(cl, V_GpuConst_MipsCount, mips_count); + G_SetRegister(cl, V_GpuReg_MipsCount, mips_count); //- Downsample for (i32 mip_idx = 0; mip_idx < mips_count; ++mip_idx) { Vec2I32 down_dims = G_DimsFromMip2D(G_Count2D(frame->backdrop_chain), mip_idx); - G_SetConstant(cl, V_GpuConst_MipIdx, mip_idx); + G_SetRegister(cl, V_GpuReg_MipIdx, mip_idx); G_Compute2D(cl, V_BackdropDownCS, down_dims); G_Sync(cl); @@ -7675,7 +7822,7 @@ void V_TickForever(WaveLaneCtx *lane) { Vec2I32 up_dims = G_DimsFromMip2D(G_Count2D(frame->backdrop_chain), mip_idx); - G_SetConstant(cl, V_GpuConst_MipIdx, mip_idx); + G_SetRegister(cl, V_GpuReg_MipIdx, mip_idx); G_Compute2D(cl, V_BackdropUpCS, up_dims); G_Sync(cl); @@ -7746,7 +7893,7 @@ void V_TickForever(WaveLaneCtx *lane) { i32 mips_count = G_CountMips(frame->bloom_chain) + 1; - G_SetConstant(cl, V_GpuConst_MipsCount, mips_count); + G_SetRegister(cl, V_GpuReg_MipsCount, mips_count); // NOTE: Because bloom mip chain starts at half screen size, mip_idx 0 // actually represents the screen texture, while mip_idx - 1 represents @@ -7758,7 +7905,7 @@ void V_TickForever(WaveLaneCtx *lane) { Vec2I32 down_dims = G_DimsFromMip2D(G_Count2D(frame->screen), mip_idx); - G_SetConstant(cl, V_GpuConst_MipIdx, mip_idx); + G_SetRegister(cl, V_GpuReg_MipIdx, mip_idx); G_Compute2D(cl, V_BloomDownCS, down_dims); G_Sync(cl); @@ -7770,7 +7917,7 @@ void V_TickForever(WaveLaneCtx *lane) { Vec2I32 up_dims = G_DimsFromMip2D(G_Count2D(frame->screen), mip_idx); - G_SetConstant(cl, V_GpuConst_MipIdx, mip_idx); + G_SetRegister(cl, V_GpuReg_MipIdx, mip_idx); G_Compute2D(cl, V_BloomUpCS, up_dims); G_Sync(cl); diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 36050d36..6d16d53c 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_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \ X(toggle_console, Toggle Developer Console, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent ), ) \ X(toggle_timeline, Toggle Debug Timeline, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent, .alt = 1, .ctrl = 1 ), ) \ - X(toggle_profiler, Toggle Profiler, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent, .alt = 1 ), ) \ + X(toggle_profiler, Toggle Profiler, V_CmdDescFlag_None, V_HOTKEY( 0 ), ) \ X(pause_timeline, Pause Debug Timeline, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_E ), ) \ X(lock_timeline, Lock Debug Timeline, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_R ), ) \ X(toggle_fullscreen, Toggle Fullscreen Mode, V_CmdDescFlag_None, V_HOTKEY( Button_Enter, .alt = 1 ) ) \ @@ -35,6 +35,7 @@ Struct(V_WidgetTheme) GC_FontKey ui_font; GC_FontKey chat_font; GC_FontKey icon_font; + GC_FontKey player_name_font; f32 ui_font_size; f32 chat_font_size; @@ -169,12 +170,13 @@ Enum(V_TextboxDeltaFlag) V_TextboxDeltaFlag_OnlyNavIfSelectionEmpty = (1 << 1), V_TextboxDeltaFlag_CopySelectionToClipboard = (1 << 2), V_TextboxDeltaFlag_InheritTextFromClipboard = (1 << 3), - V_TextboxDeltaFlag_NavDirect = (1 << 4), - V_TextboxDeltaFlag_NavLeft = (1 << 5), - V_TextboxDeltaFlag_NavRight = (1 << 6), - V_TextboxDeltaFlag_NavWord = (1 << 7), - V_TextboxDeltaFlag_NavLine = (1 << 8), - V_TextboxDeltaFlag_NavSelect = (1 << 9), + V_TextboxDeltaFlag_NavDirectStart = (1 << 4), + V_TextboxDeltaFlag_NavDirectEnd = (1 << 5), + V_TextboxDeltaFlag_NavLeft = (1 << 6), + V_TextboxDeltaFlag_NavRight = (1 << 7), + V_TextboxDeltaFlag_NavWord = (1 << 8), + V_TextboxDeltaFlag_NavLine = (1 << 9), + V_TextboxDeltaFlag_NavSelect = (1 << 10), }; Struct(V_TextboxDelta) @@ -226,6 +228,10 @@ Struct(V_Palette) Vec2 drag_cursor; f32 drag_scroll; + f32 caret_start_px; + f32 caret_end_px; + f32 text_scroll_px; + V_TextboxState search_state; }; @@ -294,9 +300,6 @@ Struct(V_Profiler) f64 target_ns_per_px; f64 ns_per_px; - f64 zoom_level; - f64 target_zoom_level; - f64 cursor_ns; f64 drag_cursor_px; }; @@ -443,6 +446,8 @@ Struct(V_Ctx) V_ZoneTrack *first_zone_track; V_ZoneTrack *last_zone_track; + P_PublicState public_state; + i64 panels_count; i64 windows_count; V_Panel *root_panel; @@ -502,8 +507,8 @@ void V_DrawPoint(Vec2 p, Vec4 srgb); //////////////////////////////////////////////////////////// //~ Text box -void V_ApplyTextboxDelta(V_TextboxState *tb, V_TextboxDelta delta); -void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas); +V_TextboxDeltaFlag V_ApplyTextboxDelta(V_TextboxState *tb, V_TextboxDelta delta); +V_TextboxDeltaFlag V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas); String V_StringFromTextbox(Arena *arena, V_TextboxState *tb); String V_StringFromTextboxSelection(Arena *arena, V_TextboxState *tb); diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index db1910f3..fd34ffe2 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -3,7 +3,7 @@ f32 V_RandFromPos(Vec3 pos) { - Texture3D noise3d = G_Deref(V_GpuConst_NoiseTex, Texture3D); + Texture3D noise3d = G_Deref(V_GpuReg_NoiseTex, Texture3D); u32 noise = noise3d[(Vec3U32)pos % G_BasicNoiseDims]; f32 rand = Norm16(noise); return rand; @@ -56,7 +56,7 @@ Vec4 V_ColorFromParticle(V_ParticleDesc desc, u32 particle_idx, u32 density) ComputeShader(V_BuildProfilerGraphCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; RWTexture2D graph = G_Deref(frame.profiler_graph, RWTexture2D); StructuredBuffer profiler_frames = G_Deref(frame.profiler_frames, StructuredBuffer); @@ -84,7 +84,7 @@ ComputeShader(V_BuildProfilerGraphCS) //- Prepare shade ComputeShader(V_PrepareShadeCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; RWTexture2D shade = G_Deref(frame.shade, RWTexture2D); Vec2 shade_pos = SV_DispatchThreadID + 0.5; if (all(shade_pos < G_Count2D(shade))) @@ -97,7 +97,7 @@ ComputeShader(V_PrepareShadeCS) //- Prepare cells ComputeShader(V_PrepareCellsCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; Texture2D tiles = G_Deref(frame.tiles, Texture2D); RWTexture2D stains = G_Deref(frame.stains, RWTexture2D); RWTexture2D dry_stains = G_Deref(frame.dry_stains, RWTexture2D); @@ -186,7 +186,7 @@ ComputeShader(V_PrepareCellsCS) //- Clear particles ComputeShader(V_ClearParticlesCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; RWStructuredBuffer particles = G_Deref(frame.particles, RWStructuredBuffer); u32 particle_idx = SV_DispatchThreadID; if (particle_idx < V_ParticlesCap) @@ -203,10 +203,10 @@ ComputeShader(V_ClearParticlesCS) ComputeShader(V_BackdropDownCS) { - i32 mip_idx = V_GpuConst_MipIdx; + i32 mip_idx = V_GpuReg_MipIdx; b32 is_first_pass = mip_idx == 0; - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror], SamplerState); Texture2D bd_up = ( is_first_pass ? @@ -263,9 +263,9 @@ ComputeShader(V_BackdropDownCS) ComputeShader(V_BackdropUpCS) { - i32 mip_idx = V_GpuConst_MipIdx; + i32 mip_idx = V_GpuReg_MipIdx; - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; Texture2D bd_down = G_Deref(frame.backdrop_chain, Texture2D, mip_idx + 1); RWTexture2D bd_up = G_Deref(frame.backdrop_chain, RWTexture2D, mip_idx); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror], SamplerState); @@ -323,7 +323,7 @@ ComputeShader(V_BackdropUpCS) VertexShader(V_QuadVS, V_QuadPSInput) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; StructuredBuffer quads = G_Deref(frame.quads, StructuredBuffer); V_Quad quad = quads[SV_InstanceID]; @@ -347,7 +347,7 @@ VertexShader(V_QuadVS, V_QuadPSInput) PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); RWTexture2D occluders = G_Deref(frame.occluders, RWTexture2D); @@ -383,7 +383,7 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) ComputeShader(V_EmitParticlesCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; StructuredBuffer emitters = G_Deref(frame.emitters, StructuredBuffer); RWStructuredBuffer particles = G_Deref(frame.particles, RWStructuredBuffer); @@ -414,7 +414,7 @@ ComputeShader(V_EmitParticlesCS) ComputeShader(V_SimParticlesCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; Texture2D tiles = G_Deref(frame.tiles, Texture2D); RWStructuredBuffer particles = G_Deref(frame.particles, RWStructuredBuffer); Texture2D occluders = G_Deref(frame.occluders, Texture2D); @@ -691,7 +691,7 @@ ComputeShader(V_SimParticlesCS) ComputeShader(V_ShadeCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); Texture2D tiles = G_Deref(frame.tiles, Texture2D); Texture2D albedo_tex = G_Deref(frame.albedo, Texture2D); @@ -727,7 +727,7 @@ ComputeShader(V_ShadeCS) ComputeShader(V_CompositeCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; // Texture2D shade_tex = G_Deref(frame.shade, Texture2D); SamplerState point_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); @@ -1128,10 +1128,10 @@ ComputeShader(V_CompositeCS) ComputeShader(V_BloomDownCS) { - i32 mip_idx = V_GpuConst_MipIdx; + i32 mip_idx = V_GpuReg_MipIdx; b32 is_first_pass = mip_idx == 1; - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); RWTexture2D bloom_down = G_Deref(frame.bloom_chain, RWTexture2D, mip_idx - 1); @@ -1198,9 +1198,9 @@ ComputeShader(V_BloomDownCS) ComputeShader(V_BloomUpCS) { - i32 mip_idx = V_GpuConst_MipIdx; + i32 mip_idx = V_GpuReg_MipIdx; - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); Texture2D bloom_down = G_Deref(frame.bloom_chain, Texture2D, mip_idx); @@ -1261,7 +1261,7 @@ ComputeShader(V_BloomUpCS) ComputeShader(V_FinalizeCS) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); Texture2D bloom_tex = G_Deref(frame.bloom_chain, Texture2D); RWTexture2D screen_tex = G_Deref(frame.screen, RWTexture2D); @@ -1294,7 +1294,7 @@ ComputeShader(V_FinalizeCS) VertexShader(V_DVertVS, V_DVertPSInput) { - V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer)[0]; StructuredBuffer verts = G_Deref(frame.dverts, StructuredBuffer); V_DVert vert = verts[SV_VertexID]; diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index e4e4325f..a067d3bc 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -4,18 +4,18 @@ // #define V_ParticlesCap Mebi(16) //////////////////////////////////////////////////////////// -//~ Constant types +//~ Shader register types Enum(V_GpuFlag) { V_GpuFlag_None = 0, }; -G_DeclConstant(V_GpuFlag, V_GpuConst_Flags, 0); -G_DeclConstant(G_BufferRef, V_GpuConst_Frame, 1); -G_DeclConstant(G_TextureRef, V_GpuConst_NoiseTex, 2); -G_DeclConstant(i32, V_GpuConst_MipsCount, 3); -G_DeclConstant(i32, V_GpuConst_MipIdx, 4); +G_DeclRegister(V_GpuFlag, V_GpuReg_Flags, 0); +G_DeclRegister(G_BufferRef, V_GpuReg_Frame, 1); +G_DeclRegister(G_TextureRef, V_GpuReg_NoiseTex, 2); +G_DeclRegister(i32, V_GpuReg_MipsCount, 3); +G_DeclRegister(i32, V_GpuReg_MipIdx, 4); //////////////////////////////////////////////////////////// //~ Particle types diff --git a/src/proto/proto.c b/src/proto/proto.c index 7635d5a1..44dd08ba 100644 --- a/src/proto/proto.c +++ b/src/proto/proto.c @@ -41,7 +41,7 @@ void PT_RunForever(WaveLaneCtx *lane) window_frame.draw_size, .flags = G_MemoryFlag_AllowTextureRW | G_MemoryFlag_AllowTextureDraw ); - G_SetConstant(cl, PT_ShaderConst_Frame, G_PushStructFromCpu(cl, gpu_frame_arena, frame)); + G_SetRegister(cl, PT_ShaderReg_Frame, G_PushStructFromCpu(cl, gpu_frame_arena, frame)); } G_Sync(cl); diff --git a/src/proto/proto_gpu.g b/src/proto/proto_gpu.g index 6b8fd989..28d94a4f 100644 --- a/src/proto/proto_gpu.g +++ b/src/proto/proto_gpu.g @@ -3,7 +3,7 @@ ComputeShader(PT_TestCS) { - PT_SharedFrame frame = G_Deref(PT_ShaderConst_Frame, StructuredBuffer)[0]; + PT_SharedFrame frame = G_Deref(PT_ShaderReg_Frame, StructuredBuffer)[0]; RWTexture2D target_tex = G_Deref(frame.compute_target, RWTexture2D); Vec2U32 target_tex_size = G_Count2D(target_tex); @@ -35,7 +35,7 @@ VertexShader(PT_BlitVS, PT_BlitPSInput) PixelShader(PT_BlitPS, PT_BlitPSOutput, PT_BlitPSInput input) { - PT_SharedFrame frame = G_Deref(PT_ShaderConst_Frame, StructuredBuffer)[0]; + PT_SharedFrame frame = G_Deref(PT_ShaderReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.sampler, SamplerState); Texture2D src = G_Deref(frame.compute_target, Texture2D); Texture3D noise = G_Deref(frame.noise_tex, Texture3D); diff --git a/src/proto/proto_shared.cgh b/src/proto/proto_shared.cgh index 1c0e90c7..48aafcb1 100644 --- a/src/proto/proto_shared.cgh +++ b/src/proto/proto_shared.cgh @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// -//~ Constants +//~ Shader register types -G_DeclConstant(G_BufferRef, PT_ShaderConst_Frame, 0); +G_DeclConstant(G_BufferRef, PT_ShaderReg_Frame, 0); //////////////////////////////////////////////////////////// //~ State types diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index e1f7beb6..fb818c55 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2069,8 +2069,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync) .name = Lit("UI gpu frame") ); - // Init constants - G_SetConstant(UI.cl, UI_GpuConst_Frame, gpu_frame_buff); + // Init registers + G_SetRegister(UI.cl, UI_GpuReg_Frame, gpu_frame_buff); } // Sync @@ -2106,7 +2106,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync) { G_ProfZoneDF(UI.cl, "UI debug rects") { - G_SetConstant(UI.cl, UI_GpuConst_DebugDraw, 1); + G_SetRegister(UI.cl, UI_GpuReg_DebugDraw, 1); G_Draw( UI.cl, UI_DRectVS, UI_DRectPS, @@ -2115,7 +2115,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync) draw_viewport, draw_scissor, G_DrawMode_WireTriangleList ); - G_SetConstant(UI.cl, UI_GpuConst_DebugDraw, 0); + G_SetRegister(UI.cl, UI_GpuReg_DebugDraw, 0); } } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 0f7d0604..5356cffb 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -524,7 +524,7 @@ UI_Style UI_PopStyle(UI_StyleDesc desc); #define UI_PeekTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, __VA_ARGS__)).name #define UI_Top(name, ...) UI_PopStyle(UI_STYLEDESC(name, .use = 1, __VA_ARGS__)).name -#define UI_SetDF(name, ...) DeferFor(UI_Push(name, __VA_ARGS__), UI_Pop(name)) +#define UI_PushDF(name, ...) DeferFor(UI_Push(name, __VA_ARGS__), UI_Pop(name)) #define UI_PushCopy(name, src, ...) do { \ UI_StyleDesc _new = src; \ diff --git a/src/ui/ui_gpu.g b/src/ui/ui_gpu.g index 66f4e0ac..2d394cfa 100644 --- a/src/ui/ui_gpu.g +++ b/src/ui/ui_gpu.g @@ -6,7 +6,7 @@ VertexShader(UI_DRectVS, UI_DRectPSInput) { - UI_GpuFrame frame = G_Deref(UI_GpuConst_Frame, StructuredBuffer)[0]; + UI_GpuFrame frame = G_Deref(UI_GpuReg_Frame, StructuredBuffer)[0]; StructuredBuffer rects = G_Deref(frame.rects, StructuredBuffer); UI_GpuRect rect = rects[SV_InstanceID]; @@ -34,7 +34,7 @@ VertexShader(UI_DRectVS, UI_DRectPSInput) PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) { - UI_GpuFrame frame = G_Deref(UI_GpuConst_Frame, StructuredBuffer)[0]; + UI_GpuFrame frame = G_Deref(UI_GpuReg_Frame, StructuredBuffer)[0]; SamplerState sampler = G_Deref(frame.sampler, SamplerState); UI_GpuRect rect = input.rect; @@ -136,7 +136,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) } //- Finalize - if (UI_GpuConst_DebugDraw) + if (UI_GpuReg_DebugDraw) { result = input.debug_premul; } diff --git a/src/ui/ui_shared.cgh b/src/ui/ui_shared.cgh index 6b07aa63..28e550d3 100644 --- a/src/ui/ui_shared.cgh +++ b/src/ui/ui_shared.cgh @@ -1,8 +1,8 @@ //////////////////////////////////////////////////////////// -//~ Constant types +//~ Shader register types -G_DeclConstant(G_BufferRef, UI_GpuConst_Frame, 0); -G_DeclConstant(b32, UI_GpuConst_DebugDraw, 1); +G_DeclRegister(G_BufferRef, UI_GpuReg_Frame, 0); +G_DeclRegister(b32, UI_GpuReg_DebugDraw, 1); //////////////////////////////////////////////////////////// //~ Rect types