prefab spawn menu

This commit is contained in:
jacob 2026-02-05 21:42:01 -06:00
parent bd6722f807
commit e0356f73e8
9 changed files with 166 additions and 140 deletions

View File

@ -202,17 +202,21 @@
#define Global static #define Global static
//- Read-only //- Read-only
#if IsPlatformWindows #if IsCpu
#if IsCompilerMsvc #if IsPlatformWindows
#pragma section(".rdata$", read) #if IsCompilerMsvc
#define Readonly __declspec(allocate(".rdata$")) #pragma section(".rdata$", read)
#define Readonly __declspec(allocate(".rdata$"))
#else
#define Readonly __declspec(allocate(".rdata$"))
#endif
#elif IsPlatformMac
#define Readonly __attribute((section("__TEXT,__const")))
#else #else
#define Readonly __declspec(allocate(".rdata$")) #define Readonly __attribute((section(".rodata")))
#endif #endif
#elif IsPlatformMac
#define Readonly __attribute((section("__TEXT,__const")))
#else #else
#define Readonly __attribute((section(".rodata"))) #define Readonly const
#endif #endif
//- Thread-local //- Thread-local

View File

@ -88,18 +88,25 @@ void P_SetEntString(P_Ent *ent, String str)
String P_NameFromTileKind(P_TileKind kind) String P_NameFromTileKind(P_TileKind kind)
{ {
// Tile names array // Tile names array
#define X(name, ...) [P_TileKind_##name] = CompLit(#name), PERSIST Readonly String names[P_TileKind_COUNT] = {
PERSIST Readonly String tile_names[] = { #define X(name, ...) [P_TileKind_##name] = CompLit(#name),
P_TilesXList(X) P_TilesXList(X)
#undef X
}; };
#undef X return names[kind];
}
String result = Lit("Unknown"); ////////////////////////////////////////////////////////////
if (kind >= 0 && kind < countof(tile_names)) //~ Prefab helpers
{
result = tile_names[kind]; String P_NameFromPrefabKind(P_PrefabKind kind)
} {
return result; PERSIST Readonly String names[P_PrefabKind_COUNT] = {
#define X(name, ...) [P_PrefabKind_##name] = CompLit(#name),
P_PrefabsXList(X)
#undef X
};
return names[kind];
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -475,6 +475,11 @@ void P_SetEntString(P_Ent *ent, String str);
String P_NameFromTileKind(P_TileKind kind); String P_NameFromTileKind(P_TileKind kind);
////////////////////////////////////////////////////////////
//~ Prefab helpers
String P_NameFromPrefabKind(P_PrefabKind kind);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Shape helpers //~ Shape helpers

View File

@ -9,39 +9,15 @@ i32 P_TileIdxFromTilePos(Vec2 p)
return result; return result;
} }
#if IsCpu
String P_TileNameFromKind(P_TileKind kind)
{
PERSIST Readonly String tile_names[P_TileKind_COUNT] = {
#define X(name, ...) [P_TileKind_##name] = CompLit(#name),
P_TilesXList(X)
#undef X
};
String result = Zi;
if (kind >= 0 && kind < countof(tile_names))
{
result = tile_names[kind];
}
return result;
}
#endif
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Prefab helpers //~ Prefab helpers
#if IsCpu P_PrefabFlag P_FlagsFromPrefabKind(P_PrefabKind kind)
String P_PrefabNameFromKind(P_PrefabKind kind) {
{ PERSIST Readonly P_PrefabFlag flags[P_PrefabKind_COUNT] = {
PERSIST Readonly String prefab_names[P_PrefabKind_COUNT] = { #define X(name, flags, ...) flags,
#define X(name, ...) [P_PrefabKind_##name] = CompLit(#name), P_PrefabsXList(X)
P_PrefabsXList(X) #undef X
#undef X };
}; return flags[kind];
String result = Zi; }
if (kind >= 0 && kind < countof(prefab_names))
{
result = prefab_names[kind];
}
return result;
}
#endif

View File

@ -21,7 +21,7 @@
X(Carpet) \ X(Carpet) \
/* -------------------- */ /* -------------------- */
//- Tiles kinds enum //- Tiles kinds
Enum(P_TileKind) Enum(P_TileKind)
{ {
#define X(name, ...) P_TileKind_##name, #define X(name, ...) P_TileKind_##name,
@ -33,13 +33,21 @@ Enum(P_TileKind)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Prefab types //~ Prefab types
#define P_PrefabsXList(X) \ #define P_PrefabsXList(X) \
X(Guy) \ X(None, P_PrefabFlag_HideFromEditor) \
X(Dummy) \ X(Guy, P_PrefabFlag_None) \
X(SpawnPoint) \ X(Dummy, P_PrefabFlag_None) \
/* --------------------- */ X(SpawnPoint, P_PrefabFlag_None) \
/* --------------------------------------------------- */
//- Prefab kinds enum //- Prefab flags
Enum(P_PrefabFlag)
{
P_PrefabFlag_None = 0,
P_PrefabFlag_HideFromEditor = (1 << 0),
};
//- Prefab kinds
Enum(P_PrefabKind) Enum(P_PrefabKind)
{ {
#define X(name, ...) P_PrefabKind_##name, #define X(name, ...) P_PrefabKind_##name,
@ -53,13 +61,7 @@ Enum(P_PrefabKind)
i32 P_TileIdxFromTilePos(Vec2 p); i32 P_TileIdxFromTilePos(Vec2 p);
#if IsCpu
String P_TileNameFromKind(P_TileKind kind);
#endif
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Prefab helpers //~ Prefab helpers
#if IsCpu P_PrefabFlag P_FlagsFromPrefabKind(P_PrefabKind kind);
String P_PrefabNameFromKind(P_PrefabKind kind);
#endif

View File

@ -562,6 +562,7 @@ void V_TickForever(WaveLaneCtx *lane)
frame->look = prev_frame->look; frame->look = prev_frame->look;
frame->edit_mode = prev_frame->edit_mode; frame->edit_mode = prev_frame->edit_mode;
frame->equipped_tile = prev_frame->equipped_tile; frame->equipped_tile = prev_frame->equipped_tile;
frame->equipped_prefab = prev_frame->equipped_prefab ;
frame->edit_camera_pos = prev_frame->edit_camera_pos; frame->edit_camera_pos = prev_frame->edit_camera_pos;
frame->edit_camera_zoom = prev_frame->edit_camera_zoom; frame->edit_camera_zoom = prev_frame->edit_camera_zoom;
frame->sim_key = prev_frame->sim_key; frame->sim_key = prev_frame->sim_key;
@ -2010,24 +2011,38 @@ void V_TickForever(WaveLaneCtx *lane)
frame->shade_selection.p1 = MulAffineVec2(frame->af.world_to_shade, frame->world_selection.p1); frame->shade_selection.p1 = MulAffineVec2(frame->af.world_to_shade, frame->world_selection.p1);
////////////////////////////// //////////////////////////////
//- Place tiles //- Edit world
// TODO: Push vis cmd instead // TODO: Push vis cmd instead
if (frame->is_editing && prev_frame->is_selecting && !frame->is_selecting) if (frame->is_editing)
{ {
if (prev_frame->selection_mode == V_SelectionMode_Tile) if (frame->edit_mode == V_EditMode_Tile)
{ {
Rng2I32 tile_range = Zi; if (prev_frame->is_selecting && !frame->is_selecting)
{ {
tile_range.p0 = Vec2I32FromVec(FloorVec2(MulAffineVec2(frame->af.world_to_tile, prev_frame->world_selection.p0))); Rng2I32 tile_range = Zi;
tile_range.p1 = Vec2I32FromVec(CeilVec2(MulAffineVec2(frame->af.world_to_tile, prev_frame->world_selection.p1))); {
tile_range.p1.x = MaxI32(tile_range.p1.x, tile_range.p0.x + 1); tile_range.p0 = Vec2I32FromVec(FloorVec2(MulAffineVec2(frame->af.world_to_tile, prev_frame->world_selection.p0)));
tile_range.p1.y = MaxI32(tile_range.p1.y, tile_range.p0.y + 1); tile_range.p1 = Vec2I32FromVec(CeilVec2(MulAffineVec2(frame->af.world_to_tile, prev_frame->world_selection.p1)));
tile_range.p1.x = MaxI32(tile_range.p1.x, tile_range.p0.x + 1);
tile_range.p1.y = MaxI32(tile_range.p1.y, tile_range.p0.y + 1);
}
P_Msg *msg = P_PushMsg(P_MsgKind_TileEdit, Zstr);
msg->tile_kind = prev_frame->equipped_tile;
msg->tile_range = tile_range;
}
}
if (frame->edit_mode == V_EditMode_Prefab)
{
if (frame->held_buttons[Button_M1] && !prev_frame->held_buttons[Button_M1])
{
P_Msg *msg = P_PushMsg(P_MsgKind_Prefab, Zstr);
msg->prefab = frame->equipped_prefab;
msg->key = P_RandKey();
msg->xf.t = frame->world_cursor;
} }
P_Msg *msg = P_PushMsg(P_MsgKind_TileEdit, Zstr);
msg->tile_kind = prev_frame->equipped_tile;
msg->tile_range = tile_range;
} }
} }
@ -3241,49 +3256,6 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Build tile window //- Build tile window
// if (window->is_tile_window)
// {
// for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind)
// {
// String name = P_NameFromTileKind(tile_kind);
// UI_Key key = UI_KeyF("Tile %F", FmtString(name));
// UI_BoxReport rep = UI_ReportsFromKey(key).draw;
// if (rep.m1.downs)
// {
// frame->equipped_tile = tile_kind;
// }
// Vec4 bg_color = Zi;
// bg_color = LerpSrgb(bg_color, theme.col.button_hot, rep.hot);
// bg_color = LerpSrgb(bg_color, theme.col.button_active, rep.active);
// b32 is_selected = tile_kind == frame->equipped_tile;
// Vec4 border_color = Zi;
// border_color = LerpSrgb(border_color, theme.col.button_selected, rep.misc);
// border_color = LerpSrgb(border_color, theme.col.button_active, rep.hot);
// UI_SetNext(BackgroundColor, bg_color);
// UI_SetNext(BorderColor, border_color);
// UI_SetNext(BorderSize, 1);
// UI_SetNext(Width, UI_GROW(1, 0));
// UI_SetNext(Height, UI_SHRINK(0, 0));
// UI_SetNext(Misc, is_selected);
// UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
// UI_PushCP(UI_BuildRowEx(key));
// {
// UI_SetNext(ChildAlignment, UI_Region_Center);
// UI_SetNext(Text, name);
// UI_SetNext(Flags, UI_BoxFlag_DrawText);
// UI_SetNext(Width, UI_SHRINK(4, 0));
// UI_SetNext(Height, UI_SHRINK(2, 0));
// UI_BuildRow();
// }
// UI_PopCP(UI_TopCP());
// }
// }
if (window->is_tile_window) if (window->is_tile_window)
{ {
for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind) for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind)
@ -3294,6 +3266,7 @@ void V_TickForever(WaveLaneCtx *lane)
if (rep.m1.downs) if (rep.m1.downs)
{ {
frame->edit_mode = V_EditMode_Tile;
frame->equipped_tile = tile_kind; frame->equipped_tile = tile_kind;
} }
@ -3301,7 +3274,10 @@ void V_TickForever(WaveLaneCtx *lane)
bg_color = LerpSrgb(bg_color, theme.col.button_hot, rep.hot); bg_color = LerpSrgb(bg_color, theme.col.button_hot, rep.hot);
bg_color = LerpSrgb(bg_color, theme.col.button_active, rep.active); bg_color = LerpSrgb(bg_color, theme.col.button_active, rep.active);
b32 is_selected = tile_kind == frame->equipped_tile; b32 is_selected = (
frame->edit_mode == V_EditMode_Tile &&
tile_kind == frame->equipped_tile
);
Vec4 border_color = Zi; Vec4 border_color = Zi;
border_color = LerpSrgb(border_color, theme.col.button_selected, rep.misc); border_color = LerpSrgb(border_color, theme.col.button_selected, rep.misc);
@ -3353,7 +3329,74 @@ void V_TickForever(WaveLaneCtx *lane)
if (window->is_prefab_window) if (window->is_prefab_window)
{ {
for (P_PrefabKind prefab_kind = 0; prefab_kind < P_PrefabKind_COUNT; ++prefab_kind)
{
String prefab_name = P_NameFromPrefabKind(prefab_kind);
P_PrefabFlag prefab_flags = P_FlagsFromPrefabKind(prefab_kind);
if (!AnyBit(prefab_flags, P_PrefabFlag_HideFromEditor))
{
UI_Key key = UI_KeyF("Prefab %F", FmtString(prefab_name));
UI_BoxReport rep = UI_ReportsFromKey(key).draw;
if (rep.m1.downs)
{
frame->edit_mode = V_EditMode_Prefab;
frame->equipped_prefab = prefab_kind;
}
Vec4 bg_color = Zi;
bg_color = LerpSrgb(bg_color, theme.col.button_hot, rep.hot);
bg_color = LerpSrgb(bg_color, theme.col.button_active, rep.active);
b32 is_selected = (
frame->edit_mode == V_EditMode_Prefab &&
prefab_kind == frame->equipped_prefab
);
Vec4 border_color = Zi;
border_color = LerpSrgb(border_color, theme.col.button_selected, rep.misc);
border_color = LerpSrgb(border_color, theme.col.button_active, rep.hot);
UI_SetNext(BackgroundColor, bg_color);
UI_SetNext(BorderColor, border_color);
UI_SetNext(BorderSize, 1);
UI_SetNext(Width, UI_GROW(1, 0));
UI_SetNext(Height, UI_SHRINK(UI_FNT(0.25, 0).v, 0));
UI_SetNext(Misc, is_selected);
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_SetNext(ChildAlignment, UI_Region_Left);
UI_PushCP(UI_BuildRowEx(key));
{
UI_BuildSpacer(UI_FNT(0.25, 0), Axis_X);
// Prefab sprite
{
String sheet_name = StringF(frame->arena, "prefab/%F.ase", FmtString(prefab_name));
ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name);
SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource);
UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetNext(Width, UI_FNT(2.5, 0));
UI_SetNext(Height, UI_FNT(2.5, 0));
UI_SetNext(SpriteSheet, sheet);
UI_BuildRow();
}
UI_BuildSpacer(UI_FNT(0.5, 0), Axis_X);
// Prefab name
{
UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetNext(Text, prefab_name);
UI_SetNext(Flags, UI_BoxFlag_DrawText);
UI_SetNext(Width, UI_SHRINK(4, 0));
UI_SetNext(Height, UI_SHRINK(2, 0));
UI_BuildRow();
}
}
UI_PopCP(UI_TopCP());
}
}
} }
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
@ -4505,7 +4548,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
SPR_Sprite tile_sprite = Zi; SPR_Sprite tile_sprite = Zi;
{ {
String tile_name = P_TileNameFromKind(tile_kind); String tile_name = P_NameFromTileKind(tile_kind);
String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name));
ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name);
SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource);

View File

@ -39,15 +39,6 @@ ComputeShader2D(V_PrepareCellsCS, 8, 8)
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(frame.cells); RWTexture2D<Vec4> cells = G_Dereference<Vec4>(frame.cells);
RWTexture2D<f32> drynesses = G_Dereference<f32>(frame.drynesses); RWTexture2D<f32> drynesses = G_Dereference<f32>(frame.drynesses);
if (all(SV_DispatchThreadID == 0))
{
G_PrintF(
"IsGpu: %F, IsCompilerClang: %F",
G_Fmt((i32)IsGpu),
G_Fmt((i32)IsCompilerClang)
);
}
Vec2 cells_pos = SV_DispatchThreadID + 0.5; Vec2 cells_pos = SV_DispatchThreadID + 0.5;
if (all(cells_pos < countof(cells))) if (all(cells_pos < countof(cells)))
{ {
@ -532,8 +523,9 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
Vec4 selection_color = 0; Vec4 selection_color = 0;
if ( if (
frame.is_editing &&
frame.edit_mode == V_EditMode_Tile &&
frame.has_mouse_focus && frame.has_mouse_focus &&
frame.selection_mode == V_SelectionMode_Tile &&
is_in_world is_in_world
) )
{ {

View File

@ -17,14 +17,13 @@ Struct(V_TileDesc)
Enum(V_SelectionMode) Enum(V_SelectionMode)
{ {
V_SelectionMode_None,
V_SelectionMode_Tile, V_SelectionMode_Tile,
}; };
Enum(V_EditMode) Enum(V_EditMode)
{ {
V_EditMode_None,
V_EditMode_Tile, V_EditMode_Tile,
V_EditMode_Prefab,
}; };
Struct(V_Affines) Struct(V_Affines)
@ -80,8 +79,11 @@ Struct(V_SharedFrame)
//- Editor state //- Editor state
V_EditMode edit_mode; V_EditMode edit_mode;
P_TileKind equipped_tile;
V_SelectionMode selection_mode; V_SelectionMode selection_mode;
P_TileKind equipped_tile;
P_PrefabKind equipped_prefab;
Vec2 world_selection_start; Vec2 world_selection_start;
Vec2 edit_camera_pos; Vec2 edit_camera_pos;
f32 edit_camera_zoom; f32 edit_camera_zoom;

View File

@ -44,12 +44,7 @@ String SPR_NameFromRayKind(SPR_RayKind kind)
SPR_RayKindXList(X) SPR_RayKindXList(X)
#undef X #undef X
}; };
String result = Zi; return names[kind];
if (kind >= 0 && kind < countof(names))
{
result = names[kind];
}
return result;
} }
SPR_LayerKind SPR_LayerKindFromName(String name) SPR_LayerKind SPR_LayerKindFromName(String name)