add clang support to metaprogram

This commit is contained in:
jacob 2026-02-12 18:32:35 -06:00
parent 4b207e81fe
commit fdd888cb32
18 changed files with 267 additions and 85 deletions

View File

@ -369,6 +369,8 @@ ASE_Meta ASE_DecodeMeta(Arena *arena, String encoded)
u64 chunk_end_pos = BB_GetCurrentReaderByte(&bbr) + chunk_size;
switch (encoded_chunk_kind)
{
default: break;
//- Layer chunk
case ASE_EncodedChunkKind_Layer:
{
@ -480,8 +482,6 @@ ASE_Meta ASE_DecodeMeta(Arena *arena, String encoded)
}
}
}
// Sanity check to make sure all data was read
Assert(BB_NumBytesRemaining(&bbr) == 0);
}
//////////////////////////////

View File

@ -204,12 +204,8 @@
//- Read-only
#if IsCpu
#if IsPlatformWindows
#if IsCompilerMsvc
#pragma section(".rdata$", read)
#define Readonly __declspec(allocate(".rdata$"))
#else
#define Readonly __declspec(allocate(".rdata$"))
#endif
#pragma section(".rdata")
#define Readonly __declspec(allocate(".rdata"))
#elif IsPlatformMac
#define Readonly __attribute((section("__TEXT,__const")))
#else
@ -222,6 +218,8 @@
//- Thread-local
#if IsCompilerMsvc
#define ThreadLocal __declspec(thread)
#else
#define ThreadLocal __thread
#endif
//- Compiler memory barriers

View File

@ -393,7 +393,7 @@ Vec2 Vec2FromAngle(f32 a);
f32 AngleFromVec2(Vec2 v);
//- Area
f32 DimsFromVec2(Vec2 v);
f32 AreaFromVec2(Vec2 v);
//- Closest point
Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p);
@ -410,6 +410,8 @@ b32 MatchVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 NegVec2I32(Vec2I32 a);
Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 MulVec2I32Vec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 DivVec2I32Vec2I32(Vec2I32 a, Vec2I32 b);
////////////////////////////////////////////////////////////
//~ Vec4
@ -489,8 +491,9 @@ Affine InvertAffine(Affine af);
//- Mul
Affine MulAffine(Affine a, Affine b);
Vec2 MulAffineVec2(Affine af, Vec2 v);
Vec2 MulAffineBasisVec2(Affine af, Vec2 v);
Vec2 MulAffineVec2(Affine af, Vec2 v);
Affine MulAffineXform(Affine af, Xform xf);
//- Helpers
Affine BasisFromAffine(Affine af);

View File

@ -79,7 +79,9 @@ String StringFromChar(Arena *arena, char c);
String StringFromUint(Arena *arena, u64 n, u64 base, u64 zfill);
String StringFromUints(Arena *arena, u64 uints_count, u64 *uints, u64 base, u64 zfill);
String StringFromSint(Arena *arena, i64 n, u64 base, u64 zfill);
String StringFromSints(Arena *arena, u64 sints_count, i64 *sints, u64 base, u64 zfill);
String StringFromFloat(Arena *arena, f64 src, u32 precision);
String StringFromFloats(Arena *arena, u64 floats_count, f64 *floats, u32 precision);
String StringFromPtr(Arena *arena, void *ptr);
String StringFromhandle(Arena *arena, u64 v);
String StringFromUid(Arena *arena, Uid uid);

View File

@ -97,10 +97,10 @@ TweakVarArray GetAllTweakVars(Arena *arena);
//~ Tweak utils
b32 TweakBool_(String name, b32 initial, TweakBoolDesc desc);
#define TweakBool(_name, _initial) TweakBool_(Lit(_name), (_initial), (TweakBoolDesc) { \
#define TweakBool(_name, _initial, ...) TweakBool_(Lit(_name), (_initial), (TweakBoolDesc) { \
.category = Lit("Debug"), \
__VA_ARGS__ \
}) \
})
f64 TweakFloat_(String name, f64 initial, TweakFloatDesc desc);
#define TweakFloat(_name, _initial, _min, _max, ...) TweakFloat_(Lit(_name), (_initial), (TweakFloatDesc) { \

View File

@ -109,7 +109,7 @@ BOOL W32_FindEmbeddedRcData(HMODULE module, LPCWSTR type, LPWSTR wstr_entry_name
////////////////////////////////////////////////////////////
//~ Log
void W32_BootstrapLogs();
void W32_BootstrapLogs(void);
void W32_Log(i32 level, String msg);
////////////////////////////////////////////////////////////

View File

@ -327,7 +327,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
// Determine pos in atlas
pos_in_atlas = atlas->cur_pos;
atlas->cur_row_height = MaxI32(atlas->cur_row_height, image_dims.y);
if (pos_in_atlas.x + image_dims.x > atlas->dims.x);
if (pos_in_atlas.x + image_dims.x > atlas->dims.x)
{
atlas->cur_pos.x = 0;
atlas->cur_pos.y += atlas->cur_row_height;

View File

@ -213,7 +213,7 @@ M_EmbedObj M_Embed(String store_name, String dir_path)
F_ClearWrite(arc_path, arc_contents);
// Generate object file
if (IsPlatformWindows)
if (M.cmdline.target_platform == M_PlatformKind_Windows)
{
// Generate RC file
String rc_out_file = StringF(perm, "%F.rc", FmtString(store_name));
@ -303,19 +303,15 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
}
//////////////////////////////
//- Command line
//- Init command line
Struct(CmdLineArgs)
// Layer name
{
String leaf_layer_name;
};
CmdLineArgs cmdline = Zi;
{
CommandlineArg layer_arg = CommandlineArgFromName(Lit("layer"));
CommandlineArg arg = CommandlineArgFromName(Lit("layer"));
String layer_name = Zi;
if (layer_arg.name.len != 0)
if (arg.name.len != 0)
{
layer_name = layer_arg.value;
layer_name = arg.value;
}
else
{
@ -329,12 +325,95 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
M_EchoLine(Lit("No layer specified, assuming \"pp\" build"));
}
}
cmdline.leaf_layer_name = layer_name;
M.cmdline.leaf_layer_name = layer_name;
}
// Platform
{
CommandlineArg arg = CommandlineArgFromName(Lit("platform"));
if (MatchString(arg.value, Lit("windows")))
{
M.cmdline.target_platform = M_PlatformKind_Windows;
}
else if (MatchString(arg.value, Lit("macos")))
{
M.cmdline.target_platform = M_PlatformKind_Mac;
}
else if (MatchString(arg.value, Lit("linux")))
{
M.cmdline.target_platform = M_PlatformKind_Linux;
}
else
{
if (IsPlatformWindows)
{
M.cmdline.target_platform = M_PlatformKind_Windows;
}
else if (IsPlatformMac)
{
M.cmdline.target_platform = M_PlatformKind_Mac;
}
else
{
M.cmdline.target_platform = M_PlatformKind_Linux;
}
}
}
// Compiler
{
CommandlineArg arg = CommandlineArgFromName(Lit("compiler"));
if (MatchString(arg.value, Lit("msvc")))
{
M.cmdline.target_compiler = M_CompilerKind_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;
}
else
{
M.cmdline.target_compiler = M_CompilerKind_Clang;
}
}
}
// Release/Debug
{
CommandlineArg arg = CommandlineArgFromName(Lit("release"));
if (arg.exists)
{
M.cmdline.release = 1;
}
}
if (lane->idx == 0)
{
M_EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(cmdline.leaf_layer_name)));
if (M.cmdline.target_compiler == M_CompilerKind_Msvc)
{
M_EchoLine(Lit("[Msvc]"));
}
else if (M.cmdline.target_compiler == M_CompilerKind_Clang)
{
M_EchoLine(Lit("[Clang]"));
}
if (M.cmdline.release)
{
M_EchoLine(Lit("[Release build]"));
}
else
{
M_EchoLine(Lit("[Debug build]"));
}
M_EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(M.cmdline.leaf_layer_name)));
}
//////////////////////////////
@ -352,19 +431,28 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
PushStringToList(perm, &cp.defs, Lit("-DIsUnoptimized=1"));
PushStringToList(perm, &cp.defs, Lit("-DIsTestingEnabled=0"));
PushStringToList(perm, &cp.defs, Lit("-DIsHotSwappingEnabled=1"));
PushStringToList(perm, &cp.defs, StringF(perm, "-DDefaultAppName=%F", FmtString(cmdline.leaf_layer_name)));
PushStringToList(perm, &cp.defs, StringF(perm, "-DDefaultAppName=%F", FmtString(M.cmdline.leaf_layer_name)));
}
//- Msvc
{
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-diagnostics:column"));
PushStringToList(perm, &cp.flags_msvc, Lit("-INCREMENTAL:NO"));
PushStringToList(perm, &cp.flags_msvc, Lit("-nologo"));
// Optimization
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Od"));
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-diagnostics:column"));
// Debug info
if (M.cmdline.release)
{
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-MT"));
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-O2"));
}
else
{
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-MTd"));
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Od"));
}
// TODO: Export debug info separately for release builds
PushStringToList(perm, &cp.flags_msvc, Lit("-DEBUG:FULL"));
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Z7"));
@ -396,17 +484,39 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
//- Clang
{
PushStringToList(perm, &cp.flags_clang, Lit("-std=c99"));
PushStringToList(perm, &cp.flags_clang, Lit("-fno-finite-loops"));
PushStringToList(perm, &cp.flags_clang, Lit("-fno-strict-aliasing"));
PushStringToList(perm, &cp.flags_clang, Lit("-g -gcodeview"));
PushStringToList(perm, &cp.flags_clang, Lit("-O0"));
PushStringToList(perm, &cp.flags_clang, Lit("-msse4.2"));
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-std=c99"));
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-fno-finite-loops"));
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-fno-strict-aliasing"));
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-msse4.2"));
// TODO: Export debug info separately for release builds
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-g -gcodeview"));
if (M.cmdline.release)
{
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-O2"));
}
else
{
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-O0"));
}
if (M.cmdline.target_platform == M_PlatformKind_Windows)
{
if (M.cmdline.release)
{
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-fms-runtime-lib=static_dbg"));
}
else
{
PushStringToList(perm, &cp.compiler_only_flags_clang, Lit("-fms-runtime-lib=static"));
}
}
// Enable warnings
PushStringToList(perm, &cp.warnings_clang, Lit("-Wall"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Werror"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wframe-larger-than=65536"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wframe-larger-than=1048575"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wmissing-prototypes"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wmissing-declarations"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wunused-variable"));
@ -418,9 +528,14 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
// Disable warnings
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-initializer-overrides"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-microsoft-enum-forward-reference"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-microsoft-anon-tag"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-variable"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-but-set-variable"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-parameter"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-incompatible-function-pointer-types"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-missing-braces"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-switch"));
PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-value"));
}
//- Dxc
@ -462,8 +577,8 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
// TODO: Dispatch OS commands asynchronously
String shader_store_name = Lit("ShadersStore");
String c_out_file = F_GetFull(perm, StringF(perm, "%F_gen.c", FmtString(cmdline.leaf_layer_name)));
String gpu_out_file = F_GetFull(perm, StringF(perm, "%F_gen.g", FmtString(cmdline.leaf_layer_name)));
String c_out_file = F_GetFull(perm, StringF(perm, "%F_gen.c", FmtString(M.cmdline.leaf_layer_name)));
String gpu_out_file = F_GetFull(perm, StringF(perm, "%F_gen.g", FmtString(M.cmdline.leaf_layer_name)));
u64 shader_store_hash = HashString(shader_store_name);
if (lane->idx == 0 && M_GetBuildStatus() == 0)
@ -480,7 +595,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
// Flatten
StringList starting_layer_names = Zi;
PushStringToList(perm, &starting_layer_names, cmdline.leaf_layer_name);
PushStringToList(perm, &starting_layer_names, M.cmdline.leaf_layer_name);
M.layers_parse = M_FlattenEntries(perm, parsed, starting_layer_names);
M_SetBuildStatus(M.layers_parse.errors.count > 0);
@ -842,8 +957,11 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
{
if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && M_GetBuildStatus() == 0)
{
M.c_obj.obj_file = StringF(perm, "%F_gen_c.obj", FmtString(cmdline.leaf_layer_name));
String cmd = StringF(
M.c_obj.obj_file = StringF(perm, "%F_gen_c.obj", FmtString(M.cmdline.leaf_layer_name));
String cmd = Zi;
if (M.cmdline.target_compiler == M_CompilerKind_Msvc)
{
cmd = StringF(
perm,
"cl.exe /c %F -Fo:%F %F %F %F %F",
FmtString(c_out_file),
@ -853,6 +971,20 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
FmtString(StringFromList(perm, cp.warnings_msvc, Lit(" "))),
FmtString(StringFromList(perm, cp.defs, Lit(" ")))
);
}
else
{
cmd = StringF(
perm,
"clang.exe -c %F -o %F %F %F %F %F",
FmtString(c_out_file),
FmtString(M.c_obj.obj_file),
FmtString(StringFromList(perm, cp.flags_clang, Lit(" "))),
FmtString(StringFromList(perm, cp.compiler_only_flags_clang, Lit(" "))),
FmtString(StringFromList(perm, cp.warnings_clang, Lit(" "))),
FmtString(StringFromList(perm, cp.defs, Lit(" ")))
);
}
OS_CommandResult cmd_result = OS_RunCommand(perm, cmd);
String cmd_output = TrimWhitespace(cmd_result.output);
M.c_obj.output = cmd_output;
@ -941,7 +1073,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
if (lane->idx == 0 && M_GetBuildStatus() == 0)
{
String exe_file = StringF(perm, "%F.exe", FmtString(cmdline.leaf_layer_name));
String exe_file = StringF(perm, "%F.exe", FmtString(M.cmdline.leaf_layer_name));
{
// Wait for exe to become writable (wait for program to close)
f32 timeout = 1.0;
@ -962,8 +1094,10 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
}
obj_files_str = StringFromList(perm, obj_files, Lit(" "));
}
String cmd = StringF(
String cmd = Zi;
if (M.cmdline.target_compiler == M_CompilerKind_Msvc)
{
cmd = StringF(
perm,
"link.exe %F /OUT:%F %F %F",
FmtString(obj_files_str),
@ -971,6 +1105,18 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
FmtString(StringFromList(perm, cp.flags_msvc, Lit(" "))),
FmtString(StringFromList(perm, cp.linker_only_flags_msvc, Lit(" ")))
);
}
else
{
cmd = StringF(
perm,
"lld-link.exe %F /OUT:%F %F %F",
FmtString(obj_files_str),
FmtString(exe_file),
FmtString(StringFromList(perm, cp.flags_clang, Lit(" "))),
FmtString(StringFromList(perm, cp.linker_only_flags_clang, Lit(" ")))
);
}
OS_CommandResult result = OS_RunCommand(perm, cmd);
M.link.output = TrimWhitespace(result.output);
M.link.return_code = result.code;

View File

@ -121,6 +121,30 @@ Struct(M_EmbedObj)
i32 return_code;
};
////////////////////////////////////////////////////////////
//~ Command line types
Enum(M_PlatformKind)
{
M_PlatformKind_Windows,
M_PlatformKind_Mac,
M_PlatformKind_Linux,
};
Enum(M_CompilerKind)
{
M_CompilerKind_Msvc,
M_CompilerKind_Clang,
};
Struct(M_CommandLine)
{
b32 release;
String leaf_layer_name;
M_PlatformKind target_platform;
M_CompilerKind target_compiler;
};
////////////////////////////////////////////////////////////
//~ State types
@ -128,6 +152,7 @@ Struct(M_Ctx)
{
Atomic32 status;
M_CommandLine cmdline;
M_Layer layers_parse;
struct

View File

@ -84,12 +84,6 @@ Enum(M_EntryKind)
M_EntryKind_EmbedDir,
};
Enum(M_PlatformKind)
{
M_PlatformKind_Any,
M_PlatformKind_Win32,
};
Global Readonly char *M_entry_kind_rules[] = {
[M_EntryKind_Layer] = "@Layer",
[M_EntryKind_Dep] = "@Dep",

View File

@ -856,7 +856,7 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
NET_W32_Packet *next = packet->next;
{
b32 msg_has_end = 0;
if (packet->msg_seq != peer->last_cont_packet->msg_seq || !!(peer->last_cont_packet->flags | NET_W32_PacketFlag_EndMsg))
if (packet->msg_seq != peer->last_cont_packet->msg_seq || !!(peer->last_cont_packet->flags & NET_W32_PacketFlag_EndMsg))
{
msg_has_end = 1;
}

View File

@ -50,6 +50,7 @@ void PLT_Bootstrap(void);
//- File system helpers
b32 PLT_IsFile(String path);
b32 PLT_IsDir(String path);
b32 PLT_MkDir(String path);
//- File creation
PLT_File PLT_OpenFileRead(String path);

View File

@ -1313,7 +1313,6 @@ P_Space P_SpaceFromWalls(Arena *arena, P_Frame *frame)
Vec2I32 end;
};
i64 walls_count = 0;
GenWall *first_wall = 0;
//- Generate horizontal walls
@ -1350,7 +1349,6 @@ P_Space P_SpaceFromWalls(Arena *arena, P_Frame *frame)
if (prev_wall_dir != WallDir_None)
{
GenWall *wall = PushStruct(scratch.arena, GenWall);
++walls_count;
SllStackPush(first_wall, wall);
wall->dir = prev_wall_dir;
wall->start = VEC2I32(wall_start, tile_y);
@ -1396,7 +1394,6 @@ P_Space P_SpaceFromWalls(Arena *arena, P_Frame *frame)
if (prev_wall_dir != WallDir_None)
{
GenWall *wall = PushStruct(scratch.arena, GenWall);
++walls_count;
SllStackPush(first_wall, wall);
wall->dir = prev_wall_dir;
wall->start = VEC2I32(tile_x, wall_start);

View File

@ -2173,11 +2173,8 @@ void V_TickForever(WaveLaneCtx *lane)
if (!skip)
{
f32 trail_len = Vec2Len(SubVec2(end, start));
// f32 particles_count = MaxF32(trail_len * 10000, 1);
// f32 particles_count = MaxF32(trail_len * 512, 1);
// f32 particles_count = MaxF32(trail_len * 64, 1);
f32 particles_count = MaxF32(trail_len * 32, 1);
f32 particles_count = trail_len * frame->dt * Kibi(8); // Particles per meter per second
particles_count = MaxF32(particles_count, 1);
f32 angle = AngleFromVec2(PerpVec2(SubVec2(end, start)));
// f32 angle = AngleFromVec2(NegVec2(SubVec2(end, start)));
@ -2490,10 +2487,23 @@ void V_TickForever(WaveLaneCtx *lane)
// }
// }
//////////////////////////////
//- Push test explosion
// if (frame->held_buttons[Button_F] && !prev_frame->held_buttons[Button_F])
// {
// }
//////////////////////////////
//- Push test emitter
if (frame->held_buttons[Button_F])
if (frame->held_buttons[Button_G])
{
V_Emitter emitter = Zi;
@ -2504,7 +2514,8 @@ void V_TickForever(WaveLaneCtx *lane)
// emitter.flags |= V_ParticleFlag_StainTrail;
emitter.count = 128;
// emitter.count = 128;
emitter.count = CeilF32(Kibi(16) * frame->dt);
emitter.speed = 10;
emitter.color_lin = LinearFromSrgb(Color_Yellow);
@ -3597,7 +3608,7 @@ void V_TickForever(WaveLaneCtx *lane)
for (u64 cmd_desc_idx = 0; cmd_desc_idx < countof(V_cmd_descs); ++cmd_desc_idx)
{
V_CmdDesc cmd_desc = V_cmd_descs[cmd_desc_idx];
if (!cmd_desc.flags & V_CmdDescFlag_HideFromPalette)
if (!(cmd_desc.flags & V_CmdDescFlag_HideFromPalette))
{
PaletteItem *item = PushStruct(frame->arena, PaletteItem);
{

View File

@ -306,6 +306,11 @@ void V_DrawPoint(Vec2 p, Vec4 srgb);
V_WidgetTheme V_GetWidgetTheme(void);
void V_PushWidgetThemeStyles(V_WidgetTheme theme);
////////////////////////////////////////////////////////////
//~ Notification helpers
void V_PushNotif(String msg);
////////////////////////////////////////////////////////////
//~ Vis tick

View File

@ -450,7 +450,7 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
// Determine pos in atlas
atlas_pos = atlas->cur_pos;
atlas->cur_row_height = MaxI32(atlas->cur_row_height, slice_dims.y);
if (atlas_pos.x + slice_dims.x > atlas->dims.x);
if (atlas_pos.x + slice_dims.x > atlas->dims.x)
{
atlas->cur_pos.x = 0;
atlas->cur_pos.y += atlas->cur_row_height;

View File

@ -1,7 +1,7 @@
// Based on Allen Webster's dwrite rasterizer example -
// https://github.com/4th-dimention/examps
extern TTF_DW_Ctx TTF_DW = Zi;
TTF_DW_Ctx TTF_DW = Zi;
////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap