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
: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 (

View File

@ -24,7 +24,7 @@
//~ 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);
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

View File

@ -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 = &params[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

View File

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

View File

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

View File

@ -267,6 +267,8 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
// Return rebuild code if metaprogram is dirty
if (lane->idx == 0)
{
b32 is_metaprogram_dirty = 0;
{
// Read old metahash
u64 old_metahash = 0;
@ -284,9 +286,13 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
u64 new_metahash = 0;
{
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;
@ -294,23 +300,28 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
new_metahash = HashStringEx(new_metahash , file);
}
}
// Exit if metaprogram needs recompilation
if (old_metahash == 0 || old_metahash == new_metahash)
{
F_ClearWrite(Lit("metahash.dat"), StringFromStruct(&new_metahash));
}
else
{
M_EchoLine(Lit("Metaprogram is dirty"));
is_metaprogram_dirty = 1;
}
}
// Exit if metaprogram needs recompilation
if (is_metaprogram_dirty)
{
ExitNow(M_RebuildCode);
}
}
//////////////////////////////
//- Init command line
//- Init environment from command line
// Layer name
{
//- Layer name
{
CommandlineArg arg = CommandlineArgFromName(Lit("layer"));
String layer_name = Zi;
@ -327,13 +338,13 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
layer_name = Lit("pp");
if (lane->idx == 0)
{
M_EchoLine(Lit("No layer specified, assuming \"pp\" build"));
M_EchoLine(Lit("No target layer specified, assuming 'pp' build"));
}
}
M.cmdline.leaf_layer_name = layer_name;
}
// Platform
//- Platform
{
CommandlineArg arg = CommandlineArgFromName(Lit("platform"));
if (MatchString(arg.value, Lit("windows")))
@ -365,7 +376,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
}
}
// Compiler
//- Compiler
{
CommandlineArg arg = CommandlineArgFromName(Lit("compiler"));
if (MatchString(arg.value, Lit("msvc")))
@ -389,7 +400,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
}
}
// Release/Debug
//- Release/Debug
{
CommandlineArg arg = CommandlineArgFromName(Lit("release"));
if (arg.exists)
@ -398,7 +409,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
}
}
// Subsystem
//- Subsystem
{
CommandlineArg arg = CommandlineArgFromName(Lit("console"));
if (arg.exists)
@ -407,7 +418,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
}
}
// Asan
//- Asan
{
CommandlineArg arg = CommandlineArgFromName(Lit("asan"));
if (arg.exists)
@ -415,6 +426,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
M.cmdline.asan = 1;
}
}
}
if (lane->idx == 0)
{
@ -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);
}

View File

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

View File

@ -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,21 +404,140 @@ 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);
{

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

View File

@ -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)
{
// Apply text input deltas
{
frame->text_input_focus = search_box;
if (text_input_deltas.first)
{
V.text_input_ns = frame->time_ns;
V_ApplyTextboxDeltas(search_state, text_input_deltas);
tb_applied_flags |= V_ApplyTextboxDeltas(search_state, text_input_deltas);
}
}
// // 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)
// Apply mouse select
if (UI_Held(search_box, Button_M1))
{
display_text_color = theme.col.hint;
display_text = Lit(" Search...");
V.text_input_ns = frame->time_ns;
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);
}
}
// Vec4 search_color = Color_Black;
Vec4 search_color = Zi;
// // Apply mouse selection drag
// if (UI_Held(search_box))
// {
// f32 drag_delta = UI_CursorPos().x - UI_DragCursorPos().x;
// }
}
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))
{
}
}
@ -6132,12 +6206,8 @@ 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_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
{
// 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();
}
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(Width, UI_Shrink(0, 0));
UI_SetNext(ChildAlignment, UI_Region_Left);
UI_SetNext(Width, UI_Grow(1, 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_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_DontTruncateText);
UI_BuildRow();
}
// Right collapsed lines
if (is_collapsed)
{
// Zag
// Right 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(" (Too small to display)");
UI_SetNext(TextColor, collapsed_text_color);
UI_BuildLabelF(" (%F)", FmtUint(zone->collapsed_count));
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);

View File

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

View File

@ -3,7 +3,7 @@
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];
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<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>);
StructuredBuffer<V_ProfilerFrame> profiler_frames = G_Deref(frame.profiler_frames, StructuredBuffer<V_ProfilerFrame>);
@ -84,7 +84,7 @@ ComputeShader(V_BuildProfilerGraphCS)
//- Prepare shade
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>);
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<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>);
RWTexture2D<Vec4> stains = G_Deref(frame.stains, RWTexture2D<Vec4>);
RWTexture2D<Vec4> dry_stains = G_Deref(frame.dry_stains, RWTexture2D<Vec4>);
@ -186,7 +186,7 @@ ComputeShader(V_PrepareCellsCS)
//- Clear particles
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>);
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<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);
Texture2D<Vec4> 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<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);
RWTexture2D<Vec4> bd_up = G_Deref(frame.backdrop_chain, RWTexture2D<Vec4>, 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<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>);
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<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);
RWTexture2D<u32> occluders = G_Deref(frame.occluders, RWTexture2D<u32>);
@ -383,7 +383,7 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
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>);
RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>);
@ -414,7 +414,7 @@ ComputeShader(V_EmitParticlesCS)
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>);
RWStructuredBuffer<V_Particle> particles = G_Deref(frame.particles, RWStructuredBuffer<V_Particle>);
Texture2D<u32> occluders = G_Deref(frame.occluders, Texture2D<u32>);
@ -691,7 +691,7 @@ ComputeShader(V_SimParticlesCS)
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);
Texture2D<P_TileKind> tiles = G_Deref(frame.tiles, Texture2D<P_TileKind>);
Texture2D<Vec4> albedo_tex = G_Deref(frame.albedo, Texture2D<Vec4>);
@ -727,7 +727,7 @@ ComputeShader(V_ShadeCS)
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>);
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<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);
RWTexture2D<Vec4> bloom_down = G_Deref(frame.bloom_chain, RWTexture2D<Vec4>, 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<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);
Texture2D<Vec4> bloom_down = G_Deref(frame.bloom_chain, Texture2D<Vec4>, mip_idx);
@ -1261,7 +1261,7 @@ ComputeShader(V_BloomUpCS)
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);
Texture2D<Vec4> bloom_tex = G_Deref(frame.bloom_chain, Texture2D<Vec4>);
RWTexture2D<Vec4> screen_tex = G_Deref(frame.screen, RWTexture2D<Vec4>);
@ -1294,7 +1294,7 @@ ComputeShader(V_FinalizeCS)
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>);
V_DVert vert = verts[SV_VertexID];

View File

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

View File

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

View File

@ -3,7 +3,7 @@
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>);
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<PT_SharedFrame>)[0];
PT_SharedFrame frame = G_Deref(PT_ShaderReg_Frame, StructuredBuffer<PT_SharedFrame>)[0];
SamplerState sampler = G_Deref(frame.sampler, SamplerState);
Texture2D<Vec4> src = G_Deref(frame.compute_target, Texture2D<Vec4>);
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

View File

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

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_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; \

View File

@ -6,7 +6,7 @@
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>);
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<UI_GpuFrame>)[0];
UI_GpuFrame frame = G_Deref(UI_GpuReg_Frame, StructuredBuffer<UI_GpuFrame>)[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;
}

View File

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