text box mouse selection & caret interpolation

This commit is contained in:
jacob 2026-04-03 00:35:07 -05:00
parent a857b39097
commit 7f3312c12a
21 changed files with 829 additions and 466 deletions

View File

@ -44,7 +44,8 @@ where /Q cl.exe || (
::- Build metaprogram ::- Build metaprogram
:meta_build :meta_build
if not exist meta.exe ( if not exist meta.exe (
echo ====== Meta Build ===== echo Metaprogram dirty since last run, rebuilding...
echo ======== Meta Build ========
%meta_build_cmd% %meta_build_cmd%
set "rc=!errorlevel!" set "rc=!errorlevel!"
if !rc! NEQ 0 ( if !rc! NEQ 0 (
@ -55,7 +56,7 @@ if not exist meta.exe (
::- Run metaprogram ::- Run metaprogram
if not "%--no_meta_run%"=="1" ( if not "%--no_meta_run%"=="1" (
echo ======== Build ======== echo =========== Build ==========
%program_build_cmd% %program_build_cmd%
set "rc=!errorlevel!" set "rc=!errorlevel!"
if !rc! NEQ 0 ( if !rc! NEQ 0 (

View File

@ -24,7 +24,7 @@
//~ Settings //~ Settings
#define PROFILING_ENABLED 1 #define PROFILING_ENABLED 0

View File

@ -537,14 +537,14 @@ void *G_CpuPointerFromBuffer(G_BufferRef buffer);
G_CommandListHandle G_PrepareCommandList(G_QueueKind queue); G_CommandListHandle G_PrepareCommandList(G_QueueKind queue);
i64 G_CommitCommandList(G_CommandListHandle cl); 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 { \ #define G_SetRegister(cl, name, value) do { \
CAT(__ShaderConstantType_,name) __src; \ CAT(__ShaderRegisterType__,name) __src; \
__src.v = value; \ __src.v = value; \
G_SetConstantEx((cl), (name), &__src, sizeof(__src)); \ G_SetRegisterEx((cl), (name), &__src, sizeof(__src)); \
} while (0) } while (0)
//- Sync //- Sync

View File

@ -517,8 +517,8 @@ void G_Bootstrap(void)
ID3D10Blob *blob = 0; ID3D10Blob *blob = 0;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
D3D12_ROOT_PARAMETER1 params[G_NumConstants] = Zi; D3D12_ROOT_PARAMETER1 params[G_NumRegisters] = Zi;
for (i32 slot = 0; slot < G_NumConstants; ++slot) for (i32 slot = 0; slot < G_NumRegisters; ++slot)
{ {
D3D12_ROOT_PARAMETER1 *param = &params[slot]; D3D12_ROOT_PARAMETER1 *param = &params[slot];
param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
@ -2498,7 +2498,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if ( if (
cmd_kind != G_D12_CmdKind_Barrier && cmd_kind != G_D12_CmdKind_Barrier &&
cmd_kind != G_D12_CmdKind_Constant && cmd_kind != G_D12_CmdKind_Register &&
cmd_kind != G_D12_CmdKind_Zone cmd_kind != G_D12_CmdKind_Zone
) )
{ {
@ -2659,24 +2659,24 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
b32 descriptor_heaps_set = 0; b32 descriptor_heaps_set = 0;
G_D12_Pipeline *bound_pipeline = 0; G_D12_Pipeline *bound_pipeline = 0;
// Constants state // Registers state
u64 slotted_constants[G_NumConstants]; u64 slotted_registers[G_NumRegisters];
u64 bound_compute_constants[G_NumConstants]; u64 bound_compute_registers[G_NumRegisters];
u64 bound_graphics_constants[G_NumConstants]; u64 bound_graphics_registers[G_NumRegisters];
for (i32 slot = 0; slot < countof(slotted_constants); ++slot) { slotted_constants[slot] = 0; } // Zero-initialize all slots 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_constants); ++slot) { bound_compute_constants[slot] = U64Max; } for (i32 slot = 0; slot < countof(bound_compute_registers); ++slot) { bound_compute_registers[slot] = U64Max; }
for (i32 slot = 0; slot < countof(bound_graphics_constants); ++slot) { bound_graphics_constants[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)) 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); b32 tweak_b32 = TweakBool("Shader tweak-bool", 1);
f32 tweak_f32 = TweakFloat("Shader tweak-float", 1, 0, 1); f32 tweak_f32 = TweakFloat("Shader tweak-float", 1, 0, 1);
slotted_constants[G_ShaderConst_TweakB32] = tweak_b32; slotted_registers[G_ShaderReg_TweakB32] = tweak_b32;
CopyBytes(&slotted_constants[G_ShaderConst_TweakF32], &tweak_f32, sizeof(tweak_f32)); CopyBytes(&slotted_registers[G_ShaderReg_TweakF32], &tweak_f32, sizeof(tweak_f32));
} }
// Rasterizer state // Rasterizer state
@ -2812,15 +2812,15 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
G_D12_Cmd *cmd = bcn->cmd; G_D12_Cmd *cmd = bcn->cmd;
switch (cmd->kind) switch (cmd->kind)
{ {
//- Constant //- Register
case G_D12_CmdKind_Constant: case G_D12_CmdKind_Register:
{ {
i32 slot = cmd->constant.slot; i32 slot = cmd->reg.slot;
u32 value = cmd->constant.value; u32 value = cmd->reg.value;
if (slot >= 0 && slot < countof(slotted_constants)) if (slot >= 0 && slot < countof(slotted_registers))
{ {
slotted_constants[slot] = value; slotted_registers[slot] = value;
} }
} break; } break;
@ -2929,12 +2929,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
} }
// Update root constants // 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); ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(d3d_cl, slot, slotted_registers[slot], 0);
bound_compute_constants[slot] = slotted_constants[slot]; bound_compute_registers[slot] = slotted_registers[slot];
} }
} }
@ -3040,12 +3040,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
} }
// Update root constants // 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); ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(d3d_cl, slot, slotted_registers[slot], 0);
bound_graphics_constants[slot] = slotted_constants[slot]; bound_graphics_registers[slot] = slotted_registers[slot];
} }
} }
@ -3248,15 +3248,15 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
return completion_target; 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_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl); G_D12_Cmd *cmd = G_D12_PushCmd(cl);
cmd->kind = G_D12_CmdKind_Constant; cmd->kind = G_D12_CmdKind_Register;
cmd->constant.slot = slot; cmd->reg.slot = slot;
CopyBytes(&cmd->constant.value, src_32bit, MinU32(size, 4)); CopyBytes(&cmd->reg.value, src_32bit, MinU32(size, 4));
} }
//- Sync //- Sync

View File

@ -310,7 +310,7 @@ Enum(G_D12_EventKind)
Enum(G_D12_CmdKind) Enum(G_D12_CmdKind)
{ {
G_D12_CmdKind_None, G_D12_CmdKind_None,
G_D12_CmdKind_Constant, G_D12_CmdKind_Register,
G_D12_CmdKind_Barrier, G_D12_CmdKind_Barrier,
G_D12_CmdKind_Zone, G_D12_CmdKind_Zone,
G_D12_CmdKind_CopyBytes, G_D12_CmdKind_CopyBytes,
@ -330,7 +330,7 @@ Struct(G_D12_Cmd)
{ {
i32 slot; i32 slot;
u32 value; u32 value;
} constant; } reg;
struct struct
{ {

View File

@ -18,44 +18,44 @@ Struct(G_SamplerRef) { G_BaseDescriptorIndex v; };
#define G_IsRefNil(r) ((r).v == 0) #define G_IsRefNil(r) ((r).v == 0)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Constant types //~ Register types
// //
// D3D12 exposes 64 root constants and Vulkan exposes 32 push constants. // D3D12 exposes 64 root constants and Vulkan exposes 32 push constants.
// Supposedly AMD hardware will start spilling constants once more than // Supposedly AMD hardware will start spilling constants once more than
// 12 are in use - https://gpuopen.com/learn/rdna-performance-guide/ // 12 are in use - https://gpuopen.com/learn/rdna-performance-guide/
// //
#define G_NumGeneralPurposeConstants (24) // Constants available for any usage #define G_NumGeneralPurposeRegisters (24) // Registers available for any usage
#define G_NumReservedConstants (4) // Constants reserved for internal usage by the GPU layer #define G_NumReservedRegisters (4) // Registers reserved for internal usage by the GPU layer
#define G_NumConstants (G_NumGeneralPurposeConstants + G_NumReservedConstants) #define G_NumRegisters (G_NumGeneralPurposeRegisters + G_NumReservedRegisters)
#if IsCpu #if IsCpu
#define G_ForceDeclConstant(type, name, slot) \ #define G_ForceDeclRegister(type, name, slot) \
enum { name = slot }; \ enum { name = slot }; \
Struct(CAT(__ShaderConstantType_,name)) { type v; } Struct(CAT(__ShaderRegisterType__,name)) { type v; }
#define G_DeclConstant(type, name, slot) \ #define G_DeclRegister(type, name, slot) \
StaticAssert(sizeof(type) <= 4); \ StaticAssert(sizeof(type) <= 4); \
StaticAssert(slot < G_NumGeneralPurposeConstants); \ StaticAssert(slot < G_NumGeneralPurposeRegisters); \
G_ForceDeclConstant(type, name, slot) G_ForceDeclRegister(type, name, slot)
#else #else
#define G_ForceDeclConstant(type, name, slot) cbuffer name : register(CAT(b,slot)) { type name; } #define G_ForceDeclRegister(type, name, slot) cbuffer name : register(CAT(b,slot)) { type name; }
#define G_DeclConstant(type, name, slot) G_ForceDeclConstant(type, name, slot) #define G_DeclRegister(type, name, slot) G_ForceDeclRegister(type, name, slot)
#endif #endif
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Reserved constants //~ Reserved registers
// The constants declared below assume this configuration is accurate for slot usage // The registers declared below assume this configuration is accurate for slot usage
StaticAssert(G_NumGeneralPurposeConstants == 24); StaticAssert(G_NumGeneralPurposeRegisters == 24);
StaticAssert(G_NumReservedConstants >= 3); StaticAssert(G_NumReservedRegisters >= 3);
G_ForceDeclConstant(G_BufferRef, G_ShaderConst_PrintBuffer, 24); G_ForceDeclRegister(G_BufferRef, G_ShaderReg_PrintBuffer, 24);
G_ForceDeclConstant(b32, G_ShaderConst_TweakB32, 25); G_ForceDeclRegister(b32, G_ShaderReg_TweakB32, 25);
G_ForceDeclConstant(f32, G_ShaderConst_TweakF32, 26); G_ForceDeclRegister(f32, G_ShaderReg_TweakF32, 26);
#if IsGpu #if IsGpu
#define G_TweakBool G_ShaderConst_TweakB32 #define G_TweakBool G_ShaderReg_TweakB32
#define G_TweakFloat G_ShaderConst_TweakF32 #define G_TweakFloat G_ShaderReg_TweakF32
#endif #endif
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -223,7 +223,7 @@ Struct(G_FmtArg)
void G_CommitPrint(G_TempPrintBuffer buff) 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) if (buff.overflowed)
{ {

View File

@ -268,151 +268,163 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
// Return rebuild code if metaprogram is dirty // Return rebuild code if metaprogram is dirty
if (lane->idx == 0) if (lane->idx == 0)
{ {
// Read old metahash b32 is_metaprogram_dirty = 0;
u64 old_metahash = 0;
if (F_IsFile(Lit("metahash.dat")))
{ {
String hashes_str = F_DataFromFile(perm, Lit("metahash.dat")); // Read old metahash
if (hashes_str.len == sizeof(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 // Compute new metahash
u64 new_metahash = 0; 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)
{ {
String file = n->s; StringList check_files = Zi;
new_metahash = MixU64s(new_metahash, OS_LastWriteTimestampFromPath(file)); {
new_metahash = HashStringEx(new_metahash , file); // 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 // 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); ExitNow(M_RebuildCode);
} }
} }
////////////////////////////// //////////////////////////////
//- Init command line //- Init environment from command line
// Layer name
{ {
CommandlineArg arg = CommandlineArgFromName(Lit("layer")); //- Layer name
String layer_name = Zi;
if (arg.name.len != 0)
{ {
layer_name = arg.value; CommandlineArg arg = CommandlineArgFromName(Lit("layer"));
} String layer_name = Zi;
else if (arg.name.len != 0)
{
layer_name = StringFromCommandlineIdx(1);
}
if (layer_name.len == 0)
{
layer_name = Lit("pp");
if (lane->idx == 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 //- Platform
{
CommandlineArg arg = CommandlineArgFromName(Lit("platform"));
if (MatchString(arg.value, Lit("windows")))
{ {
M.cmdline.target_platform = M_PlatformKind_Windows; CommandlineArg arg = CommandlineArgFromName(Lit("platform"));
} if (MatchString(arg.value, Lit("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)
{ {
M.cmdline.target_platform = M_PlatformKind_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; M.cmdline.target_platform = M_PlatformKind_Mac;
} }
else else if (MatchString(arg.value, Lit("linux")))
{ {
M.cmdline.target_platform = M_PlatformKind_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 //- Compiler
{
CommandlineArg arg = CommandlineArgFromName(Lit("compiler"));
if (MatchString(arg.value, Lit("msvc")))
{ {
M.cmdline.target_compiler = M_CompilerKind_Msvc; CommandlineArg arg = CommandlineArgFromName(Lit("compiler"));
} if (MatchString(arg.value, Lit("msvc")))
else if (MatchString(arg.value, Lit("clang")))
{
M.cmdline.target_compiler = M_CompilerKind_Clang;
}
else
{
if (IsPlatformWindows)
{ {
M.cmdline.target_compiler = M_CompilerKind_Msvc; M.cmdline.target_compiler = M_CompilerKind_Msvc;
} }
else else if (MatchString(arg.value, Lit("clang")))
{ {
M.cmdline.target_compiler = M_CompilerKind_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 //- Release/Debug
{
CommandlineArg arg = CommandlineArgFromName(Lit("release"));
if (arg.exists)
{ {
M.cmdline.release = 1; CommandlineArg arg = CommandlineArgFromName(Lit("release"));
if (arg.exists)
{
M.cmdline.release = 1;
}
} }
}
// Subsystem //- Subsystem
{
CommandlineArg arg = CommandlineArgFromName(Lit("console"));
if (arg.exists)
{ {
M.cmdline.console = 1; CommandlineArg arg = CommandlineArgFromName(Lit("console"));
if (arg.exists)
{
M.cmdline.console = 1;
}
} }
}
// Asan //- Asan
{
CommandlineArg arg = CommandlineArgFromName(Lit("asan"));
if (arg.exists)
{ {
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(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) 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()); ExitNow(M_GetBuildStatus());
} }
} }
@ -1436,7 +1452,6 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
void BootstrapLayers(void) void BootstrapLayers(void)
{ {
OS_Bootstrap(); OS_Bootstrap();
CpuTopologyInfo cpu_info = GetCpuTopologyInfo(); i32 meta_lanes_count = 32;
i32 meta_lanes_count = cpu_info.num_logical_cores - 1;
DispatchWave(Lit("Meta"), MaxI32(meta_lanes_count, 1), M_BuildEntryPoint, 0); DispatchWave(Lit("Meta"), MaxI32(meta_lanes_count, 1), M_BuildEntryPoint, 0);
} }

View File

@ -459,6 +459,7 @@ Enum(P_MsgKind)
// Server -> Client // Server -> Client
P_MsgKind_Tiles, P_MsgKind_Tiles,
P_MsgKind_PublicState,
P_MsgKind_COUNT P_MsgKind_COUNT
}; };
@ -552,6 +553,15 @@ Struct(P_RaycastResult)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ 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) Struct(P_SimStatistics)
{ {
NET_PipeStatistics pipe; NET_PipeStatistics pipe;

View File

@ -69,7 +69,7 @@ void S_TickForever(WaveLaneCtx *lane)
BB_Buff packer_bb = BB_AcquireDynamicBuff(Gibi(64)); BB_Buff packer_bb = BB_AcquireDynamicBuff(Gibi(64));
BB_Writer packer_bbw = BB_WriterFromBuff(&packer_bb); BB_Writer packer_bbw = BB_WriterFromBuff(&packer_bb);
P_PublicState *public = &S.public_state;
// FIXME: Header // FIXME: Header
@ -195,6 +195,11 @@ void S_TickForever(WaveLaneCtx *lane)
} }
} }
////////////////////////////// //////////////////////////////
//- Connect clients //- 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 //- Apply client controls
for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next) for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next)
{ {
P_Control *control = &client->controls[world_frame->tick % client->controls_cap]; P_Control *control = &client->controls[world_frame->tick % client->controls_cap];
if (control->tick == world_frame->tick) if (control->tick == world_frame->tick)
{ {
P_Ent *player = P_EntFromKey(world_frame, client->player); P_Ent *player = P_EntFromKey(world_frame, client->player);
if (!P_IsEntNil(player)) if (player->is_player)
{ {
player->control = *control; 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 //- Apply bot controls
@ -712,6 +836,18 @@ void S_TickForever(WaveLaneCtx *lane)
P_StepFrame(world_frame); 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 //- Push tile messages
@ -910,10 +1046,6 @@ void S_TickForever(WaveLaneCtx *lane)
{ {
BB_ResetWriter(&packer_bbw); BB_ResetWriter(&packer_bbw);
String packed = P_PackMessages(&packer_bbw, msgs); 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); NET_Send(net_pipe, client->net_key, packed, NET_SendFlag_None);
ZeroStruct(&client->out_msgs); 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); LockTicketMutex(&P.s2v_tm);
{ {

View File

@ -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 //~ Client types
@ -23,6 +71,9 @@ Struct(S_Client)
i64 remote_ack; i64 remote_ack;
i64 ack; i64 ack;
i64 demo_record_tick_offset;
b32 is_recording_demo;
u64 remote_tiles_hash; u64 remote_tiles_hash;
}; };
@ -45,6 +96,8 @@ Struct(S_Ctx)
i64 client_bins_count; i64 client_bins_count;
S_ClientBin *client_bins; S_ClientBin *client_bins;
P_PublicState public_state;
}; };
extern S_Ctx S; extern S_Ctx S;

View File

@ -261,28 +261,33 @@ void V_DrawPoint(Vec2 p, Vec4 srgb)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Text box //~ 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_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(); TempArena scratch = BeginScratchNoConflict();
V_TextboxDeltaFlag applied_flags = 0;
for (V_TextboxDeltaNode *tbd_node = deltas.first; tbd_node; tbd_node = tbd_node->next) for (V_TextboxDeltaNode *tbd_node = deltas.first; tbd_node; tbd_node = tbd_node->next)
{ {
V_TextboxDelta delta = tbd_node->delta; V_TextboxDelta delta = tbd_node->delta;
applied_flags |= delta.flags;
// Navigate // Navigate
{ {
b32 navigated = 0; b32 navigated = 0;
if (!(delta.flags & V_TextboxDeltaFlag_OnlyNavIfSelectionEmpty) || tb->start == tb->end) 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; navigated = 1;
tb->start = ClampI64(delta.direct_start, 0, tb->len);
tb->end = ClampI64(delta.direct_end, 0, tb->len); tb->end = ClampI64(delta.direct_end, 0, tb->len);
} }
if (delta.flags & V_TextboxDeltaFlag_NavLeft) 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; tb->start = tb->end;
} }
@ -550,6 +555,7 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas)
// } // }
} }
EndScratch(scratch); EndScratch(scratch);
return applied_flags;
} }
String V_StringFromTextbox(Arena *arena, V_TextboxState *tb) String V_StringFromTextbox(Arena *arena, V_TextboxState *tb)
@ -594,7 +600,7 @@ V_WidgetTheme V_GetWidgetTheme(void)
V_WidgetTheme theme = Zi; V_WidgetTheme theme = Zi;
theme.ui_font = GC_FontKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("font/seguisb.ttf"))); 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.chat_font = GC_FontKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("font/seguisb.ttf")));
theme.icon_font = UI_BuiltinIconFont(); theme.icon_font = UI_BuiltinIconFont();
@ -688,6 +694,9 @@ void V_TickForever(WaveLaneCtx *lane)
BB_Buff packer_bb = BB_AcquireDynamicBuff(Gibi(64)); BB_Buff packer_bb = BB_AcquireDynamicBuff(Gibi(64));
BB_Writer packer_bbw = BB_WriterFromBuff(&packer_bb); 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 //- Init vis state
@ -1256,7 +1265,7 @@ void V_TickForever(WaveLaneCtx *lane)
} }
if (down && cev->button == Button_A && frame->real_held_buttons[Button_Ctrl]) 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_start = 0;
delta.direct_end = V_MaxTextboxLen; delta.direct_end = V_MaxTextboxLen;
} }
@ -1779,6 +1788,17 @@ void V_TickForever(WaveLaneCtx *lane)
V_PushNotif(txt); 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 //- Tiles
if (msg->kind == P_MsgKind_Tiles && sim_world->tiles_hash != msg->tiles_hash) 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 //- 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 (frame->held_buttons[Button_F] && !prev_frame->held_buttons[Button_F])
if (0) // if (0)
{ {
{ {
V_Emitter emitter = Zi; V_Emitter emitter = Zi;
@ -3372,9 +3392,9 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Push test explosion //- 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 (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G])
if (0) // if (0)
{ {
// Fire // Fire
{ {
@ -3634,7 +3654,7 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Build panels //- Build panels
UI_SetDF(Parent, vis_game_box) UI_PushDF(Parent, vis_game_box)
// if (show_editor_ui && frame->is_editing) // if (show_editor_ui && frame->is_editing)
{ {
Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; };
@ -4324,7 +4344,7 @@ void V_TickForever(WaveLaneCtx *lane)
//- Build command palette //- Build command palette
V_Palette *palette = &frame->palette; V_Palette *palette = &frame->palette;
UI_SetDF(Parent, UI_RootKey) UI_PushDF(Parent, UI_RootKey)
{ {
UI_Push(Tag, HashF("developer command palette")); UI_Push(Tag, HashF("developer command palette"));
@ -4542,8 +4562,31 @@ void V_TickForever(WaveLaneCtx *lane)
//- Search box //- Search box
{ {
UI_Key search_box = UI_KeyF("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; 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); b32 has_focus = UI_MatchKey(search_box, prev_frame->text_input_focus);
// FIXME: Remove this // FIXME: Remove this
@ -4566,123 +4609,94 @@ void V_TickForever(WaveLaneCtx *lane)
WND_SetCursor(window_frame, WND_CursorKind_Text); 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) if (has_focus)
{ {
frame->text_input_focus = search_box; // Apply text input deltas
if (text_input_deltas.first) {
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.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(Width, UI_Grow(1, 0));
UI_SetNext(Height, search_height); UI_SetNext(Height, search_height);
UI_SetNext(BackgroundColor, search_color); UI_SetNext(BackgroundColor, search_color);
UI_SetNext(ChildAlignment, UI_Region_Right);
// UI_SetNext(BorderColor, item_border_color); // UI_SetNext(BorderColor, item_border_color);
UI_SetNext(BorderSize, 0); UI_PushDF(BorderSize, 0);
// UI_SetNext(Rounding, UI_Rpx(5)); // UI_SetNext(Rounding, UI_Rpx(5));
UI_SetNext(ChildAlignment, UI_Region_Left); UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_Scissor);
UI_SetNext(TextColor, display_text_color); UI_PushDF(Parent, UI_BuildRowEx(search_box))
UI_SetNext(Text, display_text);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse);
UI_PushCp(UI_BuildRowEx(search_box));
{ {
f32 font_size = UI_Top(FontSize); //- Compute caret / selection pos
GC_FontKey font = UI_Top(Font);
//- Text caret/selection
if (has_focus)
{ {
UI_Key caret_box = UI_KeyF("search caret"); // TODO: Cache result of caret search when textbox
UI_Key selection_box = UI_KeyF("search selection"); f32 target_caret_start_px = 0;
f32 target_caret_end_px = 0;
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
if (search_text.len > 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) 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) if (rect_idx < search_state->start)
{ {
GC_RunRect rect = run.rects[rect_idx]; target_caret_start_px = rect.baseline_pos + rect.advance;
start_offset_px = rect.baseline_pos + rect.advance;
} }
if (rect_idx < search_state->end) if (rect_idx < search_state->end)
{ {
GC_RunRect rect = run.rects[rect_idx]; target_caret_end_px = rect.baseline_pos + rect.advance;
end_offset_px = rect.baseline_pos + rect.advance;
} }
if (rect_idx >= search_state->start && rect_idx >= search_state->end) if (rect_idx >= search_state->start && rect_idx >= search_state->end)
{ {
@ -4691,21 +4705,74 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
f32 caret_start_lerp_rate = 25 * frame->dt;
f32 caret_end_lerp_rate = 50 * frame->dt;
// {
// i64 offset_
// }
// Selection
{ {
f32 min = MinF32(start_offset_px, end_offset_px); if (started_dragging_text)
f32 max = MaxF32(start_offset_px, end_offset_px); {
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(Width, UI_Px(max - min, 1));
UI_SetNext(Height, caret_height); UI_SetNext(Height, caret_height);
@ -4718,11 +4785,12 @@ void V_TickForever(WaveLaneCtx *lane)
UI_BuildBoxEx(selection_box); UI_BuildBoxEx(selection_box);
} }
// Caret //- Caret
if (has_focus)
{ {
UI_SetNext(Width, caret_width); UI_SetNext(Width, caret_width);
UI_SetNext(Height, caret_height); 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(Anchor, UI_Region_Left);
UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse); UI_SetNext(Flags, UI_BoxFlag_Floating, UI_BoxFlag_CaptureMouse);
UI_SetNext(BorderSize, 0); UI_SetNext(BorderSize, 0);
@ -4732,7 +4800,6 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
} }
UI_PopCp(UI_TopCp());
} }
} }
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); 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_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) if (profiler->is_showing)
{ {
@ -5548,8 +5615,8 @@ void V_TickForever(WaveLaneCtx *lane)
//- Build profiler //- Build profiler
UI_Key profiler_box = UI_KeyF("profiler"); UI_Key profiler_box = UI_KeyF("profiler");
ProfZoneDF("Build profiler") ProfZoneDF("Build profiler")
UI_SetDF(Tag, profiler_box.v) UI_PushDF(Tag, profiler_box.v)
UI_SetDF(Parent, profiler_box) UI_PushDF(Parent, profiler_box)
{ {
UI_Key main_box = UI_KeyF("main"); 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_zoom_delta = profiler->target_ns_per_px - profiler->ns_per_px;
profiler->last_view_delta = profiler->target_view_ns - profiler->view_ns; profiler->last_view_delta = profiler->target_view_ns - profiler->view_ns;
} }
f64 overshoot_rate = 2 * frame->dt; f64 overshoot_factor = 0.01;
profiler->ns_per_px = LerpF64(profiler->ns_per_px, profiler->target_ns_per_px + profiler->last_zoom_delta * overshoot_rate, prof_lerp_rate); 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_rate, 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) if (profiler->last_zoom_delta < 0)
{ {
@ -5796,7 +5863,8 @@ void V_TickForever(WaveLaneCtx *lane)
VisTrack *first_vis_track = 0; VisTrack *first_vis_track = 0;
VisTrack *last_vis_track = 0; VisTrack *last_vis_track = 0;
f32 zone_collapse_threshold_px = 10; 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") ProfZoneDF("Generate visible zones")
{ {
for (V_ZoneTrack *zone_track = V.first_zone_track; zone_track; zone_track = zone_track->next) 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 // Process child zones
{ {
VisZone *left_vis = 0;
b32 reached_end_of_view = 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) for (V_ZoneChunk *chunk = parent->first_chunk; chunk && !reached_end_of_view; chunk = chunk->next)
{ {
i64 chunk_start_ns = chunk->zones[0].start_ns; 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) 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) 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]; 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); visual_zone_start_px = MaxF64(visual_zone_start_px, parent_vis->start_px);
if (left_vis) 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 // Push vis zone
@ -5946,7 +6020,7 @@ void V_TickForever(WaveLaneCtx *lane)
f32 profiler_opacity = TweakFloat("Profiler opacity", 1, 0, 1); f32 profiler_opacity = TweakFloat("Profiler opacity", 1, 0, 1);
Vec4 timeline_cursor_color = theme.col.window_bd; 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_Size timeline_cursor_width = UI_Fnt(0.15, 1);
UI_Key hovered_zone_box = Zi; UI_Key hovered_zone_box = Zi;
@ -5976,22 +6050,22 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(Height, profiler_height); UI_SetNext(Height, profiler_height);
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_SetNext(Opacity, profiler_opacity); UI_SetNext(Opacity, profiler_opacity);
UI_SetDF(Width, UI_Grow(1, 0)) UI_PushDF(Width, UI_Grow(1, 0))
UI_SetDF(Parent, UI_BuildColumnEx(profiler_box)) UI_PushDF(Parent, UI_BuildColumnEx(profiler_box))
UI_SetDF(Parent, UI_BuildRow()) UI_PushDF(Parent, UI_BuildRow())
{ {
UI_BuildSpacer(window_padding, Axis_X); UI_BuildSpacer(window_padding, Axis_X);
UI_SetDF(Parent, UI_BuildColumn()) UI_PushDF(Parent, UI_BuildColumn())
{ {
//- Header //- Header
// UI_SetDF(BackgroundColor, Color_Red) // UI_PushDF(BackgroundColor, Color_Red)
// UI_SetNext(BorderColor, Color_Red); // UI_SetNext(BorderColor, Color_Red);
// UI_SetNext(BorderSize, 1); // UI_SetNext(BorderSize, 1);
UI_SetNext(ChildAlignment, UI_Region_Center); UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetDF(Height, header_height) UI_PushDF(Height, header_height)
UI_SetDF(Parent, UI_BuildBoxEx(UI_KeyF("profiler header"))) UI_PushDF(Parent, UI_BuildBoxEx(UI_KeyF("profiler header")))
{ {
UI_SetDF(TextColor, theme.col.hint) UI_PushDF(TextColor, theme.col.hint)
UI_BuildLabelF("Profiler"); UI_BuildLabelF("Profiler");
} }
@ -6002,7 +6076,7 @@ void V_TickForever(WaveLaneCtx *lane)
//- Graph //- Graph
// UI_SetNext(BackgroundColor, Color_Cyan); // UI_SetNext(BackgroundColor, Color_Cyan);
UI_SetNext(Height, graph_height); 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); // 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_BoxFlag_Scissor);
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_CaptureThroughChildren); UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_CaptureThroughChildren);
// UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_SetDF(Parent, UI_BuildColumnEx(main_box)) UI_PushDF(Parent, UI_BuildColumnEx(main_box))
{ {
//- Active area background //- Active area background
UI_SetDF(Opacity, 0.75) UI_PushDF(Opacity, 0.75)
{ {
f64 aabg_left_ns = MaxF64(0, profiler->view_ns); f64 aabg_left_ns = MaxF64(0, profiler->view_ns);
f64 aabg_right_ns = MinF64(frame->time_ns, view_end_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) for (VisTrack *vis_track = first_vis_track; vis_track; vis_track = vis_track->next)
{ {
UI_SetNext(Height, track_height); UI_SetNext(Height, track_height);
UI_SetDF(Tag, HashF("vis track %F", FmtUint(vis_track->id))) UI_PushDF(Tag, HashF("vis track %F", FmtUint(vis_track->id)))
UI_SetDF(Parent, UI_BuildColumn()) UI_PushDF(Parent, UI_BuildColumn())
{ {
//- Zone rows //- Zone rows
UI_Key *zone_row_boxes = PushStructs(frame->arena, UI_Key, vis_track->rows_count); 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; zone_row_boxes[zone_row_box_idx] = zone_row_box;
// UI_SetNext(Height, zone_height); // UI_SetNext(Height, zone_height);
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; String zone_text = zone->name;
if (is_collapsed) if (is_collapsed)
{ {
zone_text = Zstr; zone_text = StringF(frame->arena, "%F", FmtUint(zone->collapsed_count));
if (zone->collapsed_count > 1)
{
zone_text = StringF(frame->arena, "%F", FmtUint(zone->collapsed_count));
}
zone_text_color = collapsed_text_color; zone_text_color = collapsed_text_color;
zone_line_color = collapsed_line_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_color_bd = LerpSrgb(zone_color_bd, Color_White, zone_hovered * !is_collapsed);
zone_text_color = LerpSrgb(zone_text_color, Color_White, zone_hovered); zone_text_color = LerpSrgb(zone_text_color, Color_White, zone_hovered);
zone_line_color = LerpSrgb(zone_line_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 = 10;
f32 top_zag_information_density = zone_collapse_threshold_px; 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 zag_intensity = TweakFloat("RAAAAAAAAAAAAAH", 1, 0, 1);
f32 period_max = 20; f32 period_max = 20;
@ -6206,75 +6283,62 @@ void V_TickForever(WaveLaneCtx *lane)
UI_BoxFlag_Scissor UI_BoxFlag_Scissor
); );
UI_SetNext(Parent, zone_row_box); UI_SetNext(Parent, zone_row_box);
UI_SetDF(OrFlags, UI_Top(OrFlags) | (UI_BoxFlag_DontTruncateText * !!(is_collapsed))) // UI_PushDF(OrFlags, UI_Top(OrFlags) | (UI_BoxFlag_DontTruncateText * !!(is_collapsed)))
// UI_SetDF(OmitFlags, UI_Top(OmitFlags) | (UI_BoxFlag_Scissor * !!(is_collapsed))) // UI_PushDF(OmitFlags, UI_Top(OmitFlags) | (UI_BoxFlag_Scissor * !!(is_collapsed)))
// UI_SetDF(ZagPeriod, UI_Top(FontSize) * 1) // UI_PushDF(ZagPeriod, UI_Top(FontSize) * 1)
// UI_SetDF(ZagPeriod, (collapsed_zones_per_px * UI_Top(FontSize)) * 0.1) // UI_PushDF(ZagPeriod, (collapsed_zones_per_px * UI_Top(FontSize)) * 0.1)
// UI_SetDF(ZagPeriod, collapsed_zones_per_px / (UI_Top(FontSize) * 1)) // UI_PushDF(ZagPeriod, collapsed_zones_per_px / (UI_Top(FontSize) * 1))
UI_SetDF(ZagPeriod, zag_period) UI_PushDF(ZagPeriod, zag_period)
UI_SetDF(ZagThickness, 1.5) UI_PushDF(ZagThickness, 1.5)
UI_SetDF(ZagRoundness, 0) UI_PushDF(ZagRoundness, 1)
UI_SetDF(ZagAmplitude, zag_amplitude) UI_PushDF(ZagAmplitude, zag_amplitude)
UI_SetDF(Parent, UI_BuildRowEx(zone_box)) UI_PushDF(Parent, UI_BuildRowEx(zone_box))
{ {
// Left collapsed lines
if (is_collapsed) if (is_collapsed)
{ {
// // Vertical line // Left zag
// { UI_SetNext(Width, UI_Grow(1, 0));
// UI_SetDF(Opacity, 1.0 - zone_hovered) UI_SetNext(ZagColor, zone_line_color);
// UI_SetNext(BackgroundColor, collapsed_line_color); UI_BuildBox();
// UI_SetNext(Width, collapsed_line_size); }
// UI_SetNext(Height, UI_Grow(1, 0)); else
// UI_BuildBox(); {
// } UI_SetNext(Width, UI_Px(3, 1));
UI_BuildBox();
// Zag
{
UI_SetNext(Width, UI_Grow(1, 0));
UI_SetNext(ZagColor, zone_line_color);
UI_BuildBox();
}
} }
// Zone name if (zone_text.len > 0)
// if (zone_len_px > zone_collapse_threshold_px * 3)
{ {
// 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) 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 //- 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); 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(BorderSize, 1);
// UI_SetNext(BorderColor, Color_White); // UI_SetNext(BorderColor, Color_White);
// UI_SetDF(Opacity, profiler->ruler_opacity) // UI_PushDF(Opacity, profiler->ruler_opacity)
UI_SetNext(Width, ruler_width); UI_SetNext(Width, ruler_width);
UI_SetNext(FloatingPos, ruler_pos); UI_SetNext(FloatingPos, ruler_pos);
UI_SetNext(BackgroundColor, ruler_color); UI_SetNext(BackgroundColor, ruler_color);
@ -6365,15 +6429,15 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(Anchor, UI_Region_TopLeft); UI_SetNext(Anchor, UI_Region_TopLeft);
UI_SetNext(FloatingPos, tooltip_pos); UI_SetNext(FloatingPos, tooltip_pos);
UI_SetNext(Flags, UI_BoxFlag_Floating); UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_SetDF(Width, UI_Shrink(0, 1)) UI_PushDF(Width, UI_Shrink(0, 1))
UI_SetDF(Height, UI_Shrink(0, 1)) UI_PushDF(Height, UI_Shrink(0, 1))
UI_SetDF(Parent, UI_BuildRowEx(tooltip_box)) UI_PushDF(Parent, UI_BuildRowEx(tooltip_box))
{ {
UI_BuildSpacer(window_padding, Axis_X); UI_BuildSpacer(window_padding, Axis_X);
UI_SetNext(Width, UI_Shrink(0, 1)); UI_SetNext(Width, UI_Shrink(0, 1));
UI_SetNext(Height, 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); UI_BuildSpacer(window_padding, Axis_Y);
@ -6400,22 +6464,44 @@ void V_TickForever(WaveLaneCtx *lane)
if (show_hovered_zone) if (show_hovered_zone)
{ {
VisZone *zone = 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; 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)); 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); if (zone->collapsed_count == 1)
UI_BuildLabelF("Zones too small to display"); {
// // 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_SetNext(TextColor, collapsed_text_color);
UI_BuildLabelF(" (%F)", FmtUint(zone->collapsed_count)); // 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 else
@ -6438,17 +6524,17 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_BuildSpacer(window_padding, Axis_Y); // UI_BuildSpacer(window_padding, Axis_Y);
//- Footer //- Footer
UI_SetDF(Height, footer_height) UI_PushDF(Height, footer_height)
UI_SetDF(ChildAlignment, UI_Region_Center) UI_PushDF(ChildAlignment, UI_Region_Center)
UI_SetDF(Parent, UI_BuildRow()) UI_PushDF(Parent, UI_BuildRow())
{ {
if (IsUnoptimized) if (IsUnoptimized)
{ {
UI_SetDF(Width, UI_Shrink(0, 1)) UI_PushDF(Width, UI_Shrink(0, 1))
UI_SetDF(Height, UI_Shrink(0, 1)) UI_PushDF(Height, UI_Shrink(0, 1))
UI_SetDF(ChildAlignment, UI_Region_Left) UI_PushDF(ChildAlignment, UI_Region_Left)
UI_SetDF(TextColor, theme.col.warn) UI_PushDF(TextColor, theme.col.warn)
UI_SetDF(Parent, UI_BuildRow()) UI_PushDF(Parent, UI_BuildRow())
{ {
UI_BuildIcon(theme.icon_font, UI_Icon_Warning); UI_BuildIcon(theme.icon_font, UI_Icon_Warning);
// UI_BuildIcon(theme.icon_font, UI_Icon_Info); // UI_BuildIcon(theme.icon_font, UI_Icon_Info);
@ -7084,6 +7170,67 @@ void V_TickForever(WaveLaneCtx *lane)
UI_PopCp(UI_TopCp()); 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 //- Build console UI
@ -7621,11 +7768,11 @@ void V_TickForever(WaveLaneCtx *lane)
.name = StringF(frame->arena, "Gpu frame [%F]", FmtSint(frame->tick)) .name = StringF(frame->arena, "Gpu frame [%F]", FmtSint(frame->tick))
); );
// Set initial constants // Init registers
V_GpuFlag gpu_flags = V_GpuFlag_None; V_GpuFlag gpu_flags = V_GpuFlag_None;
G_SetConstant(cl, V_GpuConst_Flags, gpu_flags); G_SetRegister(cl, V_GpuReg_Flags, gpu_flags);
G_SetConstant(cl, V_GpuConst_Frame, gpu_frame); G_SetRegister(cl, V_GpuReg_Frame, gpu_frame);
G_SetConstant(cl, V_GpuConst_NoiseTex, G_BasicNoise3D()); G_SetRegister(cl, V_GpuReg_NoiseTex, G_BasicNoise3D());
} }
G_Sync(cl); G_Sync(cl);
@ -7657,14 +7804,14 @@ void V_TickForever(WaveLaneCtx *lane)
// Backdrop passes // Backdrop passes
{ {
i32 mips_count = G_CountMips(frame->backdrop_chain); 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 //- Downsample
for (i32 mip_idx = 0; mip_idx < mips_count; ++mip_idx) for (i32 mip_idx = 0; mip_idx < mips_count; ++mip_idx)
{ {
Vec2I32 down_dims = G_DimsFromMip2D(G_Count2D(frame->backdrop_chain), 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_Compute2D(cl, V_BackdropDownCS, down_dims);
G_Sync(cl); G_Sync(cl);
@ -7675,7 +7822,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
Vec2I32 up_dims = G_DimsFromMip2D(G_Count2D(frame->backdrop_chain), mip_idx); 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_Compute2D(cl, V_BackdropUpCS, up_dims);
G_Sync(cl); G_Sync(cl);
@ -7746,7 +7893,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
i32 mips_count = G_CountMips(frame->bloom_chain) + 1; 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 // NOTE: Because bloom mip chain starts at half screen size, mip_idx 0
// actually represents the screen texture, while mip_idx - 1 represents // 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); 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_Compute2D(cl, V_BloomDownCS, down_dims);
G_Sync(cl); G_Sync(cl);
@ -7770,7 +7917,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
Vec2I32 up_dims = G_DimsFromMip2D(G_Count2D(frame->screen), mip_idx); 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_Compute2D(cl, V_BloomUpCS, up_dims);
G_Sync(cl); G_Sync(cl);

View File

@ -12,7 +12,7 @@
X(toggle_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \ 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_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_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(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(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 ) ) \ 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 ui_font;
GC_FontKey chat_font; GC_FontKey chat_font;
GC_FontKey icon_font; GC_FontKey icon_font;
GC_FontKey player_name_font;
f32 ui_font_size; f32 ui_font_size;
f32 chat_font_size; f32 chat_font_size;
@ -169,12 +170,13 @@ Enum(V_TextboxDeltaFlag)
V_TextboxDeltaFlag_OnlyNavIfSelectionEmpty = (1 << 1), V_TextboxDeltaFlag_OnlyNavIfSelectionEmpty = (1 << 1),
V_TextboxDeltaFlag_CopySelectionToClipboard = (1 << 2), V_TextboxDeltaFlag_CopySelectionToClipboard = (1 << 2),
V_TextboxDeltaFlag_InheritTextFromClipboard = (1 << 3), V_TextboxDeltaFlag_InheritTextFromClipboard = (1 << 3),
V_TextboxDeltaFlag_NavDirect = (1 << 4), V_TextboxDeltaFlag_NavDirectStart = (1 << 4),
V_TextboxDeltaFlag_NavLeft = (1 << 5), V_TextboxDeltaFlag_NavDirectEnd = (1 << 5),
V_TextboxDeltaFlag_NavRight = (1 << 6), V_TextboxDeltaFlag_NavLeft = (1 << 6),
V_TextboxDeltaFlag_NavWord = (1 << 7), V_TextboxDeltaFlag_NavRight = (1 << 7),
V_TextboxDeltaFlag_NavLine = (1 << 8), V_TextboxDeltaFlag_NavWord = (1 << 8),
V_TextboxDeltaFlag_NavSelect = (1 << 9), V_TextboxDeltaFlag_NavLine = (1 << 9),
V_TextboxDeltaFlag_NavSelect = (1 << 10),
}; };
Struct(V_TextboxDelta) Struct(V_TextboxDelta)
@ -226,6 +228,10 @@ Struct(V_Palette)
Vec2 drag_cursor; Vec2 drag_cursor;
f32 drag_scroll; f32 drag_scroll;
f32 caret_start_px;
f32 caret_end_px;
f32 text_scroll_px;
V_TextboxState search_state; V_TextboxState search_state;
}; };
@ -294,9 +300,6 @@ Struct(V_Profiler)
f64 target_ns_per_px; f64 target_ns_per_px;
f64 ns_per_px; f64 ns_per_px;
f64 zoom_level;
f64 target_zoom_level;
f64 cursor_ns; f64 cursor_ns;
f64 drag_cursor_px; f64 drag_cursor_px;
}; };
@ -443,6 +446,8 @@ Struct(V_Ctx)
V_ZoneTrack *first_zone_track; V_ZoneTrack *first_zone_track;
V_ZoneTrack *last_zone_track; V_ZoneTrack *last_zone_track;
P_PublicState public_state;
i64 panels_count; i64 panels_count;
i64 windows_count; i64 windows_count;
V_Panel *root_panel; V_Panel *root_panel;
@ -502,8 +507,8 @@ void V_DrawPoint(Vec2 p, Vec4 srgb);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Text box //~ Text box
void V_ApplyTextboxDelta(V_TextboxState *tb, V_TextboxDelta delta); V_TextboxDeltaFlag V_ApplyTextboxDelta(V_TextboxState *tb, V_TextboxDelta delta);
void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas); V_TextboxDeltaFlag V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas);
String V_StringFromTextbox(Arena *arena, V_TextboxState *tb); String V_StringFromTextbox(Arena *arena, V_TextboxState *tb);
String V_StringFromTextboxSelection(Arena *arena, V_TextboxState *tb); String V_StringFromTextboxSelection(Arena *arena, V_TextboxState *tb);

View File

@ -3,7 +3,7 @@
f32 V_RandFromPos(Vec3 pos) f32 V_RandFromPos(Vec3 pos)
{ {
Texture3D<u32> noise3d = G_Deref(V_GpuConst_NoiseTex, Texture3D<u32>); Texture3D<u32> noise3d = G_Deref(V_GpuReg_NoiseTex, Texture3D<u32>);
u32 noise = noise3d[(Vec3U32)pos % G_BasicNoiseDims]; u32 noise = noise3d[(Vec3U32)pos % G_BasicNoiseDims];
f32 rand = Norm16(noise); f32 rand = Norm16(noise);
return rand; return rand;
@ -56,7 +56,7 @@ Vec4 V_ColorFromParticle(V_ParticleDesc desc, u32 particle_idx, u32 density)
ComputeShader(V_BuildProfilerGraphCS) ComputeShader(V_BuildProfilerGraphCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
RWTexture2D<Vec4> graph = G_Deref(frame.profiler_graph, RWTexture2D<Vec4>); RWTexture2D<Vec4> graph = G_Deref(frame.profiler_graph, RWTexture2D<Vec4>);
StructuredBuffer<V_ProfilerFrame> profiler_frames = G_Deref(frame.profiler_frames, StructuredBuffer<V_ProfilerFrame>); StructuredBuffer<V_ProfilerFrame> profiler_frames = G_Deref(frame.profiler_frames, StructuredBuffer<V_ProfilerFrame>);
@ -84,7 +84,7 @@ ComputeShader(V_BuildProfilerGraphCS)
//- Prepare shade //- Prepare shade
ComputeShader(V_PrepareShadeCS) ComputeShader(V_PrepareShadeCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
RWTexture2D<Vec4> shade = G_Deref(frame.shade, RWTexture2D<Vec4>); RWTexture2D<Vec4> shade = G_Deref(frame.shade, RWTexture2D<Vec4>);
Vec2 shade_pos = SV_DispatchThreadID + 0.5; Vec2 shade_pos = SV_DispatchThreadID + 0.5;
if (all(shade_pos < G_Count2D(shade))) if (all(shade_pos < G_Count2D(shade)))
@ -97,7 +97,7 @@ ComputeShader(V_PrepareShadeCS)
//- Prepare cells //- Prepare cells
ComputeShader(V_PrepareCellsCS) ComputeShader(V_PrepareCellsCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>); Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>);
RWTexture2D<Vec4> stains = G_Deref(frame.stains, RWTexture2D<Vec4>); RWTexture2D<Vec4> stains = G_Deref(frame.stains, RWTexture2D<Vec4>);
RWTexture2D<Vec4> dry_stains = G_Deref(frame.dry_stains, RWTexture2D<Vec4>); RWTexture2D<Vec4> dry_stains = G_Deref(frame.dry_stains, RWTexture2D<Vec4>);
@ -186,7 +186,7 @@ ComputeShader(V_PrepareCellsCS)
//- Clear particles //- Clear particles
ComputeShader(V_ClearParticlesCS) ComputeShader(V_ClearParticlesCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>); RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>);
u32 particle_idx = SV_DispatchThreadID; u32 particle_idx = SV_DispatchThreadID;
if (particle_idx < V_ParticlesCap) if (particle_idx < V_ParticlesCap)
@ -203,10 +203,10 @@ ComputeShader(V_ClearParticlesCS)
ComputeShader(V_BackdropDownCS) ComputeShader(V_BackdropDownCS)
{ {
i32 mip_idx = V_GpuConst_MipIdx; i32 mip_idx = V_GpuReg_MipIdx;
b32 is_first_pass = mip_idx == 0; b32 is_first_pass = mip_idx == 0;
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror], SamplerState);
Texture2D<Vec4> bd_up = ( Texture2D<Vec4> bd_up = (
is_first_pass ? is_first_pass ?
@ -263,9 +263,9 @@ ComputeShader(V_BackdropDownCS)
ComputeShader(V_BackdropUpCS) ComputeShader(V_BackdropUpCS)
{ {
i32 mip_idx = V_GpuConst_MipIdx; i32 mip_idx = V_GpuReg_MipIdx;
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
Texture2D<Vec4> bd_down = G_Deref(frame.backdrop_chain, Texture2D<Vec4>, mip_idx + 1); Texture2D<Vec4> bd_down = G_Deref(frame.backdrop_chain, Texture2D<Vec4>, mip_idx + 1);
RWTexture2D<Vec4> bd_up = G_Deref(frame.backdrop_chain, RWTexture2D<Vec4>, mip_idx); RWTexture2D<Vec4> bd_up = G_Deref(frame.backdrop_chain, RWTexture2D<Vec4>, mip_idx);
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror], SamplerState);
@ -323,7 +323,7 @@ ComputeShader(V_BackdropUpCS)
VertexShader(V_QuadVS, V_QuadPSInput) VertexShader(V_QuadVS, V_QuadPSInput)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
StructuredBuffer<V_Quad> quads = G_Deref(frame.quads, StructuredBuffer<V_Quad>); StructuredBuffer<V_Quad> quads = G_Deref(frame.quads, StructuredBuffer<V_Quad>);
V_Quad quad = quads[SV_InstanceID]; V_Quad quad = quads[SV_InstanceID];
@ -347,7 +347,7 @@ VertexShader(V_QuadVS, V_QuadPSInput)
PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState);
RWTexture2D<u32> occluders = G_Deref(frame.occluders, RWTexture2D<u32>); RWTexture2D<u32> occluders = G_Deref(frame.occluders, RWTexture2D<u32>);
@ -383,7 +383,7 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
ComputeShader(V_EmitParticlesCS) ComputeShader(V_EmitParticlesCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
StructuredBuffer<V_Emitter> emitters = G_Deref(frame.emitters, StructuredBuffer<V_Emitter>); StructuredBuffer<V_Emitter> emitters = G_Deref(frame.emitters, StructuredBuffer<V_Emitter>);
RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>); RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>);
@ -414,7 +414,7 @@ ComputeShader(V_EmitParticlesCS)
ComputeShader(V_SimParticlesCS) ComputeShader(V_SimParticlesCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>); Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>);
RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>); RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>);
Texture2D<u32> occluders = G_Deref(frame.occluders, Texture2D<u32>); Texture2D<u32> occluders = G_Deref(frame.occluders, Texture2D<u32>);
@ -691,7 +691,7 @@ ComputeShader(V_SimParticlesCS)
ComputeShader(V_ShadeCS) ComputeShader(V_ShadeCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState);
Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>); Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>);
Texture2D<Vec4> albedo_tex = G_Deref(frame.albedo, Texture2D<Vec4>); Texture2D<Vec4> albedo_tex = G_Deref(frame.albedo, Texture2D<Vec4>);
@ -727,7 +727,7 @@ ComputeShader(V_ShadeCS)
ComputeShader(V_CompositeCS) ComputeShader(V_CompositeCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
// Texture2D<Vec4> shade_tex = G_Deref(frame.shade, Texture2D<Vec4>); // Texture2D<Vec4> shade_tex = G_Deref(frame.shade, Texture2D<Vec4>);
SamplerState point_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); SamplerState point_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState);
SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState);
@ -1128,10 +1128,10 @@ ComputeShader(V_CompositeCS)
ComputeShader(V_BloomDownCS) ComputeShader(V_BloomDownCS)
{ {
i32 mip_idx = V_GpuConst_MipIdx; i32 mip_idx = V_GpuReg_MipIdx;
b32 is_first_pass = mip_idx == 1; b32 is_first_pass = mip_idx == 1;
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState);
RWTexture2D<Vec4> bloom_down = G_Deref(frame.bloom_chain, RWTexture2D<Vec4>, mip_idx - 1); RWTexture2D<Vec4> bloom_down = G_Deref(frame.bloom_chain, RWTexture2D<Vec4>, mip_idx - 1);
@ -1198,9 +1198,9 @@ ComputeShader(V_BloomDownCS)
ComputeShader(V_BloomUpCS) ComputeShader(V_BloomUpCS)
{ {
i32 mip_idx = V_GpuConst_MipIdx; i32 mip_idx = V_GpuReg_MipIdx;
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState);
Texture2D<Vec4> bloom_down = G_Deref(frame.bloom_chain, Texture2D<Vec4>, mip_idx); Texture2D<Vec4> bloom_down = G_Deref(frame.bloom_chain, Texture2D<Vec4>, mip_idx);
@ -1261,7 +1261,7 @@ ComputeShader(V_BloomUpCS)
ComputeShader(V_FinalizeCS) ComputeShader(V_FinalizeCS)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState);
Texture2D<Vec4> bloom_tex = G_Deref(frame.bloom_chain, Texture2D<Vec4>); Texture2D<Vec4> bloom_tex = G_Deref(frame.bloom_chain, Texture2D<Vec4>);
RWTexture2D<Vec4> screen_tex = G_Deref(frame.screen, RWTexture2D<Vec4>); RWTexture2D<Vec4> screen_tex = G_Deref(frame.screen, RWTexture2D<Vec4>);
@ -1294,7 +1294,7 @@ ComputeShader(V_FinalizeCS)
VertexShader(V_DVertVS, V_DVertPSInput) VertexShader(V_DVertVS, V_DVertPSInput)
{ {
V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
StructuredBuffer<V_DVert> verts = G_Deref(frame.dverts, StructuredBuffer<V_DVert>); StructuredBuffer<V_DVert> verts = G_Deref(frame.dverts, StructuredBuffer<V_DVert>);
V_DVert vert = verts[SV_VertexID]; V_DVert vert = verts[SV_VertexID];

View File

@ -4,18 +4,18 @@
// #define V_ParticlesCap Mebi(16) // #define V_ParticlesCap Mebi(16)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Constant types //~ Shader register types
Enum(V_GpuFlag) Enum(V_GpuFlag)
{ {
V_GpuFlag_None = 0, V_GpuFlag_None = 0,
}; };
G_DeclConstant(V_GpuFlag, V_GpuConst_Flags, 0); G_DeclRegister(V_GpuFlag, V_GpuReg_Flags, 0);
G_DeclConstant(G_BufferRef, V_GpuConst_Frame, 1); G_DeclRegister(G_BufferRef, V_GpuReg_Frame, 1);
G_DeclConstant(G_TextureRef, V_GpuConst_NoiseTex, 2); G_DeclRegister(G_TextureRef, V_GpuReg_NoiseTex, 2);
G_DeclConstant(i32, V_GpuConst_MipsCount, 3); G_DeclRegister(i32, V_GpuReg_MipsCount, 3);
G_DeclConstant(i32, V_GpuConst_MipIdx, 4); G_DeclRegister(i32, V_GpuReg_MipIdx, 4);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Particle types //~ Particle types

View File

@ -41,7 +41,7 @@ void PT_RunForever(WaveLaneCtx *lane)
window_frame.draw_size, window_frame.draw_size,
.flags = G_MemoryFlag_AllowTextureRW | G_MemoryFlag_AllowTextureDraw .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); G_Sync(cl);

View File

@ -3,7 +3,7 @@
ComputeShader(PT_TestCS) ComputeShader(PT_TestCS)
{ {
PT_SharedFrame frame = G_Deref(PT_ShaderConst_Frame, StructuredBuffer<PT_SharedFrame>)[0]; PT_SharedFrame frame = G_Deref(PT_ShaderReg_Frame, StructuredBuffer<PT_SharedFrame>)[0];
RWTexture2D<Vec4> target_tex = G_Deref(frame.compute_target, RWTexture2D<Vec4>); RWTexture2D<Vec4> target_tex = G_Deref(frame.compute_target, RWTexture2D<Vec4>);
Vec2U32 target_tex_size = G_Count2D(target_tex); 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) PixelShader(PT_BlitPS, PT_BlitPSOutput, PT_BlitPSInput input)
{ {
PT_SharedFrame frame = G_Deref(PT_ShaderConst_Frame, StructuredBuffer<PT_SharedFrame>)[0]; PT_SharedFrame frame = G_Deref(PT_ShaderReg_Frame, StructuredBuffer<PT_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.sampler, SamplerState); SamplerState sampler = G_Deref(frame.sampler, SamplerState);
Texture2D<Vec4> src = G_Deref(frame.compute_target, Texture2D<Vec4>); Texture2D<Vec4> src = G_Deref(frame.compute_target, Texture2D<Vec4>);
Texture3D<u32> noise = G_Deref(frame.noise_tex, Texture3D<u32>); Texture3D<u32> noise = G_Deref(frame.noise_tex, Texture3D<u32>);

View File

@ -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 //~ State types

View File

@ -2069,8 +2069,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
.name = Lit("UI gpu frame") .name = Lit("UI gpu frame")
); );
// Init constants // Init registers
G_SetConstant(UI.cl, UI_GpuConst_Frame, gpu_frame_buff); G_SetRegister(UI.cl, UI_GpuReg_Frame, gpu_frame_buff);
} }
// Sync // Sync
@ -2106,7 +2106,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
{ {
G_ProfZoneDF(UI.cl, "UI debug rects") 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( G_Draw(
UI.cl, UI.cl,
UI_DRectVS, UI_DRectPS, UI_DRectVS, UI_DRectPS,
@ -2115,7 +2115,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
draw_viewport, draw_scissor, draw_viewport, draw_scissor,
G_DrawMode_WireTriangleList G_DrawMode_WireTriangleList
); );
G_SetConstant(UI.cl, UI_GpuConst_DebugDraw, 0); G_SetRegister(UI.cl, UI_GpuReg_DebugDraw, 0);
} }
} }
} }

View File

@ -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_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_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 { \ #define UI_PushCopy(name, src, ...) do { \
UI_StyleDesc _new = src; \ UI_StyleDesc _new = src; \

View File

@ -6,7 +6,7 @@
VertexShader(UI_DRectVS, UI_DRectPSInput) VertexShader(UI_DRectVS, UI_DRectPSInput)
{ {
UI_GpuFrame frame = G_Deref(UI_GpuConst_Frame, StructuredBuffer<UI_GpuFrame>)[0]; UI_GpuFrame frame = G_Deref(UI_GpuReg_Frame, StructuredBuffer<UI_GpuFrame>)[0];
StructuredBuffer<UI_GpuRect> rects = G_Deref(frame.rects, StructuredBuffer<UI_GpuRect>); StructuredBuffer<UI_GpuRect> rects = G_Deref(frame.rects, StructuredBuffer<UI_GpuRect>);
UI_GpuRect rect = rects[SV_InstanceID]; UI_GpuRect rect = rects[SV_InstanceID];
@ -34,7 +34,7 @@ VertexShader(UI_DRectVS, UI_DRectPSInput)
PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
{ {
UI_GpuFrame frame = G_Deref(UI_GpuConst_Frame, StructuredBuffer<UI_GpuFrame>)[0]; UI_GpuFrame frame = G_Deref(UI_GpuReg_Frame, StructuredBuffer<UI_GpuFrame>)[0];
SamplerState sampler = G_Deref(frame.sampler, SamplerState); SamplerState sampler = G_Deref(frame.sampler, SamplerState);
UI_GpuRect rect = input.rect; UI_GpuRect rect = input.rect;
@ -136,7 +136,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
} }
//- Finalize //- Finalize
if (UI_GpuConst_DebugDraw) if (UI_GpuReg_DebugDraw)
{ {
result = input.debug_premul; result = input.debug_premul;
} }

View File

@ -1,8 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Constant types //~ Shader register types
G_DeclConstant(G_BufferRef, UI_GpuConst_Frame, 0); G_DeclRegister(G_BufferRef, UI_GpuReg_Frame, 0);
G_DeclConstant(b32, UI_GpuConst_DebugDraw, 1); G_DeclRegister(b32, UI_GpuReg_DebugDraw, 1);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Rect types //~ Rect types