base layer refactored

This commit is contained in:
jacob 2025-07-30 15:47:14 -05:00
parent 380f63cacf
commit 1215f9ff58
39 changed files with 1574 additions and 1337 deletions

View File

@ -13,12 +13,12 @@ internal String initialize_write_directory(Arena *arena, String write_dir)
/* Create write path */ /* Create write path */
String base_write_dir = P_GetWritePath(scratch.arena); String base_write_dir = P_GetWritePath(scratch.arena);
String write_path_fmt = base_write_dir.len > 0 ? LIT("%F/%F/") : LIT("%F%F/"); String write_path_fmt = base_write_dir.len > 0 ? Lit("%F/%F/") : Lit("%F%F/");
String write_path = string_format( String write_path = StringFormat(
arena, arena,
write_path_fmt, write_path_fmt,
FMT_STR(base_write_dir), FmtString(base_write_dir),
FMT_STR(write_dir) FmtString(write_dir)
); );
/* Create write dir if not present */ /* Create write dir if not present */
@ -34,7 +34,7 @@ internal String initialize_write_directory(Arena *arena, String write_dir)
String app_write_path_cat(Arena *arena, String filename) String app_write_path_cat(Arena *arena, String filename)
{ {
return string_cat(arena, G.write_path, filename); return CatString(arena, G.write_path, filename);
} }
/* ========================== * /* ========================== *
@ -118,8 +118,8 @@ internal struct app_arg_list parse_args(Arena *arena, String args_str)
value_end = i + 1; value_end = i + 1;
} }
if (key_start >= 0 && key_end > key_start && key_end <= (i64)args_str.len && value_start >= 0 && value_end > value_start && value_end <= (i64)args_str.len) { if (key_start >= 0 && key_end > key_start && key_end <= (i64)args_str.len && value_start >= 0 && value_end > value_start && value_end <= (i64)args_str.len) {
String key = string_copy(arena, STRING(key_end - key_start, args_str.text + key_start)); String key = CopyString(arena, STRING(key_end - key_start, args_str.text + key_start));
String value = string_copy(arena, STRING(value_end - value_start, args_str.text + value_start)); String value = CopyString(arena, STRING(value_end - value_start, args_str.text + value_start));
struct app_arg *arg = PushStruct(arena, struct app_arg); struct app_arg *arg = PushStruct(arena, struct app_arg);
arg->key = key; arg->key = key;
arg->value = value; arg->value = value;
@ -152,17 +152,17 @@ void P_AppStartup(String args_str)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
struct app_arg_list args = parse_args(scratch.arena, args_str); struct app_arg_list args = parse_args(scratch.arena, args_str);
String logfile_name = LIT("log.log"); String logfile_name = Lit("log.log");
String settings_file_name = LIT("settings.txt"); String settings_file_name = Lit("settings.txt");
String connect_address = ZI; String connect_address = ZI;
for (struct app_arg *arg = args.first; arg; arg = arg->next) { for (struct app_arg *arg = args.first; arg; arg = arg->next) {
String key = arg->key; String key = arg->key;
String value = arg->value; String value = arg->value;
if (string_eq(key, LIT("log"))) { if (EqString(key, Lit("log"))) {
logfile_name = value; logfile_name = value;
} else if (string_eq(key, LIT("settings"))) { } else if (EqString(key, Lit("settings"))) {
settings_file_name = value; settings_file_name = value;
} else if (string_eq(key, LIT("connect"))) { } else if (EqString(key, Lit("connect"))) {
connect_address = value; connect_address = value;
} }
} }
@ -190,23 +190,23 @@ void P_AppStartup(String args_str)
G.arena = AllocArena(Gibi(64)); G.arena = AllocArena(Gibi(64));
G.write_path = initialize_write_directory(G.arena, LIT(WRITE_DIR)); G.write_path = initialize_write_directory(G.arena, Lit(WRITE_DIR));
/* Startup logging */ /* Startup logging */
{ {
TempArena temp = BeginTempArena(scratch.arena); TempArena temp = BeginTempArena(scratch.arena);
String logfile_dir = string_cat(temp.arena, G.write_path, LIT("logs/")); String logfile_dir = CatString(temp.arena, G.write_path, Lit("logs/"));
String logfile_path = string_cat(temp.arena, logfile_dir, logfile_name); String logfile_path = CatString(temp.arena, logfile_dir, logfile_name);
P_MkDir(logfile_dir); P_MkDir(logfile_dir);
P_LogStartup(logfile_path); P_LogStartup(logfile_path);
P_LogInfoF("Start of logs"); P_LogInfoF("Start of logs");
EndTempArena(temp); EndTempArena(temp);
} }
P_LogInfoF("App started with args \"%F\" (%F parsed)", FMT_STR(args_str), FMT_UINT(args.count)); P_LogInfoF("App started with args \"%F\" (%F parsed)", FmtString(args_str), FmtUint(args.count));
for (struct app_arg *arg = args.first; arg; arg = arg->next) { for (struct app_arg *arg = args.first; arg; arg = arg->next) {
P_LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FMT_STR(arg->key), FMT_STR(arg->value)); P_LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FmtString(arg->key), FmtString(arg->value));
} }
#if 0 #if 0
@ -216,27 +216,27 @@ void P_AppStartup(String args_str)
P_WindowSettings window_settings = ZI; P_WindowSettings window_settings = ZI;
String settings_path = app_write_path_cat(temp.arena, settings_file_name); String settings_path = app_write_path_cat(temp.arena, settings_file_name);
P_LogInfoF("Looking for settings file \"%F\"", FMT_STR(settings_path)); P_LogInfoF("Looking for settings file \"%F\"", FmtString(settings_path));
if (P_IsFile(settings_path)) { if (P_IsFile(settings_path)) {
P_LogInfoF("Settings file found"); P_LogInfoF("Settings file found");
P_File settings_file = P_OpenFileRead(settings_path); P_File settings_file = P_OpenFileRead(settings_path);
String file_data = P_ReadFile(temp.arena, settings_file); String file_data = P_ReadFile(temp.arena, settings_file);
P_CloseFIle(settings_file); P_CloseFIle(settings_file);
P_LogInfoF("Deserializing settings file data: %F", FMT_STR(file_data)); P_LogInfoF("Deserializing settings file data: %F", FmtString(file_data));
String error = ZI; String error = ZI;
P_WindowSettings *res = settings_deserialize(temp.arena, file_data, &error); P_WindowSettings *res = settings_deserialize(temp.arena, file_data, &error);
if (error.len > 0) { if (error.len > 0) {
P_LogInfoF("Failed to load settings file with error - %F", FMT_STR(error)); P_LogInfoF("Failed to load settings file with error - %F", FmtString(error));
String msg = string_format(temp.arena, String msg = StringFormat(temp.arena,
LIT( Lit(
"Failed to loading settings file \"%F\":\n" "Failed to loading settings file \"%F\":\n"
"------------\n" "------------\n"
"%F\n" "%F\n"
"------------\n" "------------\n"
"To stop this error from appearing, either fix the issue above or delete the file from the system." "To stop this error from appearing, either fix the issue above or delete the file from the system."
), ),
FMT_STR(settings_path), FmtString(settings_path),
FMT_STR(error)); FmtString(error));
P_Panic(msg); P_Panic(msg);
} }
P_LogInfoF("Settings file loaded successfully"); P_LogInfoF("Settings file loaded successfully");
@ -245,7 +245,7 @@ void P_AppStartup(String args_str)
P_LogInfoF("Settings file not found, loading default"); P_LogInfoF("Settings file not found, loading default");
window_settings = default_window_settings(window); window_settings = default_window_settings(window);
} }
string_copy_to_string(STRING_FROM_ARRAY(window_settings.title), LIT(WINDOW_TITLE)); CopyStringToBuffer(StringFromArray(window_settings.title), Lit(WINDOW_TITLE));
P_UpdateWindowSettings(window, &window_settings); P_UpdateWindowSettings(window, &window_settings);
EndTempArena(temp); EndTempArena(temp);
@ -285,9 +285,9 @@ void P_AppStartup(String args_str)
P_WindowSettings settings = P_GetWindowSettings(window); P_WindowSettings settings = P_GetWindowSettings(window);
String str = settings_serialize(temp.arena, &settings); String str = settings_serialize(temp.arena, &settings);
P_LogInfoF("Serialized window settings: %F", FMT_STR(str)); P_LogInfoF("Serialized window settings: %F", FmtString(str));
P_LogInfoF("Writing settings file to path \"%F\"", FMT_STR(window_settings_path)); P_LogInfoF("Writing settings file to path \"%F\"", FmtString(window_settings_path));
P_File settings_file = P_OpenFileWrite(window_settings_path); P_File settings_file = P_OpenFileWrite(window_settings_path);
P_WriteFile(settings_file, str); P_WriteFile(settings_file, str);
P_CloseFIle(settings_file); P_CloseFIle(settings_file);

View File

@ -443,7 +443,7 @@ Packed(struct frame_header {
internal void push_error_copy_msg(Arena *arena, Ase_ErrorList *list, String msg_src) internal void push_error_copy_msg(Arena *arena, Ase_ErrorList *list, String msg_src)
{ {
Ase_Error *e = PushStruct(arena, Ase_Error); Ase_Error *e = PushStruct(arena, Ase_Error);
e->msg = string_copy(arena, msg_src); e->msg = CopyString(arena, msg_src);
if (!list->first) { if (!list->first) {
list->first = e; list->first = e;
} else { } else {
@ -554,17 +554,17 @@ Ase_DecodedImage ase_decode_image(Arena *arena, String encoded)
BB_Buff bb = BitbuffFromString(encoded); BB_Buff bb = BitbuffFromString(encoded);
BB_Reader br = BB_ReaderFromBuffNoDebug(&bb); BB_Reader br = BB_ReaderFromBuffNoDebug(&bb);
struct ase_header ase_header; struct ase_header ase_header;
BB_ReadBytes(&br, STRING_FROM_STRUCT(&ase_header)); BB_ReadBytes(&br, StringFromStruct(&ase_header));
if (ase_header.magic != 0xA5E0) { if (ase_header.magic != 0xA5E0) {
push_error_copy_msg(arena, &res.errors, LIT("Not a valid aseprite file")); push_error_copy_msg(arena, &res.errors, Lit("Not a valid aseprite file"));
goto abort; goto abort;
} }
if (ase_header.color_depth != 32) { if (ase_header.color_depth != 32) {
String msg = string_format(scratch.arena, String msg = StringFormat(scratch.arena,
LIT("Only 32 bit rgba color mode is supported (got %F)"), Lit("Only 32 bit rgba color mode is supported (got %F)"),
FMT_UINT(ase_header.color_depth)); FmtUint(ase_header.color_depth));
push_error_copy_msg(arena, &res.errors, msg); push_error_copy_msg(arena, &res.errors, msg);
goto abort; goto abort;
} }
@ -593,7 +593,7 @@ Ase_DecodedImage ase_decode_image(Arena *arena, String encoded)
u32 num_frames = 0; u32 num_frames = 0;
for (u16 i = 0; i < ase_header.frames; ++i) { for (u16 i = 0; i < ase_header.frames; ++i) {
struct frame_header frame_header; struct frame_header frame_header;
BB_ReadBytes(&br, STRING_FROM_STRUCT(&frame_header)); BB_ReadBytes(&br, StringFromStruct(&frame_header));
u32 num_chunks = frame_header.chunks_new; u32 num_chunks = frame_header.chunks_new;
if (num_chunks == 0) { if (num_chunks == 0) {
@ -629,7 +629,7 @@ Ase_DecodedImage ase_decode_image(Arena *arena, String encoded)
if (layer->blend_mode != 0) { if (layer->blend_mode != 0) {
push_error_copy_msg(arena, push_error_copy_msg(arena,
&res.errors, &res.errors,
LIT("Layer has unsupported blend mode (only 'Normal' mode is supported). Tip: Try using 'merge down' to create a normal layer as a workaround")); Lit("Layer has unsupported blend mode (only 'Normal' mode is supported). Tip: Try using 'merge down' to create a normal layer as a workaround"));
goto abort; goto abort;
} }
@ -694,7 +694,7 @@ Ase_DecodedImage ase_decode_image(Arena *arena, String encoded)
case CEL_TYPE_COMPRESSED_TILEMAP: { case CEL_TYPE_COMPRESSED_TILEMAP: {
/* Unsupported */ /* Unsupported */
push_error_copy_msg(arena, &res.errors, LIT("Tilemaps are not supported")); push_error_copy_msg(arena, &res.errors, Lit("Tilemaps are not supported"));
goto abort; goto abort;
} break; } break;
} }
@ -815,7 +815,7 @@ Ase_DecodedSheet ase_decode_sheet(Arena *arena, String encoded)
BB_Buff bb = BitbuffFromString(encoded); BB_Buff bb = BitbuffFromString(encoded);
BB_Reader br = BB_ReaderFromBuffNoDebug(&bb); BB_Reader br = BB_ReaderFromBuffNoDebug(&bb);
struct ase_header ase_header; struct ase_header ase_header;
BB_ReadBytes(&br, STRING_FROM_STRUCT(&ase_header)); BB_ReadBytes(&br, StringFromStruct(&ase_header));
u64 frame_width = ase_header.width; u64 frame_width = ase_header.width;
u64 frame_height = ase_header.height; u64 frame_height = ase_header.height;
@ -838,7 +838,7 @@ Ase_DecodedSheet ase_decode_sheet(Arena *arena, String encoded)
/* Iterate frames */ /* Iterate frames */
for (u16 i = 0; i < ase_header.frames; ++i) { for (u16 i = 0; i < ase_header.frames; ++i) {
struct frame_header frame_header; struct frame_header frame_header;
BB_ReadBytes(&br, STRING_FROM_STRUCT(&frame_header)); BB_ReadBytes(&br, StringFromStruct(&frame_header));
u32 num_chunks = frame_header.chunks_new; u32 num_chunks = frame_header.chunks_new;
if (num_chunks == 0) { if (num_chunks == 0) {

View File

@ -65,7 +65,7 @@ internal AC_Asset *asset_cache_get_slot_locked(P_Lock *lock, String key, u64 has
AC_Asset *slot = &G.lookup[index]; AC_Asset *slot = &G.lookup[index];
if (slot->hash) { if (slot->hash) {
/* Occupied */ /* Occupied */
if (hash == slot->hash && string_eq(key, slot->key)) { if (hash == slot->hash && EqString(key, slot->key)) {
/* Matched slot */ /* Matched slot */
return slot; return slot;
} else { } else {
@ -84,7 +84,7 @@ internal AC_Asset *asset_cache_get_slot_locked(P_Lock *lock, String key, u64 has
u64 asset_cache_hash(String key) u64 asset_cache_hash(String key)
{ {
/* TODO: Better hash */ /* TODO: Better hash */
return hash_fnv64(HASH_FNV64_BASIS, key); return HashFnv64(Fnv64Basis, key);
} }
/* `key` text is copied by this function /* `key` text is copied by this function
@ -119,17 +119,17 @@ AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch)
if (!asset->hash) { if (!asset->hash) {
if (G.num_assets >= MAX_ASSETS) { if (G.num_assets >= MAX_ASSETS) {
P_Panic(LIT("Max assets reached")); P_Panic(Lit("Max assets reached"));
} }
String key_stored = ZI; String key_stored = ZI;
{ {
/* CopyStruct key to store */ /* CopyStruct key to store */
AC_Store store = asset_cache_store_open(); AC_Store store = asset_cache_store_open();
key_stored = string_copy(store.arena, key); key_stored = CopyString(store.arena, key);
asset_cache_store_close(&store); asset_cache_store_close(&store);
} }
/* Initialize asset data */ /* Initialize asset data */
P_LogInfoF("Inserting asset cache entry for \"%F\"", FMT_STR(key)); P_LogInfoF("Inserting asset cache entry for \"%F\"", FmtString(key));
*asset = (AC_Asset) { *asset = (AC_Asset) {
.status = ASSET_STATUS_UNINITIALIZED, .status = ASSET_STATUS_UNINITIALIZED,
.hash = hash, .hash = hash,

View File

@ -18,7 +18,7 @@ Arena *AllocArena(u64 reserve)
{ {
/* Hard fail on memory reserve failure for now */ /* Hard fail on memory reserve failure for now */
/* FIXME: Enable this */ /* FIXME: Enable this */
//P_Panic(LIT("Failed to reserve memory")); //P_Panic(Lit("Failed to reserve memory"));
(*(volatile int *)0) = 0; (*(volatile int *)0) = 0;
} }
u64 reserved = reserve; u64 reserved = reserve;
@ -30,7 +30,7 @@ Arena *AllocArena(u64 reserve)
{ {
/* Hard fail on commit failure */ /* Hard fail on commit failure */
/* FIXME: Enable this */ /* FIXME: Enable this */
//P_Panic(LIT("Failed to commit initial memory block: System may be out of memory")); //P_Panic(Lit("Failed to commit initial memory block: System may be out of memory"));
(*(volatile int *)0) = 0; (*(volatile int *)0) = 0;
} }
@ -89,7 +89,7 @@ void *PushBytesNoZero(Arena *arena, u64 size, u64 align)
{ {
/* Hard fail if we overflow reserved memory for now */ /* Hard fail if we overflow reserved memory for now */
/* FIXME: Enable this */ /* FIXME: Enable this */
//P_Panic(LIT("Failed to commit new memory block: Overflow of reserved memory")); //P_Panic(Lit("Failed to commit new memory block: Overflow of reserved memory"));
(*(volatile int *)0) = 0; (*(volatile int *)0) = 0;
} }
void *commit_address = base + arena->committed; void *commit_address = base + arena->committed;
@ -97,7 +97,7 @@ void *PushBytesNoZero(Arena *arena, u64 size, u64 align)
{ {
/* Hard fail on memory allocation failure for now */ /* Hard fail on memory allocation failure for now */
/* FIXME: Enable this */ /* FIXME: Enable this */
//P_Panic(LIT("Failed to commit new memory block: System may be out of memory")); //P_Panic(Lit("Failed to commit new memory block: System may be out of memory"));
(*(volatile int *)0) = 0; (*(volatile int *)0) = 0;
} }
arena->committed += commit_bytes; arena->committed += commit_bytes;

View File

@ -9,10 +9,10 @@ BOOL CALLBACK IncbinEnumerateResourceNamesFunc(HMODULE module, LPCWSTR type, LPC
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
IncbinRcSearchParams *params = (IncbinRcSearchParams *)udata; IncbinRcSearchParams *params = (IncbinRcSearchParams *)udata;
String entry_name_lower = string_lower(scratch.arena, string_from_wstr_no_limit(scratch.arena, (LPWSTR)wstr_entry_name)); String entry_name_lower = LowerString(scratch.arena, StringFromWstrNoLimit(scratch.arena, (LPWSTR)wstr_entry_name));
params->found = 0; params->found = 0;
params->data = STRING(0, 0); params->data = STRING(0, 0);
if (string_eq(entry_name_lower, params->name_lower)) if (EqString(entry_name_lower, params->name_lower))
{ {
HRSRC hres = FindResourceW(module, wstr_entry_name, type); HRSRC hres = FindResourceW(module, wstr_entry_name, type);
if (hres) if (hres)
@ -43,15 +43,15 @@ String StringFromIncbinRcResource(IncbinRcResource *inc)
if (v == state) if (v == state)
{ {
/* Search RC file for the resource name */ /* Search RC file for the resource name */
String name_lower = string_lower(scratch.arena, inc->rc_name); String name_lower = LowerString(scratch.arena, inc->rc_name);
IncbinRcSearchParams params = { .name_lower = name_lower }; IncbinRcSearchParams params = { .name_lower = name_lower };
EnumResourceNamesW(0, RT_RCDATA, &IncbinEnumerateResourceNamesFunc, (LONG_PTR)&params); EnumResourceNamesW(0, RT_RCDATA, &IncbinEnumerateResourceNamesFunc, (LONG_PTR)&params);
if (!params.found) if (!params.found)
{ {
/* FIXME: enable this */ /* FIXME: enable this */
//P_Panic(string_format(scratch.arena, //P_Panic(StringFormat(scratch.arena,
// LIT("INCBIN include not found in RC file: \"%F\""), // Lit("INCBIN include not found in RC file: \"%F\""),
// FMT_STR(inc->rc_name))); // FmtString(inc->rc_name)));
(*(volatile int *)0) = 0; (*(volatile int *)0) = 0;
} }
inc->data = params.data; inc->data = params.data;

View File

@ -38,7 +38,7 @@ String StringFromIncbinRcResource(IncbinRcResource *inc);
* RC file). * RC file).
*/ */
#define IncbinInclude(var, _rc_name) static IncbinRcResource _incbin_ ## var = { .rc_name = LIT_NOCAST((_rc_name)) } #define IncbinInclude(var, _rc_name) static IncbinRcResource _incbin_ ## var = { .rc_name = LitNoCast((_rc_name)) }
#define IncbinGet(var) StringFromIncbinRcResource(&_incbin_ ## var) #define IncbinGet(var) StringFromIncbinRcResource(&_incbin_ ## var)
String StringFromIncbinRcResource(struct IncbinRcResource *inc); String StringFromIncbinRcResource(struct IncbinRcResource *inc);
@ -73,6 +73,6 @@ String StringFromIncbinRcResource(struct IncbinRcResource *inc);
extern const char _incbin_ ## var ## _end[] extern const char _incbin_ ## var ## _end[]
/* Retrieve a string from included data using the variable supplied to IncbinInclude */ /* Retrieve a string from included data using the variable supplied to IncbinInclude */
#define IncbinGet(var) STRING_FROM_POINTERS(_incbin_ ## var ## _start, _incbin_ ## var ## _end) #define IncbinGet(var) StringFromPointers(_incbin_ ## var ## _start, _incbin_ ## var ## _end)
#endif /* CompilerIsClang */ #endif /* CompilerIsClang */

View File

@ -58,7 +58,8 @@ void SetMemoryReadWrite(void *address, u64 size)
__attribute((section(".text.memcpy"))) __attribute((section(".text.memcpy")))
void *memcpy(void *__restrict dst, const void *__restrict src, u64 n) void *memcpy(void *__restrict dst, const void *__restrict src, u64 n)
{ {
for (u64 i = 0; i < n; ++i) { for (u64 i = 0; i < n; ++i)
{
((u8 *)dst)[i] = ((u8 *)src)[i]; ((u8 *)dst)[i] = ((u8 *)src)[i];
} }
return dst; return dst;
@ -68,7 +69,8 @@ void *memcpy(void *__restrict dst, const void *__restrict src, u64 n)
__attribute((section(".text.memset"))) __attribute((section(".text.memset")))
void *memset(void *dst, i32 c, u64 n) void *memset(void *dst, i32 c, u64 n)
{ {
for (u64 i = 0; i < n; ++i) { for (u64 i = 0; i < n; ++i)
{
((u8 *)dst)[i] = c; ((u8 *)dst)[i] = c;
} }
return dst; return dst;
@ -79,9 +81,11 @@ __attribute((section(".text.memcmp")))
i32 memcmp(const void *p1, const void *p2, u64 n) i32 memcmp(const void *p1, const void *p2, u64 n)
{ {
i32 res = 0; i32 res = 0;
for (u64 i = 0; i < n; ++i) { for (u64 i = 0; i < n; ++i)
{
res = ((u8 *)p1)[i] - ((u8 *)p2)[i]; res = ((u8 *)p1)[i] - ((u8 *)p2)[i];
if (res != 0) { if (res != 0)
{
break; break;
} }
} }

View File

@ -18,8 +18,9 @@ void TrueRand(String buffer)
u64 RandU64FromState(RandState *state) u64 RandU64FromState(RandState *state)
{ {
u64 seed = state->seed; u64 seed = state->seed;
if (seed == 0) { if (seed == 0)
TrueRand(STRING_FROM_STRUCT(&seed)); {
TrueRand(StringFromStruct(&seed));
state->seed = seed; state->seed = seed;
} }
return seed ^ RandU64FromSeed(++state->counter); return seed ^ RandU64FromSeed(++state->counter);

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +1,182 @@
Struct(String) { ////////////////////////////////
//~ String types
Struct(String)
{
u64 len; u64 len;
u8 *text; u8 *text;
}; };
Struct(String16) { Struct(String16)
{
u64 len; u64 len;
u16 *text; u16 *text;
}; };
Struct(String32) { Struct(String32)
{
u64 len; u64 len;
u32 *text; u32 *text;
}; };
Struct(StringArray) { Struct(StringArray)
{
u64 count; u64 count;
String *strings; String *strings;
}; };
/* ========================== * ////////////////////////////////
* String utils //~ Formatting types
* ========================== */
/* Expand C string literal with size for string initialization */ #define DefaultFmtPrecision 3
#define LIT(cstr_lit) CppCompatInitListType(String) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) } #define IntChars ("0123456789abcdef")
/* Same as `STR`, but works with static variable initialization */ typedef i32 FmtKind; enum
#define LIT_NOCAST(cstr_lit) { .len = (sizeof((cstr_lit)) - 1), .text = (u8 *)(cstr_lit) } {
FmtKind_None,
#define STRING(size, data) (CppCompatInitListType(String) { (size), (data) }) /* Arbitrary magic numbers for argument validation */
FmtKind_Char = 0x0f5281df,
FmtKind_String = 0x0a5ffa9a,
FmtKind_Uint = 0x0746f19b,
FmtKind_Sint = 0x08603694,
FmtKind_Hex = 0x0a3d0792,
FmtKind_Ptr = 0x0c4519e4,
FmtKind_Float = 0x04814143,
FmtKind_Handle = 0x0f112992,
FmtKind_Uid = 0x0beb23dd,
#define STRING_FROM_POINTERS(p0, p1) (CppCompatInitListType(String) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 }) FmtKind_End = 0x0ecbc5ae
#define STRING_FROM_STRUCT(ptr) (CppCompatInitListType(String) { sizeof(*(ptr)), (u8 *)(ptr) })
#define STRING_FROM_ARENA(arena) (STRING((arena)->pos, ArenaBase(arena)))
/* String from static array */
#define STRING_FROM_ARRAY(a) \
( \
/* Must be array */ \
Assert(IsArray(a)), \
((String) { .len = sizeof(a), .text = (u8 *)(a) }) \
)
/* ========================== *
* Conversion
* ========================== */
String string_from_char(Arena *arena, char c);
String string_from_uint(Arena *arena, u64 n, u64 base, u64 zfill);
String string_from_int(Arena *arena, i64 n, u64 base, u64 zfill);
String string_from_ptr(Arena *arena, void *ptr);
String string_from_float(Arena *arena, f64 f, u32 precision);
String string_from_handle(Arena *arena, u64 v0, u64 v1);
String string_from_uid(Arena *arena, UID uid);
/* ========================== *
* String operations
* ========================== */
String string_copy(Arena *arena, String src);
String string_copy_to_string(String dst, String src);
String string_repeat(Arena *arena, String src, u64 count);
String string_cat(Arena *arena, String str1, String str2);
StringArray string_split(Arena *arena, String str, String delim);
String string_indent(Arena *arena, String str, u32 indent);
String string_lower(Arena *arena, String str);
b32 string_eq(String str1, String str2);
i32 string_cmp(String str1, String str2);
b32 string_contains(String str, String substring);
b32 string_starts_with(String str, String substring);
b32 string_ends_with(String str, String substring);
/* ========================== *
* Format
* ========================== */
#define DEFAULT_FMT_PRECISION 3
enum fmt_type {
FMT_TYPE_NONE,
/* Arbitrary magic numbers to avoid accidental non-fmt arguments */
FMT_TYPE_CHAR = 0x0f5281df,
FMT_TYPE_STR = 0x0a5ffa9a,
FMT_TYPE_UINT = 0x0746f19b,
FMT_TYPE_SINT = 0x08603694,
FMT_TYPE_HEX = 0x0a3d0792,
FMT_TYPE_PTR = 0x0c4519e4,
FMT_TYPE_FLOAT = 0x04814143,
FMT_TYPE_HANDLE = 0x0f112992,
FMT_TYPE_UID = 0x0beb23dd,
FMT_TYPE_END = 0x0ecbc5ae
}; };
struct fmt_arg { Struct(FmtArg)
enum fmt_type type; {
FmtKind kind;
u32 precision; u32 precision;
u32 zfill; u32 zfill;
union { union
{
u8 c; u8 c;
String string; String string;
u64 uint; u64 uint;
i64 sint; i64 sint;
void *ptr; void *ptr;
f64 f; f64 f;
struct { struct
{
u64 h64[2]; u64 h64[2];
} handle; } handle;
UID uid; Uid uid;
} value; } value;
}; };
#define FMT_END (struct fmt_arg) {.type = FMT_TYPE_END} ////////////////////////////////
//~ Unicode types
#define FMT_CHAR(v) (struct fmt_arg) {.type = FMT_TYPE_CHAR, .value.c = (v)} Struct(CodepointIter)
#define FMT_STR(v) (struct fmt_arg) {.type = FMT_TYPE_STR, .value.string = (v)} {
#define FMT_UINT(v) (struct fmt_arg) {.type = FMT_TYPE_UINT, .value.uint = (v)}
#define FMT_UINT_Z(v, z) (struct fmt_arg) {.type = FMT_TYPE_UINT, .value.uint = (v), .zfill = (z)}
#define FMT_SINT(v) (struct fmt_arg) {.type = FMT_TYPE_SINT, .value.sint = (v)}
#define FMT_HEX(v) (struct fmt_arg) {.type = FMT_TYPE_HEX, .value.uint = (v)}
#define FMT_PTR(v) (struct fmt_arg) {.type = FMT_TYPE_PTR, .value.ptr = (v)}
#define FMT_FLOAT(v) FMT_FLOAT_P(v, DEFAULT_FMT_PRECISION)
#define FMT_FLOAT_P(v, p) (struct fmt_arg) {.type = FMT_TYPE_FLOAT, .value.f = (v), .precision = (p)}
#define FMT_HANDLE(v) (struct fmt_arg) {.type = FMT_TYPE_HANDLE, .value.handle.h64[0] = (v).idx, .value.handle.h64[1] = (v).gen}
#define FMT_UID(v) (struct fmt_arg) {.type = FMT_TYPE_UID, .value.uid = (v) }
#define string_format(arena, fmt, ...) _string_format((arena), (fmt), __VA_ARGS__, FMT_END)
String _string_format(Arena *arena, String fmt, ...);
String string_formatv(Arena *arena, String fmt, va_list args);
/* ========================== *
* Unicode
* ========================== */
struct string_codepoint_iter {
u32 codepoint; u32 codepoint;
/* internal */ /* Internal */
String src; String src;
u64 pos; u64 pos;
}; };
struct string_codepoint_iter string_codepoint_iter_begin(String str); ////////////////////////////////
b32 string_codepoint_iter_next(struct string_codepoint_iter *iter); //~ String utils
void string_codepoint_iter_end(struct string_codepoint_iter *iter);
String string_from_string16(Arena *arena, String16 str16); #define STRING(size, data) (CppCompatInitListType(String) { (size), (data) })
String string_from_string32(Arena *arena, String32 str32); #define Lit(cstr_lit) CppCompatInitListType(String) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) }
#define LitNoCast(cstr_lit) { .len = (sizeof((cstr_lit)) - 1), .text = (u8 *)(cstr_lit) }
#define StringFromPointers(p0, p1) (CppCompatInitListType(String) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 })
#define StringFromStruct(ptr) (CppCompatInitListType(String) { sizeof(*(ptr)), (u8 *)(ptr) })
#define StringFromArena(arena) (STRING((arena)->pos, ArenaBase(arena)))
String16 string16_from_string(Arena *arena, String str8); /* String from static array */
String32 string32_from_string(Arena *arena, String str8); #define StringFromArray(a) \
( \
Assert(IsArray(a)), \
((String) { .len = sizeof(a), .text = (u8 *)(a) }) \
)
/* ========================== * ////////////////////////////////
* Legacy strings //~ String operartions
* ========================== */
u64 cstr_len_no_limit(char *cstr); //- Conversion
u64 cstr_len(char *cstr, u64 limit); String StringFromChar(Arena *arena, char c);
char *cstr_from_string(Arena *arena, String src); String StringFromU64(Arena *arena, u64 n, u64 base, u64 zfill);
char *cstr_buff_from_string(String dest_buff, String src); String StringFromI64(Arena *arena, i64 n, u64 base, u64 zfill);
String string_from_cstr_no_limit(char *cstr); String StringFromPtr(Arena *arena, void *ptr);
String string_from_cstr(char *cstr, u64 limit); String StringFromF64(Arena *arena, f64 f, u32 precision);
String StringFromhandle(Arena *arena, u64 v0, u64 v1);
String StringFromUid(Arena *arena, Uid uid);
u64 wstr_len_no_limit(wchar_t *wstr); //- Modification
u64 wstr_len(wchar_t *wstr, u64 limit); String CopyString(Arena *arena, String src);
wchar_t *wstr_from_string(Arena *arena, String src); String CopyStringToBuffer(String dst, String src);
wchar_t *wstr_from_string16(Arena *arena, String16 src); String RepeatString(Arena *arena, String src, u64 count);
String string_from_wstr_no_limit(Arena *arena, wchar_t *wstr); String CatString(Arena *arena, String str1, String str2);
String string_from_wstr(Arena *arena, wchar_t *wstr, u64 limit); StringArray SplitString(Arena *arena, String str, String delim);
String16 string16_from_wstr_no_limit(wchar_t *wstr); String IndentString(Arena *arena, String str, u32 indent);
String16 string16_from_wstr(wchar_t *wstr, u64 limit); String LowerString(Arena *arena, String str);
b32 EqString(String str1, String str2);
i32 CmpString(String str1, String str2);
b32 StringContains(String str, String substring);
b32 StringStartsWith(String str, String substring);
b32 StringEndsWith(String str, String substring);
//- Formatting helpers
#define FmtChar(v) (FmtArg) {.kind = FmtKind_Char, .value.c = (v)}
#define FmtString(v) (FmtArg) {.kind = FmtKind_String, .value.string = (v)}
#define FmtUint(v) (FmtArg) {.kind = FmtKind_Uint, .value.uint = (v)}
#define FmtUintZ(v, z) (FmtArg) {.kind = FmtKind_Uint, .value.uint = (v), .zfill = (z)}
#define FmtSint(v) (FmtArg) {.kind = FmtKind_Sint, .value.sint = (v)}
#define FmtHex(v) (FmtArg) {.kind = FmtKind_Hex, .value.uint = (v)}
#define FmtPtr(v) (FmtArg) {.kind = FmtKind_Ptr, .value.ptr = (v)}
#define FmtFloat(v) FmtFloatP(v, DefaultFmtPrecision)
#define FmtFloatP(v, p) (FmtArg) {.kind = FmtKind_Float, .value.f = (v), .precision = (p)}
#define FmtHandle(v) (FmtArg) {.kind = FmtKind_Handle, .value.handle.h64[0] = (v).idx, .value.handle.h64[1] = (v).gen}
#define FmtUid(v) (FmtArg) {.kind = FmtKind_Uid, .value.uid = (v) }
#define FmtEnd (FmtArg) {.kind = FmtKind_End}
//- Formatting
#define StringFormat(arena, fmt, ...) _StringFormat((arena), (fmt), __VA_ARGS__, FmtEnd)
String _StringFormat(Arena *arena, String fmt, ...);
String StringFormatV(Arena *arena, String fmt, va_list args);
////////////////////////////////
//~ Unicode operations
//- Iter
CodepointIter BeginCodepointIter(String str);
b32 AdvanceCodepointIter(CodepointIter *iter);
void EndCodepointIter(CodepointIter *iter);
//- Decode string
String StringFromString16(Arena *arena, String16 str16);
String StringFromString32(Arena *arena, String32 str32);
//- Encode string
String16 String16FromString(Arena *arena, String str8);
String32 String32FromString(Arena *arena, String str8);
////////////////////////////////
//~ Legacy C string operations
//- Narrow strings
u64 CstrLenNoLimit(char *cstr);
u64 CstrLen(char *cstr, u64 limit);
char *CstrFromString(Arena *arena, String src);
char *CstrBuffFromStringToBuff(String dest_buff, String src);
String StringFromCstrNoLimit(char *cstr);
String StringFromCstr(char *cstr, u64 limit);
//- Wide strings
u64 WstrLenNoLimit(wchar_t *wstr);
u64 WstrLen(wchar_t *wstr, u64 limit);
wchar_t *WstrFromString(Arena *arena, String src);
wchar_t *WstrFromString16(Arena *arena, String16 src);
String StringFromWstrNoLimit(Arena *arena, wchar_t *wstr);
String StringFromWstr(Arena *arena, wchar_t *wstr, u64 limit);
String16 String16FromWstrNoLimit(wchar_t *wstr);
String16 String16FromWstr(wchar_t *wstr, u64 limit);

View File

@ -1,15 +1,15 @@
/* Returns a uid generated from the system's random number generator */ /* Returns a uid generated from the system's random number generator */
UID uid_true_rand(void) Uid UidFromTrueRand(void)
{ {
UID res = ZI; Uid res = ZI;
TrueRand(STRING_FROM_STRUCT(&res)); TrueRand(StringFromStruct(&res));
return res; return res;
} }
/* Combines 2 uids into a new uid */ /* Combines 2 uids into a new uid */
UID uid_combine(UID a, UID b) Uid CombineUid(Uid a, Uid b)
{ {
UID res; Uid res;
res.hi = (a.hi * 3) + b.hi; res.hi = (a.hi * 3) + b.hi;
res.lo = (a.lo * 3) + b.lo; res.lo = (a.lo * 3) + b.lo;
res.hi += res.lo; res.hi += res.lo;

View File

@ -1,13 +1,18 @@
#define MakeUID(hi64, lo64) ((UID) { .hi = (hi64), .lo = (lo64) }) ////////////////////////////////
Struct(UID) { //~ Uid types
Struct(Uid) {
u64 hi; u64 hi;
u64 lo; u64 lo;
}; };
Inline b32 uid_eq(UID a, UID b) { return a.hi == b.hi && a.lo == b.lo; } ////////////////////////////////
//~ Uid operations
Inline b32 uid_is_zero(UID v) { return v.hi == 0 && v.lo == 0; } #define UID(hi64, lo64) ((Uid) { .hi = (hi64), .lo = (lo64) })
UID uid_true_rand(void); Uid UidFromTrueRand(void);
Uid CombineUid(Uid a, Uid b);
UID uid_combine(UID a, UID b); Inline b32 EqUid(Uid a, Uid b) { return a.hi == b.hi && a.lo == b.lo; }
Inline b32 IsUidZero(Uid v) { return v.hi == 0 && v.lo == 0; }

View File

@ -1,29 +1,37 @@
/* ========================== * ////////////////////////////////
* utf8 //~ Utf8
* ========================== */
Utf8DecodeResult uni_decode_utf8(String str) //- Decode
Utf8DecodeResult DecodeUtf8(String str)
{ {
LocalPersist const u8 lengths[32] = { LocalPersist const u8 lengths[32] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5
}; };
Utf8DecodeResult result = ZI;
u32 codepoint = U32Max; u32 codepoint = U32Max;
u32 advance = 0; u32 advance = 0;
if (str.len > 0) { if (str.len > 0)
{
u8 c0 = str.text[0]; u8 c0 = str.text[0];
u8 utf8_len = lengths[c0 >> 3]; u8 utf8_len = lengths[c0 >> 3];
advance = 1; advance = 1;
switch (utf8_len) { switch (utf8_len)
case 1: { {
case 1:
{
codepoint = c0; codepoint = c0;
} break; } break;
case 2: { case 2:
if (str.len >= 2) { {
if (str.len >= 2)
{
u8 c1 = str.text[1]; u8 c1 = str.text[1];
if (lengths[c1 >> 3] == 0) { if (lengths[c1 >> 3] == 0)
{
codepoint = (c1 & 0x3F) << 0; codepoint = (c1 & 0x3F) << 0;
codepoint |= (c0 & 0x1F) << 6; codepoint |= (c0 & 0x1F) << 6;
advance = 2; advance = 2;
@ -31,12 +39,15 @@ Utf8DecodeResult uni_decode_utf8(String str)
} }
} break; } break;
case 3: { case 3:
if (str.len >= 3) { {
if (str.len >= 3)
{
u8 c1 = str.text[1]; u8 c1 = str.text[1];
u8 c2 = str.text[2]; u8 c2 = str.text[2];
if (lengths[c1 >> 3] == 0 && if (lengths[c1 >> 3] == 0 &&
lengths[c2 >> 3] == 0) { lengths[c2 >> 3] == 0)
{
codepoint = (c2 & 0x3F) << 0; codepoint = (c2 & 0x3F) << 0;
codepoint |= (c1 & 0x3F) << 6; codepoint |= (c1 & 0x3F) << 6;
codepoint |= (c0 & 0x0F) << 12; codepoint |= (c0 & 0x0F) << 12;
@ -45,14 +56,17 @@ Utf8DecodeResult uni_decode_utf8(String str)
} }
} break; } break;
case 4: { case 4:
if (str.len >= 4) { {
if (str.len >= 4)
{
u8 c1 = str.text[1]; u8 c1 = str.text[1];
u8 c2 = str.text[2]; u8 c2 = str.text[2];
u8 c3 = str.text[3]; u8 c3 = str.text[3];
if (lengths[c1 >> 3] == 0 && if (lengths[c1 >> 3] == 0 &&
lengths[c2 >> 3] == 0 && lengths[c2 >> 3] == 0 &&
lengths[c3 >> 3] == 0) { lengths[c3 >> 3] == 0)
{
codepoint = (c3 & 0x3F) << 0; codepoint = (c3 & 0x3F) << 0;
codepoint |= (c2 & 0x3F) << 6; codepoint |= (c2 & 0x3F) << 6;
codepoint |= (c1 & 0x3F) << 12; codepoint |= (c1 & 0x3F) << 12;
@ -66,59 +80,74 @@ Utf8DecodeResult uni_decode_utf8(String str)
} }
} }
return (Utf8DecodeResult) { result.advance8 = advance;
.advance8 = advance, result.codepoint = codepoint;
.codepoint = codepoint return result;
};
} }
Utf8EncodeResult uni_encode_utf8(u32 codepoint) //- Encode
{
Utf8EncodeResult res = ZI;
if (codepoint <= 0x7F) { Utf8EncodeResult EncodeUtf8(u32 codepoint)
res.count8 = 1; {
res.chars8[0] = codepoint; Utf8EncodeResult result = ZI;
} else if (codepoint <= 0x7FF) {
res.count8 = 2; if (codepoint <= 0x7F)
res.chars8[1] = 0x80 | ((codepoint >> 0) & 0x3F); {
res.chars8[0] = 0xC0 | ((codepoint >> 6) & 0x1F); result.count8 = 1;
} else if (codepoint <= 0xFFFF) { result.chars8[0] = codepoint;
res.count8 = 3; }
res.chars8[2] = 0x80 | ((codepoint >> 0) & 0x3F); else if (codepoint <= 0x7FF)
res.chars8[1] = 0x80 | ((codepoint >> 6) & 0x3F); {
res.chars8[0] = 0xE0 | ((codepoint >> 12) & 0x0F); result.count8 = 2;
} else if (codepoint <= 0x10FFFF) { result.chars8[1] = 0x80 | ((codepoint >> 0) & 0x3F);
res.count8 = 4; result.chars8[0] = 0xC0 | ((codepoint >> 6) & 0x1F);
res.chars8[3] = 0x80 | ((codepoint >> 0) & 0x3F); }
res.chars8[2] = 0x80 | ((codepoint >> 6) & 0x3F); else if (codepoint <= 0xFFFF)
res.chars8[1] = 0x80 | ((codepoint >> 12) & 0x3F); {
res.chars8[0] = 0xF0 | ((codepoint >> 18) & 0x07); result.count8 = 3;
} else { result.chars8[2] = 0x80 | ((codepoint >> 0) & 0x3F);
result.chars8[1] = 0x80 | ((codepoint >> 6) & 0x3F);
result.chars8[0] = 0xE0 | ((codepoint >> 12) & 0x0F);
}
else if (codepoint <= 0x10FFFF)
{
result.count8 = 4;
result.chars8[3] = 0x80 | ((codepoint >> 0) & 0x3F);
result.chars8[2] = 0x80 | ((codepoint >> 6) & 0x3F);
result.chars8[1] = 0x80 | ((codepoint >> 12) & 0x3F);
result.chars8[0] = 0xF0 | ((codepoint >> 18) & 0x07);
}
else
{
/* Invalid codepoint */ /* Invalid codepoint */
res.count8 = 1; result.count8 = 1;
res.chars8[0] = '?'; result.chars8[0] = '?';
} }
return res; return result;
} }
/* ========================== * ////////////////////////////////
* utf16 //~ Utf16
* ========================== */
Utf16DecodeResult uni_decode_utf16(String16 str) //- Decode
Utf16DecodeResult DecodeUtf16(String16 str)
{ {
Utf16DecodeResult result = ZI;
u32 codepoint = U32Max; u32 codepoint = U32Max;
u32 advance = 0; u32 advance = 0;
if (str.len >= 1) { if (str.len >= 1)
{
u16 c0 = str.text[0]; u16 c0 = str.text[0];
codepoint = c0; codepoint = c0;
advance = 1; advance = 1;
if (str.len >= 2) { if (str.len >= 2)
{
u16 c1 = str.text[1]; u16 c1 = str.text[1];
if ((0xD800 <= c0 && c0 < 0xDC00) && (0xDC00 <= c1 && c1 < 0xE000)) { if ((0xD800 <= c0 && c0 < 0xDC00) && (0xDC00 <= c1 && c1 < 0xE000))
{
codepoint = (c1 & 0x3FF) << 0; codepoint = (c1 & 0x3FF) << 0;
codepoint |= (c0 & 0x3FF) << 10; codepoint |= (c0 & 0x3FF) << 10;
advance = 2; advance = 2;
@ -126,75 +155,91 @@ Utf16DecodeResult uni_decode_utf16(String16 str)
} }
} }
return (Utf16DecodeResult) { result.advance16 = advance;
.advance16 = advance, result.codepoint = codepoint;
.codepoint = codepoint return result;
};
} }
Utf16EncodeResult uni_encode_utf16(u32 codepoint) //- Encode
Utf16EncodeResult EncodeUtf16(u32 codepoint)
{ {
Utf16EncodeResult res = ZI; Utf16EncodeResult result = ZI;
if (codepoint <= 0xFFFF) { if (codepoint <= 0xFFFF)
res.count16 = 1; {
res.chars16[0] = codepoint; result.count16 = 1;
} else if (codepoint <= 0x10FFFF) { result.chars16[0] = codepoint;
res.count16 = 2; }
res.chars16[1] = 0xDC00 | ((codepoint >> 0) & 0x3FF); else if (codepoint <= 0x10FFFF)
res.chars16[0] = 0xD800 | ((codepoint >> 10) & 0x3FF); {
} else { result.count16 = 2;
result.chars16[1] = 0xDC00 | ((codepoint >> 0) & 0x3FF);
result.chars16[0] = 0xD800 | ((codepoint >> 10) & 0x3FF);
}
else
{
/* Invalid codepoint */ /* Invalid codepoint */
res.count16 = 1; result.count16 = 1;
res.chars16[0] = '?'; result.chars16[0] = '?';
} }
return res; return result;
} }
b32 uni_is_utf16_high_surrogate(u16 c) //- Surrogate check
b32 IsUtf16HighSurrogate(u16 c)
{ {
return 0xD800 <= c && c < 0xDC00; return 0xD800 <= c && c < 0xDC00;
} }
b32 uni_is_utf16_low_surrogate(u16 c) b32 IsUtf16LowSurrogate(u16 c)
{ {
return 0xDC00 <= c && c < 0xE000; return 0xDC00 <= c && c < 0xE000;
} }
/* ========================== * ////////////////////////////////
* utf32 //~ Utf32
* ========================== */
Utf32DecodeResult uni_decode_utf32(String32 str) //- Decode
Utf32DecodeResult DecodeUtf32(String32 str)
{ {
Utf32DecodeResult result = ZI;
u32 codepoint = U32Max; u32 codepoint = U32Max;
u32 advance = 0; u32 advance = 0;
if (str.len >= 1) { if (str.len >= 1)
{
u32 c = str.text[0]; u32 c = str.text[0];
advance = 1; advance = 1;
if (c <= 0x10FFFF) { if (c <= 0x10FFFF)
{
codepoint = c; codepoint = c;
} }
} }
return (Utf32DecodeResult) { result.advance32 = advance;
.advance32 = advance, result.codepoint = codepoint;
.codepoint = codepoint return result;
};
} }
Utf32EncodeResult uni_encode_utf32(u32 codepoint) //- Encode
Utf32EncodeResult EncodeUtf32(u32 codepoint)
{ {
Utf32EncodeResult res = ZI; Utf32EncodeResult result = ZI;
if (codepoint <= 0x10FFFF) { if (codepoint <= 0x10FFFF)
res.chars32 = codepoint; {
} else { result.chars32 = codepoint;
}
else
{
/* Invalid codepoint */ /* Invalid codepoint */
res.chars32 = '?'; result.chars32 = '?';
} }
return res; return result;
} }

View File

@ -1,51 +1,64 @@
/* ========================== * ////////////////////////////////
* utf8 //~ Utf8 types
* ========================== */
Struct(Utf8DecodeResult) { Struct(Utf8DecodeResult)
{
u32 advance8; u32 advance8;
u32 codepoint; u32 codepoint;
}; };
Struct(Utf8EncodeResult) { Struct(Utf8EncodeResult)
{
u32 count8; u32 count8;
u8 chars8[4]; u8 chars8[4];
}; };
Utf8DecodeResult uni_decode_utf8(String str); ////////////////////////////////
Utf8EncodeResult uni_encode_utf8(u32 codepoint); //~ Utf16 types
/* ========================== * Struct(Utf16DecodeResult)
* utf16 {
* ========================== */
Struct(Utf16DecodeResult) {
u32 advance16; u32 advance16;
u32 codepoint; u32 codepoint;
}; };
Struct(Utf16EncodeResult) { Struct(Utf16EncodeResult)
{
u32 count16; u32 count16;
u16 chars16[2]; u16 chars16[2];
}; };
Utf16DecodeResult uni_decode_utf16(String16 str); ////////////////////////////////
Utf16EncodeResult uni_encode_utf16(u32 codepoint); //~ Utf32 types
b32 uni_is_utf16_high_surrogate(u16 c);
b32 uni_is_utf16_low_surrogate(u16 c);
/* ========================== * Struct(Utf32DecodeResult)
* utf32 {
* ========================== */
Struct(Utf32DecodeResult) {
u32 advance32; u32 advance32;
u32 codepoint; u32 codepoint;
}; };
Struct(Utf32EncodeResult) { Struct(Utf32EncodeResult)
{
u32 chars32; u32 chars32;
}; };
Utf32DecodeResult uni_decode_utf32(String32 str); ////////////////////////////////
Utf32EncodeResult uni_encode_utf32(u32 codepoint); //~ Utf8 operations
Utf8DecodeResult DecodeUtf8(String str);
Utf8EncodeResult EncodeUtf8(u32 codepoint);
////////////////////////////////
//~ Utf16 operations
Utf16DecodeResult DecodeUtf16(String16 str);
Utf16EncodeResult EncodeUtf16(u32 codepoint);
b32 IsUtf16HighSurrogate(u16 c);
b32 IsUtf16LowSurrogate(u16 c);
////////////////////////////////
//~ Utf32 operations
Utf32DecodeResult DecodeUtf32(String32 str);
Utf32EncodeResult EncodeUtf32(u32 codepoint);

View File

@ -1,63 +1,101 @@
/* Utility functions and stuff that don't have a home :( */ ////////////////////////////////
//~ Hash types
/* ========================== * #define Fnv64Basis 0xCBF29CE484222325
* Hash utils
* ========================== */
/* FNV-1a parameters for different hash sizes: ////////////////////////////////
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_hash_parameters //~ Mergesort types
*/
#define HASH_FNV64_BASIS 0xCBF29CE484222325
Inline u64 hash_fnv64(u64 seed, String s)
{
u64 hash = seed;
for (u64 i = 0; i < s.len; ++i) {
hash ^= (u8)s.text[i];
hash *= 0x100000001B3;
}
return hash;
}
/* ========================== *
* Merge sort
* ========================== */
/* Compare functions should /* Compare functions should
* return a positive value if a should go before b * return a positive value if a should go before b
* return a negative value if a should go after b * return a negative value if a should go after b
* return 0 otherwise * return 0 otherwise
*/ */
#define SORT_COMPARE_FUNC_DEF(name, arg_a, arg_b, arg_udata) i32 name(void *arg_a, void *arg_b, void *arg_udata) #define MergesortCompareFuncDef(name, arg_a, arg_b, arg_udata) i32 name(void *arg_a, void *arg_b, void *arg_udata)
typedef SORT_COMPARE_FUNC_DEF(sort_compare_func, a, b, udata); typedef MergesortCompareFuncDef(MergesortCompareFunc, a, b, udata);
Inline void merge_sort_internal(u8 *left, u8 *right, u8 *items, u64 left_count, u64 right_count, u64 item_size, sort_compare_func *callback, void *udata) ////////////////////////////////
//~ Dict types
Struct(DictEntry)
{
u64 hash;
u64 value;
DictEntry *prev_in_bin;
DictEntry *next_in_bin;
DictEntry *prev;
DictEntry *next;
};
Struct(DictBin)
{
DictEntry *first;
DictEntry *last;
};
Struct(Dict)
{
u64 bins_count;
DictBin *bins;
DictEntry *first_free;
DictEntry *first;
DictEntry *last;
};
////////////////////////////////
//~ Hash utils
/* FNV-1a parameters for different hash sizes:
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_hash_parameters
*/
Inline u64 HashFnv64(u64 seed, String s)
{
u64 hash = seed;
for (u64 i = 0; i < s.len; ++i)
{
hash ^= (u8)s.text[i];
hash *= 0x100000001B3;
}
return hash;
}
////////////////////////////////
//~ Mergesort utils
Inline void MergesortInternal(u8 *left, u8 *right, u8 *items, u64 left_count, u64 right_count, u64 item_size, MergesortCompareFunc *callback, void *udata)
{ {
/* Sort */ /* Sort */
u64 i = 0; u64 i = 0;
u64 l = 0; u64 l = 0;
u64 r = 0; u64 r = 0;
while (l < left_count && r < right_count) { while (l < left_count && r < right_count)
{
u8 *dst = items + (i * item_size); u8 *dst = items + (i * item_size);
u8 *left_item = left + (l * item_size); u8 *left_item = left + (l * item_size);
u8 *right_item = right + (r * item_size); u8 *right_item = right + (r * item_size);
++i; ++i;
if (callback(left_item, right_item, udata) > 0) { if (callback(left_item, right_item, udata) > 0)
{
CopyBytes(dst, left_item, item_size); CopyBytes(dst, left_item, item_size);
++l; ++l;
} else { }
else
{
CopyBytes(dst, right_item, item_size); CopyBytes(dst, right_item, item_size);
++r; ++r;
} }
} }
/* CopyStruct remaining */ /* CopyStruct remaining */
if (l != left_count) { if (l != left_count)
{
u64 remaining_count = left_count - l; u64 remaining_count = left_count - l;
u64 remaining_bytes = remaining_count * item_size; u64 remaining_bytes = remaining_count * item_size;
u8 *dst = items + (i * item_size); u8 *dst = items + (i * item_size);
u8 *src = left + (l * item_size); u8 *src = left + (l * item_size);
CopyBytes(dst, src, remaining_bytes); CopyBytes(dst, src, remaining_bytes);
} else if (r != right_count) { }
else if (r != right_count)
{
u64 remaining_count = right_count - r; u64 remaining_count = right_count - r;
u64 remaining_bytes = remaining_count * item_size; u64 remaining_bytes = remaining_count * item_size;
u8 *dst = items + (i * item_size); u8 *dst = items + (i * item_size);
@ -66,9 +104,10 @@ Inline void merge_sort_internal(u8 *left, u8 *right, u8 *items, u64 left_count,
} }
} }
Inline void merge_sort(void *items, u64 item_count, u64 item_size, sort_compare_func *callback, void *udata) Inline void Mergesort(void *items, u64 item_count, u64 item_size, MergesortCompareFunc *callback, void *udata)
{
if (item_count > 1)
{ {
if (item_count > 1) {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
u64 left_count = item_count / 2; u64 left_count = item_count / 2;
u64 right_count = item_count - left_count; u64 right_count = item_count - left_count;
@ -81,42 +120,19 @@ Inline void merge_sort(void *items, u64 item_count, u64 item_size, sort_compare_
CopyBytes(left, items, left_size); CopyBytes(left, items, left_size);
CopyBytes(right, (u8 *)items + left_size, right_size); CopyBytes(right, (u8 *)items + left_size, right_size);
merge_sort(left, left_count, item_size, callback, udata); Mergesort(left, left_count, item_size, callback, udata);
merge_sort(right, right_count, item_size, callback, udata); Mergesort(right, right_count, item_size, callback, udata);
merge_sort_internal(left, right, (u8 *)items, left_count, right_count, item_size, callback, udata); MergesortInternal(left, right, (u8 *)items, left_count, right_count, item_size, callback, udata);
EndScratch(scratch); EndScratch(scratch);
} }
} }
/* ========================== * ////////////////////////////////
* Dict //~ Dict utils
*
* Simple chaining hash -> 64 bit value table for generic use
* ========================== */
Struct(DictEntry) { //- Dict init
u64 hash;
u64 value;
DictEntry *prev_in_bin;
DictEntry *next_in_bin;
DictEntry *prev;
DictEntry *next;
};
Struct(DictBin) { Inline Dict *InitDict(Arena *arena, u64 bins_count)
DictEntry *first;
DictEntry *last;
};
Struct(Dict) {
u64 bins_count;
DictBin *bins;
DictEntry *first_free;
DictEntry *first;
DictEntry *last;
};
Inline Dict *dict_init(Arena *arena, u64 bins_count)
{ {
__prof; __prof;
Dict *dict = PushStruct(arena, Dict); Dict *dict = PushStruct(arena, Dict);
@ -125,23 +141,28 @@ Inline Dict *dict_init(Arena *arena, u64 bins_count)
return dict; return dict;
} }
Inline void dict_reset(Dict *dict) Inline void ResetDict(Dict *dict)
{ {
ZeroBytes(dict->bins, sizeof(*dict->bins) * dict->bins_count); ZeroBytes(dict->bins, sizeof(*dict->bins) * dict->bins_count);
if (dict->first) { if (dict->first)
{
dict->last->next = dict->first_free; dict->last->next = dict->first_free;
dict->first_free = dict->first; dict->first_free = dict->first;
} }
} }
Inline DictEntry *dict_ensure_entry(Arena *arena, Dict *dict, u64 hash) //- Dict set
Inline DictEntry *EnsureDictEntry(Arena *arena, Dict *dict, u64 hash)
{ {
__prof; __prof;
DictBin *bin = &dict->bins[hash % dict->bins_count]; DictBin *bin = &dict->bins[hash % dict->bins_count];
DictEntry *entry = bin->first; DictEntry *entry = bin->first;
while (entry) { while (entry)
if (hash == entry->hash) { {
if (hash == entry->hash)
{
/* Existing match found */ /* Existing match found */
break; break;
} }
@ -149,26 +170,36 @@ Inline DictEntry *dict_ensure_entry(Arena *arena, Dict *dict, u64 hash)
} }
/* No match found, create new entry */ /* No match found, create new entry */
if (!entry) { if (!entry)
if (dict->first_free) { {
if (dict->first_free)
{
entry = dict->first_free; entry = dict->first_free;
dict->first_free = entry->next; dict->first_free = entry->next;
} else { }
else
{
entry = PushStructNoZero(arena, DictEntry); entry = PushStructNoZero(arena, DictEntry);
} }
ZeroStruct(entry); ZeroStruct(entry);
entry->hash = hash; entry->hash = hash;
if (bin->last) { if (bin->last)
{
bin->last->next_in_bin = entry; bin->last->next_in_bin = entry;
entry->prev_in_bin = bin->last; entry->prev_in_bin = bin->last;
} else { }
else
{
bin->first = entry; bin->first = entry;
} }
bin->last = entry; bin->last = entry;
if (dict->last) { if (dict->last)
{
dict->last->next = entry; dict->last->next = entry;
entry->prev = dict->last; entry->prev = dict->last;
} else { }
else
{
dict->first = entry; dict->first = entry;
} }
dict->last = entry; dict->last = entry;
@ -177,50 +208,36 @@ Inline DictEntry *dict_ensure_entry(Arena *arena, Dict *dict, u64 hash)
return entry; return entry;
} }
Inline void dict_set(Arena *arena, Dict *dict, u64 hash, u64 value) Inline void SetDictValue(Arena *arena, Dict *dict, u64 hash, u64 value)
{ {
__prof; __prof;
DictEntry *entry = dict_ensure_entry(arena, dict, hash); DictEntry *entry = EnsureDictEntry(arena, dict, hash);
entry->value = value; entry->value = value;
} }
Inline DictEntry *dict_get_entry(Dict *dict, u64 hash) //- Dict remove
{
__prof;
DictEntry *result = 0;
DictBin *bin = &dict->bins[hash % dict->bins_count];
for (DictEntry *entry = bin->first; entry; entry = entry->next_in_bin) {
if (hash == entry->hash) {
/* Match found */
result = entry;
break;
}
}
return result;
}
Inline u64 dict_get(Dict *dict, u64 hash) Inline void RemoveDictEntry(Dict *dict, DictEntry *entry)
{
__prof;
DictEntry *entry = dict_get_entry(dict, hash);
return entry ? entry->value : 0;
}
Inline void dict_remove_entry(Dict *dict, DictEntry *entry)
{ {
/* Remove from bin */ /* Remove from bin */
{ {
DictBin *bin = &dict->bins[entry->hash % dict->bins_count]; DictBin *bin = &dict->bins[entry->hash % dict->bins_count];
DictEntry *prev_in_bin = entry->prev_in_bin; DictEntry *prev_in_bin = entry->prev_in_bin;
DictEntry *next_in_bin = entry->next_in_bin; DictEntry *next_in_bin = entry->next_in_bin;
if (prev_in_bin) { if (prev_in_bin)
{
prev_in_bin->next_in_bin = next_in_bin; prev_in_bin->next_in_bin = next_in_bin;
} else { }
else
{
bin->first = next_in_bin; bin->first = next_in_bin;
} }
if (next_in_bin) { if (next_in_bin)
{
next_in_bin->prev_in_bin = prev_in_bin; next_in_bin->prev_in_bin = prev_in_bin;
} else { }
else
{
bin->last = prev_in_bin; bin->last = prev_in_bin;
} }
} }
@ -228,14 +245,20 @@ Inline void dict_remove_entry(Dict *dict, DictEntry *entry)
{ {
DictEntry *prev = entry->prev; DictEntry *prev = entry->prev;
DictEntry *next = entry->next; DictEntry *next = entry->next;
if (prev) { if (prev)
{
prev->next = next; prev->next = next;
} else { }
else
{
dict->first = next; dict->first = next;
} }
if (next) { if (next)
{
next->prev = prev; next->prev = prev;
} else { }
else
{
dict->last = prev; dict->last = prev;
} }
} }
@ -245,3 +268,29 @@ Inline void dict_remove_entry(Dict *dict, DictEntry *entry)
dict->first_free = entry; dict->first_free = entry;
} }
} }
//- Dict index
Inline DictEntry *DictEntryFromHash(Dict *dict, u64 hash)
{
__prof;
DictEntry *result = 0;
DictBin *bin = &dict->bins[hash % dict->bins_count];
for (DictEntry *entry = bin->first; entry; entry = entry->next_in_bin)
{
if (hash == entry->hash)
{
/* Match found */
result = entry;
break;
}
}
return result;
}
Inline u64 DictValueFromHash(Dict *dict, u64 hash)
{
__prof;
DictEntry *entry = DictEntryFromHash(dict, hash);
return entry ? entry->value : 0;
}

View File

@ -279,11 +279,11 @@ void BB_WriteF64(BB_Writer *bw, f64 value)
} }
//////////////////////////////// ////////////////////////////////
//~ Write UID //~ Write Uid
void BB_WriteUID(BB_Writer *bw, UID value) void BB_WriteUid(BB_Writer *bw, Uid value)
{ {
BB_WriteDebugMagic(bw, BB_DebugMagicKind_UID, 128); BB_WriteDebugMagic(bw, BB_DebugMagicKind_Uid, 128);
BB_WriteUBits(bw, value.hi, 64); BB_WriteUBits(bw, value.hi, 64);
BB_WriteUBits(bw, value.lo, 64); BB_WriteUBits(bw, value.lo, 64);
} }
@ -584,14 +584,14 @@ f64 BB_ReadF64(BB_Reader *br)
} }
//////////////////////////////// ////////////////////////////////
//~ Read UID //~ Read Uid
UID BB_ReadUID(BB_Reader *br) Uid BB_ReadUid(BB_Reader *br)
{ {
BB_ReadDebugMagic(br, BB_DebugMagicKind_UID, 128); BB_ReadDebugMagic(br, BB_DebugMagicKind_Uid, 128);
u64 hi = BB_ReadUBits(br, 64); u64 hi = BB_ReadUBits(br, 64);
u64 lo = BB_ReadUBits(br, 64); u64 lo = BB_ReadUBits(br, 64);
return MakeUID(hi, lo); return UID(hi, lo);
} }
//////////////////////////////// ////////////////////////////////
@ -801,10 +801,10 @@ void BB_Test(void)
{ kind_iv, .iv = { I64Max } }, { kind_iv, .iv = { I64Max } },
{ kind_iv, .iv = { I64Min } }, { kind_iv, .iv = { I64Min } },
{ kind_string, .s = { LIT("Hello there! Hope you're doing well.") } }, { kind_string, .s = { Lit("Hello there! Hope you're doing well.") } },
{ kind_ibits, .ibits = { 3, 3 } }, { kind_ibits, .ibits = { 3, 3 } },
{ kind_string, .s = { LIT("Alriiiiiiiiiiiiiiiiiiighty then") } }, { kind_string, .s = { Lit("Alriiiiiiiiiiiiiiiiiiighty then") } },
{ kind_string, .s = { LIT("Alriiiiiiiiiiiiiiiiiiighty then") } }, { kind_string, .s = { Lit("Alriiiiiiiiiiiiiiiiiiighty then") } },
}; };
String encoded = ZI; String encoded = ZI;
@ -876,7 +876,7 @@ void BB_Test(void)
{ {
String w = c.s.v; String w = c.s.v;
String r = BB_ReadString(scratch.arena, &br); String r = BB_ReadString(scratch.arena, &br);
Assert(string_eq(r, w)); Assert(EqString(r, w));
} }
else else
{ {

View File

@ -56,7 +56,7 @@ typedef u32 BB_DebugMagicKind; enum
BB_DebugMagicKind_IV = 0x981f, BB_DebugMagicKind_IV = 0x981f,
BB_DebugMagicKind_F32 = 0x56F9, BB_DebugMagicKind_F32 = 0x56F9,
BB_DebugMagicKind_F64 = 0x7053, BB_DebugMagicKind_F64 = 0x7053,
BB_DebugMagicKind_UID = 0xA24E, BB_DebugMagicKind_Uid = 0xA24E,
BB_DebugMagicKind_String = 0x7866 BB_DebugMagicKind_String = 0x7866
}; };
@ -104,8 +104,8 @@ void BB_WriteIV(BB_Writer *bw, i64 value);
void BB_WriteF32(BB_Writer *bw, f32 value); void BB_WriteF32(BB_Writer *bw, f32 value);
void BB_WriteF64(BB_Writer *bw, f64 value); void BB_WriteF64(BB_Writer *bw, f64 value);
//- UID //- Uid
void BB_WriteUID(BB_Writer *bw, UID value); void BB_WriteUid(BB_Writer *bw, Uid value);
//- Raw data //- Raw data
void BB_WriteString(BB_Writer *bw, String s); void BB_WriteString(BB_Writer *bw, String s);
@ -156,8 +156,8 @@ i64 BB_ReadIV(BB_Reader *br);
f32 BB_ReadF32(BB_Reader *br); f32 BB_ReadF32(BB_Reader *br);
f64 BB_ReadF64(BB_Reader *br); f64 BB_ReadF64(BB_Reader *br);
//- UID //- Uid
UID BB_ReadUID(BB_Reader *br); Uid BB_ReadUid(BB_Reader *br);
//- Raw data //- Raw data
String BB_ReadString(Arena *arena, BB_Reader *br); String BB_ReadString(Arena *arena, BB_Reader *br);

View File

@ -332,7 +332,7 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
if (params.str.len > 0) { if (params.str.len > 0) {
b32 string_done = 0; b32 string_done = 0;
struct string_codepoint_iter iter = string_codepoint_iter_begin(params.str); CodepointIter iter = BeginCodepointIter(params.str);
while (!string_done) { while (!string_done) {
f32 line_width = 0; f32 line_width = 0;
f32 top_offset = 0; f32 top_offset = 0;
@ -342,7 +342,7 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
b32 line_done = 0; b32 line_done = 0;
while (!line_done) { while (!line_done) {
string_done = !string_codepoint_iter_next(&iter); string_done = !AdvanceCodepointIter(&iter);
if (string_done) { if (string_done) {
line_done = 1; line_done = 1;
} else { } else {
@ -393,7 +393,7 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
widest_line = MaxF32(widest_line, line_width); widest_line = MaxF32(widest_line, line_width);
++num_lines; ++num_lines;
} }
string_codepoint_iter_end(&iter); EndCodepointIter(&iter);
} }
/* ========================== * /* ========================== *

View File

@ -37,7 +37,7 @@ DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String
wchar_t **wstr_args = PushStructs(scratch.arena, wchar_t *, num_args); wchar_t **wstr_args = PushStructs(scratch.arena, wchar_t *, num_args);
for (i32 i = 0; i < num_args; ++i) { for (i32 i = 0; i < num_args; ++i) {
wstr_args[i] = wstr_from_string(scratch.arena, args[i]); wstr_args[i] = WstrFromString(scratch.arena, args[i]);
} }
DxcBuffer dxc_src_buffer = ZI; DxcBuffer dxc_src_buffer = ZI;
@ -64,7 +64,7 @@ DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String
String blob_str = ZI; String blob_str = ZI;
blob_str.len = dxc_errors->GetBufferSize(); blob_str.len = dxc_errors->GetBufferSize();
blob_str.text = (u8 *)dxc_errors->GetBufferPointer(); blob_str.text = (u8 *)dxc_errors->GetBufferPointer();
res.errors = string_copy(arena, blob_str); res.errors = CopyString(arena, blob_str);
} }
/* Get status */ /* Get status */
@ -80,7 +80,7 @@ DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String
String blob_str = ZI; String blob_str = ZI;
blob_str.len = dxc_shader->GetBufferSize(); blob_str.len = dxc_shader->GetBufferSize();
blob_str.text = (u8 *)dxc_shader->GetBufferPointer(); blob_str.text = (u8 *)dxc_shader->GetBufferPointer();
res.dxc = string_copy(arena, blob_str); res.dxc = CopyString(arena, blob_str);
} }
} }

View File

@ -82,19 +82,19 @@ internal P_JobDef(font_load_asset_job, job)
f32 point_size = params->point_size; f32 point_size = params->point_size;
AC_Asset *asset = params->asset; AC_Asset *asset = params->asset;
P_LogInfoF("Loading font \"%F\" (point size %F)", FMT_STR(path), FMT_FLOAT((f64)point_size)); P_LogInfoF("Loading font \"%F\" (point size %F)", FmtString(path), FmtFloat((f64)point_size));
i64 start_ns = P_TimeNs(); i64 start_ns = P_TimeNs();
Assert(string_ends_with(path, LIT(".ttf"))); Assert(StringEndsWith(path, Lit(".ttf")));
Assert(countof(g_font_codes) < LOOKUP_TABLE_SIZE); Assert(countof(g_font_codes) < LOOKUP_TABLE_SIZE);
/* Decode */ /* Decode */
R_Resource res = resource_open(path); R_Resource res = resource_open(path);
if (!resource_exists(&res)) { if (!resource_exists(&res)) {
/* FIME: Load baked font instead of panicking */ /* FIME: Load baked font instead of panicking */
P_Panic(string_format(scratch.arena, P_Panic(StringFormat(scratch.arena,
LIT("Font \"%F\" not found"), Lit("Font \"%F\" not found"),
FMT_STR(path))); FmtString(path)));
} }
TTF_Result result = ttf_decode(scratch.arena, resource_get_data(&res), point_size, g_font_codes, countof(g_font_codes)); TTF_Result result = ttf_decode(scratch.arena, resource_get_data(&res), point_size, g_font_codes, countof(g_font_codes));
resource_close(&res); resource_close(&res);
@ -121,9 +121,9 @@ internal P_JobDef(font_load_asset_job, job)
/* FIXME: Load baked font instead of panicking */ /* FIXME: Load baked font instead of panicking */
if (font->glyphs_count <= 0) { if (font->glyphs_count <= 0) {
P_Panic(string_format(scratch.arena, P_Panic(StringFormat(scratch.arena,
LIT("Parsed 0 glyphs from font \"%F\"!"), Lit("Parsed 0 glyphs from font \"%F\"!"),
FMT_STR(path))); FmtString(path)));
} }
/* CopyStruct glyphs from decode result */ /* CopyStruct glyphs from decode result */
@ -138,7 +138,7 @@ internal P_JobDef(font_load_asset_job, job)
font_task_params_release(params); font_task_params_release(params);
P_LogSuccessF("Loaded font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(SecondsFromNs(P_TimeNs() - start_ns))); P_LogSuccessF("Loaded font \"%F\" (point size %F) in %F seconds", FmtString(path), FmtFloat((f64)point_size), FmtFloat(SecondsFromNs(P_TimeNs() - start_ns)));
asset_cache_mark_ready(asset, font); asset_cache_mark_ready(asset, font);
EndScratch(scratch); EndScratch(scratch);
@ -151,10 +151,10 @@ AC_Asset *font_load_asset(String path, f32 point_size, b32 wait)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
/* Concatenate point_size to path for key */ /* Concatenate point_size to path for key */
String key = string_format(scratch.arena, String key = StringFormat(scratch.arena,
LIT("%F%F_font"), Lit("%F%F_font"),
FMT_STR(path), FmtString(path),
FMT_FLOAT_P((f64)point_size, 1)); FmtFloatP((f64)point_size, 1));
u64 hash = asset_cache_hash(key); u64 hash = asset_cache_hash(key);
b32 is_first_touch; b32 is_first_touch;
AC_Asset *asset = asset_cache_touch(key, hash, &is_first_touch); AC_Asset *asset = asset_cache_touch(key, hash, &is_first_touch);
@ -163,11 +163,11 @@ AC_Asset *font_load_asset(String path, f32 point_size, b32 wait)
/* Assemble task params */ /* Assemble task params */
struct font_task_params *params = font_task_params_alloc(); struct font_task_params *params = font_task_params_alloc();
if (path.len > (sizeof(params->path_cstr) - 1)) { if (path.len > (sizeof(params->path_cstr) - 1)) {
P_Panic(string_format(scratch.arena, P_Panic(StringFormat(scratch.arena,
LIT("Font path \"%F\" too long!"), Lit("Font path \"%F\" too long!"),
FMT_STR(path))); FmtString(path)));
} }
cstr_buff_from_string(STRING_FROM_ARRAY(params->path_cstr), path); CstrBuffFromStringToBuff(StringFromArray(params->path_cstr), path);
params->path_len = path.len; params->path_len = path.len;
params->asset = asset; params->asset = asset;
params->point_size = point_size; params->point_size = point_size;

View File

@ -383,7 +383,7 @@ void gp_startup(void)
{ {
__prof; __prof;
if (Atomic32FetchTestSet(&G.initialized, 0, 1) != 0) { if (Atomic32FetchTestSet(&G.initialized, 0, 1) != 0) {
P_Panic(LIT("GP layer already initialized")); P_Panic(Lit("GP layer already initialized"));
} }
/* Initialize command descriptor heaps pool */ /* Initialize command descriptor heaps pool */
@ -391,7 +391,7 @@ void gp_startup(void)
/* Initialize command buffers pool */ /* Initialize command buffers pool */
G.command_buffers_arena = AllocArena(Gibi(64)); G.command_buffers_arena = AllocArena(Gibi(64));
G.command_buffers_dict = dict_init(G.command_buffers_arena, 4096); G.command_buffers_dict = InitDict(G.command_buffers_arena, 4096);
/* Initialize resources pool */ /* Initialize resources pool */
G.resources_arena = AllocArena(Gibi(64)); G.resources_arena = AllocArena(Gibi(64));
@ -401,9 +401,9 @@ void gp_startup(void)
/* Initialize pipeline cache */ /* Initialize pipeline cache */
G.pipelines_arena = AllocArena(Gibi(64)); G.pipelines_arena = AllocArena(Gibi(64));
G.pipeline_descs = dict_init(G.pipelines_arena, 1024); G.pipeline_descs = InitDict(G.pipelines_arena, 1024);
G.top_pipelines = dict_init(G.pipelines_arena, 1024); G.top_pipelines = InitDict(G.pipelines_arena, 1024);
G.top_successful_pipelines = dict_init(G.pipelines_arena, 1024); G.top_successful_pipelines = InitDict(G.pipelines_arena, 1024);
/* Initialize fenced releases queue */ /* Initialize fenced releases queue */
G.fenced_releases_arena = AllocArena(Gibi(64)); G.fenced_releases_arena = AllocArena(Gibi(64));
@ -411,9 +411,9 @@ void gp_startup(void)
/* Initialize embedded shader archive */ /* Initialize embedded shader archive */
String embedded_data = inc_dxc_tar(); String embedded_data = inc_dxc_tar();
if (embedded_data.len <= 0) { if (embedded_data.len <= 0) {
P_Panic(LIT("No embedded shaders found")); P_Panic(Lit("No embedded shaders found"));
} }
G.dxc_archive = tar_parse(G.pipelines_arena, embedded_data, LIT("")); G.dxc_archive = tar_parse(G.pipelines_arena, embedded_data, Lit(""));
/* Initialize dx12 */ /* Initialize dx12 */
/* TODO: Parallelize phases */ /* TODO: Parallelize phases */
@ -463,7 +463,7 @@ internal P_ExitFuncDef(gp_shutdown)
internal void dx12_init_error(String error) internal void dx12_init_error(String error)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String msg = string_format(scratch.arena, LIT("Failed to initialize DirectX 12.\n\n%F"), FMT_STR(error)); String msg = StringFormat(scratch.arena, Lit("Failed to initialize DirectX 12.\n\n%F"), FmtString(error));
P_Panic(msg); P_Panic(msg);
EndScratch(scratch); EndScratch(scratch);
} }
@ -482,13 +482,13 @@ internal void dx12_init_device(void)
ID3D12Debug *debug_controller0 = 0; ID3D12Debug *debug_controller0 = 0;
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0); hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (FAILED(hr)) { if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create ID3D12Debug0")); dx12_init_error(Lit("Failed to create ID3D12Debug0"));
} }
ID3D12Debug1 *debug_controller1 = 0; ID3D12Debug1 *debug_controller1 = 0;
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1); hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
if (FAILED(hr)) { if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create ID3D12Debug1")); dx12_init_error(Lit("Failed to create ID3D12Debug1"));
} }
ID3D12Debug_EnableDebugLayer(debug_controller0); ID3D12Debug_EnableDebugLayer(debug_controller0);
@ -507,7 +507,7 @@ internal void dx12_init_device(void)
__profn("Create factory"); __profn("Create factory");
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&G.factory); hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&G.factory);
if (FAILED(hr)) { if (FAILED(hr)) {
dx12_init_error(LIT("Failed to initialize DXGI factory")); dx12_init_error(Lit("Failed to initialize DXGI factory"));
} }
} }
@ -516,7 +516,7 @@ internal void dx12_init_device(void)
__profn("Create device"); __profn("Create device");
IDXGIAdapter1 *adapter = 0; IDXGIAdapter1 *adapter = 0;
ID3D12Device *device = 0; ID3D12Device *device = 0;
String error = LIT("Could not initialize GPU device."); String error = Lit("Could not initialize GPU device.");
String first_gpu_name = ZI; String first_gpu_name = ZI;
u32 adapter_index = 0; u32 adapter_index = 0;
b32 skip = 0; /* For debugging iGPU */ b32 skip = 0; /* For debugging iGPU */
@ -528,7 +528,7 @@ internal void dx12_init_device(void)
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
IDXGIAdapter1_GetDesc1(adapter, &desc); IDXGIAdapter1_GetDesc1(adapter, &desc);
if (first_gpu_name.len == 0) { if (first_gpu_name.len == 0) {
first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description); first_gpu_name = StringFromWstrNoLimit(scratch.arena, desc.Description);
} }
{ {
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device); hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
@ -548,8 +548,8 @@ internal void dx12_init_device(void)
} }
if (!device) { if (!device) {
if (first_gpu_name.len > 0) { if (first_gpu_name.len > 0) {
String fmt = LIT("Could not initialize device '%F' with D3D_FEATURE_LEVEL_12_0. Ensure that the device is capable and drivers are up to date."); String fmt = Lit("Could not initialize device '%F' with D3D_FEATURE_LEVEL_12_0. Ensure that the device is capable and drivers are up to date.");
error = string_format(scratch.arena, fmt, FMT_STR(first_gpu_name)); error = StringFormat(scratch.arena, fmt, FmtString(first_gpu_name));
} }
dx12_init_error(error); dx12_init_error(error);
} }
@ -564,7 +564,7 @@ internal void dx12_init_device(void)
ID3D12InfoQueue *info = 0; ID3D12InfoQueue *info = 0;
hr = ID3D12Device_QueryInterface(G.device, &IID_ID3D12InfoQueue, (void **)&info); hr = ID3D12Device_QueryInterface(G.device, &IID_ID3D12InfoQueue, (void **)&info);
if (FAILED(hr)) { if (FAILED(hr)) {
dx12_init_error(LIT("Failed to query ID3D12Device interface")); dx12_init_error(Lit("Failed to query ID3D12Device interface"));
} }
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, 1); ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, 1);
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, 1); ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, 1);
@ -577,7 +577,7 @@ internal void dx12_init_device(void)
IDXGIInfoQueue *dxgi_info = 0; IDXGIInfoQueue *dxgi_info = 0;
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info); hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
if (FAILED(hr)) { if (FAILED(hr)) {
dx12_init_error(LIT("Failed to get DXGI debug interface")); dx12_init_error(Lit("Failed to get DXGI debug interface"));
} }
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, 1); IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, 1);
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, 1); IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, 1);
@ -649,10 +649,10 @@ internal void dx12_init_objects(void)
{ {
__profn("Allocate command queues"); __profn("Allocate command queues");
struct command_queue_desc params[] = { struct command_queue_desc params[] = {
{.type = D3D12_COMMAND_LIST_TYPE_DIRECT, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = LIT("Direct queue") }, {.type = D3D12_COMMAND_LIST_TYPE_DIRECT, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Direct queue") },
{.type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = LIT("Compute queue") }, {.type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Compute queue") },
{.type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH, .dbg_name = LIT("CopyStruct queue") }, {.type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH, .dbg_name = Lit("CopyStruct queue") },
{.type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = LIT("Background copy queue") } {.type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Background copy queue") }
}; };
struct command_queue_alloc_job_sig sig = ZI; struct command_queue_alloc_job_sig sig = ZI;
sig.descs_in = params; sig.descs_in = params;
@ -693,48 +693,48 @@ internal void dx12_init_pipelines(void)
/* Material pipeline */ /* Material pipeline */
{ {
struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("kernel_material"); desc->name = Lit("kernel_material");
desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[0].blending = 1; desc->rtvs[0].blending = 1;
desc->rtvs[1].format = DXGI_FORMAT_R16G16B16A16_FLOAT; desc->rtvs[1].format = DXGI_FORMAT_R16G16B16A16_FLOAT;
desc->rtvs[1].blending = 1; desc->rtvs[1].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); SetDictValue(G.pipelines_arena, G.pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc);
} }
/* Flood pipeline */ /* Flood pipeline */
{ {
struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("kernel_flood"); desc->name = Lit("kernel_flood");
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); SetDictValue(G.pipelines_arena, G.pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc);
} }
/* Shade pipeline */ /* Shade pipeline */
{ {
struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("kernel_shade"); desc->name = Lit("kernel_shade");
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); SetDictValue(G.pipelines_arena, G.pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc);
} }
/* Shape pipeline */ /* Shape pipeline */
{ {
struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("kernel_shape"); desc->name = Lit("kernel_shape");
desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[0].blending = 1; desc->rtvs[0].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); SetDictValue(G.pipelines_arena, G.pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc);
} }
/* UI pipeline */ /* UI pipeline */
{ {
struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("kernel_ui"); desc->name = Lit("kernel_ui");
desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[0].blending = 1; desc->rtvs[0].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); SetDictValue(G.pipelines_arena, G.pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc);
} }
/* Blit pipeilne */ /* Blit pipeilne */
{ {
struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc); struct pipeline_desc *desc = PushStruct(G.pipelines_arena, struct pipeline_desc);
desc->name = LIT("kernel_blit"); desc->name = Lit("kernel_blit");
desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc->rtvs[0].blending = 1; desc->rtvs[0].blending = 1;
dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); SetDictValue(G.pipelines_arena, G.pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc);
} }
} }
@ -759,14 +759,14 @@ internal void dx12_init_pipelines(void)
for (u32 i = 0; i < num_pipelines; ++i) { for (u32 i = 0; i < num_pipelines; ++i) {
struct pipeline *pipeline = pipelines[i]; struct pipeline *pipeline = pipelines[i];
if (pipeline->success) { if (pipeline->success) {
P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SecondsFromNs(pipeline->compilation_time_ns))); P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FmtString(pipeline->name), FmtFloat(SecondsFromNs(pipeline->compilation_time_ns)));
if (pipeline->error.len) { if (pipeline->error.len) {
String msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error)); String msg = StringFormat(scratch.arena, Lit("Warning while compiling pipeline \"%F\":\n%F"), FmtString(pipeline->name), FmtString(pipeline->error));
P_LogWarning(msg); P_LogWarning(msg);
} }
} else { } else {
String error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error"); String error = pipeline->error.len > 0 ? pipeline->error : Lit("Unknown error");
String msg = string_format(scratch.arena, LIT("Error initializing pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error)); String msg = StringFormat(scratch.arena, Lit("Error initializing pipeline \"%F\":\n\n%F"), FmtString(pipeline->name), FmtString(error));
P_LogError(msg); P_LogError(msg);
P_MessageBox(P_MessageBoxKind_Warning, msg); P_MessageBox(P_MessageBoxKind_Warning, msg);
} }
@ -785,7 +785,7 @@ internal void dx12_init_noise(void)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
{ {
String noise_res_name = LIT("noise_128x128x64_16.dat"); String noise_res_name = Lit("noise_128x128x64_16.dat");
R_Resource noise_res = resource_open(noise_res_name); R_Resource noise_res = resource_open(noise_res_name);
DXGI_FORMAT format = DXGI_FORMAT_R16_UINT; DXGI_FORMAT format = DXGI_FORMAT_R16_UINT;
//u32 expected_size = K_BLUE_NOISE_TEX_WIDTH * K_BLUE_NOISE_TEX_HEIGHT * K_BLUE_NOISE_TEX_DEPTH * 2; //u32 expected_size = K_BLUE_NOISE_TEX_WIDTH * K_BLUE_NOISE_TEX_HEIGHT * K_BLUE_NOISE_TEX_DEPTH * 2;
@ -793,10 +793,10 @@ internal void dx12_init_noise(void)
if (resource_exists(&noise_res)) { if (resource_exists(&noise_res)) {
String data = resource_get_data(&noise_res); String data = resource_get_data(&noise_res);
if (data.len != expected_size) { if (data.len != expected_size) {
P_Panic(string_format(scratch.arena, P_Panic(StringFormat(scratch.arena,
LIT("Noise texture has unexpected size for a %Fx%Fx%F texture (expected %F, got %F)"), Lit("Noise texture has unexpected size for a %Fx%Fx%F texture (expected %F, got %F)"),
FMT_UINT(K_BLUE_NOISE_TEX_WIDTH), FMT_UINT(K_BLUE_NOISE_TEX_HEIGHT), FMT_UINT(K_BLUE_NOISE_TEX_DEPTH), FmtUint(K_BLUE_NOISE_TEX_WIDTH), FmtUint(K_BLUE_NOISE_TEX_HEIGHT), FmtUint(K_BLUE_NOISE_TEX_DEPTH),
FMT_UINT(expected_size), FMT_UINT(data.len))); FmtUint(expected_size), FmtUint(data.len)));
} }
{ {
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
@ -833,7 +833,7 @@ internal void dx12_init_noise(void)
} }
} }
} else { } else {
P_Panic(string_format(scratch.arena, LIT("Noise resource \"%F\" not found"), FMT_STR(noise_res_name))); P_Panic(StringFormat(scratch.arena, Lit("Noise resource \"%F\" not found"), FmtString(noise_res_name)));
} }
resource_close(&noise_res); resource_close(&noise_res);
} }
@ -881,15 +881,15 @@ internal P_JobDef(shader_compile_job, job)
DXC_Result dxc_result = ZI; DXC_Result dxc_result = ZI;
{ {
__profn("Compile shader"); __profn("Compile shader");
P_LogInfoF("Compiling shader \"%F:%F\"", FMT_STR(desc->friendly_name), FMT_STR(desc->entry)); P_LogInfoF("Compiling shader \"%F:%F\"", FmtString(desc->friendly_name), FmtString(desc->entry));
/* NOTE: `DXC_ARGS` is supplied by build system at compile time */ /* NOTE: `DXC_ARGS` is supplied by build system at compile time */
char *dxc_args_cstr = Stringize(DXC_ARGS); char *dxc_args_cstr = Stringize(DXC_ARGS);
String dxc_args_str = string_from_cstr_no_limit(dxc_args_cstr); String dxc_args_str = StringFromCstrNoLimit(dxc_args_cstr);
StringArray dxc_args_array = string_split(scratch.arena, dxc_args_str, LIT(" ")); StringArray dxc_args_array = SplitString(scratch.arena, dxc_args_str, Lit(" "));
String shader_args[] = { String shader_args[] = {
desc->friendly_name, desc->friendly_name,
LIT("-E"), desc->entry, Lit("-E"), desc->entry,
LIT("-T"), desc->target, Lit("-T"), desc->target,
}; };
u32 num_args = countof(shader_args) + dxc_args_array.count; u32 num_args = countof(shader_args) + dxc_args_array.count;
String *args = PushStructs(scratch.arena, String, num_args); String *args = PushStructs(scratch.arena, String, num_args);
@ -938,35 +938,35 @@ internal P_JobDef(pipeline_alloc_job, job)
pipelines_out[job.id] = pipeline; pipelines_out[job.id] = pipeline;
pipeline->desc = *desc; pipeline->desc = *desc;
pipeline->name = desc->name; pipeline->name = desc->name;
pipeline->hash = hash_fnv64(HASH_FNV64_BASIS, pipeline->name); pipeline->hash = HashFnv64(Fnv64Basis, pipeline->name);
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
{ {
i64 start_ns = P_TimeNs(); i64 start_ns = P_TimeNs();
String pipeline_name = pipeline->name; String pipeline_name = pipeline->name;
P_LogInfoF("Loading pipeline \"%F\"", FMT_STR(pipeline_name)); P_LogInfoF("Loading pipeline \"%F\"", FmtString(pipeline_name));
b32 success = 1; b32 success = 1;
HRESULT hr = 0; HRESULT hr = 0;
String error_str = ZI; String error_str = ZI;
String vs_dxc = desc->vs_dxc.len > 0 ? desc->vs_dxc : tar_get(&G.dxc_archive, string_cat(scratch.arena, pipeline_name, LIT(".vs")))->data; String vs_dxc = desc->vs_dxc.len > 0 ? desc->vs_dxc : tar_get(&G.dxc_archive, CatString(scratch.arena, pipeline_name, Lit(".vs")))->data;
String ps_dxc = desc->ps_dxc.len > 0 ? desc->ps_dxc : tar_get(&G.dxc_archive, string_cat(scratch.arena, pipeline_name, LIT(".ps")))->data; String ps_dxc = desc->ps_dxc.len > 0 ? desc->ps_dxc : tar_get(&G.dxc_archive, CatString(scratch.arena, pipeline_name, Lit(".ps")))->data;
String cs_dxc = desc->cs_dxc.len > 0 ? desc->cs_dxc : tar_get(&G.dxc_archive, string_cat(scratch.arena, pipeline_name, LIT(".cs")))->data; String cs_dxc = desc->cs_dxc.len > 0 ? desc->cs_dxc : tar_get(&G.dxc_archive, CatString(scratch.arena, pipeline_name, Lit(".cs")))->data;
if (success && vs_dxc.len > 0 && ps_dxc.len <= 0) { if (success && vs_dxc.len > 0 && ps_dxc.len <= 0) {
error_str = LIT("Pipeline has vertex shader without pixel shader"); error_str = Lit("Pipeline has vertex shader without pixel shader");
success = 0; success = 0;
} }
if (success && vs_dxc.len <= 0 && ps_dxc.len > 0) { if (success && vs_dxc.len <= 0 && ps_dxc.len > 0) {
error_str = LIT("Pipeline has pixel shader without vertex shader"); error_str = Lit("Pipeline has pixel shader without vertex shader");
success = 0; success = 0;
} }
if (success && cs_dxc.len > 0 && (vs_dxc.len > 0 || ps_dxc.len > 0)) { if (success && cs_dxc.len > 0 && (vs_dxc.len > 0 || ps_dxc.len > 0)) {
error_str = LIT("Pipeline has a compute shader with a vertex/pixel shader"); error_str = Lit("Pipeline has a compute shader with a vertex/pixel shader");
success = 0; success = 0;
} }
if (success && cs_dxc.len <= 0 && vs_dxc.len <= 0 && ps_dxc.len <= 0) { if (success && cs_dxc.len <= 0 && vs_dxc.len <= 0 && ps_dxc.len <= 0) {
error_str = LIT("Pipeline has no shaders"); error_str = Lit("Pipeline has no shaders");
success = 0; success = 0;
} }
@ -978,7 +978,7 @@ internal P_JobDef(pipeline_alloc_job, job)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
CopyBytes(ID3D10Blob_GetBufferPointer(vs_blob), vs_dxc.text, vs_dxc.len); CopyBytes(ID3D10Blob_GetBufferPointer(vs_blob), vs_dxc.text, vs_dxc.len);
} else { } else {
error_str = LIT("Failed to create vertex shader blob"); error_str = Lit("Failed to create vertex shader blob");
success = 0; success = 0;
} }
} }
@ -987,7 +987,7 @@ internal P_JobDef(pipeline_alloc_job, job)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
CopyBytes(ID3D10Blob_GetBufferPointer(ps_blob), ps_dxc.text, ps_dxc.len); CopyBytes(ID3D10Blob_GetBufferPointer(ps_blob), ps_dxc.text, ps_dxc.len);
} else { } else {
error_str = LIT("Failed to create pixel shader blob"); error_str = Lit("Failed to create pixel shader blob");
success = 0; success = 0;
} }
} }
@ -996,7 +996,7 @@ internal P_JobDef(pipeline_alloc_job, job)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
CopyBytes(ID3D10Blob_GetBufferPointer(cs_blob), cs_dxc.text, cs_dxc.len); CopyBytes(ID3D10Blob_GetBufferPointer(cs_blob), cs_dxc.text, cs_dxc.len);
} else { } else {
error_str = LIT("Failed to create compute shader blob"); error_str = Lit("Failed to create compute shader blob");
success = 0; success = 0;
} }
} }
@ -1017,7 +1017,7 @@ internal P_JobDef(pipeline_alloc_job, job)
} }
if (cs_rootsig_data_len == 0) { if (cs_rootsig_data_len == 0) {
success = 0; success = 0;
error_str = LIT("Compute shader is missing root signature"); error_str = Lit("Compute shader is missing root signature");
} else { } else {
rootsig_blob = cs_rootsig_blob; rootsig_blob = cs_rootsig_blob;
} }
@ -1040,13 +1040,13 @@ internal P_JobDef(pipeline_alloc_job, job)
} }
if (vs_rootsig_data_len == 0) { if (vs_rootsig_data_len == 0) {
success = 0; success = 0;
error_str = LIT("Vertex shader is missing root signature"); error_str = Lit("Vertex shader is missing root signature");
} else if (ps_rootsig_data_len == 0) { } else if (ps_rootsig_data_len == 0) {
success = 0; success = 0;
error_str = LIT("Pixel shader is missing root signature"); error_str = Lit("Pixel shader is missing root signature");
} else if (vs_rootsig_data_len != ps_rootsig_data_len || !EqBytes(vs_rootsig_data, ps_rootsig_data, vs_rootsig_data_len)) { } else if (vs_rootsig_data_len != ps_rootsig_data_len || !EqBytes(vs_rootsig_data, ps_rootsig_data, vs_rootsig_data_len)) {
success = 0; success = 0;
error_str = LIT("Root signature mismatch between vertex and pixel shader"); error_str = Lit("Root signature mismatch between vertex and pixel shader");
} else { } else {
rootsig_blob = vs_rootsig_blob; rootsig_blob = vs_rootsig_blob;
} }
@ -1062,7 +1062,7 @@ internal P_JobDef(pipeline_alloc_job, job)
__profn("Create root signature"); __profn("Create root signature");
hr = ID3D12Device_CreateRootSignature(G.device, 0, ID3D10Blob_GetBufferPointer(rootsig_blob), ID3D10Blob_GetBufferSize(rootsig_blob), &IID_ID3D12RootSignature, (void **)&rootsig); hr = ID3D12Device_CreateRootSignature(G.device, 0, ID3D10Blob_GetBufferPointer(rootsig_blob), ID3D10Blob_GetBufferSize(rootsig_blob), &IID_ID3D12RootSignature, (void **)&rootsig);
if (FAILED(hr)) { if (FAILED(hr)) {
error_str = LIT("Failed to create root signature"); error_str = Lit("Failed to create root signature");
success = 0; success = 0;
} }
} }
@ -1153,14 +1153,14 @@ internal P_JobDef(pipeline_alloc_job, job)
hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
} }
if (FAILED(hr)) { if (FAILED(hr)) {
error_str = LIT("Failed to create pipeline state object"); error_str = Lit("Failed to create pipeline state object");
success = 0; success = 0;
} }
} }
/* Parse errors */ /* Parse errors */
if (!success && error_str.len <= 0) { if (!success && error_str.len <= 0) {
error_str = LIT("Unknown error"); error_str = Lit("Unknown error");
} }
pipeline->pso = pso; pipeline->pso = pso;
@ -1225,7 +1225,7 @@ internal struct pipeline_scope *pipeline_scope_begin(void)
ResetArena(arena); ResetArena(arena);
scope = PushStruct(arena, struct pipeline_scope); scope = PushStruct(arena, struct pipeline_scope);
scope->arena = arena; scope->arena = arena;
scope->refs = dict_init(scope->arena, 64); scope->refs = InitDict(scope->arena, 64);
return scope; return scope;
} }
@ -1251,22 +1251,22 @@ internal struct pipeline *pipeline_from_name(struct pipeline_scope *scope, Strin
{ {
__prof; __prof;
struct pipeline *res = &g_nil_pipeline; struct pipeline *res = &g_nil_pipeline;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
struct pipeline *tmp = (struct pipeline *)dict_get(scope->refs, hash); struct pipeline *tmp = (struct pipeline *)DictValueFromHash(scope->refs, hash);
if (tmp) { if (tmp) {
res = tmp; res = tmp;
} else { } else {
{ {
P_Lock lock = P_LockE(&G.pipelines_mutex); P_Lock lock = P_LockE(&G.pipelines_mutex);
tmp = (struct pipeline *)dict_get(G.top_successful_pipelines, hash); tmp = (struct pipeline *)DictValueFromHash(G.top_successful_pipelines, hash);
if (tmp) { if (tmp) {
++tmp->refcount; ++tmp->refcount;
} }
P_Unlock(&lock); P_Unlock(&lock);
} }
if (tmp) { if (tmp) {
dict_set(scope->arena, scope->refs, hash, (u64)tmp); SetDictValue(scope->arena, scope->refs, hash, (u64)tmp);
res = tmp; res = tmp;
} }
} }
@ -1284,20 +1284,20 @@ internal void pipeline_register(u64 num_pipelines, struct pipeline **pipelines)
u64 hash = pipeline->hash; u64 hash = pipeline->hash;
/* Insert into top dict */ /* Insert into top dict */
{ {
struct pipeline *old_pipeline = (struct pipeline *)dict_get(G.top_pipelines, hash); struct pipeline *old_pipeline = (struct pipeline *)DictValueFromHash(G.top_pipelines, hash);
if (old_pipeline && --old_pipeline->refcount <= 0) { if (old_pipeline && --old_pipeline->refcount <= 0) {
fenced_release(old_pipeline, FENCED_RELEASE_KIND_PIPELINE); fenced_release(old_pipeline, FENCED_RELEASE_KIND_PIPELINE);
} }
dict_set(G.pipelines_arena, G.top_pipelines, hash, (u64)pipeline); SetDictValue(G.pipelines_arena, G.top_pipelines, hash, (u64)pipeline);
++pipeline->refcount; ++pipeline->refcount;
} }
/* Insert into success dict */ /* Insert into success dict */
if (pipeline->success) { if (pipeline->success) {
struct pipeline *old_pipeline = (struct pipeline *)dict_get(G.top_successful_pipelines, hash); struct pipeline *old_pipeline = (struct pipeline *)DictValueFromHash(G.top_successful_pipelines, hash);
if (old_pipeline && --old_pipeline->refcount <= 0) { if (old_pipeline && --old_pipeline->refcount <= 0) {
fenced_release(old_pipeline, FENCED_RELEASE_KIND_PIPELINE); fenced_release(old_pipeline, FENCED_RELEASE_KIND_PIPELINE);
} }
dict_set(G.pipelines_arena, G.top_successful_pipelines, hash, (u64)pipeline); SetDictValue(G.pipelines_arena, G.top_successful_pipelines, hash, (u64)pipeline);
++pipeline->refcount; ++pipeline->refcount;
} }
} }
@ -1311,12 +1311,12 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
__prof; __prof;
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String rst_extension = LIT(".rst"); String rst_extension = Lit(".rst");
String knl_extension = LIT(".knl"); String knl_extension = Lit(".knl");
b32 is_src = string_starts_with(name, LIT("src/")); b32 is_src = StringStartsWith(name, Lit("src/"));
b32 is_rs = is_src && string_ends_with(name, rst_extension); b32 is_rs = is_src && StringEndsWith(name, rst_extension);
b32 is_cs = is_src && !is_rs && string_ends_with(name, knl_extension); b32 is_cs = is_src && !is_rs && StringEndsWith(name, knl_extension);
b32 success = 0; b32 success = 0;
/* Recompile shaders */ /* Recompile shaders */
@ -1326,20 +1326,20 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
struct shader_compile_desc *shader_descs = 0; struct shader_compile_desc *shader_descs = 0;
struct shader_compile_result *shader_results = 0; struct shader_compile_result *shader_results = 0;
if (is_rs || is_cs) { if (is_rs || is_cs) {
P_LogDebugF("Change detected in shader source file \"%F\", recompiling...", FMT_STR(name)); P_LogDebugF("Change detected in shader source file \"%F\", recompiling...", FmtString(name));
success = 1; success = 1;
P_File file = P_OpenFileReadWait(name); P_File file = P_OpenFileReadWait(name);
String data = P_ReadFile(scratch.arena, file); String data = P_ReadFile(scratch.arena, file);
{ {
friendly_name = name; friendly_name = name;
StringArray split = string_split(scratch.arena, friendly_name, LIT("src/")); StringArray split = SplitString(scratch.arena, friendly_name, Lit("src/"));
friendly_name = split.count > 0 ? string_cat(scratch.arena, LIT("src/"), split.strings[split.count - 1]) : friendly_name; friendly_name = split.count > 0 ? CatString(scratch.arena, Lit("src/"), split.strings[split.count - 1]) : friendly_name;
} }
{ {
pipeline_name = name; pipeline_name = name;
StringArray split = string_split(scratch.arena, pipeline_name, LIT("/")); StringArray split = SplitString(scratch.arena, pipeline_name, Lit("/"));
pipeline_name = split.count > 0 ? split.strings[split.count - 1] : pipeline_name; pipeline_name = split.count > 0 ? split.strings[split.count - 1] : pipeline_name;
split = string_split(scratch.arena, pipeline_name, LIT(".")); split = SplitString(scratch.arena, pipeline_name, Lit("."));
pipeline_name = split.count > 1 ? split.strings[split.count - 2] : pipeline_name; pipeline_name = split.count > 1 ? split.strings[split.count - 2] : pipeline_name;
} }
{ {
@ -1353,12 +1353,12 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
sig.results = shader_results; sig.results = shader_results;
sig.descs[0].src = data; sig.descs[0].src = data;
sig.descs[0].friendly_name = friendly_name; sig.descs[0].friendly_name = friendly_name;
sig.descs[0].entry = LIT("vs"); sig.descs[0].entry = Lit("vs");
sig.descs[0].target = LIT("vs_6_6"); sig.descs[0].target = Lit("vs_6_6");
sig.descs[1].src = data; sig.descs[1].src = data;
sig.descs[1].friendly_name = friendly_name; sig.descs[1].friendly_name = friendly_name;
sig.descs[1].entry = LIT("ps"); sig.descs[1].entry = Lit("ps");
sig.descs[1].target = LIT("ps_6_6"); sig.descs[1].target = Lit("ps_6_6");
} else if (is_cs) { } else if (is_cs) {
num_shaders = 1; num_shaders = 1;
shader_descs = PushStructs(scratch.arena, struct shader_compile_desc, num_shaders); shader_descs = PushStructs(scratch.arena, struct shader_compile_desc, num_shaders);
@ -1367,8 +1367,8 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
sig.results = shader_results; sig.results = shader_results;
sig.descs[0].src = data; sig.descs[0].src = data;
sig.descs[0].friendly_name = friendly_name; sig.descs[0].friendly_name = friendly_name;
sig.descs[0].entry = LIT("cs"); sig.descs[0].entry = Lit("cs");
sig.descs[0].target = LIT("cs_6_6"); sig.descs[0].target = Lit("cs_6_6");
} }
{ {
P_Counter counter = ZI; P_Counter counter = ZI;
@ -1384,7 +1384,7 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
struct shader_compile_desc *desc = &shader_descs[i]; struct shader_compile_desc *desc = &shader_descs[i];
struct shader_compile_result *result = &shader_results[i]; struct shader_compile_result *result = &shader_results[i];
if (result->success) { if (result->success) {
P_LogSuccessF("Finished compiling shader \"%F:%F\" in %F seconds", FMT_STR(desc->friendly_name), FMT_STR(desc->entry), FMT_FLOAT(SecondsFromNs(result->elapsed_ns))); P_LogSuccessF("Finished compiling shader \"%F:%F\" in %F seconds", FmtString(desc->friendly_name), FmtString(desc->entry), FmtFloat(SecondsFromNs(result->elapsed_ns)));
if (result->errors.len > 0) { if (result->errors.len > 0) {
String msg = result->errors; String msg = result->errors;
P_LogWarning(msg); P_LogWarning(msg);
@ -1403,7 +1403,7 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
for (DictEntry *entry = G.pipeline_descs->first; entry; entry = entry->next) { for (DictEntry *entry = G.pipeline_descs->first; entry; entry = entry->next) {
struct pipeline_desc *pipeline_desc = (struct pipeline_desc *)entry->value; struct pipeline_desc *pipeline_desc = (struct pipeline_desc *)entry->value;
struct pipeline_desc new_pipeline_desc = *pipeline_desc; struct pipeline_desc new_pipeline_desc = *pipeline_desc;
if (string_eq(pipeline_desc->name, pipeline_name)) { if (EqString(pipeline_desc->name, pipeline_name)) {
if (is_rs) { if (is_rs) {
new_pipeline_desc.vs_dxc = shader_results[0].dxc; new_pipeline_desc.vs_dxc = shader_results[0].dxc;
new_pipeline_desc.ps_dxc = shader_results[1].dxc; new_pipeline_desc.ps_dxc = shader_results[1].dxc;
@ -1432,22 +1432,22 @@ internal WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
for (u32 i = 0; i < num_pipelines; ++i) { for (u32 i = 0; i < num_pipelines; ++i) {
struct pipeline *pipeline = pipelines[i]; struct pipeline *pipeline = pipelines[i];
if (pipeline->success) { if (pipeline->success) {
P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SecondsFromNs(pipeline->compilation_time_ns))); P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FmtString(pipeline->name), FmtFloat(SecondsFromNs(pipeline->compilation_time_ns)));
if (pipeline->error.len > 0) { if (pipeline->error.len > 0) {
String msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error)); String msg = StringFormat(scratch.arena, Lit("Warning while compiling pipeline \"%F\":\n%F"), FmtString(pipeline->name), FmtString(pipeline->error));
P_LogWarning(msg); P_LogWarning(msg);
} }
} else { } else {
{ {
String error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error"); String error = pipeline->error.len > 0 ? pipeline->error : Lit("Unknown error");
String msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(error)); String msg = StringFormat(scratch.arena, Lit("Error compiling pipeline \"%F\":\n%F"), FmtString(pipeline->name), FmtString(error));
P_LogError(msg); P_LogError(msg);
} }
struct pipeline *old_pipeline = (struct pipeline *)dict_get(G.top_successful_pipelines, pipeline->hash); struct pipeline *old_pipeline = (struct pipeline *)DictValueFromHash(G.top_successful_pipelines, pipeline->hash);
if (!old_pipeline) { if (!old_pipeline) {
/* If no previously successful pipeline exists, then show a message box rather than logging since logs may not be visible to user */ /* If no previously successful pipeline exists, then show a message box rather than logging since logs may not be visible to user */
String error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error"); String error = pipeline->error.len > 0 ? pipeline->error : Lit("Unknown error");
String msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error)); String msg = StringFormat(scratch.arena, Lit("Error compiling pipeline \"%F\":\n\n%F"), FmtString(pipeline->name), FmtString(error));
P_MessageBox(P_MessageBoxKind_Warning, msg); P_MessageBox(P_MessageBoxKind_Warning, msg);
} }
@ -1482,7 +1482,7 @@ internal struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh)
index = d->index; index = d->index;
} else { } else {
if (dh->num_descriptors_reserved >= dh->num_descriptors_capacity) { if (dh->num_descriptors_reserved >= dh->num_descriptors_capacity) {
P_Panic(LIT("Max descriptors reached in heap")); P_Panic(Lit("Max descriptors reached in heap"));
} }
d = PushStructNoZero(dh->arena, struct descriptor); d = PushStructNoZero(dh->arena, struct descriptor);
index = dh->num_descriptors_reserved++; index = dh->num_descriptors_reserved++;
@ -1529,7 +1529,7 @@ internal struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRI
descriptor_size = G.desc_sizes[type]; descriptor_size = G.desc_sizes[type];
} }
if (num_descriptors == 0 || descriptor_size == 0) { if (num_descriptors == 0 || descriptor_size == 0) {
P_Panic(LIT("Unsupported CPU descriptor type")); P_Panic(Lit("Unsupported CPU descriptor type"));
} }
dh->num_descriptors_capacity = num_descriptors; dh->num_descriptors_capacity = num_descriptors;
dh->descriptor_size = descriptor_size; dh->descriptor_size = descriptor_size;
@ -1539,7 +1539,7 @@ internal struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRI
desc.NumDescriptors = num_descriptors; desc.NumDescriptors = num_descriptors;
HRESULT hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&dh->heap); HRESULT hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&dh->heap);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create CPU descriptor heap")); P_Panic(Lit("Failed to create CPU descriptor heap"));
} }
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(dh->heap, &dh->handle); ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(dh->heap, &dh->handle);
@ -1622,7 +1622,7 @@ internal struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr
HRESULT hr = ID3D12Device_CreateCommittedResource(G.device, &heap_props, heap_flags, &desc, initial_state, clear_value_ptr, &IID_ID3D12Resource, (void **)&r->resource); HRESULT hr = ID3D12Device_CreateCommittedResource(G.device, &heap_props, heap_flags, &desc, initial_state, clear_value_ptr, &IID_ID3D12Resource, (void **)&r->resource);
if (FAILED(hr)) { if (FAILED(hr)) {
/* TODO: Don't panic */ /* TODO: Don't panic */
P_Panic(LIT("Failed to create resource")); P_Panic(Lit("Failed to create resource"));
} }
r->state = initial_state; r->state = initial_state;
@ -1749,12 +1749,12 @@ internal P_JobDef(command_queue_alloc_job, job)
dx12_desc.Priority = desc->priority; dx12_desc.Priority = desc->priority;
HRESULT hr = ID3D12Device_CreateCommandQueue(G.device, &dx12_desc, &IID_ID3D12CommandQueue, (void **)&cq->cq); HRESULT hr = ID3D12Device_CreateCommandQueue(G.device, &dx12_desc, &IID_ID3D12CommandQueue, (void **)&cq->cq);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create command queue")); P_Panic(Lit("Failed to create command queue"));
} }
hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&cq->submit_fence); hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&cq->submit_fence);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create command queue fence")); P_Panic(Lit("Failed to create command queue fence"));
} }
cq->cl_pool = command_list_pool_alloc(cq); cq->cl_pool = command_list_pool_alloc(cq);
@ -1838,29 +1838,29 @@ internal struct command_list *command_list_open(struct command_list_pool *pool)
} else { } else {
hr = ID3D12Device_CreateCommandAllocator(G.device, cq->desc.type, &IID_ID3D12CommandAllocator, (void **)&cl->ca); hr = ID3D12Device_CreateCommandAllocator(G.device, cq->desc.type, &IID_ID3D12CommandAllocator, (void **)&cl->ca);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create command allocator")); P_Panic(Lit("Failed to create command allocator"));
} }
hr = ID3D12Device_CreateCommandList(G.device, 0, cq->desc.type, cl->ca, 0, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl); hr = ID3D12Device_CreateCommandList(G.device, 0, cq->desc.type, cl->ca, 0, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create command list")); P_Panic(Lit("Failed to create command list"));
} }
hr = ID3D12GraphicsCommandList_Close(cl->cl); hr = ID3D12GraphicsCommandList_Close(cl->cl);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to close command list during initialization")); P_Panic(Lit("Failed to close command list during initialization"));
} }
} }
/* Reset */ /* Reset */
hr = ID3D12CommandAllocator_Reset(cl->ca); hr = ID3D12CommandAllocator_Reset(cl->ca);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to reset command allocator")); P_Panic(Lit("Failed to reset command allocator"));
} }
hr = ID3D12GraphicsCommandList_Reset(cl->cl, cl->ca, 0); hr = ID3D12GraphicsCommandList_Reset(cl->cl, cl->ca, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to reset command list")); P_Panic(Lit("Failed to reset command list"));
} }
return cl; return cl;
@ -1879,7 +1879,7 @@ internal u64 command_list_close(struct command_list *cl)
HRESULT hr = ID3D12GraphicsCommandList_Close(cl->cl); HRESULT hr = ID3D12GraphicsCommandList_Close(cl->cl);
if (FAILED(hr)) { if (FAILED(hr)) {
/* TODO: Don't panic */ /* TODO: Don't panic */
P_Panic(LIT("Failed to close command list before execution")); P_Panic(Lit("Failed to close command list before execution"));
} }
} }
@ -2009,7 +2009,7 @@ internal struct command_descriptor_heap *command_list_push_descriptor_heap(struc
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
HRESULT hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&cdh->heap); HRESULT hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&cdh->heap);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create GPU descriptor heap")); P_Panic(Lit("Failed to create GPU descriptor heap"));
} }
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_cpu_handle); ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_cpu_handle);
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_gpu_handle); ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_gpu_handle);
@ -2075,7 +2075,7 @@ internal struct command_buffer *_command_list_push_buffer(struct command_list *c
{ {
u64 group_hash = command_buffer_hash_from_size(size); u64 group_hash = command_buffer_hash_from_size(size);
DictEntry *cb_group_entry = dict_ensure_entry(G.command_buffers_arena, G.command_buffers_dict, group_hash); DictEntry *cb_group_entry = EnsureDictEntry(G.command_buffers_arena, G.command_buffers_dict, group_hash);
cb_group = (struct command_buffer_group *)cb_group_entry->value; cb_group = (struct command_buffer_group *)cb_group_entry->value;
if (!cb_group) { if (!cb_group) {
/* Create group */ /* Create group */
@ -2163,7 +2163,7 @@ internal struct command_buffer *_command_list_push_buffer(struct command_list *c
HRESULT hr = ID3D12Resource_Map(cb->resource->resource, 0, &read_range, &dst); HRESULT hr = ID3D12Resource_Map(cb->resource->resource, 0, &read_range, &dst);
if (FAILED(hr) || !dst) { if (FAILED(hr) || !dst) {
/* TODO: Don't panic */ /* TODO: Don't panic */
P_Panic(LIT("Failed to map command buffer resource")); P_Panic(Lit("Failed to map command buffer resource"));
} }
CopyBytes(dst, data, data_len); CopyBytes(dst, data, data_len);
ID3D12Resource_Unmap(cb->resource->resource, 0, 0); ID3D12Resource_Unmap(cb->resource->resource, 0, 0);
@ -2208,7 +2208,7 @@ G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, Vec2I32 size, vo
{ {
__prof; __prof;
if (size.x <= 0 || size.y <= 0) { if (size.x <= 0 || size.y <= 0) {
P_Panic(LIT("Tried to create texture with dimension <= 0")); P_Panic(Lit("Tried to create texture with dimension <= 0"));
} }
LocalPersist const DXGI_FORMAT formats[] = { LocalPersist const DXGI_FORMAT formats[] = {
[GP_TEXTURE_FORMAT_R8_UNORM] = DXGI_FORMAT_R8_UNORM, [GP_TEXTURE_FORMAT_R8_UNORM] = DXGI_FORMAT_R8_UNORM,
@ -2222,7 +2222,7 @@ G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, Vec2I32 size, vo
dxgi_format = formats[format]; dxgi_format = formats[format];
} }
if (format == 0) { if (format == 0) {
P_Panic(LIT("Tried to create texture with unknown format")); P_Panic(Lit("Tried to create texture with unknown format"));
} }
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
@ -2335,7 +2335,7 @@ internal P_JobDef(dx12_upload_job, job)
HRESULT hr = ID3D12Resource_Map(upload->resource, 0, &read_range, &mapped); HRESULT hr = ID3D12Resource_Map(upload->resource, 0, &read_range, &mapped);
if (FAILED(hr) || !mapped) { if (FAILED(hr) || !mapped) {
/* TODO: Don't panic */ /* TODO: Don't panic */
P_Panic(LIT("Failed to map texture upload resource")); P_Panic(Lit("Failed to map texture upload resource"));
} }
u8 *dst = (u8 *)mapped + placed_footprint.Offset; u8 *dst = (u8 *)mapped + placed_footprint.Offset;
u8 *src = data; u8 *src = data;
@ -2735,12 +2735,12 @@ G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams params)
} }
struct pipeline_scope *pipeline_scope = pipeline_scope_begin(); struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_material")); struct pipeline *material_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_material"));
struct pipeline *flood_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_flood")); struct pipeline *flood_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_flood"));
struct pipeline *shade_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_shade")); struct pipeline *shade_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_shade"));
struct pipeline *blit_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_blit")); struct pipeline *blit_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_blit"));
struct pipeline *ui_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_ui")); struct pipeline *ui_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_ui"));
struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_shape")); struct pipeline *shape_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_shape"));
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT]; struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
struct command_list *cl = command_list_open(cq->cl_pool); struct command_list *cl = command_list_open(cq->cl_pool);
{ {
@ -3189,7 +3189,7 @@ internal void swapchain_init_resources(struct swapchain *swapchain)
HRESULT hr = IDXGISwapChain3_GetBuffer(swapchain->swapchain, i, &IID_ID3D12Resource, (void **)&resource); HRESULT hr = IDXGISwapChain3_GetBuffer(swapchain->swapchain, i, &IID_ID3D12Resource, (void **)&resource);
if (FAILED(hr)) { if (FAILED(hr)) {
/* TODO: Don't panic */ /* TODO: Don't panic */
P_Panic(LIT("Failed to get swapchain buffer")); P_Panic(Lit("Failed to get swapchain buffer"));
} }
struct swapchain_buffer *sb = &swapchain->buffers[i]; struct swapchain_buffer *sb = &swapchain->buffers[i];
ZeroStruct(sb); ZeroStruct(sb);
@ -3236,14 +3236,14 @@ G_Swapchain *gp_swapchain_alloc(P_Window *window, Vec2I32 resolution)
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)cq->cq, hwnd, &desc, 0, 0, &swapchain1); hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)cq->cq, hwnd, &desc, 0, 0, &swapchain1);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create IDXGISwapChain1")); P_Panic(Lit("Failed to create IDXGISwapChain1"));
} }
} }
/* Upgrade to swapchain3 */ /* Upgrade to swapchain3 */
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain->swapchain); hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain->swapchain);
if (FAILED(hr)) { if (FAILED(hr)) {
P_Panic(LIT("Failed to create IDXGISwapChain3")); P_Panic(Lit("Failed to create IDXGISwapChain3"));
} }
/* Create waitable object */ /* Create waitable object */
@ -3317,7 +3317,7 @@ internal struct swapchain_buffer *update_swapchain(struct swapchain *swapchain,
hr = IDXGISwapChain_ResizeBuffers(swapchain->swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, DX12_SWAPCHAIN_FLAGS); hr = IDXGISwapChain_ResizeBuffers(swapchain->swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, DX12_SWAPCHAIN_FLAGS);
if (FAILED(hr)) { if (FAILED(hr)) {
/* TODO: Don't panic */ /* TODO: Don't panic */
P_Panic(LIT("Failed to resize swapchain")); P_Panic(Lit("Failed to resize swapchain"));
} }
} }
P_Unlock(&lock); P_Unlock(&lock);
@ -3339,7 +3339,7 @@ internal void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
{ {
__prof; __prof;
struct pipeline_scope *pipeline_scope = pipeline_scope_begin(); struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
struct pipeline *blit_pipeline = pipeline_from_name(pipeline_scope, LIT("kernel_blit")); struct pipeline *blit_pipeline = pipeline_from_name(pipeline_scope, Lit("kernel_blit"));
if (blit_pipeline->success) { if (blit_pipeline->success) {
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT]; struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
struct command_list *cl = command_list_open(cq->cl_pool); struct command_list *cl = command_list_open(cq->cl_pool);

View File

@ -64,9 +64,9 @@ enum lex_number_state {
}; };
Global Readonly String g_keyword_strings[] = { Global Readonly String g_keyword_strings[] = {
['t'] = LIT_NOCAST("true"), ['t'] = LitNoCast("true"),
['f'] = LIT_NOCAST("false"), ['f'] = LitNoCast("false"),
['n'] = LIT_NOCAST("null") ['n'] = LitNoCast("null")
}; };
Global Readonly enum token_type g_keyword_types[] = { Global Readonly enum token_type g_keyword_types[] = {
@ -308,7 +308,7 @@ internal struct token_list lex(Arena *arena, String src)
.len = keyword.len, .len = keyword.len,
.text = &src.text[pos] .text = &src.text[pos]
}; };
match = string_eq(cmp_str, keyword); match = EqString(cmp_str, keyword);
} }
} }
@ -531,7 +531,7 @@ internal String interpret_string(Arena *arena, String src, String *error)
if (src.len < 2) { if (src.len < 2) {
if (error) { if (error) {
*error = LIT("Malformed string."); *error = Lit("Malformed string.");
} }
return res; return res;
} }
@ -593,7 +593,7 @@ internal String interpret_string(Arena *arena, String src, String *error)
default: { default: {
if (error) { if (error) {
*error = LIT("Invalid escape character in string."); *error = Lit("Invalid escape character in string.");
return res; return res;
} }
} break; } break;
@ -621,7 +621,7 @@ internal String interpret_string(Arena *arena, String src, String *error)
if (!valid_close) { if (!valid_close) {
if (error) { if (error) {
*error = LIT("Expected end of string."); *error = Lit("Expected end of string.");
} }
} }
@ -688,7 +688,7 @@ internal void parse(Arena *arena, struct parser *p)
if (at->type == tok_close_type) { if (at->type == tok_close_type) {
at = at->next; at = at->next;
} else { } else {
push_error(arena, p, at, LIT("Expected comma.")); push_error(arena, p, at, Lit("Expected comma."));
at = at->next; at = at->next;
goto abort; goto abort;
} }
@ -708,7 +708,7 @@ internal void parse(Arena *arena, struct parser *p)
at = at->next; at = at->next;
} }
} else { } else {
push_error(arena, p, at, LIT("Key expected.")); push_error(arena, p, at, Lit("Key expected."));
goto abort; goto abort;
} }
@ -716,7 +716,7 @@ internal void parse(Arena *arena, struct parser *p)
if (at->type == TOKEN_TYPE_COLON) { if (at->type == TOKEN_TYPE_COLON) {
at = at->next; at = at->next;
} else { } else {
push_error(arena, p, at, LIT("Colon expected.")); push_error(arena, p, at, Lit("Colon expected."));
goto abort; goto abort;
} }
} }
@ -783,7 +783,7 @@ internal void parse(Arena *arena, struct parser *p)
} break; } break;
default: { default: {
push_error(arena, p, at, LIT("Value expected.")); push_error(arena, p, at, Lit("Value expected."));
at = at->next; at = at->next;
goto abort; goto abort;
} break; } break;
@ -840,7 +840,7 @@ JSON_Result json_from_string(Arena *arena, String src)
/* Verify end of file */ /* Verify end of file */
if (p.errors.count == 0 && p.at->type != TOKEN_TYPE_EOF) { if (p.errors.count == 0 && p.at->type != TOKEN_TYPE_EOF) {
push_error(arena, &p, p.at, LIT("Expected end of file.")); push_error(arena, &p, p.at, Lit("Expected end of file."));
} }
EndScratch(scratch); EndScratch(scratch);

View File

@ -182,7 +182,7 @@ void host_release(N_Host *host)
internal u64 hash_from_address(P_Address address) internal u64 hash_from_address(P_Address address)
{ {
return hash_fnv64(HASH_FNV64_BASIS, STRING_FROM_STRUCT(&address)); return HashFnv64(Fnv64Basis, StringFromStruct(&address));
} }
internal struct host_channel *host_channel_from_address(N_Host *host, P_Address address) internal struct host_channel *host_channel_from_address(N_Host *host, P_Address address)
@ -324,9 +324,9 @@ internal void host_channel_release(struct host_channel *channel)
internal u64 hash_from_channel_msg(N_ChannelId channel_id, u64 msg_id) internal u64 hash_from_channel_msg(N_ChannelId channel_id, u64 msg_id)
{ {
u64 res = HASH_FNV64_BASIS; u64 res = Fnv64Basis;
res = hash_fnv64(res, STRING_FROM_STRUCT(&channel_id)); res = HashFnv64(res, StringFromStruct(&channel_id));
res = hash_fnv64(res, STRING_FROM_STRUCT(&msg_id)); res = HashFnv64(res, StringFromStruct(&msg_id));
return res; return res;
} }
@ -566,7 +566,7 @@ void host_queue_write(N_Host *host, N_ChannelId channel_id, String msg, u32 flag
N_Cmd *cmd = host_cmd_alloc_and_append(host); N_Cmd *cmd = host_cmd_alloc_and_append(host);
cmd->kind = HOST_CMD_KIND_WRITE; cmd->kind = HOST_CMD_KIND_WRITE;
cmd->channel_id = channel_id; cmd->channel_id = channel_id;
cmd->write_msg = string_copy(host->cmd_arena, msg); cmd->write_msg = CopyString(host->cmd_arena, msg);
cmd->write_reliable = flags & HOST_WRITE_FLAG_RELIABLE; cmd->write_reliable = flags & HOST_WRITE_FLAG_RELIABLE;
} }
@ -619,7 +619,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host)
if (data.len > 0) { if (data.len > 0) {
struct host_rcv_packet *packet = PushStruct(scratch.arena, struct host_rcv_packet); struct host_rcv_packet *packet = PushStruct(scratch.arena, struct host_rcv_packet);
packet->address = address; packet->address = address;
packet->data = string_copy(scratch.arena, data); packet->data = CopyString(scratch.arena, data);
if (last_packet) { if (last_packet) {
last_packet->next = packet; last_packet->next = packet;
} else { } else {
@ -672,7 +672,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host)
{ {
/* A foreign host is trying to connect to us */ /* A foreign host is trying to connect to us */
if (!channel->valid) { if (!channel->valid) {
P_LogInfoF("Host received conection attempt from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); P_LogInfoF("Host received conection attempt from %F", FmtString(P_StringFromAddress(scratch.arena, address)));
/* TODO: Verify that some per-host uuid isn't present in a rolling window to prevent reconnects right after a disconnect? */ /* TODO: Verify that some per-host uuid isn't present in a rolling window to prevent reconnects right after a disconnect? */
channel = host_channel_alloc(host, address); channel = host_channel_alloc(host, address);
} }
@ -685,7 +685,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host)
{ {
/* We successfully connected to a foreign host and they are ready to receive messages */ /* We successfully connected to a foreign host and they are ready to receive messages */
if (channel->valid && !channel->connected) { if (channel->valid && !channel->connected) {
P_LogInfoF("Host received connection from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); P_LogInfoF("Host received connection from %F", FmtString(P_StringFromAddress(scratch.arena, address)));
N_Event *event = push_event(arena, &events); N_Event *event = push_event(arena, &events);
event->kind = HOST_EVENT_KIND_CHANNEL_OPENED; event->kind = HOST_EVENT_KIND_CHANNEL_OPENED;
event->channel_id = channel->id; event->channel_id = channel->id;
@ -697,7 +697,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host)
{ {
/* A foreign host disconnected from us */ /* A foreign host disconnected from us */
if (channel->valid) { if (channel->valid) {
P_LogInfoF("Host received disconnection from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); P_LogInfoF("Host received disconnection from %F", FmtString(P_StringFromAddress(scratch.arena, address)));
N_Event *event = push_event(arena, &events); N_Event *event = push_event(arena, &events);
event->kind = HOST_EVENT_KIND_CHANNEL_CLOSED; event->kind = HOST_EVENT_KIND_CHANNEL_CLOSED;
event->channel_id = channel->id; event->channel_id = channel->id;
@ -876,7 +876,7 @@ void host_update_end(N_Host *host)
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0); N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
BB_Buff bb = BitbuffFromString(STRING_FROM_ARRAY(packet->data)); BB_Buff bb = BitbuffFromString(StringFromArray(packet->data));
BB_Writer bw = BB_WriterFromBuff(&bb); BB_Writer bw = BB_WriterFromBuff(&bb);
BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */ BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
BB_WriteIBits(&bw, HOST_PACKET_KIND_TRY_CONNECT, 8); BB_WriteIBits(&bw, HOST_PACKET_KIND_TRY_CONNECT, 8);
@ -889,7 +889,7 @@ void host_update_end(N_Host *host)
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0); N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
BB_Buff bb = BitbuffFromString(STRING_FROM_ARRAY(packet->data)); BB_Buff bb = BitbuffFromString(StringFromArray(packet->data));
BB_Writer bw = BB_WriterFromBuff(&bb); BB_Writer bw = BB_WriterFromBuff(&bb);
BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */ BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
BB_WriteIBits(&bw, HOST_PACKET_KIND_CONNECT_SUCCESS, 8); BB_WriteIBits(&bw, HOST_PACKET_KIND_CONNECT_SUCCESS, 8);
@ -902,7 +902,7 @@ void host_update_end(N_Host *host)
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0); N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
BB_Buff bb = BitbuffFromString(STRING_FROM_ARRAY(packet->data)); BB_Buff bb = BitbuffFromString(StringFromArray(packet->data));
BB_Writer bw = BB_WriterFromBuff(&bb); BB_Writer bw = BB_WriterFromBuff(&bb);
BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */ BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
BB_WriteIBits(&bw, HOST_PACKET_KIND_DISCONNECT, 8); BB_WriteIBits(&bw, HOST_PACKET_KIND_DISCONNECT, 8);
@ -915,7 +915,7 @@ void host_update_end(N_Host *host)
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0); N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
BB_Buff bb = BitbuffFromString(STRING_FROM_ARRAY(packet->data)); BB_Buff bb = BitbuffFromString(StringFromArray(packet->data));
BB_Writer bw = BB_WriterFromBuff(&bb); BB_Writer bw = BB_WriterFromBuff(&bb);
BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */ BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
BB_WriteIBits(&bw, HOST_PACKET_KIND_HEARTBEAT, 8); BB_WriteIBits(&bw, HOST_PACKET_KIND_HEARTBEAT, 8);
@ -949,7 +949,7 @@ void host_update_end(N_Host *host)
} }
} }
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, is_reliable); N_SndPacket *packet = host_channel_snd_packet_alloc(channel, is_reliable);
BB_Buff bb = BitbuffFromString(STRING_FROM_ARRAY(packet->data)); BB_Buff bb = BitbuffFromString(StringFromArray(packet->data));
BB_Writer bw = BB_WriterFromBuff(&bb); BB_Writer bw = BB_WriterFromBuff(&bb);
BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */ BB_WriteUBits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
BB_WriteIBits(&bw, HOST_PACKET_KIND_MSG_CHUNK, 8); BB_WriteIBits(&bw, HOST_PACKET_KIND_MSG_CHUNK, 8);

View File

@ -5,32 +5,32 @@ P_SharedLogCtx P_shared_log_ctx = ZI;
Readonly P_LogLevelSettings P_log_settings[P_LogLevel_Count] = { Readonly P_LogLevelSettings P_log_settings[P_LogLevel_Count] = {
[P_LogLevel_Critical] = { [P_LogLevel_Critical] = {
LIT_NOCAST("CRITICAL"), LitNoCast("CRITICAL"),
ColorPurple ColorPurple
}, },
[P_LogLevel_Error] = { [P_LogLevel_Error] = {
LIT_NOCAST("ERROR"), LitNoCast("ERROR"),
ColorRed ColorRed
}, },
[P_LogLevel_Warning] = { [P_LogLevel_Warning] = {
LIT_NOCAST("WARNING"), LitNoCast("WARNING"),
ColorYellow ColorYellow
}, },
[P_LogLevel_Success] = { [P_LogLevel_Success] = {
LIT_NOCAST("SUCCESS"), LitNoCast("SUCCESS"),
ColorGreen ColorGreen
}, },
[P_LogLevel_Info] = { [P_LogLevel_Info] = {
LIT_NOCAST("INFO"), LitNoCast("INFO"),
ColorWhite ColorWhite
}, },
[P_LogLevel_Debug] = { [P_LogLevel_Debug] = {
LIT_NOCAST("DEBUG"), LitNoCast("DEBUG"),
ColorBlue ColorBlue
} }
}; };
@ -94,7 +94,7 @@ void P__LogAppend(String msg)
if (ctx->file_valid) if (ctx->file_valid)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String msg_line = string_cat(scratch.arena, msg, LIT("\n")); String msg_line = CatString(scratch.arena, msg, Lit("\n"));
P_WriteFile(ctx->file, msg_line); P_WriteFile(ctx->file, msg_line);
EndScratch(scratch); EndScratch(scratch);
} }
@ -112,9 +112,9 @@ void P__LogPanic(String msg)
if (ctx->file_valid) if (ctx->file_valid)
{ {
P_WriteFile(ctx->file, LIT("******** PANICKING ********\n")); P_WriteFile(ctx->file, Lit("******** PANICKING ********\n"));
P_WriteFile(ctx->file, msg); P_WriteFile(ctx->file, msg);
P_WriteFile(ctx->file, LIT("\n***************************\n")); P_WriteFile(ctx->file, Lit("\n***************************\n"));
} }
} }
@ -130,7 +130,7 @@ void P__LogFV(i32 level, String fmt, va_list args)
P_SharedLogCtx *ctx = &P_shared_log_ctx; P_SharedLogCtx *ctx = &P_shared_log_ctx;
if (!Atomic32Fetch(&ctx->initialized)) { return; } if (!Atomic32Fetch(&ctx->initialized)) { return; }
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String msg = string_formatv(scratch.arena, fmt, args); String msg = StringFormatV(scratch.arena, fmt, args);
#if P_IncludeLogSourceLocation #if P_IncludeLogSourceLocation
P__log(level, file, line, msg); P__log(level, file, line, msg);
#else #else
@ -177,7 +177,7 @@ void P__log(i32 level, String msg)
P_LogLevelSettings settings = P_log_settings[level]; P_LogLevelSettings settings = P_log_settings[level];
if (level < 0 || level >= P_LogLevel_Count) if (level < 0 || level >= P_LogLevel_Count)
{ {
P_Panic(LIT("Invalid log level")); P_Panic(Lit("Invalid log level"));
} }
@ -190,48 +190,48 @@ void P__log(i32 level, String msg)
String shorthand = settings.shorthand; String shorthand = settings.shorthand;
#if P_IncludeLogSourceLocation #if P_IncludeLogSourceLocation
String msg_formatted = string_format( String msg_formatted = StringFormat(
scratch.arena, scratch.arena,
LIT("[%F:%F:%F.%F] |%F| [%F] <%F:%F> %F"), Lit("[%F:%F:%F.%F] |%F| [%F] <%F:%F> %F"),
/* Time */ /* Time */
FMT_UINT_Z(datetime.hour, 2), FmtUintZ(datetime.hour, 2),
FMT_UINT_Z(datetime.minute, 2), FmtUintZ(datetime.minute, 2),
FMT_UINT_Z(datetime.second, 2), FmtUintZ(datetime.second, 2),
FMT_UINT_Z(datetime.milliseconds, 3), FmtUintZ(datetime.milliseconds, 3),
/* TID */ /* TID */
FMT_UINT_Z(tid, 5), FmtUintZ(tid, 5),
/* Level */ /* Level */
FMT_STR(shorthand), FmtString(shorthand),
/* Source location */ /* Source location */
FMT_STR(file), FmtString(file),
FMT_SINT(line), FmtSint(line),
/* Message */ /* Message */
FMT_STR(msg) FmtString(msg)
); );
#else #else
String msg_formatted = string_format( String msg_formatted = StringFormat(
scratch.arena, scratch.arena,
LIT("[%F:%F:%F.%F] |%F| [%F] %F"), Lit("[%F:%F:%F.%F] |%F| [%F] %F"),
/* Time */ /* Time */
FMT_UINT_Z(datetime.hour, 2), FmtUintZ(datetime.hour, 2),
FMT_UINT_Z(datetime.minute, 2), FmtUintZ(datetime.minute, 2),
FMT_UINT_Z(datetime.second, 2), FmtUintZ(datetime.second, 2),
FMT_UINT_Z(datetime.milliseconds, 3), FmtUintZ(datetime.milliseconds, 3),
/* TID */ /* TID */
FMT_UINT_Z(tid, 5), FmtUintZ(tid, 5),
/* Level */ /* Level */
FMT_STR(shorthand), FmtString(shorthand),
/* Message */ /* Message */
FMT_STR(msg) FmtString(msg)
); );
#endif #endif

View File

@ -95,11 +95,11 @@ void P_LogStartup(String logfile_path);
#if P_LogLevel(P_LogLevel_Critical) #if P_LogLevel(P_LogLevel_Critical)
# if P_IncludeLogSourceLocation # if P_IncludeLogSourceLocation
# define P_LogCritical(msg) P__log(P_LogLevel_Critical, LIT(__FILE__), __LINE__, msg) # define P_LogCritical(msg) P__log(P_LogLevel_Critical, Lit(__FILE__), __LINE__, msg)
# define P_LogCriticalF(fmt_lit, ...) P__LogF(P_LogLevel_Critical, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogCriticalF(fmt_lit, ...) P__LogF(P_LogLevel_Critical, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# else # else
# define P_LogCritical(msg) P__log(P_LogLevel_Critical, msg) # define P_LogCritical(msg) P__log(P_LogLevel_Critical, msg)
# define P_LogCriticalF(fmt_lit, ...) P__LogF(P_LogLevel_Critical, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogCriticalF(fmt_lit, ...) P__LogF(P_LogLevel_Critical, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# endif # endif
#else #else
# define P_LogCritical(msg) # define P_LogCritical(msg)
@ -108,11 +108,11 @@ void P_LogStartup(String logfile_path);
#if P_LogLevel(P_LogLevel_Error) #if P_LogLevel(P_LogLevel_Error)
# if P_IncludeLogSourceLocation # if P_IncludeLogSourceLocation
# define P_LogError(msg) P__log(P_LogLevel_Error, LIT(__FILE__), __LINE__, msg) # define P_LogError(msg) P__log(P_LogLevel_Error, Lit(__FILE__), __LINE__, msg)
# define P_LogErrorF(fmt_lit, ...) P__LogF(P_LogLevel_Error, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogErrorF(fmt_lit, ...) P__LogF(P_LogLevel_Error, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# else # else
# define P_LogError(msg) P__log(P_LogLevel_Error, msg) # define P_LogError(msg) P__log(P_LogLevel_Error, msg)
# define P_LogErrorF(fmt_lit, ...) P__LogF(P_LogLevel_Error, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogErrorF(fmt_lit, ...) P__LogF(P_LogLevel_Error, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# endif # endif
#else #else
# define P_LogError(msg) # define P_LogError(msg)
@ -121,11 +121,11 @@ void P_LogStartup(String logfile_path);
#if P_LogLevel(P_LogLevel_Warning) #if P_LogLevel(P_LogLevel_Warning)
# if P_IncludeLogSourceLocation # if P_IncludeLogSourceLocation
# define P_LogWarning(msg) P__log(P_LogLevel_Warning, LIT(__FILE__), __LINE__, msg) # define P_LogWarning(msg) P__log(P_LogLevel_Warning, Lit(__FILE__), __LINE__, msg)
# define P_LogWarningF(fmt_lit, ...) P__LogF(P_LogLevel_Warning, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogWarningF(fmt_lit, ...) P__LogF(P_LogLevel_Warning, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# else # else
# define P_LogWarning(msg) P__log(P_LogLevel_Warning, msg) # define P_LogWarning(msg) P__log(P_LogLevel_Warning, msg)
# define P_LogWarningF(fmt_lit, ...) P__LogF(P_LogLevel_Warning, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogWarningF(fmt_lit, ...) P__LogF(P_LogLevel_Warning, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# endif # endif
#else #else
# define P_LogWarning(msg) # define P_LogWarning(msg)
@ -134,11 +134,11 @@ void P_LogStartup(String logfile_path);
#if P_LogLevel(P_LogLevel_Success) #if P_LogLevel(P_LogLevel_Success)
# if P_IncludeLogSourceLocation # if P_IncludeLogSourceLocation
# define P_LogSuccess(msg) P__log(P_LogLevel_Success, LIT(__FILE__), __LINE__, msg) # define P_LogSuccess(msg) P__log(P_LogLevel_Success, Lit(__FILE__), __LINE__, msg)
# define P_LogSuccessF(fmt_lit, ...) P__LogF(P_LogLevel_Success, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogSuccessF(fmt_lit, ...) P__LogF(P_LogLevel_Success, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# else # else
# define P_LogSuccess(msg) P__log(P_LogLevel_Success, msg) # define P_LogSuccess(msg) P__log(P_LogLevel_Success, msg)
# define P_LogSuccessF(fmt_lit, ...) P__LogF(P_LogLevel_Success, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogSuccessF(fmt_lit, ...) P__LogF(P_LogLevel_Success, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# endif # endif
#else #else
# define P_LogSuccess(msg) # define P_LogSuccess(msg)
@ -147,11 +147,11 @@ void P_LogStartup(String logfile_path);
#if P_LogLevel(P_LogLevel_Info) #if P_LogLevel(P_LogLevel_Info)
# if P_IncludeLogSourceLocation # if P_IncludeLogSourceLocation
# define P_LogInfo(msg) P__log(P_LogLevel_Info, LIT(__FILE__), __LINE__, msg) # define P_LogInfo(msg) P__log(P_LogLevel_Info, Lit(__FILE__), __LINE__, msg)
# define P_LogInfoF(fmt_lit, ...) P__LogF(P_LogLevel_Info, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogInfoF(fmt_lit, ...) P__LogF(P_LogLevel_Info, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# else # else
# define P_LogInfo(msg) P__log(P_LogLevel_Info, msg) # define P_LogInfo(msg) P__log(P_LogLevel_Info, msg)
# define P_LogInfoF(fmt_lit, ...) P__LogF(P_LogLevel_Info, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogInfoF(fmt_lit, ...) P__LogF(P_LogLevel_Info, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# endif # endif
#else #else
# define P_LogInfo(msg) # define P_LogInfo(msg)
@ -160,11 +160,11 @@ void P_LogStartup(String logfile_path);
#if P_LogLevel(P_LogLevel_Debug) #if P_LogLevel(P_LogLevel_Debug)
# if P_IncludeLogSourceLocation # if P_IncludeLogSourceLocation
# define P_LogDebug(msg) P__log(P_LogLevel_Debug, LIT(__FILE__), __LINE__, msg) # define P_LogDebug(msg) P__log(P_LogLevel_Debug, Lit(__FILE__), __LINE__, msg)
# define P_LogDebugF(fmt_lit, ...) P__LogF(P_LogLevel_Debug, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogDebugF(fmt_lit, ...) P__LogF(P_LogLevel_Debug, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# else # else
# define P_LogDebug(msg) P__log(P_LogLevel_Debug, msg) # define P_LogDebug(msg) P__log(P_LogLevel_Debug, msg)
# define P_LogDebugF(fmt_lit, ...) P__LogF(P_LogLevel_Debug, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # define P_LogDebugF(fmt_lit, ...) P__LogF(P_LogLevel_Debug, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
# endif # endif
#else #else
# define P_LogDebug(msg) # define P_LogDebug(msg)

View File

@ -50,7 +50,7 @@ DWORD WINAPI P_W32_Win32ThreadProc(LPVOID vt)
SetThreadDescription(GetCurrentThread(), t->thread_name_wstr); SetThreadDescription(GetCurrentThread(), t->thread_name_wstr);
} }
P_LogInfoF("New thread \"%F\" created with ID %F", FMT_STR(string_from_cstr_no_limit(t->thread_name_cstr)), FMT_UINT(P_GetThreadId())); P_LogInfoF("New thread \"%F\" created with ID %F", FmtString(StringFromCstrNoLimit(t->thread_name_cstr)), FmtUint(P_GetThreadId()));
/* Enter thread entry point */ /* Enter thread entry point */
t->entry_point(t->thread_data); t->entry_point(t->thread_data);
@ -67,7 +67,7 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_W32_SharedCtx *g = &P_W32_shared_ctx; P_W32_SharedCtx *g = &P_W32_shared_ctx;
Assert(entry_point != 0); Assert(entry_point != 0);
P_LogInfoF("Creating thread \"%F\"", FMT_STR(thread_name)); P_LogInfoF("Creating thread \"%F\"", FmtString(thread_name));
/* Allocate thread object */ /* Allocate thread object */
@ -104,15 +104,15 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data
/* CopyStruct thread name to params */ /* CopyStruct thread name to params */
{ {
u64 cstr_len = MinU64((countof(t->thread_name_cstr) - 1), thread_name.len); u64 CstrLen = MinU64((countof(t->thread_name_cstr) - 1), thread_name.len);
CopyBytes(t->thread_name_cstr, thread_name.text, cstr_len * sizeof(*t->thread_name_cstr)); CopyBytes(t->thread_name_cstr, thread_name.text, CstrLen * sizeof(*t->thread_name_cstr));
t->thread_name_cstr[cstr_len] = 0; t->thread_name_cstr[CstrLen] = 0;
} }
{ {
String16 thread_name16 = string16_from_string(scratch.arena, thread_name); String16 thread_name16 = String16FromString(scratch.arena, thread_name);
u64 wstr_len = MinU64((countof(t->thread_name_wstr) - 1), thread_name16.len); u64 WstrLen = MinU64((countof(t->thread_name_wstr) - 1), thread_name16.len);
CopyBytes(t->thread_name_wstr, thread_name16.text, wstr_len * sizeof(*t->thread_name_wstr)); CopyBytes(t->thread_name_wstr, thread_name16.text, WstrLen * sizeof(*t->thread_name_wstr));
t->thread_name_wstr[wstr_len] = 0; t->thread_name_wstr[WstrLen] = 0;
} }
t->handle = CreateThread( t->handle = CreateThread(
@ -126,7 +126,7 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data
if (!t->handle) if (!t->handle)
{ {
P_Panic(LIT("Failed to create thread")); P_Panic(Lit("Failed to create thread"));
} }
EndScratch(scratch); EndScratch(scratch);
@ -559,7 +559,7 @@ P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool)
fiber_id = g->num_fibers++; fiber_id = g->num_fibers++;
if (fiber_id >= MaxFibers) if (fiber_id >= MaxFibers)
{ {
P_Panic(LIT("Max fibers reached")); P_Panic(Lit("Max fibers reached"));
} }
fiber = &g->fibers[fiber_id]; fiber = &g->fibers[fiber_id];
new_name_cstr = PushStructs(g->fiber_names_arena, char, P_W32_FiberNameMaxSize); new_name_cstr = PushStructs(g->fiber_names_arena, char, P_W32_FiberNameMaxSize);
@ -891,7 +891,7 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg)
{ {
/* Invalid yield kind */ /* Invalid yield kind */
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_Panic(string_format(scratch.arena, LIT("Invalid fiber yield kind \"%F\""), FMT_SINT(yield.kind))); P_Panic(StringFormat(scratch.arena, Lit("Invalid fiber yield kind \"%F\""), FmtSint(yield.kind)));
EndScratch(scratch); EndScratch(scratch);
} break; } break;
@ -1116,7 +1116,7 @@ P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _)
HANDLE timer = CreateWaitableTimerExW(0, 0, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); HANDLE timer = CreateWaitableTimerExW(0, 0, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
if (!timer) if (!timer)
{ {
P_Panic(LIT("Failed to create high resolution timer")); P_Panic(Lit("Failed to create high resolution timer"));
} }
/* Create rolling buffer of scheduler cycles initialized to default value */ /* Create rolling buffer of scheduler cycles initialized to default value */
@ -1203,8 +1203,8 @@ String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src)
while (*src) while (*src)
{ {
String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src }; String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src };
Utf16DecodeResult decoded = uni_decode_utf16(decode_str); Utf16DecodeResult decoded = DecodeUtf16(decode_str);
Utf8EncodeResult encoded = uni_encode_utf8(decoded.codepoint); Utf8EncodeResult encoded = EncodeUtf8(decoded.codepoint);
u8 *dest = PushStructsNoZero(arena, u8, encoded.count8); u8 *dest = PushStructsNoZero(arena, u8, encoded.count8);
for (u32 i = 0; i < encoded.count8; ++i) for (u32 i = 0; i < encoded.count8; ++i)
{ {
@ -1252,7 +1252,7 @@ P_W32_Window *P_W32_AllocWindow(void)
* created and receive a HWND, because on Windows a the event proc must run on * created and receive a HWND, because on Windows a the event proc must run on
* the same thread that created the window. */ * the same thread that created the window. */
P_CounterAdd(&window->ready_fence, 1); P_CounterAdd(&window->ready_fence, 1);
window->window_thread = P_W32_AllocThread(&P_W32_WindowThreadEntryFunc, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW); window->window_thread = P_W32_AllocThread(&P_W32_WindowThreadEntryFunc, window, Lit("Window thread"), PROF_THREAD_GROUP_WINDOW);
P_WaitOnCounter(&window->ready_fence); P_WaitOnCounter(&window->ready_fence);
return window; return window;
@ -1451,7 +1451,7 @@ void P_W32_UpdateWindowFromSettings(P_W32_Window *window, P_WindowSettings *sett
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr_no_limit(settings->title)); wchar_t *title_wstr = WstrFromString(scratch.arena, StringFromCstrNoLimit(settings->title));
SetWindowTextW(hwnd, title_wstr); SetWindowTextW(hwnd, title_wstr);
EndScratch(scratch); EndScratch(scratch);
} }
@ -1664,18 +1664,18 @@ LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
/* Decode */ /* Decode */
u32 codepoint = 0; u32 codepoint = 0;
if (uni_is_utf16_high_surrogate(utf16_char)) if (IsUtf16HighSurrogate(utf16_char))
{ {
window->utf16_high_surrogate_last_input = utf16_char; window->utf16_high_surrogate_last_input = utf16_char;
} }
else if (uni_is_utf16_low_surrogate(utf16_char)) else if (IsUtf16LowSurrogate(utf16_char))
{ {
u16 high = window->utf16_high_surrogate_last_input; u16 high = window->utf16_high_surrogate_last_input;
u16 low = utf16_char; u16 low = utf16_char;
if (high) if (high)
{ {
u16 utf16_pair_bytes[2] = { high, low }; u16 utf16_pair_bytes[2] = { high, low };
Utf16DecodeResult decoded = uni_decode_utf16((String16) { .len = countof(utf16_pair_bytes), .text = utf16_pair_bytes }); Utf16DecodeResult decoded = DecodeUtf16((String16) { .len = countof(utf16_pair_bytes), .text = utf16_pair_bytes });
if (decoded.advance16 == 2 && decoded.codepoint < U32Max) if (decoded.advance16 == 2 && decoded.codepoint < U32Max)
{ {
codepoint = decoded.codepoint; codepoint = decoded.codepoint;
@ -2098,7 +2098,7 @@ b32 P_IsFile(String path)
{ {
__prof; __prof;
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
DWORD attributes = GetFileAttributesW(path_wstr); DWORD attributes = GetFileAttributesW(path_wstr);
EndScratch(scratch); EndScratch(scratch);
return attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY); return attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY);
@ -2107,7 +2107,7 @@ b32 P_IsFile(String path)
b32 P_IsDir(String path) b32 P_IsDir(String path)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
DWORD attributes = GetFileAttributesW(path_wstr); DWORD attributes = GetFileAttributesW(path_wstr);
EndScratch(scratch); EndScratch(scratch);
return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY); return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY);
@ -2117,39 +2117,39 @@ void P_MkDir(String path)
{ {
__prof; __prof;
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
int err_code = SHCreateDirectory(0, path_wstr); int err_code = SHCreateDirectory(0, path_wstr);
String err = ZI; String err = ZI;
switch (err_code) switch (err_code)
{ {
case ERROR_BAD_PATHNAME: case ERROR_BAD_PATHNAME:
{ {
err = LIT("Bad path name"); err = Lit("Bad path name");
} break; } break;
case ERROR_FILENAME_EXCED_RANGE: case ERROR_FILENAME_EXCED_RANGE:
{ {
err = LIT("Path name too long"); err = Lit("Path name too long");
} break; } break;
case ERROR_FILE_EXISTS: case ERROR_FILE_EXISTS:
{ {
err = LIT("A file already exists at this location"); err = Lit("A file already exists at this location");
} break; } break;
case ERROR_CANCELLED: case ERROR_CANCELLED:
{ {
err = LIT("User canceled the operation"); err = Lit("User canceled the operation");
} break; } break;
default: break; default: break;
} }
if (err.len > 0) if (err.len > 0)
{ {
String msg = string_format(scratch.arena, String msg = StringFormat(scratch.arena,
LIT("Failed to create directory \"%F\": %F"), Lit("Failed to create directory \"%F\": %F"),
FMT_STR(path), FmtString(path),
FMT_STR(err)); FmtString(err));
P_Panic(msg); P_Panic(msg);
} }
EndScratch(scratch); EndScratch(scratch);
@ -2161,7 +2161,7 @@ P_File P_OpenFileRead(String path)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_File file = ZI; P_File file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
HANDLE handle = CreateFileW( HANDLE handle = CreateFileW(
path_wstr, path_wstr,
GENERIC_READ, GENERIC_READ,
@ -2184,7 +2184,7 @@ P_File P_OpenFileReadWait(String path)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_File file = ZI; P_File file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
i32 delay_ms = 1; i32 delay_ms = 1;
HANDLE handle; HANDLE handle;
while ((handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) while ((handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE)
@ -2216,7 +2216,7 @@ P_File P_OpenFileWrite(String path)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_File file = ZI; P_File file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
HANDLE handle = CreateFileW( HANDLE handle = CreateFileW(
path_wstr, path_wstr,
GENERIC_WRITE, GENERIC_WRITE,
@ -2239,7 +2239,7 @@ P_File P_OpenFileAppend(String path)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_File file = ZI; P_File file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
HANDLE handle = CreateFileW( HANDLE handle = CreateFileW(
path_wstr, path_wstr,
FILE_APPEND_DATA, FILE_APPEND_DATA,
@ -2302,9 +2302,9 @@ void P_WriteFile(P_File file, String data)
if (data.len >= 0x7FFF) if (data.len >= 0x7FFF)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
P_Panic(string_format(scratch.arena, P_Panic(StringFormat(scratch.arena,
LIT("Tried to write too many bytes to disk (%F)"), Lit("Tried to write too many bytes to disk (%F)"),
FMT_UINT(data.len))); FmtUint(data.len)));
EndScratch(scratch); EndScratch(scratch);
} }
@ -2456,7 +2456,7 @@ P_Watch *P_AllocWatch(String dir_path)
} }
ZeroStruct(w32_watch); ZeroStruct(w32_watch);
wchar_t *dir_path_wstr = wstr_from_string(scratch.arena, dir_path); wchar_t *dir_path_wstr = WstrFromString(scratch.arena, dir_path);
w32_watch->dir_handle = CreateFileW( w32_watch->dir_handle = CreateFileW(
dir_path_wstr, dir_path_wstr,
FILE_LIST_DIRECTORY, FILE_LIST_DIRECTORY,
@ -2547,7 +2547,7 @@ P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw)
name16.text = res->FileName; name16.text = res->FileName;
name16.len = res->FileNameLength / sizeof(wchar_t); name16.len = res->FileNameLength / sizeof(wchar_t);
info->name = string_from_string16(arena, name16); info->name = StringFromString16(arena, name16);
for (u64 i = 0; i < info->name.len; ++i) for (u64 i = 0; i < info->name.len; ++i)
{ {
if (info->name.text[i] == '\\') if (info->name.text[i] == '\\')
@ -2954,7 +2954,7 @@ String P_StringFromAddress(Arena *arena, P_Address address)
ip[i] = ntohs(address.ipnb[i]); ip[i] = ntohs(address.ipnb[i]);
} }
u16 port = ntohs(address.portnb); u16 port = ntohs(address.portnb);
res = string_format(arena, LIT("%F.%F.%F.%F:%F"), FMT_UINT(ip[0]), FMT_UINT(ip[1]), FMT_UINT(ip[2]), FMT_UINT(ip[3]), FMT_UINT(port)); res = StringFormat(arena, Lit("%F.%F.%F.%F:%F"), FmtUint(ip[0]), FmtUint(ip[1]), FmtUint(ip[2]), FmtUint(ip[3]), FmtUint(port));
} }
return res; return res;
@ -3084,7 +3084,7 @@ void P_MessageBox(P_MessageBoxKind kind, String message)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
wchar_t *message_wstr = wstr_from_string(scratch.arena, message); wchar_t *message_wstr = WstrFromString(scratch.arena, message);
const wchar_t *title = L""; const wchar_t *title = L"";
UINT mbox_type = MB_SETFOREGROUND; UINT mbox_type = MB_SETFOREGROUND;
@ -3114,7 +3114,7 @@ void P_MessageBox(P_MessageBoxKind kind, String message)
} break; } break;
} }
P_LogDebugF("Showing message box kind %F with text \"%F\"", FMT_SINT(kind), FMT_STR(message)); P_LogDebugF("Showing message box kind %F with text \"%F\"", FmtSint(kind), FmtString(message));
MessageBoxExW(0, message_wstr, title, mbox_type, 0); MessageBoxExW(0, message_wstr, title, mbox_type, 0);
EndScratch(scratch); EndScratch(scratch);
@ -3125,7 +3125,7 @@ void P_SetClipboardText(String str)
if (OpenClipboard(0)) if (OpenClipboard(0))
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String16 str16 = string16_from_string(scratch.arena, str); String16 str16 = String16FromString(scratch.arena, str);
u64 str16_size_bytes = str16.len * 2; u64 str16_size_bytes = str16.len * 2;
EmptyClipboard(); EmptyClipboard();
HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, str16_size_bytes + 1); HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, str16_size_bytes + 1);
@ -3151,7 +3151,7 @@ String P_GetClipboardText(Arena *arena)
if (handle) if (handle)
{ {
u16 *src_wstr = (u16 *)GlobalLock(handle); u16 *src_wstr = (u16 *)GlobalLock(handle);
res = string_from_string16(arena, string16_from_wstr_no_limit(src_wstr)); res = StringFromString16(arena, String16FromWstrNoLimit(src_wstr));
GlobalUnlock(handle); GlobalUnlock(handle);
} }
CloseClipboard(); CloseClipboard();
@ -3231,7 +3231,7 @@ void P_OnExit(P_ExitFunc *func)
i32 index = Atomic32FetchAdd(&g->num_exit_funcs, 1); i32 index = Atomic32FetchAdd(&g->num_exit_funcs, 1);
if (index >= P_W32_MaxOnExitFuncs) if (index >= P_W32_MaxOnExitFuncs)
{ {
P_Panic(LIT("Maximum on exit functions registered")); P_Panic(Lit("Maximum on exit functions registered"));
} }
g->exit_funcs[index] = func; g->exit_funcs[index] = func;
} }
@ -3250,11 +3250,11 @@ void P_Panic(String msg)
log_panic(msg); log_panic(msg);
wchar_t *wstr = g->panic_wstr; wchar_t *wstr = g->panic_wstr;
u64 wstr_len = 0; u64 WstrLen = 0;
wchar_t prefix[] = L"A fatal error has occured and the application needs to exit:\n\n"; wchar_t prefix[] = L"A fatal error has occured and the application needs to exit:\n\n";
CopyBytes(wstr, prefix, MinU64(countof(g->panic_wstr), (countof(prefix) << 1))); CopyBytes(wstr, prefix, MinU64(countof(g->panic_wstr), (countof(prefix) << 1)));
wstr_len += countof(prefix) - 1; WstrLen += countof(prefix) - 1;
/* Perform manual string encode to avoid any implicit memory /* Perform manual string encode to avoid any implicit memory
* allocation (in case allocation is unreliable) */ * allocation (in case allocation is unreliable) */
@ -3263,14 +3263,14 @@ void P_Panic(String msg)
while (pos8 < str8.len) while (pos8 < str8.len)
{ {
String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
Utf8DecodeResult decoded = uni_decode_utf8(str8_remaining); Utf8DecodeResult decoded = DecodeUtf8(str8_remaining);
Utf16EncodeResult encoded = uni_encode_utf16(decoded.codepoint); Utf16EncodeResult encoded = EncodeUtf16(decoded.codepoint);
u64 wstr_new_len = wstr_len + encoded.count16; u64 wstr_new_len = WstrLen + encoded.count16;
if (wstr_new_len < (countof(g->panic_wstr) - 1)) if (wstr_new_len < (countof(g->panic_wstr) - 1))
{ {
u16 *dest = wstr + wstr_len; u16 *dest = wstr + WstrLen;
CopyBytes(dest, encoded.chars16, (encoded.count16 << 1)); CopyBytes(dest, encoded.chars16, (encoded.count16 << 1));
wstr_len = wstr_new_len; WstrLen = wstr_new_len;
pos8 += decoded.advance8; pos8 += decoded.advance8;
} }
else else
@ -3279,7 +3279,7 @@ void P_Panic(String msg)
} }
} }
wstr[wstr_len] = 0; wstr[WstrLen] = 0;
#if RtcIsEnabled #if RtcIsEnabled
MessageBoxExW(0, wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); MessageBoxExW(0, wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0);
@ -3353,7 +3353,7 @@ P_JobDef(P_W32_AppStartupJob, _)
P_W32_SharedCtx *g = &P_W32_shared_ctx; P_W32_SharedCtx *g = &P_W32_shared_ctx;
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
{ {
String cmdline_args = string_from_wstr(scratch.arena, g->cmdline_args_wstr, countof(g->cmdline_args_wstr)); String cmdline_args = StringFromWstr(scratch.arena, g->cmdline_args_wstr, countof(g->cmdline_args_wstr));
P_AppStartup(cmdline_args); P_AppStartup(cmdline_args);
SetEvent(g->startup_end_event); SetEvent(g->startup_end_event);
} }
@ -3427,7 +3427,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
HRESULT hr = GetThreadDescription(thread, &thread_name_wstr); HRESULT hr = GetThreadDescription(thread, &thread_name_wstr);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
u64 thread_name_len = wstr_len_no_limit(thread_name_wstr); u64 thread_name_len = WstrLenNoLimit(thread_name_wstr);
if (thread_name_len >= prefix_name_wstr_len && EqBytes(thread_name_wstr, prefix_name_wstr, prefix_name_wstr_len)) if (thread_name_len >= prefix_name_wstr_len && EqBytes(thread_name_wstr, prefix_name_wstr, prefix_name_wstr_len))
{ {
__profn("Set profiler thread affinity"); __profn("Set profiler thread affinity");
@ -3499,7 +3499,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
} }
} }
u64 cmdline_len = wstr_len(cmdline_wstr, countof(g->cmdline_args_wstr) - 1); u64 cmdline_len = WstrLen(cmdline_wstr, countof(g->cmdline_args_wstr) - 1);
CopyBytes(g->cmdline_args_wstr, cmdline_wstr, cmdline_len * sizeof(*cmdline_wstr)); CopyBytes(g->cmdline_args_wstr, cmdline_wstr, cmdline_len * sizeof(*cmdline_wstr));
g->cmdline_args_wstr[cmdline_len] = 0; g->cmdline_args_wstr[cmdline_len] = 0;
@ -3531,7 +3531,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
if (!RegisterClassExW(wc)) if (!RegisterClassExW(wc))
{ {
P_Panic(LIT("Failed to register window class")); P_Panic(Lit("Failed to register window class"));
} }
} }
@ -3564,7 +3564,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
/* Start job scheduler */ /* Start job scheduler */
Atomic64FetchSet(&g->current_scheduler_cycle_period_ns.v, P_W32_DefaultSchedulerPeriodNs); Atomic64FetchSet(&g->current_scheduler_cycle_period_ns.v, P_W32_DefaultSchedulerPeriodNs);
P_W32_Thread *scheduler_thread = P_W32_AllocThread(P_W32_JobSchedulerEntryFunc, 0, LIT("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER); P_W32_Thread *scheduler_thread = P_W32_AllocThread(P_W32_JobSchedulerEntryFunc, 0, Lit("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER);
//- Start job workers //- Start job workers
/* TODO: Heuristic worker counts & affinities */ /* TODO: Heuristic worker counts & affinities */
@ -3581,7 +3581,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
case P_Pool_Sim: case P_Pool_Sim:
{ {
name_fmt = LIT("Sim worker #%F"); name_fmt = Lit("Sim worker #%F");
pool->num_worker_threads = 4; pool->num_worker_threads = 4;
pool->thread_affinity_mask = 0x000000000000000Full; pool->thread_affinity_mask = 0x000000000000000Full;
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL; pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
@ -3589,7 +3589,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
case P_Pool_User: case P_Pool_User:
{ {
name_fmt = LIT("User worker #%F"); name_fmt = Lit("User worker #%F");
pool->num_worker_threads = 4; pool->num_worker_threads = 4;
pool->thread_affinity_mask = 0x00000000000000F0ull; pool->thread_affinity_mask = 0x00000000000000F0ull;
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL; pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
@ -3597,7 +3597,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
case P_Pool_Audio: case P_Pool_Audio:
{ {
name_fmt = LIT("Audio worker #%F"); name_fmt = Lit("Audio worker #%F");
pool->num_worker_threads = 2; pool->num_worker_threads = 2;
pool->thread_affinity_mask = 0x0000000000000300ull; pool->thread_affinity_mask = 0x0000000000000300ull;
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL; pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
@ -3606,14 +3606,14 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
case P_Pool_Background: case P_Pool_Background:
{ {
name_fmt = LIT("Background worker #%F"); name_fmt = Lit("Background worker #%F");
pool->num_worker_threads = 2; pool->num_worker_threads = 2;
pool->thread_affinity_mask = 0x0000000000000C00ull; pool->thread_affinity_mask = 0x0000000000000C00ull;
} break; } break;
case P_Pool_Floating: case P_Pool_Floating:
{ {
name_fmt = LIT("Floating worker #%F"); name_fmt = Lit("Floating worker #%F");
pool->num_worker_threads = 8; pool->num_worker_threads = 8;
pool->thread_affinity_mask = 0x0000000000000FFFull; pool->thread_affinity_mask = 0x0000000000000FFFull;
} break; } break;
@ -3626,7 +3626,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
P_W32_WorkerCtx *ctx = &pool->worker_contexts[i]; P_W32_WorkerCtx *ctx = &pool->worker_contexts[i];
ctx->pool_kind = pool_kind; ctx->pool_kind = pool_kind;
ctx->id = i; ctx->id = i;
String name = string_format(pool->worker_threads_arena, name_fmt, FMT_SINT(i)); String name = StringFormat(pool->worker_threads_arena, name_fmt, FmtSint(i));
pool->worker_threads[i] = P_W32_AllocThread(P_W32_JobWorkerEntryFunc, ctx, name, prof_group + i); pool->worker_threads[i] = P_W32_AllocThread(P_W32_JobWorkerEntryFunc, ctx, name, prof_group + i);
} }
} }
@ -3727,11 +3727,11 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
threads_msg.text = PushDry(scratch.arena, u8); threads_msg.text = PushDry(scratch.arena, u8);
for (P_W32_Thread *t = g->first_thread; t; t = t->next) for (P_W32_Thread *t = g->first_thread; t; t = t->next)
{ {
String name = string_from_cstr(t->thread_name_cstr, countof(t->thread_name_cstr)); String name = StringFromCstr(t->thread_name_cstr, countof(t->thread_name_cstr));
threads_msg.len += string_format(scratch.arena, LIT(" \"%F\"\n"), FMT_STR(name)).len; threads_msg.len += StringFormat(scratch.arena, Lit(" \"%F\"\n"), FmtString(name)).len;
++num_dangling_threads; ++num_dangling_threads;
} }
threads_msg = string_format(scratch.arena, LIT("%F dangling thread(s):\n%F"), FMT_UINT(num_dangling_threads), FMT_STR(threads_msg)); threads_msg = StringFormat(scratch.arena, Lit("%F dangling thread(s):\n%F"), FmtUint(num_dangling_threads), FmtString(threads_msg));
P_Panic(threads_msg); P_Panic(threads_msg);
EndScratch(scratch); EndScratch(scratch);
} }

View File

@ -24,13 +24,13 @@ R_StartupReceipt resource_startup(void)
#if RESOURCES_EMBEDDED #if RESOURCES_EMBEDDED
String embedded_data = inc_res_tar(); String embedded_data = inc_res_tar();
if (embedded_data.len <= 0) { if (embedded_data.len <= 0) {
P_Panic(LIT("No embedded resources found")); P_Panic(Lit("No embedded resources found"));
} }
G.archive = tar_parse(G.arena, embedded_data, LIT("")); G.archive = tar_parse(G.arena, embedded_data, Lit(""));
#else #else
/* Ensure we have the right working directory */ /* Ensure we have the right working directory */
if (!P_IsDir(LIT("res"))) { if (!P_IsDir(Lit("res"))) {
P_Panic(LIT("Resource directory \"res\" not found. Make sure the executable is being launched from the correct working directory.")); P_Panic(Lit("Resource directory \"res\" not found. Make sure the executable is being launched from the correct working directory."));
} }
#endif #endif

View File

@ -2,15 +2,15 @@ String settings_serialize(Arena *arena, const P_WindowSettings *settings)
{ {
__prof; __prof;
String minimized = settings->flags & P_WindowSettingsFlag_Minimized ? LIT("true") : LIT("false"); String minimized = settings->flags & P_WindowSettingsFlag_Minimized ? Lit("true") : Lit("false");
String maximized = settings->flags & P_WindowSettingsFlag_Maximized ? LIT("true") : LIT("false"); String maximized = settings->flags & P_WindowSettingsFlag_Maximized ? Lit("true") : Lit("false");
String fullscreen = settings->flags & P_WindowSettingsFlag_Fullscreen ? LIT("true") : LIT("false"); String fullscreen = settings->flags & P_WindowSettingsFlag_Fullscreen ? Lit("true") : Lit("false");
i32 x = settings->floating_x; i32 x = settings->floating_x;
i32 y = settings->floating_y; i32 y = settings->floating_y;
i32 width = settings->floating_width; i32 width = settings->floating_width;
i32 height = settings->floating_height; i32 height = settings->floating_height;
String fmt = LIT( String fmt = Lit(
"{\n" "{\n"
" \"window\": {\n" " \"window\": {\n"
" \"minimized\": %F,\n" " \"minimized\": %F,\n"
@ -24,15 +24,15 @@ String settings_serialize(Arena *arena, const P_WindowSettings *settings)
"}\n" "}\n"
); );
String formatted = string_format(arena, String formatted = StringFormat(arena,
fmt, fmt,
FMT_STR(minimized), FmtString(minimized),
FMT_STR(maximized), FmtString(maximized),
FMT_STR(fullscreen), FmtString(fullscreen),
FMT_SINT(x), FmtSint(x),
FMT_SINT(y), FmtSint(y),
FMT_SINT(width), FmtSint(width),
FMT_SINT(height)); FmtSint(height));
return formatted; return formatted;
} }
@ -55,13 +55,13 @@ P_WindowSettings *settings_deserialize(Arena *arena, String src, String *error_o
JSON_Blob *root = parse_res.root; JSON_Blob *root = parse_res.root;
if (!root) { if (!root) {
error = LIT("Root object not found."); error = Lit("Root object not found.");
goto abort; goto abort;
} }
JSON_Blob *window = root->child_first; JSON_Blob *window = root->child_first;
if (!window || window->type != JSON_TYPE_OBJECT || !string_eq(window->key, LIT("window"))) { if (!window || window->type != JSON_TYPE_OBJECT || !EqString(window->key, Lit("window"))) {
error = LIT("\"window\" object not found"); error = Lit("\"window\" object not found");
goto abort; goto abort;
} }
@ -74,48 +74,48 @@ P_WindowSettings *settings_deserialize(Arena *arena, String src, String *error_o
for (JSON_Blob *child = window->child_first; child; child = child->next) { for (JSON_Blob *child = window->child_first; child; child = child->next) {
String key = child->key; String key = child->key;
if (string_eq(key, LIT("maximized"))) { if (EqString(key, Lit("maximized"))) {
if (child->type != JSON_TYPE_BOOL) { if (child->type != JSON_TYPE_BOOL) {
error = LIT("Expected boolean for \"maximized\""); error = Lit("Expected boolean for \"maximized\"");
goto abort; goto abort;
} }
if (child->value.boolean) { if (child->value.boolean) {
settings->flags |= P_WindowSettingsFlag_Maximized; settings->flags |= P_WindowSettingsFlag_Maximized;
} }
found_maximized = 1; found_maximized = 1;
} else if (string_eq(key, LIT("fullscreen"))) { } else if (EqString(key, Lit("fullscreen"))) {
if (child->type != JSON_TYPE_BOOL) { if (child->type != JSON_TYPE_BOOL) {
error = LIT("Expected boolean for \"fulscreen\""); error = Lit("Expected boolean for \"fulscreen\"");
goto abort; goto abort;
} }
if (child->value.boolean) { if (child->value.boolean) {
settings->flags |= P_WindowSettingsFlag_Fullscreen; settings->flags |= P_WindowSettingsFlag_Fullscreen;
} }
found_fullscreen = 1; found_fullscreen = 1;
} else if (string_eq(key, LIT("x"))) { } else if (EqString(key, Lit("x"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = LIT("Expected number for \"x\""); error = Lit("Expected number for \"x\"");
goto abort; goto abort;
} }
settings->floating_x = RoundF32ToI32(child->value.number); settings->floating_x = RoundF32ToI32(child->value.number);
found_x = 1; found_x = 1;
} else if (string_eq(key, LIT("y"))) { } else if (EqString(key, Lit("y"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = LIT("Expected number for \"y\""); error = Lit("Expected number for \"y\"");
goto abort; goto abort;
} }
settings->floating_y = RoundF32ToI32(child->value.number); settings->floating_y = RoundF32ToI32(child->value.number);
found_y = 1; found_y = 1;
} else if (string_eq(key, LIT("width"))) { } else if (EqString(key, Lit("width"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = LIT("Expected number for \"width\""); error = Lit("Expected number for \"width\"");
goto abort; goto abort;
} }
settings->floating_width = RoundF32ToI32(child->value.number); settings->floating_width = RoundF32ToI32(child->value.number);
found_width = 1; found_width = 1;
} else if (string_eq(key, LIT("height"))) { } else if (EqString(key, Lit("height"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = LIT("Expected number for \"height\""); error = Lit("Expected number for \"height\"");
goto abort; goto abort;
} }
settings->floating_height = RoundF32ToI32(child->value.number); settings->floating_height = RoundF32ToI32(child->value.number);
@ -123,24 +123,24 @@ P_WindowSettings *settings_deserialize(Arena *arena, String src, String *error_o
} }
} }
if (!found_maximized) { error = LIT("Missing \"maximized\""); goto abort; } if (!found_maximized) { error = Lit("Missing \"maximized\""); goto abort; }
if (!found_fullscreen) { error = LIT("Missing \"fullscreen\""); goto abort; } if (!found_fullscreen) { error = Lit("Missing \"fullscreen\""); goto abort; }
if (!found_x) { error = LIT("Missing \"x\""); goto abort; } if (!found_x) { error = Lit("Missing \"x\""); goto abort; }
if (!found_y) { error = LIT("Missing \"y\""); goto abort; } if (!found_y) { error = Lit("Missing \"y\""); goto abort; }
if (!found_width) { error = LIT("Missing \"width\""); goto abort; } if (!found_width) { error = Lit("Missing \"width\""); goto abort; }
if (!found_height) { error = LIT("Missing \"height\""); goto abort; } if (!found_height) { error = Lit("Missing \"height\""); goto abort; }
abort: abort:
if (error_out && (error.len > 0 || json_error.msg.len > 0)) { if (error_out && (error.len > 0 || json_error.msg.len > 0)) {
if (json_error.msg.len > 0) { if (json_error.msg.len > 0) {
*error_out = string_format(arena, *error_out = StringFormat(arena,
LIT("%F\n(%F:%F)"), Lit("%F\n(%F:%F)"),
FMT_STR(json_error.msg), FmtString(json_error.msg),
FMT_UINT(json_error.start), FmtUint(json_error.start),
FMT_UINT(json_error.end)); FmtUint(json_error.end));
} else { } else {
*error_out = string_copy(arena, error); *error_out = CopyString(arena, error);
} }
} }

View File

@ -189,7 +189,7 @@ void sim_client_release(Client *client)
internal u64 hash_from_channel_id(N_ChannelId channel_id) internal u64 hash_from_channel_id(N_ChannelId channel_id)
{ {
return hash_fnv64(HASH_FNV64_BASIS, STRING_FROM_STRUCT(&channel_id)); return HashFnv64(Fnv64Basis, StringFromStruct(&channel_id));
} }
void sim_client_set_channel_id(Client *client, N_ChannelId channel_id) void sim_client_set_channel_id(Client *client, N_ChannelId channel_id)
@ -667,7 +667,7 @@ void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntId remot
/* FIXME: Don't trust non-master clients: /* FIXME: Don't trust non-master clients:
* - Only sync cmd ents * - Only sync cmd ents
* - Determine new UUIDs for newly created ents * - Determine new UUids for newly created ents
*/ */
Ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID); Ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID);
@ -724,7 +724,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
{ {
__prof; __prof;
BB_WriteDebugMarker(bw, LIT("SNAPSHOT START")); BB_WriteDebugMarker(bw, Lit("SNAPSHOT START"));
BB_WriteIV(bw, ss1->sim_dt_ns); BB_WriteIV(bw, ss1->sim_dt_ns);
BB_WriteIV(bw, ss1->sim_time_ns); BB_WriteIV(bw, ss1->sim_time_ns);
@ -732,11 +732,11 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteUV(bw, ss1->continuity_gen); BB_WriteUV(bw, ss1->continuity_gen);
BB_WriteUV(bw, ss1->phys_iteration); BB_WriteUV(bw, ss1->phys_iteration);
BB_WriteUID(bw, receiver->player_id.uid); BB_WriteUid(bw, receiver->player_id.uid);
/* Id bins */ /* Id bins */
/* TODO: Don't encode these */ /* TODO: Don't encode these */
BB_WriteDebugMarker(bw, LIT("SNAPSHOT BINS")); BB_WriteDebugMarker(bw, Lit("SNAPSHOT BINS"));
for (u64 i = 0; i < ss1->num_id_bins; ++i) { for (u64 i = 0; i < ss1->num_id_bins; ++i) {
u32 old_first = 0; u32 old_first = 0;
u32 old_last = 0; u32 old_last = 0;
@ -762,7 +762,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteBit(bw, 0); BB_WriteBit(bw, 0);
/* Ents */ /* Ents */
BB_WriteDebugMarker(bw, LIT("SNAPSHOT NUM ENTS")); BB_WriteDebugMarker(bw, Lit("SNAPSHOT NUM ENTS"));
if (BB_WriteBit(bw, ss1->num_ents_allocated != ss0->num_ents_allocated)) { if (BB_WriteBit(bw, ss1->num_ents_allocated != ss0->num_ents_allocated)) {
BB_WriteUV(bw, ss1->num_ents_allocated); BB_WriteUV(bw, ss1->num_ents_allocated);
} }
@ -770,8 +770,8 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteUV(bw, ss1->num_ents_reserved); BB_WriteUV(bw, ss1->num_ents_reserved);
} }
BB_WriteDebugMarker(bw, LIT("SNAPSHOT ENTS")); BB_WriteDebugMarker(bw, Lit("SNAPSHOT ENTS"));
BB_WriteDebugMarker(bw, STRING_FROM_STRUCT(&ss1->num_ents_reserved)); BB_WriteDebugMarker(bw, StringFromStruct(&ss1->num_ents_reserved));
for (u64 i = 1; i < ss1->num_ents_reserved; ++i) { for (u64 i = 1; i < ss1->num_ents_reserved; ++i) {
Ent *e0 = sim_ent_nil(); Ent *e0 = sim_ent_nil();
@ -782,7 +782,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
sim_ent_encode(bw, e0, e1); sim_ent_encode(bw, e0, e1);
} }
BB_WriteDebugMarker(bw, LIT("SNAPSHOT END")); BB_WriteDebugMarker(bw, Lit("SNAPSHOT END"));
} }
/* ========================== * /* ========================== *
@ -793,7 +793,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
{ {
__prof; __prof;
BB_ReadDebugMarker(br, LIT("SNAPSHOT START")); BB_ReadDebugMarker(br, Lit("SNAPSHOT START"));
ss->sim_dt_ns = BB_ReadIV(br); ss->sim_dt_ns = BB_ReadIV(br);
ss->sim_time_ns = BB_ReadIV(br); ss->sim_time_ns = BB_ReadIV(br);
@ -801,11 +801,11 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->continuity_gen = BB_ReadUV(br); ss->continuity_gen = BB_ReadUV(br);
ss->phys_iteration = BB_ReadUV(br); ss->phys_iteration = BB_ReadUV(br);
ss->local_player = (EntId) { .uid = BB_ReadUID(br) }; ss->local_player = (EntId) { .uid = BB_ReadUid(br) };
/* Id bins */ /* Id bins */
/* TODO: Don't decode these, determine them implicitly from decoded ents */ /* TODO: Don't decode these, determine them implicitly from decoded ents */
BB_ReadDebugMarker(br, LIT("SNAPSHOT BINS")); BB_ReadDebugMarker(br, Lit("SNAPSHOT BINS"));
{ {
b32 bin_changed = BB_ReadBit(br); b32 bin_changed = BB_ReadBit(br);
while (bin_changed) { while (bin_changed) {
@ -828,7 +828,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
} }
/* Ents */ /* Ents */
BB_ReadDebugMarker(br, LIT("SNAPSHOT NUM ENTS")); BB_ReadDebugMarker(br, Lit("SNAPSHOT NUM ENTS"));
if (BB_ReadBit(br)) { if (BB_ReadBit(br)) {
ss->num_ents_allocated = BB_ReadUV(br); ss->num_ents_allocated = BB_ReadUV(br);
} }
@ -851,15 +851,15 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
} }
} }
BB_ReadDebugMarker(br, LIT("SNAPSHOT ENTS")); BB_ReadDebugMarker(br, Lit("SNAPSHOT ENTS"));
BB_ReadDebugMarker(br, STRING_FROM_STRUCT(&ss->num_ents_reserved)); BB_ReadDebugMarker(br, StringFromStruct(&ss->num_ents_reserved));
for (u64 i = 1; i < ss->num_ents_reserved; ++i) { for (u64 i = 1; i < ss->num_ents_reserved; ++i) {
Ent *e = &ss->ents[i]; Ent *e = &ss->ents[i];
e->ss = ss; e->ss = ss;
sim_ent_decode(br, e); sim_ent_decode(br, e);
} }
BB_ReadDebugMarker(br, LIT("SNAPSHOT END")); BB_ReadDebugMarker(br, Lit("SNAPSHOT END"));
} }
@ -879,7 +879,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteUV(bw, ss1->continuity_gen); BB_WriteUV(bw, ss1->continuity_gen);
BB_WriteUV(bw, ss1->phys_iteration); BB_WriteUV(bw, ss1->phys_iteration);
BB_WriteUID(bw, receiver->player_id.uid); BB_WriteUid(bw, receiver->player_id.uid);
/* Ents */ /* Ents */
@ -910,7 +910,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteBit(1); BB_WriteBit(1);
BB_WriteBit(e1->valid); BB_WriteBit(e1->valid);
if (e1->valid) { if (e1->valid) {
BB_WriteUID(bw, e1->id.uid); BB_WriteUid(bw, e1->id.uid);
} }
} else { } else {
BB_WriteBit(0); BB_WriteBit(0);
@ -947,7 +947,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->continuity_gen = BB_ReadUV(br); ss->continuity_gen = BB_ReadUV(br);
ss->phys_iteration = BB_ReadUV(br); ss->phys_iteration = BB_ReadUV(br);
ss->local_player = (EntId) { .uid = BB_ReadUID(br) }; ss->local_player = (EntId) { .uid = BB_ReadUid(br) };
#if 1 #if 1
@ -989,7 +989,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
} }
} else { } else {
alloc_parent_index = BB_ReadUV(); alloc_parent_index = BB_ReadUV();
alloc_ent_id = sim_ent_id_from_uid(BB_ReadUID(br)); alloc_ent_id = sim_ent_id_from_uid(BB_ReadUid(br));
} }
} }

View File

@ -12,7 +12,7 @@
#define SIM_LAYER_RELATIVE_WEAPON (1) #define SIM_LAYER_RELATIVE_WEAPON (1)
Struct(EntId) { Struct(EntId) {
UID uid; Uid uid;
}; };
Struct(ClientHandle) { Struct(ClientHandle) {

View File

@ -1,7 +1,7 @@
/* Id magic number constants (to be used in conjunction with ent ids in deterministic id combinations) */ /* Id magic number constants (to be used in conjunction with ent ids in deterministic id combinations) */
#define SIM_ENT_CONTACT_BASIS_UID (MakeUID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af)) #define SIM_ENT_CONTACT_BASIS_Uid (UID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af))
#define SIM_ENT_COLLISION_DEBUG_BASIS_UID (MakeUID(0x302c01182013bb02, 0x570bd270399d11a5)) #define SIM_ENT_COLLISION_DEBUG_BASIS_Uid (UID(0x302c01182013bb02, 0x570bd270399d11a5))
#define SIM_ENT_TILE_CHUNK_BASIS_UID (MakeUID(0x3ce42de071dd226b, 0x9b566f7df30c813a)) #define SIM_ENT_TILE_CHUNK_BASIS_Uid (UID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
internal u32 index_from_ent(Snapshot *ss, Ent *ent) internal u32 index_from_ent(Snapshot *ss, Ent *ent)
{ {
@ -262,7 +262,7 @@ Ent *sim_ent_from_id(Snapshot *ss, EntId id)
EntId sim_ent_random_id(void) EntId sim_ent_random_id(void)
{ {
EntId res = ZI; EntId res = ZI;
res.uid = uid_true_rand(); res.uid = UidFromTrueRand();
return res; return res;
} }
@ -270,10 +270,10 @@ EntId sim_ent_random_id(void)
EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1) EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1)
{ {
EntId res = ZI; EntId res = ZI;
res.uid = SIM_ENT_CONTACT_BASIS_UID; res.uid = SIM_ENT_CONTACT_BASIS_Uid;
res.uid = uid_combine(res.uid, player_id.uid); res.uid = CombineUid(res.uid, player_id.uid);
res.uid = uid_combine(res.uid, id0.uid); res.uid = CombineUid(res.uid, id0.uid);
res.uid = uid_combine(res.uid, id1.uid); res.uid = CombineUid(res.uid, id1.uid);
return res; return res;
} }
@ -281,10 +281,10 @@ EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId i
EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1) EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1)
{ {
EntId res = ZI; EntId res = ZI;
res.uid = SIM_ENT_COLLISION_DEBUG_BASIS_UID; res.uid = SIM_ENT_COLLISION_DEBUG_BASIS_Uid;
res.uid = uid_combine(res.uid, player_id.uid); res.uid = CombineUid(res.uid, player_id.uid);
res.uid = uid_combine(res.uid, id0.uid); res.uid = CombineUid(res.uid, id0.uid);
res.uid = uid_combine(res.uid, id1.uid); res.uid = CombineUid(res.uid, id1.uid);
return res; return res;
} }
@ -292,8 +292,8 @@ EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1)
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index) EntId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index)
{ {
EntId res = ZI; EntId res = ZI;
res.uid = SIM_ENT_TILE_CHUNK_BASIS_UID; res.uid = SIM_ENT_TILE_CHUNK_BASIS_Uid;
res.uid = uid_combine(res.uid, MakeUID(RandU64FromSeed(chunk_index.x), RandU64FromSeed(chunk_index.y))); res.uid = CombineUid(res.uid, UID(RandU64FromSeed(chunk_index.x), RandU64FromSeed(chunk_index.y)));
return res; return res;
} }

View File

@ -1,5 +1,5 @@
#define SIM_ENT_NIL_ID ((EntId) { MakeUID(0, 0) }) #define SIM_ENT_NIL_ID ((EntId) { UID(0, 0) })
#define SIM_ENT_ROOT_ID ((EntId) { MakeUID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) }) #define SIM_ENT_ROOT_ID ((EntId) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
typedef i32 EntProp; enum { typedef i32 EntProp; enum {
SEPROP_ACTIVE, SEPROP_ACTIVE,
@ -422,12 +422,12 @@ Inline Ent *sim_ent_nil(void)
Inline b32 sim_ent_id_eq(EntId a, EntId b) Inline b32 sim_ent_id_eq(EntId a, EntId b)
{ {
return uid_eq(a.uid, b.uid); return EqUid(a.uid, b.uid);
} }
Inline b32 sim_ent_id_is_nil(EntId id) Inline b32 sim_ent_id_is_nil(EntId id)
{ {
return uid_eq(id.uid, SIM_ENT_NIL_ID.uid); return EqUid(id.uid, SIM_ENT_NIL_ID.uid);
} }
/* ========================== * /* ========================== *

View File

@ -36,10 +36,10 @@ void sim_accel_reset(Snapshot *ss, SimAccel *accel)
internal Ent *test_spawn_smg(Ent *parent) internal Ent *test_spawn_smg(Ent *parent)
{ {
Ent *e = sim_ent_alloc_sync_src(parent); Ent *e = sim_ent_alloc_sync_src(parent);
e->sprite = sprite_tag_from_path(LIT("sprite/gun.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/gun.ase"));
sim_ent_enable_prop(e, SEPROP_ATTACHED); sim_ent_enable_prop(e, SEPROP_ATTACHED);
e->attach_slice = LIT("attach.wep"); e->attach_slice = Lit("attach.wep");
e->layer = SIM_LAYER_RELATIVE_WEAPON; e->layer = SIM_LAYER_RELATIVE_WEAPON;
sim_ent_enable_prop(e, SEPROP_WEAPON_SMG); sim_ent_enable_prop(e, SEPROP_WEAPON_SMG);
@ -52,10 +52,10 @@ internal Ent *test_spawn_smg(Ent *parent)
internal Ent *test_spawn_launcher(Ent *parent) internal Ent *test_spawn_launcher(Ent *parent)
{ {
Ent *e = sim_ent_alloc_sync_src(parent); Ent *e = sim_ent_alloc_sync_src(parent);
e->sprite = sprite_tag_from_path(LIT("sprite/gun.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/gun.ase"));
sim_ent_enable_prop(e, SEPROP_ATTACHED); sim_ent_enable_prop(e, SEPROP_ATTACHED);
e->attach_slice = LIT("attach.wep"); e->attach_slice = Lit("attach.wep");
e->layer = SIM_LAYER_RELATIVE_WEAPON; e->layer = SIM_LAYER_RELATIVE_WEAPON;
sim_ent_enable_prop(e, SEPROP_WEAPON_LAUNCHER); sim_ent_enable_prop(e, SEPROP_WEAPON_LAUNCHER);
@ -68,10 +68,10 @@ internal Ent *test_spawn_launcher(Ent *parent)
internal Ent *test_spawn_chucker(Ent *parent) internal Ent *test_spawn_chucker(Ent *parent)
{ {
Ent *chucker = sim_ent_alloc_sync_src(parent); Ent *chucker = sim_ent_alloc_sync_src(parent);
chucker->sprite = sprite_tag_from_path(LIT("sprite/gun.ase")); chucker->sprite = sprite_tag_from_path(Lit("sprite/gun.ase"));
sim_ent_enable_prop(chucker, SEPROP_ATTACHED); sim_ent_enable_prop(chucker, SEPROP_ATTACHED);
chucker->attach_slice = LIT("attach.wep"); chucker->attach_slice = Lit("attach.wep");
chucker->layer = SIM_LAYER_RELATIVE_WEAPON; chucker->layer = SIM_LAYER_RELATIVE_WEAPON;
sim_ent_enable_prop(chucker, SEPROP_WEAPON_CHUCKER); sim_ent_enable_prop(chucker, SEPROP_WEAPON_CHUCKER);
@ -85,7 +85,7 @@ internal Ent *test_spawn_chucker(Ent *parent)
sim_ent_enable_prop(zone, SEPROP_CHUCKER_ZONE); sim_ent_enable_prop(zone, SEPROP_CHUCKER_ZONE);
sim_ent_enable_prop(zone, SEPROP_ATTACHED); sim_ent_enable_prop(zone, SEPROP_ATTACHED);
zone->attach_slice = LIT("out"); zone->attach_slice = Lit("out");
sim_ent_enable_prop(zone, SEPROP_SENSOR); sim_ent_enable_prop(zone, SEPROP_SENSOR);
CLD_Shape collider = ZI; CLD_Shape collider = ZI;
@ -119,15 +119,15 @@ internal Ent *test_spawn_employee(Ent *parent)
{ {
sim_ent_enable_prop(e, SEPROP_TEST); sim_ent_enable_prop(e, SEPROP_TEST);
e->sprite = sprite_tag_from_path(LIT("sprite/tim.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/tim.ase"));
e->mass_unscaled = 10; e->mass_unscaled = 10;
e->inertia_unscaled = 5; e->inertia_unscaled = 5;
} }
//e->sprite = sprite_tag_from_path(LIT("sprite/box_rounded.ase")); //e->sprite = sprite_tag_from_path(Lit("sprite/box_rounded.ase"));
//e->sprite_span_name = LIT("idle.unarmed"); //e->sprite_span_name = Lit("idle.unarmed");
//e->sprite_span_name = LIT("idle.one_handed"); //e->sprite_span_name = Lit("idle.one_handed");
e->sprite_span_name = LIT("idle.two_handed"); e->sprite_span_name = Lit("idle.two_handed");
e->layer = SIM_LAYER_SHOULDERS; e->layer = SIM_LAYER_SHOULDERS;
e->local_collider.points[0] = VEC2(0, 0); e->local_collider.points[0] = VEC2(0, 0);
@ -255,7 +255,7 @@ internal void test_spawn_entities2(Ent *parent, Vec2 pos)
Xform xf = XformFromTrs(TRS(.t = pos, .r = rot, .s = size)); Xform xf = XformFromTrs(TRS(.t = pos, .r = rot, .s = size));
sim_ent_set_xform(e, xf); sim_ent_set_xform(e, xf);
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/tile.ase"));
e->layer = SIM_LAYER_SHOULDERS; e->layer = SIM_LAYER_SHOULDERS;
//e->sprite_tint = Alpha32F(ColorBlue, 0.75); //e->sprite_tint = Alpha32F(ColorBlue, 0.75);
@ -297,8 +297,8 @@ internal void test_spawn_entities2(Ent *parent, Vec2 pos)
Xform xf = XformFromTrs(.t = pos, .r = r, .s = size); Xform xf = XformFromTrs(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf); sim_ent_set_xform(e, xf);
e->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/bullet.ase"));
e->sprite_collider_slice = LIT("shape"); e->sprite_collider_slice = Lit("shape");
e->layer = SIM_LAYER_SHOULDERS; e->layer = SIM_LAYER_SHOULDERS;
sim_ent_enable_prop(e, SEPROP_SOLID); sim_ent_enable_prop(e, SEPROP_SOLID);
@ -325,7 +325,7 @@ internal void test_spawn_entities3(Ent *parent, Vec2 pos)
Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size)); Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size));
sim_ent_set_xform(e, xf); sim_ent_set_xform(e, xf);
e->sprite = sprite_tag_from_path(LIT("sprite/box.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/box.ase"));
e->layer = SIM_LAYER_SHOULDERS; e->layer = SIM_LAYER_SHOULDERS;
e->sprite_tint = ColorRed; e->sprite_tint = ColorRed;
@ -348,8 +348,8 @@ internal void test_spawn_entities4(Ent *parent, Vec2 pos)
Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size)); Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size));
sim_ent_set_xform(e, xf); sim_ent_set_xform(e, xf);
//e->sprite = sprite_tag_from_path(LIT("sprite/box.ase")); //e->sprite = sprite_tag_from_path(Lit("sprite/box.ase"));
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/tile.ase"));
e->layer = SIM_LAYER_SHOULDERS; e->layer = SIM_LAYER_SHOULDERS;
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST); sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
@ -378,7 +378,7 @@ internal void test_spawn_tile(Snapshot *world, Vec2 world_pos)
sim_ent_set_xform(e, xf); sim_ent_set_xform(e, xf);
e->layer = SIM_LAYER_WALLS; e->layer = SIM_LAYER_WALLS;
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase")); e->sprite = sprite_tag_from_path(Lit("sprite/tile.ase"));
e->sprite_tint = ColorRed; e->sprite_tint = ColorRed;
{ {
@ -405,7 +405,7 @@ internal void test_spawn_tile(Snapshot *world, Vec2 world_pos)
internal SORT_COMPARE_FUNC_DEF(tile_chunk_sort_x, arg_a, arg_b, udata) internal MergesortCompareFuncDef(tile_chunk_sort_x, arg_a, arg_b, udata)
{ {
(UNUSED)udata; (UNUSED)udata;
Ent *a = *(Ent **)arg_a; Ent *a = *(Ent **)arg_a;
@ -418,7 +418,7 @@ internal SORT_COMPARE_FUNC_DEF(tile_chunk_sort_x, arg_a, arg_b, udata)
return res; return res;
} }
internal SORT_COMPARE_FUNC_DEF(tile_chunk_sort_y, arg_a, arg_b, udata) internal MergesortCompareFuncDef(tile_chunk_sort_y, arg_a, arg_b, udata)
{ {
(UNUSED)udata; (UNUSED)udata;
Ent *a = *(Ent **)arg_a; Ent *a = *(Ent **)arg_a;
@ -462,8 +462,8 @@ internal void test_generate_walls(Snapshot *world)
/* NOTE: We sort x & y separately because it's possible that a wall /* NOTE: We sort x & y separately because it's possible that a wall
* should merge with another wall that was generated from a diagonal chunk. */ * should merge with another wall that was generated from a diagonal chunk. */
merge_sort(x_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*x_sorted_tile_chunks), tile_chunk_sort_x, 0); Mergesort(x_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*x_sorted_tile_chunks), tile_chunk_sort_x, 0);
merge_sort(y_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*y_sorted_tile_chunks), tile_chunk_sort_y, 0); Mergesort(y_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*y_sorted_tile_chunks), tile_chunk_sort_y, 0);
} }
struct wall_node { struct wall_node {
@ -475,8 +475,8 @@ internal void test_generate_walls(Snapshot *world)
/* Dicts containing walls that end on edge of tile chunk, keyed by tile end index. /* Dicts containing walls that end on edge of tile chunk, keyed by tile end index.
* Used to merge walls accross tile chunks. */ * Used to merge walls accross tile chunks. */
Dict *horizontal_ends_dict = dict_init(scratch.arena, 1024); Dict *horizontal_ends_dict = InitDict(scratch.arena, 1024);
Dict *vertical_ends_dict = dict_init(scratch.arena, 1024); Dict *vertical_ends_dict = InitDict(scratch.arena, 1024);
struct wall_node *first_wall = 0; struct wall_node *first_wall = 0;
@ -530,11 +530,11 @@ internal void test_generate_walls(Snapshot *world)
if (wall_start == 0) { if (wall_start == 0) {
u64 start_hash = RandU64FromSeed(*(u64 *)&start); u64 start_hash = RandU64FromSeed(*(u64 *)&start);
start_hash = RandU64FromSeeds(start_hash, wall_dir); start_hash = RandU64FromSeeds(start_hash, wall_dir);
DictEntry *entry = dict_get_entry(horizontal_ends_dict, start_hash); DictEntry *entry = DictEntryFromHash(horizontal_ends_dict, start_hash);
if (entry) { if (entry) {
/* Existing wall exists accross chunk boundary */ /* Existing wall exists accross chunk boundary */
node = (struct wall_node *)entry->value; node = (struct wall_node *)entry->value;
dict_remove_entry(horizontal_ends_dict, entry); RemoveDictEntry(horizontal_ends_dict, entry);
} }
} }
if (!node) { if (!node) {
@ -548,7 +548,7 @@ internal void test_generate_walls(Snapshot *world)
if (wall_end == SIM_TILES_PER_CHUNK_SQRT) { if (wall_end == SIM_TILES_PER_CHUNK_SQRT) {
u64 end_hash = RandU64FromSeed(*(u64 *)&end); u64 end_hash = RandU64FromSeed(*(u64 *)&end);
end_hash = RandU64FromSeeds(end_hash, wall_dir); end_hash = RandU64FromSeeds(end_hash, wall_dir);
dict_set(scratch.arena, horizontal_ends_dict, end_hash, (u64)node); SetDictValue(scratch.arena, horizontal_ends_dict, end_hash, (u64)node);
} }
wall_start = -1; wall_start = -1;
wall_end = -1; wall_end = -1;
@ -620,11 +620,11 @@ internal void test_generate_walls(Snapshot *world)
if (wall_start == 0) { if (wall_start == 0) {
u64 start_hash = RandU64FromSeed(*(u64 *)&start); u64 start_hash = RandU64FromSeed(*(u64 *)&start);
start_hash = RandU64FromSeeds(start_hash, wall_dir); start_hash = RandU64FromSeeds(start_hash, wall_dir);
DictEntry *entry = dict_get_entry(vertical_ends_dict, start_hash); DictEntry *entry = DictEntryFromHash(vertical_ends_dict, start_hash);
if (entry) { if (entry) {
/* Existing wall exists accross chunk boundary */ /* Existing wall exists accross chunk boundary */
node = (struct wall_node *)entry->value; node = (struct wall_node *)entry->value;
dict_remove_entry(vertical_ends_dict, entry); RemoveDictEntry(vertical_ends_dict, entry);
} }
} }
if (!node) { if (!node) {
@ -638,7 +638,7 @@ internal void test_generate_walls(Snapshot *world)
if (wall_end == SIM_TILES_PER_CHUNK_SQRT) { if (wall_end == SIM_TILES_PER_CHUNK_SQRT) {
u64 end_hash = RandU64FromSeed(*(u64 *)&end); u64 end_hash = RandU64FromSeed(*(u64 *)&end);
end_hash = RandU64FromSeeds(end_hash, wall_dir); end_hash = RandU64FromSeeds(end_hash, wall_dir);
dict_set(scratch.arena, vertical_ends_dict, end_hash, (u64)node); SetDictValue(scratch.arena, vertical_ends_dict, end_hash, (u64)node);
} }
wall_start = -1; wall_start = -1;
wall_end = -1; wall_end = -1;
@ -750,7 +750,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
{ {
Xform xf = XformFromTrs(TRS(.t = point, .r = RandF64FromState(&step_ctx->rand, 0, Tau))); Xform xf = XformFromTrs(TRS(.t = point, .r = RandF64FromState(&step_ctx->rand, 0, Tau)));
Ent *decal = sim_ent_alloc_sync_src(root); Ent *decal = sim_ent_alloc_sync_src(root);
decal->sprite = sprite_tag_from_path(LIT("sprite/blood.ase")); decal->sprite = sprite_tag_from_path(Lit("sprite/blood.ase"));
decal->sprite_tint = Rgba32F(1, 1, 1, 0.25f); decal->sprite_tint = Rgba32F(1, 1, 1, 0.25f);
decal->layer = SIM_LAYER_FLOOR_DECALS; decal->layer = SIM_LAYER_FLOOR_DECALS;
sim_ent_set_xform(decal, xf); sim_ent_set_xform(decal, xf);
@ -892,7 +892,7 @@ void sim_step(SimStepCtx *ctx)
player->owner = player->id; player->owner = player->id;
sim_ent_enable_prop(player, SEPROP_PLAYER_IS_MASTER); sim_ent_enable_prop(player, SEPROP_PLAYER_IS_MASTER);
} }
P_LogInfoF("Created player with id %F for sim client %F. is_master: %F", FMT_UID(player->id.uid), FMT_HANDLE(client->handle), FMT_UINT(sim_ent_has_prop(player, SEPROP_PLAYER_IS_MASTER))); P_LogInfoF("Created player with id %F for sim client %F. is_master: %F", FmtUid(player->id.uid), FmtHandle(client->handle), FmtUint(sim_ent_has_prop(player, SEPROP_PLAYER_IS_MASTER)));
} }
/* Update rtt */ /* Update rtt */
@ -1205,7 +1205,7 @@ void sim_step(SimStepCtx *ctx)
#if 0 #if 0
/* Update sprite local xform */ /* Update sprite local xform */
{ {
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("pivot"), ent->animation_frame); S_SheetSlice slice = sprite_sheet_get_slice(sheet, Lit("pivot"), ent->animation_frame);
Vec2 sprite_size = DivVec2(sheet->frame_size, (f32)PIXELS_PER_UNIT); Vec2 sprite_size = DivVec2(sheet->frame_size, (f32)PIXELS_PER_UNIT);
Vec2 dir = MulVec2Vec2(sprite_size, slice.dir); Vec2 dir = MulVec2Vec2(sprite_size, slice.dir);
@ -1354,7 +1354,7 @@ void sim_step(SimStepCtx *ctx)
u32 animation_frame = ent->animation_frame; u32 animation_frame = ent->animation_frame;
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
Xform sprite_local_xform = ent->sprite_local_xform; Xform sprite_local_xform = ent->sprite_local_xform;
S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame); S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, Lit("out"), animation_frame);
Vec2 rel_pos = MulXformV2(sprite_local_xform, out_slice.center); Vec2 rel_pos = MulXformV2(sprite_local_xform, out_slice.center);
Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir); Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir);
@ -1377,8 +1377,8 @@ void sim_step(SimStepCtx *ctx)
bullet->local_collider.points[0] = VEC2(0, 0); bullet->local_collider.points[0] = VEC2(0, 0);
bullet->local_collider.count = 1; bullet->local_collider.count = 1;
#else #else
bullet->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase")); bullet->sprite = sprite_tag_from_path(Lit("sprite/bullet.ase"));
bullet->sprite_collider_slice = LIT("shape"); bullet->sprite_collider_slice = Lit("shape");
#endif #endif
} }
@ -1401,7 +1401,7 @@ void sim_step(SimStepCtx *ctx)
u32 animation_frame = ent->animation_frame; u32 animation_frame = ent->animation_frame;
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
Xform sprite_local_xform = ent->sprite_local_xform; Xform sprite_local_xform = ent->sprite_local_xform;
S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame); S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, Lit("out"), animation_frame);
Vec2 rel_pos = MulXformV2(sprite_local_xform, out_slice.center); Vec2 rel_pos = MulXformV2(sprite_local_xform, out_slice.center);
Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir); Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir);
@ -1562,7 +1562,7 @@ void sim_step(SimStepCtx *ctx)
Vec2 sprite_hold_dir; Vec2 sprite_hold_dir;
{ {
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame); S_SheetSlice slice = sprite_sheet_get_slice(sheet, Lit("attach.wep"), ent->animation_frame);
sprite_hold_pos = slice.center; sprite_hold_pos = slice.center;
sprite_hold_dir = slice.dir; sprite_hold_dir = slice.dir;
} }

View File

@ -76,12 +76,12 @@ internal P_JobDef(sound_load_asset_job, job)
AC_Asset *asset = params->asset; AC_Asset *asset = params->asset;
u32 flags = params->flags; u32 flags = params->flags;
P_LogInfoF("Loading sound \"%F\"", FMT_STR(path)); P_LogInfoF("Loading sound \"%F\"", FmtString(path));
i64 start_ns = P_TimeNs(); i64 start_ns = P_TimeNs();
String error_msg = LIT("Unknown error"); String error_msg = Lit("Unknown error");
Assert(string_ends_with(path, LIT(".mp3"))); Assert(StringEndsWith(path, Lit(".mp3")));
/* Decode */ /* Decode */
MP3_Result decoded = ZI; MP3_Result decoded = ZI;
@ -94,10 +94,10 @@ internal P_JobDef(sound_load_asset_job, job)
} }
decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), SOUND_SAMPLE_RATE, decode_flags); decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), SOUND_SAMPLE_RATE, decode_flags);
if (!decoded.success) { if (!decoded.success) {
error_msg = LIT("Failed to decode sound file"); error_msg = Lit("Failed to decode sound file");
} }
} else { } else {
error_msg = LIT("Resource not found"); error_msg = Lit("Resource not found");
} }
resource_close(&sound_rs); resource_close(&sound_rs);
} }
@ -121,10 +121,10 @@ internal P_JobDef(sound_load_asset_job, job)
sound->samples = samples; sound->samples = samples;
CopyBytes(sound->samples, decoded.samples, decoded.samples_count * sizeof(*decoded.samples)); CopyBytes(sound->samples, decoded.samples, decoded.samples_count * sizeof(*decoded.samples));
P_LogSuccessF("Loaded sound \"%F\" in %F seconds", FMT_STR(path), FMT_FLOAT(SecondsFromNs(P_TimeNs() - start_ns))); P_LogSuccessF("Loaded sound \"%F\" in %F seconds", FmtString(path), FmtFloat(SecondsFromNs(P_TimeNs() - start_ns)));
asset_cache_mark_ready(asset, sound); asset_cache_mark_ready(asset, sound);
} else { } else {
P_LogErrorF("Error loading sound \"%F\": %F", FMT_STR(path), FMT_STR(error_msg)); P_LogErrorF("Error loading sound \"%F\": %F", FmtString(path), FmtString(error_msg));
/* Store */ /* Store */
SND_Sound *sound = 0; SND_Sound *sound = 0;
@ -148,10 +148,10 @@ AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
/* Generate and append sound flags to path key */ /* Generate and append sound flags to path key */
String key = string_format(scratch.arena, String key = StringFormat(scratch.arena,
LIT("%F%F_sound"), Lit("%F%F_sound"),
FMT_STR(path), FmtString(path),
FMT_UINT((u64)flags)); FmtUint((u64)flags));
u64 hash = asset_cache_hash(key); u64 hash = asset_cache_hash(key);
b32 is_first_touch; b32 is_first_touch;
AC_Asset *asset = asset_cache_touch(key, hash, &is_first_touch); AC_Asset *asset = asset_cache_touch(key, hash, &is_first_touch);
@ -160,11 +160,11 @@ AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
/* Assemble task params */ /* Assemble task params */
struct sound_task_params *params = sound_task_params_alloc(); struct sound_task_params *params = sound_task_params_alloc();
if (path.len > (sizeof(params->path_cstr) - 1)) { if (path.len > (sizeof(params->path_cstr) - 1)) {
P_Panic(string_format(scratch.arena, P_Panic(StringFormat(scratch.arena,
LIT("Sound path \"%F\" too long!"), Lit("Sound path \"%F\" too long!"),
FMT_STR(path))); FmtString(path)));
} }
cstr_buff_from_string(STRING_FROM_ARRAY(params->path_cstr), path); CstrBuffFromStringToBuff(StringFromArray(params->path_cstr), path);
params->path_len = path.len; params->path_len = path.len;
params->asset = asset; params->asset = asset;
params->flags = flags; params->flags = flags;

View File

@ -259,7 +259,7 @@ internal P_ExitFuncDef(sprite_shutdown)
S_Tag sprite_tag_from_path(String path) S_Tag sprite_tag_from_path(String path)
{ {
S_Tag res = ZI; S_Tag res = ZI;
res.hash = hash_fnv64(HASH_FNV64_BASIS, path); res.hash = HashFnv64(Fnv64Basis, path);
res.path = path; res.path = path;
return res; return res;
} }
@ -322,11 +322,11 @@ internal void cache_entry_load_texture(struct cache_ref ref, S_Tag tag)
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_WORKING); Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_WORKING);
String path = tag.path; String path = tag.path;
P_LogInfoF("Loading sprite texture [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path)); P_LogInfoF("Loading sprite texture [%F] \"%F\"", FmtHex(e->hash.v), FmtString(path));
b32 success = 0; b32 success = 0;
i64 start_ns = P_TimeNs(); i64 start_ns = P_TimeNs();
Assert(string_ends_with(path, LIT(".ase"))); Assert(StringEndsWith(path, Lit(".ase")));
Assert(e->kind == CACHE_ENTRY_KIND_TEXTURE); Assert(e->kind == CACHE_ENTRY_KIND_TEXTURE);
/* TODO: Replace arena allocs w/ buddy allocator */ /* TODO: Replace arena allocs w/ buddy allocator */
@ -341,7 +341,7 @@ internal void cache_entry_load_texture(struct cache_ref ref, S_Tag tag)
if (resource_exists(&texture_rs)) { if (resource_exists(&texture_rs)) {
decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs)); decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs));
} else { } else {
P_LogErrorF("Sprite texture for \"%F\" not found", FMT_STR(path)); P_LogErrorF("Sprite texture for \"%F\" not found", FmtString(path));
} }
resource_close(&texture_rs); resource_close(&texture_rs);
} }
@ -365,10 +365,10 @@ internal void cache_entry_load_texture(struct cache_ref ref, S_Tag tag)
if (success) { if (success) {
P_LogSuccessF("Loaded sprite texture [%F] \"%F\" in %F seconds (cache size: %F bytes).", P_LogSuccessF("Loaded sprite texture [%F] \"%F\" in %F seconds (cache size: %F bytes).",
FMT_HEX(e->hash.v), FmtHex(e->hash.v),
FMT_STR(path), FmtString(path),
FMT_FLOAT(SecondsFromNs(P_TimeNs() - start_ns)), FmtFloat(SecondsFromNs(P_TimeNs() - start_ns)),
FMT_UINT(e->memory_usage)); FmtUint(e->memory_usage));
} }
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_LOADED); Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_LOADED);
@ -426,16 +426,16 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
if (ase.num_spans > 0) { if (ase.num_spans > 0) {
__profn("Init spans"); __profn("Init spans");
sheet.spans = PushStructs(arena, S_SheetSpan, sheet.spans_count); sheet.spans = PushStructs(arena, S_SheetSpan, sheet.spans_count);
sheet.spans_dict = dict_init(arena, (u64)(ase.num_spans * SHEET_SPAN_LOOKUP_TABLE_BIN_RATIO)); sheet.spans_dict = InitDict(arena, (u64)(ase.num_spans * SHEET_SPAN_LOOKUP_TABLE_BIN_RATIO));
u64 index = 0; u64 index = 0;
for (Ase_Span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) { for (Ase_Span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) {
String name = string_copy(arena, ase_span->name); String name = CopyString(arena, ase_span->name);
S_SheetSpan *span = &sheet.spans[index]; S_SheetSpan *span = &sheet.spans[index];
span->name = name; span->name = name;
span->start = ase_span->start; span->start = ase_span->start;
span->end = ase_span->end; span->end = ase_span->end;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
dict_set(arena, sheet.spans_dict, hash, (u64)span); SetDictValue(arena, sheet.spans_dict, hash, (u64)span);
++index; ++index;
} }
} }
@ -466,15 +466,15 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
u64 num_temp_slice_group_nodes = 0; u64 num_temp_slice_group_nodes = 0;
struct temp_slice_group_node *temp_slice_group_head = 0; struct temp_slice_group_node *temp_slice_group_head = 0;
{ {
Dict *temp_slice_dict = dict_init(scratch.arena, (u64)(ase.num_slice_keys * 2)); Dict *temp_slice_dict = InitDict(scratch.arena, (u64)(ase.num_slice_keys * 2));
for (Ase_SliceKey *ase_slice_key = ase.slice_key_head; ase_slice_key; ase_slice_key = ase_slice_key->next) { for (Ase_SliceKey *ase_slice_key = ase.slice_key_head; ase_slice_key; ase_slice_key = ase_slice_key->next) {
String name = ase_slice_key->name; String name = ase_slice_key->name;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
struct temp_slice_group_node *temp_slice_group_node = (struct temp_slice_group_node *)dict_get(temp_slice_dict, hash); struct temp_slice_group_node *temp_slice_group_node = (struct temp_slice_group_node *)DictValueFromHash(temp_slice_dict, hash);
if (!temp_slice_group_node) { if (!temp_slice_group_node) {
temp_slice_group_node = PushStruct(scratch.arena, struct temp_slice_group_node); temp_slice_group_node = PushStruct(scratch.arena, struct temp_slice_group_node);
temp_slice_group_node->name = name; temp_slice_group_node->name = name;
dict_set(scratch.arena, temp_slice_dict, hash, (u64)temp_slice_group_node); SetDictValue(scratch.arena, temp_slice_dict, hash, (u64)temp_slice_group_node);
++num_temp_slice_group_nodes; ++num_temp_slice_group_nodes;
temp_slice_group_node->next = temp_slice_group_head; temp_slice_group_node->next = temp_slice_group_head;
@ -495,12 +495,12 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
/* Allocate slice groups & fill originals in 2d array */ /* Allocate slice groups & fill originals in 2d array */
sheet.slice_groups_count = num_temp_slice_group_nodes; sheet.slice_groups_count = num_temp_slice_group_nodes;
sheet.slice_groups = PushStructs(arena, S_SheetSliceGroup, sheet.slice_groups_count); sheet.slice_groups = PushStructs(arena, S_SheetSliceGroup, sheet.slice_groups_count);
sheet.slice_groups_dict = dict_init(arena, (u64)(num_temp_slice_group_nodes * SHEET_SLICE_LOOKUP_TABLE_BIN_RATIO)); sheet.slice_groups_dict = InitDict(arena, (u64)(num_temp_slice_group_nodes * SHEET_SLICE_LOOKUP_TABLE_BIN_RATIO));
u64 index = 0; u64 index = 0;
for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) { for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) {
S_SheetSliceGroup *slice_group = &sheet.slice_groups[index]; S_SheetSliceGroup *slice_group = &sheet.slice_groups[index];
slice_group->name = string_copy(arena, temp_slice_group_node->name); slice_group->name = CopyString(arena, temp_slice_group_node->name);
slice_group->per_frame_count = temp_slice_group_node->per_frame_count; slice_group->per_frame_count = temp_slice_group_node->per_frame_count;
slice_group->frame_slices = PushStructs(arena, S_SheetSlice, ase.num_frames * slice_group->per_frame_count); slice_group->frame_slices = PushStructs(arena, S_SheetSlice, ase.num_frames * slice_group->per_frame_count);
@ -557,8 +557,8 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
} }
temp_slice_group_node->final_slice_group = slice_group; temp_slice_group_node->final_slice_group = slice_group;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, slice_group->name); u64 hash = HashFnv64(Fnv64Basis, slice_group->name);
dict_set(arena, sheet.slice_groups_dict, hash, (u64)slice_group); SetDictValue(arena, sheet.slice_groups_dict, hash, (u64)slice_group);
++index; ++index;
} }
@ -599,15 +599,15 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
/* Calculate direction vectors */ /* Calculate direction vectors */
for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) { for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) {
String ray_suffix = LIT(".ray"); String ray_suffix = Lit(".ray");
S_SheetSliceGroup *ray_slice_group = temp_slice_group_node->final_slice_group; S_SheetSliceGroup *ray_slice_group = temp_slice_group_node->final_slice_group;
String ray_slice_name = ray_slice_group->name; String ray_slice_name = ray_slice_group->name;
if (string_ends_with(ray_slice_name, ray_suffix)) { if (StringEndsWith(ray_slice_name, ray_suffix)) {
String point_slice_name = ray_slice_name; String point_slice_name = ray_slice_name;
point_slice_name.len -= ray_suffix.len; point_slice_name.len -= ray_suffix.len;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, point_slice_name); u64 hash = HashFnv64(Fnv64Basis, point_slice_name);
S_SheetSliceGroup *point_slice_group = (S_SheetSliceGroup *)dict_get(sheet.slice_groups_dict, hash); S_SheetSliceGroup *point_slice_group = (S_SheetSliceGroup *)DictValueFromHash(sheet.slice_groups_dict, hash);
if (point_slice_group) { if (point_slice_group) {
u32 point_slices_per_frame = point_slice_group->per_frame_count; u32 point_slices_per_frame = point_slice_group->per_frame_count;
@ -645,7 +645,7 @@ internal void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag)
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_WORKING); Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_WORKING);
String path = tag.path; String path = tag.path;
P_LogInfoF("Loading sprite sheet [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path)); P_LogInfoF("Loading sprite sheet [%F] \"%F\"", FmtHex(e->hash.v), FmtString(path));
b32 success = 0; b32 success = 0;
i64 start_ns = P_TimeNs(); i64 start_ns = P_TimeNs();
@ -661,7 +661,7 @@ internal void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag)
if (resource_exists(&sheet_rs)) { if (resource_exists(&sheet_rs)) {
decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs)); decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs));
} else { } else {
P_LogErrorF("Sprite sheet for \"%F\" not found", FMT_STR(path)); P_LogErrorF("Sprite sheet for \"%F\" not found", FmtString(path));
} }
resource_close(&sheet_rs); resource_close(&sheet_rs);
} }
@ -686,10 +686,10 @@ internal void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag)
if (success) { if (success) {
P_LogSuccessF("Loaded sprite sheet [%F] \"%F\" in %F seconds (cache size: %F bytes).", P_LogSuccessF("Loaded sprite sheet [%F] \"%F\" in %F seconds (cache size: %F bytes).",
FMT_HEX(e->hash.v), FmtHex(e->hash.v),
FMT_STR(path), FmtString(path),
FMT_FLOAT(SecondsFromNs(P_TimeNs() - start_ns)), FmtFloat(SecondsFromNs(P_TimeNs() - start_ns)),
FMT_UINT(e->memory_usage)); FmtUint(e->memory_usage));
} }
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_LOADED); Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_LOADED);
@ -749,7 +749,7 @@ internal struct sprite_scope_cache_ref *scope_ensure_ref_unsafe(S_Scope *scope,
if (*slot == 0) { if (*slot == 0) {
if (scope->num_references >= MAX_SCOPE_REFERENCES) { if (scope->num_references >= MAX_SCOPE_REFERENCES) {
P_Panic(LIT("Max sprite scope references reached")); P_Panic(Lit("Max sprite scope references reached"));
} }
/* Increment refcount */ /* Increment refcount */
@ -953,7 +953,7 @@ internal void *data_from_tag_internal(S_Scope *scope, S_Tag tag, enum cache_entr
switch (kind) { switch (kind) {
case CACHE_ENTRY_KIND_TEXTURE: { res = G.loading_texture; } break; case CACHE_ENTRY_KIND_TEXTURE: { res = G.loading_texture; } break;
case CACHE_ENTRY_KIND_SHEET: { res = G.loading_sheet; } break; case CACHE_ENTRY_KIND_SHEET: { res = G.loading_sheet; } break;
default: { P_Panic(LIT("Unknown sprite cache entry kind")); } break; default: { P_Panic(Lit("Unknown sprite cache entry kind")); } break;
} }
struct sprite_scope_cache_ref *scope_ref = cache_entry_from_tag(scope, tag, kind, 0); struct sprite_scope_cache_ref *scope_ref = cache_entry_from_tag(scope, tag, kind, 0);
@ -964,7 +964,7 @@ internal void *data_from_tag_internal(S_Scope *scope, S_Tag tag, enum cache_entr
switch (kind) { switch (kind) {
case CACHE_ENTRY_KIND_TEXTURE: { res = ref.e->texture; } break; case CACHE_ENTRY_KIND_TEXTURE: { res = ref.e->texture; } break;
case CACHE_ENTRY_KIND_SHEET: { res = ref.e->sheet; } break; case CACHE_ENTRY_KIND_SHEET: { res = ref.e->sheet; } break;
default: { P_Panic(LIT("Unknown sprite cache entry kind")); } break; default: { P_Panic(Lit("Unknown sprite cache entry kind")); } break;
} }
} else if (state == CACHE_ENTRY_STATE_NONE) { } else if (state == CACHE_ENTRY_STATE_NONE) {
/* If entry is new, load texture */ /* If entry is new, load texture */
@ -980,7 +980,7 @@ internal void *data_from_tag_internal(S_Scope *scope, S_Tag tag, enum cache_entr
cache_entry_load_sheet(ref, tag); cache_entry_load_sheet(ref, tag);
res = ref.e->sheet; res = ref.e->sheet;
} break; } break;
default: { P_Panic(LIT("Unknown sprite cache entry kind")); } break; default: { P_Panic(Lit("Unknown sprite cache entry kind")); } break;
} }
} else { } else {
/* Allocate cmd */ /* Allocate cmd */
@ -1055,8 +1055,8 @@ S_SheetSpan sprite_sheet_get_span(S_Sheet *sheet, String name)
{ {
S_SheetSpan res = ZI; S_SheetSpan res = ZI;
if (sheet->spans_count > 0) { if (sheet->spans_count > 0) {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
S_SheetSpan *entry = (S_SheetSpan *)dict_get(sheet->spans_dict, hash); S_SheetSpan *entry = (S_SheetSpan *)DictValueFromHash(sheet->spans_dict, hash);
if (entry) { if (entry) {
res = *entry; res = *entry;
} }
@ -1067,8 +1067,8 @@ S_SheetSpan sprite_sheet_get_span(S_Sheet *sheet, String name)
S_SheetSlice sprite_sheet_get_slice(S_Sheet *sheet, String name, u32 frame_index) S_SheetSlice sprite_sheet_get_slice(S_Sheet *sheet, String name, u32 frame_index)
{ {
if (sheet->slice_groups_count > 0) { if (sheet->slice_groups_count > 0) {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
S_SheetSliceGroup *group = (S_SheetSliceGroup *)dict_get(sheet->slice_groups_dict, hash); S_SheetSliceGroup *group = (S_SheetSliceGroup *)DictValueFromHash(sheet->slice_groups_dict, hash);
if (group) { if (group) {
return group->frame_slices[frame_index * group->per_frame_count]; return group->frame_slices[frame_index * group->per_frame_count];
} }
@ -1076,14 +1076,14 @@ S_SheetSlice sprite_sheet_get_slice(S_Sheet *sheet, String name, u32 frame_index
/* Return 'pivot' by default */ /* Return 'pivot' by default */
S_SheetSlice res = ZI; S_SheetSlice res = ZI;
if (string_eq(name, LIT("pivot"))) { if (EqString(name, Lit("pivot"))) {
/* 'pivot' slice does not exist, return center */ /* 'pivot' slice does not exist, return center */
res.center = VEC2(0, 0); res.center = VEC2(0, 0);
res.center_px = MulVec2(sheet->frame_size, 0.5f); res.center_px = MulVec2(sheet->frame_size, 0.5f);
res.dir_px = VEC2(res.center_px.x, 0); res.dir_px = VEC2(res.center_px.x, 0);
res.dir = VEC2(0, -0.5); res.dir = VEC2(0, -0.5);
} else { } else {
res = sprite_sheet_get_slice(sheet, LIT("pivot"), frame_index); res = sprite_sheet_get_slice(sheet, Lit("pivot"), frame_index);
} }
return res; return res;
@ -1093,8 +1093,8 @@ S_SheetSliceArray sprite_sheet_get_slices(S_Sheet *sheet, String name, u32 frame
{ {
S_SheetSliceArray res = ZI; S_SheetSliceArray res = ZI;
if (sheet->slice_groups_count > 0) { if (sheet->slice_groups_count > 0) {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
S_SheetSliceGroup *group = (S_SheetSliceGroup *)dict_get(sheet->slice_groups_dict, hash); S_SheetSliceGroup *group = (S_SheetSliceGroup *)DictValueFromHash(sheet->slice_groups_dict, hash);
if (group) { if (group) {
res.count = group->per_frame_count; res.count = group->per_frame_count;
res.slices = &group->frame_slices[frame_index * group->per_frame_count]; res.slices = &group->frame_slices[frame_index * group->per_frame_count];
@ -1120,7 +1120,7 @@ internal P_JobDef(sprite_load_job, job)
case CACHE_ENTRY_KIND_SHEET: { case CACHE_ENTRY_KIND_SHEET: {
cache_entry_load_sheet(ref, cmd->tag); cache_entry_load_sheet(ref, cmd->tag);
} break; } break;
default: { P_Panic(LIT("Unknown sprite cache node kind")); } break; default: { P_Panic(Lit("Unknown sprite cache node kind")); } break;
} }
/* Free cmd */ /* Free cmd */
@ -1151,7 +1151,7 @@ internal void reload_if_exists(S_Scope *scope, S_Tag tag, enum cache_entry_kind
P_Unlock(&bin_lock); P_Unlock(&bin_lock);
if (existing_ref) { if (existing_ref) {
P_LogInfoF("Sprite resource file \"%F\" has changed for sprite [%F].", FMT_STR(tag.path), FMT_HEX(hash.v)); P_LogInfoF("Sprite resource file \"%F\" has changed for sprite [%F].", FmtString(tag.path), FmtHex(hash.v));
struct sprite_scope_cache_ref *scope_ref = cache_entry_from_tag(scope, tag, kind, 1); struct sprite_scope_cache_ref *scope_ref = cache_entry_from_tag(scope, tag, kind, 1);
push_load_job(scope_ref->ref, tag); push_load_job(scope_ref->ref, tag);
} }
@ -1161,9 +1161,9 @@ internal WATCH_CALLBACK_FUNC_DEF(sprite_watch_callback, name)
{ {
S_Scope *scope = sprite_scope_begin(); S_Scope *scope = sprite_scope_begin();
if (string_starts_with(name, LIT("res/"))) { if (StringStartsWith(name, Lit("res/"))) {
name.len -= LIT("res/").len; name.len -= Lit("res/").len;
name.text += LIT("res/").len; name.text += Lit("res/").len;
} }
S_Tag tag = sprite_tag_from_path(name); S_Tag tag = sprite_tag_from_path(name);
@ -1188,7 +1188,7 @@ struct evict_node {
struct evict_node *next_evicted; struct evict_node *next_evicted;
}; };
internal SORT_COMPARE_FUNC_DEF(evict_sort, arg_a, arg_b, udata) internal MergesortCompareFuncDef(evict_sort, arg_a, arg_b, udata)
{ {
(UNUSED)udata; (UNUSED)udata;
struct evict_node *a = arg_a; struct evict_node *a = arg_a;
@ -1266,7 +1266,7 @@ internal P_JobDef(sprite_evictor_job, _)
/* Sort evict nodes */ /* Sort evict nodes */
{ {
__profn("Evictor sort"); __profn("Evictor sort");
merge_sort(evict_array, evict_array_count, sizeof(*evict_array), evict_sort, 0); Mergesort(evict_array, evict_array_count, sizeof(*evict_array), evict_sort, 0);
} }
/* Remove evictable nodes from cache until under budget */ /* Remove evictable nodes from cache until under budget */

View File

@ -71,9 +71,9 @@ struct tar_archive tar_parse(Arena *arena, String data, String prefix)
while (BB_NumBytesRemaining(&br) > 1024) { while (BB_NumBytesRemaining(&br) > 1024) {
struct tar_header header = ZI; struct tar_header header = ZI;
BB_ReadBytes(&br, STRING_FROM_STRUCT(&header)); BB_ReadBytes(&br, StringFromStruct(&header));
if (!string_eq(STRING_FROM_ARRAY(header.ustar_indicator), LIT("ustar\0"))) { if (!EqString(StringFromArray(header.ustar_indicator), Lit("ustar\0"))) {
/* Invalid header */ /* Invalid header */
Assert(0); Assert(0);
continue; continue;
@ -106,13 +106,13 @@ struct tar_archive tar_parse(Arena *arena, String data, String prefix)
continue; continue;
} }
String file_name_cstr = string_from_cstr_no_limit((char *)header.file_name); String file_name_cstr = StringFromCstrNoLimit((char *)header.file_name);
if (file_name_cstr.len >= 2) { if (file_name_cstr.len >= 2) {
/* Chop off './' prefix */ /* Chop off './' prefix */
file_name_cstr.len -= 2; file_name_cstr.len -= 2;
file_name_cstr.text += 2; file_name_cstr.text += 2;
} }
String file_name = string_cat(arena, prefix, file_name_cstr); String file_name = CatString(arena, prefix, file_name_cstr);
struct tar_entry *entry = PushStruct(arena, struct tar_entry); struct tar_entry *entry = PushStruct(arena, struct tar_entry);
entry->valid = 1; entry->valid = 1;
@ -126,10 +126,10 @@ struct tar_archive tar_parse(Arena *arena, String data, String prefix)
} }
/* Build lookup table */ /* Build lookup table */
archive.lookup = dict_init(arena, (u64)((f64)num_files * ARCHIVE_LOOKUP_TABLE_CAPACITY_FACTOR)); archive.lookup = InitDict(arena, (u64)((f64)num_files * ARCHIVE_LOOKUP_TABLE_CAPACITY_FACTOR));
for (struct tar_entry *entry = archive.head; entry; entry = entry->next) { for (struct tar_entry *entry = archive.head; entry; entry = entry->next) {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, entry->file_name); u64 hash = HashFnv64(Fnv64Basis, entry->file_name);
dict_set(arena, archive.lookup, hash, (u64)entry); SetDictValue(arena, archive.lookup, hash, (u64)entry);
} }
/* Build hierarchy */ /* Build hierarchy */
@ -142,8 +142,8 @@ struct tar_archive tar_parse(Arena *arena, String data, String prefix)
struct tar_entry *parent_entry = 0; struct tar_entry *parent_entry = 0;
for (String parent_dir_name = entry->file_name; parent_dir_name.len > 0; --parent_dir_name.len) { for (String parent_dir_name = entry->file_name; parent_dir_name.len > 0; --parent_dir_name.len) {
if (parent_dir_name.text[parent_dir_name.len - 1] == '/') { if (parent_dir_name.text[parent_dir_name.len - 1] == '/') {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, parent_dir_name); u64 hash = HashFnv64(Fnv64Basis, parent_dir_name);
parent_entry = (struct tar_entry *)dict_get(archive.lookup, hash); parent_entry = (struct tar_entry *)DictValueFromHash(archive.lookup, hash);
break; break;
} }
} }
@ -161,7 +161,7 @@ struct tar_archive tar_parse(Arena *arena, String data, String prefix)
Readonly Global struct tar_entry g_nil_tar_entry = ZI; Readonly Global struct tar_entry g_nil_tar_entry = ZI;
struct tar_entry *tar_get(struct tar_archive *archive, String name) struct tar_entry *tar_get(struct tar_archive *archive, String name)
{ {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name); u64 hash = HashFnv64(Fnv64Basis, name);
struct tar_entry *lookup = (struct tar_entry *)dict_get(archive->lookup, hash); struct tar_entry *lookup = (struct tar_entry *)DictValueFromHash(archive->lookup, hash);
return lookup ? lookup : &g_nil_tar_entry; return lookup ? lookup : &g_nil_tar_entry;
} }

View File

@ -59,7 +59,7 @@ TTF_StartupReceipt ttf_startup(void)
#endif #endif
if (error != S_OK) { if (error != S_OK) {
/* FIXME: Enable this */ /* FIXME: Enable this */
//P_Panic(LIT("Error creating DWrite factory")); //P_Panic(Lit("Error creating DWrite factory"));
(*(volatile int *)0) = 0; (*(volatile int *)0) = 0;
} }

View File

@ -204,7 +204,7 @@ struct user_startup_receipt user_startup(F_StartupReceipt *font_sr,
G.real_time_ns = P_TimeNs(); G.real_time_ns = P_TimeNs();
/* TODO: Remove this */ /* TODO: Remove this */
G.connect_address_str = string_copy(G.arena, connect_address_str); G.connect_address_str = CopyString(G.arena, connect_address_str);
/* Initialize average dt to a reasonable value */ /* Initialize average dt to a reasonable value */
G.average_local_to_user_snapshot_publish_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND; G.average_local_to_user_snapshot_publish_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
@ -303,76 +303,76 @@ internal String get_ent_debug_text(Arena *arena, Ent *ent)
String res = ZI; String res = ZI;
res.text = PushDry(arena, u8); res.text = PushDry(arena, u8);
res.len += string_format(arena, LIT("[%F]"), FMT_UID(ent->id.uid)).len; res.len += StringFormat(arena, Lit("[%F]"), FmtUid(ent->id.uid)).len;
{ {
b32 transmitting = sim_ent_has_prop(ent, SEPROP_SYNC_SRC); b32 transmitting = sim_ent_has_prop(ent, SEPROP_SYNC_SRC);
b32 receiving = sim_ent_has_prop(ent, SEPROP_SYNC_DST); b32 receiving = sim_ent_has_prop(ent, SEPROP_SYNC_DST);
if (transmitting & receiving) { if (transmitting & receiving) {
res.len += string_copy(arena, LIT(" networked (sending & receiving)")).len; res.len += CopyString(arena, Lit(" networked (sending & receiving)")).len;
} else if (transmitting) { } else if (transmitting) {
res.len += string_copy(arena, LIT(" networked (sending)")).len; res.len += CopyString(arena, Lit(" networked (sending)")).len;
} else if (receiving) { } else if (receiving) {
res.len += string_copy(arena, LIT(" networked (receiving)")).len; res.len += CopyString(arena, Lit(" networked (receiving)")).len;
} else { } else {
res.len += string_copy(arena, LIT(" local")).len; res.len += CopyString(arena, Lit(" local")).len;
} }
} }
res.len += string_copy(arena, LIT("\n")).len; res.len += CopyString(arena, Lit("\n")).len;
res.len += string_format(arena, LIT("owner: [%F]\n"), FMT_UID(ent->owner.uid)).len; res.len += StringFormat(arena, Lit("owner: [%F]\n"), FmtUid(ent->owner.uid)).len;
res.len += string_copy(arena, LIT("\n")).len; res.len += CopyString(arena, Lit("\n")).len;
{ {
res.len += string_copy(arena, LIT("props: 0x")).len; res.len += CopyString(arena, Lit("props: 0x")).len;
for (u64 chunk_index = countof(ent->props); chunk_index-- > 0;) { for (u64 chunk_index = countof(ent->props); chunk_index-- > 0;) {
u64 chunk = ent->props[chunk_index]; u64 chunk = ent->props[chunk_index];
for (u64 part_index = 8; part_index-- > 0;) { for (u64 part_index = 8; part_index-- > 0;) {
if ((chunk_index != (countof(ent->props) - 1)) || ((chunk_index * 64) + (part_index * 8)) <= SEPROP_COUNT) { if ((chunk_index != (countof(ent->props) - 1)) || ((chunk_index * 64) + (part_index * 8)) <= SEPROP_COUNT) {
u8 part = (chunk >> (part_index * 8)) & 0xFF; u8 part = (chunk >> (part_index * 8)) & 0xFF;
string_from_char(arena, hex[(part >> 4) & 0x0F]); StringFromChar(arena, hex[(part >> 4) & 0x0F]);
string_from_char(arena, hex[(part >> 0) & 0x0F]); StringFromChar(arena, hex[(part >> 0) & 0x0F]);
res.len += 2; res.len += 2;
} }
} }
} }
res.len += string_copy(arena, LIT("\n")).len; res.len += CopyString(arena, Lit("\n")).len;
} }
if (!sim_ent_id_eq(ent->parent, SIM_ENT_ROOT_ID)) { if (!sim_ent_id_eq(ent->parent, SIM_ENT_ROOT_ID)) {
res.len += string_format(arena, LIT("parent: [%F]\n"), FMT_UID(ent->parent.uid)).len; res.len += StringFormat(arena, Lit("parent: [%F]\n"), FmtUid(ent->parent.uid)).len;
} }
if (!sim_ent_id_is_nil(ent->next) || !sim_ent_id_is_nil(ent->prev)) { if (!sim_ent_id_is_nil(ent->next) || !sim_ent_id_is_nil(ent->prev)) {
res.len += string_format(arena, LIT("prev: [%F]\n"), FMT_UID(ent->prev.uid)).len; res.len += StringFormat(arena, Lit("prev: [%F]\n"), FmtUid(ent->prev.uid)).len;
res.len += string_format(arena, LIT("next: [%F]\n"), FMT_UID(ent->next.uid)).len; res.len += StringFormat(arena, Lit("next: [%F]\n"), FmtUid(ent->next.uid)).len;
} }
res.len += string_copy(arena, LIT("\n")).len; res.len += CopyString(arena, Lit("\n")).len;
/* Pos */ /* Pos */
Xform xf = sim_ent_get_xform(ent); Xform xf = sim_ent_get_xform(ent);
Vec2 linear_velocity = ent->linear_velocity; Vec2 linear_velocity = ent->linear_velocity;
f32 angular_velocity = ent->angular_velocity; f32 angular_velocity = ent->angular_velocity;
res.len += string_format(arena, LIT("pos: (%F, %F)\n"), FMT_FLOAT(xf.og.x), FMT_FLOAT(xf.og.y)).len; res.len += StringFormat(arena, Lit("pos: (%F, %F)\n"), FmtFloat(xf.og.x), FmtFloat(xf.og.y)).len;
res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT(linear_velocity.x), FMT_FLOAT(linear_velocity.y)).len; res.len += StringFormat(arena, Lit("linear velocity: (%F, %F)\n"), FmtFloat(linear_velocity.x), FmtFloat(linear_velocity.y)).len;
res.len += string_format(arena, LIT("angular velocity: %F\n"), FMT_FLOAT(angular_velocity)).len; res.len += StringFormat(arena, Lit("angular velocity: %F\n"), FmtFloat(angular_velocity)).len;
/* Test */ /* Test */
res.len += string_format(arena, LIT("collision dir: (%F, %F)\n"), FMT_FLOAT(ent->collision_dir.x), FMT_FLOAT(ent->collision_dir.y)).len; res.len += StringFormat(arena, Lit("collision dir: (%F, %F)\n"), FmtFloat(ent->collision_dir.x), FmtFloat(ent->collision_dir.y)).len;
/* Children */ /* Children */
if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) { if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) {
Ent *child = sim_ent_from_id(ss, ent->first); Ent *child = sim_ent_from_id(ss, ent->first);
if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid) { if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid) {
res.len += string_format(arena, LIT("first child: [%F]\n"), FMT_UID(ent->first.uid)).len; res.len += StringFormat(arena, Lit("first child: [%F]\n"), FmtUid(ent->first.uid)).len;
res.len += string_format(arena, LIT("last child: [%F]\n"), FMT_UID(ent->last.uid)).len; res.len += StringFormat(arena, Lit("last child: [%F]\n"), FmtUid(ent->last.uid)).len;
} }
while (child->valid) { while (child->valid) {
res.len += string_copy(arena, LIT("\n---------------------------------\n")).len; res.len += CopyString(arena, Lit("\n---------------------------------\n")).len;
res.len += string_copy(arena, LIT("CHILD\n")).len; res.len += CopyString(arena, Lit("CHILD\n")).len;
String child_text = get_ent_debug_text(scratch.arena, child); String child_text = get_ent_debug_text(scratch.arena, child);
res.len += string_indent(arena, child_text, 4).len; res.len += IndentString(arena, child_text, 4).len;
child = sim_ent_from_id(ss, child->next); child = sim_ent_from_id(ss, child->next);
} }
} }
@ -392,7 +392,7 @@ internal P_LogEventCallbackFuncDef(debug_console_log_callback, log)
{ {
struct console_log *clog = PushStruct(G.console_logs_arena, struct console_log); struct console_log *clog = PushStruct(G.console_logs_arena, struct console_log);
clog->level = log.level; clog->level = log.level;
clog->msg = string_copy(G.console_logs_arena, log.msg); clog->msg = CopyString(G.console_logs_arena, log.msg);
clog->datetime = log.datetime; clog->datetime = log.datetime;
clog->time_ns = log.time_ns; clog->time_ns = log.time_ns;
@ -447,7 +447,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
G.console_logs_height = 0; G.console_logs_height = 0;
i64 now_ns = P_TimeNs(); i64 now_ns = P_TimeNs();
F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); F_Font *font = font_load_async(Lit("font/fixedsys.ttf"), 12.0f);
if (font) { if (font) {
P_Lock lock = P_LockE(&G.console_logs_mutex); P_Lock lock = P_LockE(&G.console_logs_mutex);
{ {
@ -467,14 +467,14 @@ internal void draw_debug_console(i32 level, b32 minimized)
String text = log->msg; String text = log->msg;
if (!minimized) { if (!minimized) {
P_DateTime datetime = log->datetime; P_DateTime datetime = log->datetime;
text = string_format( text = StringFormat(
scratch.arena, scratch.arena,
LIT("[%F:%F:%F.%F] %F"), Lit("[%F:%F:%F.%F] %F"),
FMT_UINT_Z(datetime.hour, 2), FmtUintZ(datetime.hour, 2),
FMT_UINT_Z(datetime.minute, 2), FmtUintZ(datetime.minute, 2),
FMT_UINT_Z(datetime.second, 2), FmtUintZ(datetime.second, 2),
FMT_UINT_Z(datetime.milliseconds, 3), FmtUintZ(datetime.milliseconds, 3),
FMT_STR(text)); FmtString(text));
} }
D_TextParams params = DRAW_TEXT_PARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = Alpha32F(ColorWhite, opacity), .str = text); D_TextParams params = DRAW_TEXT_PARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = Alpha32F(ColorWhite, opacity), .str = text);
@ -508,7 +508,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
* Sort entities * Sort entities
* ========================== */ * ========================== */
internal SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata) internal MergesortCompareFuncDef(ent_draw_order_cmp, arg_a, arg_b, udata)
{ {
(UNUSED)udata; (UNUSED)udata;
Ent *a = *(Ent **)arg_a; Ent *a = *(Ent **)arg_a;
@ -1151,7 +1151,7 @@ internal void user_update(P_Window *window)
/* Sort */ /* Sort */
{ {
__profn("Sort ents"); __profn("Sort ents");
merge_sort(sorted, sorted_count, sizeof(*sorted), ent_draw_order_cmp, 0); Mergesort(sorted, sorted_count, sizeof(*sorted), ent_draw_order_cmp, 0);
} }
} }
@ -1241,7 +1241,7 @@ internal void user_update(P_Window *window)
/* TODO: Something better */ /* TODO: Something better */
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) { if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
Vec2I32 chunk_index = ent->tile_chunk_index; Vec2I32 chunk_index = ent->tile_chunk_index;
S_Tag tile_sprite = sprite_tag_from_path(LIT("sprite/tile.ase")); S_Tag tile_sprite = sprite_tag_from_path(Lit("sprite/tile.ase"));
S_Texture *tile_texture = sprite_texture_from_tag_async(sprite_frame_scope, tile_sprite); S_Texture *tile_texture = sprite_texture_from_tag_async(sprite_frame_scope, tile_sprite);
if (tile_texture->loaded) { if (tile_texture->loaded) {
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT; f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
@ -1290,7 +1290,7 @@ internal void user_update(P_Window *window)
/* Draw focus arrow */ /* Draw focus arrow */
if (ent == local_control || sim_ent_id_eq(ent->id, G.debug_following)) { if (ent == local_control || sim_ent_id_eq(ent->id, G.debug_following)) {
S_Sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite); S_Sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame); S_SheetSlice slice = sprite_sheet_get_slice(sheet, Lit("attach.wep"), ent->animation_frame);
Vec2 start = MulXformV2(sprite_xform, slice.center); Vec2 start = MulXformV2(sprite_xform, slice.center);
start = MulXformV2(G.world_to_ui_xf, start); start = MulXformV2(G.world_to_ui_xf, start);
Vec2 end = AddVec2(xf.og, ent->control.focus); Vec2 end = AddVec2(xf.og, ent->control.focus);
@ -1309,7 +1309,7 @@ internal void user_update(P_Window *window)
for (u64 i = 0; i < sheet->slice_groups_count; ++i) { for (u64 i = 0; i < sheet->slice_groups_count; ++i) {
S_SheetSliceGroup *group = &sheet->slice_groups[i]; S_SheetSliceGroup *group = &sheet->slice_groups[i];
if (string_ends_with(group->name, LIT(".ray"))) continue; if (StringEndsWith(group->name, Lit(".ray"))) continue;
for (u32 j = 0; j < group->per_frame_count; ++j) { for (u32 j = 0; j < group->per_frame_count; ++j) {
S_SheetSlice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j]; S_SheetSlice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j];
@ -1436,11 +1436,11 @@ internal void user_update(P_Window *window)
#if 0 #if 0
/* Draw contact info */ /* Draw contact info */
{ {
F_Font *disp_font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); F_Font *disp_font = font_load_async(Lit("font/fixedsys.ttf"), 12.0f);
if (disp_font) { if (disp_font) {
f32 offset_px = 10; f32 offset_px = 10;
String fmt = LIT( String fmt = Lit(
"e0 index: %F\n" "e0 index: %F\n"
"e1 index: %F\n" "e1 index: %F\n"
"id: 0x%F\n" "id: 0x%F\n"
@ -1450,15 +1450,15 @@ internal void user_update(P_Window *window)
"normal: (%F, %F)\n" "normal: (%F, %F)\n"
"num contacts: %F" "num contacts: %F"
); );
String text = string_format(temp.arena, fmt, String text = StringFormat(temp.arena, fmt,
FMT_UINT(e0->handle.idx), FmtUint(e0->handle.idx),
FMT_UINT(e1->handle.idx), FmtUint(e1->handle.idx),
FMT_HEX(point.id), FmtHex(point.id),
FMT_FLOAT(point.normal_impulse), FmtFloat(point.normal_impulse),
FMT_FLOAT(point.tangent_impulse), FmtFloat(point.tangent_impulse),
FMT_FLOAT_P(point.starting_separation, 6), FmtFloatP(point.starting_separation, 6),
FMT_FLOAT_P(data->normal.x, 6), FMT_FLOAT_P(data->normal.y, 6), FmtFloatP(data->normal.x, 6), FmtFloatP(data->normal.y, 6),
FMT_UINT(data->num_points)); FmtUint(data->num_points));
draw_text(G.render_sig, disp_font, AddVec2(RoundVec2(MulXformV2(G.world_to_ui_xf, dbg_pt)), VEC2(0, offset_px)), text); draw_text(G.render_sig, disp_font, AddVec2(RoundVec2(MulXformV2(G.world_to_ui_xf, dbg_pt)), VEC2(0, offset_px)), text);
@ -1553,20 +1553,20 @@ internal void user_update(P_Window *window)
#if 0 #if 0
/* Test info */ /* Test info */
{ {
F_Font *disp_font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); F_Font *disp_font = font_load_async(Lit("font/fixedsys.ttf"), 12.0f);
if (disp_font) { if (disp_font) {
f32 offset_px = 10; f32 offset_px = 10;
String fmt = LIT( String fmt = Lit(
"e0 pos: (%F, %F)\n" "e0 pos: (%F, %F)\n"
"e0 rot: %F\n" "e0 rot: %F\n"
"e1 pos: (%F, %F)\n" "e1 pos: (%F, %F)\n"
"e1 rot: %F\n" "e1 rot: %F\n"
); );
String text = string_format(temp.arena, fmt, String text = StringFormat(temp.arena, fmt,
FMT_FLOAT_P(e0_xf.og.x, 24), FMT_FLOAT_P(e0_xf.og.y, 24), FmtFloatP(e0_xf.og.x, 24), FmtFloatP(e0_xf.og.y, 24),
FMT_FLOAT_P(RotationFromXform(e0_xf), 24), FmtFloatP(RotationFromXform(e0_xf), 24),
FMT_FLOAT_P(e1_xf.og.x, 24), FMT_FLOAT_P(e1_xf.og.y, 24), FmtFloatP(e1_xf.og.x, 24), FmtFloatP(e1_xf.og.y, 24),
FMT_FLOAT_P(RotationFromXform(e1_xf), 24)); FmtFloatP(RotationFromXform(e1_xf), 24));
draw_text(G.render_sig, disp_font, AddVec2(RoundVec2(MulXformV2(G.world_to_ui_xf, VEC2(0, 0))), VEC2(0, offset_px)), text); draw_text(G.render_sig, disp_font, AddVec2(RoundVec2(MulXformV2(G.world_to_ui_xf, VEC2(0, 0))), VEC2(0, offset_px)), text);
@ -1693,7 +1693,7 @@ internal void user_update(P_Window *window)
if (!G.debug_camera) { if (!G.debug_camera) {
__profn("Draw crosshair"); __profn("Draw crosshair");
Vec2 crosshair_pos = G.ui_cursor; Vec2 crosshair_pos = G.ui_cursor;
S_Tag crosshair = sprite_tag_from_path(LIT("sprite/crosshair.ase")); S_Tag crosshair = sprite_tag_from_path(Lit("sprite/crosshair.ase"));
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair); S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair);
Vec2 size = VEC2(t->width, t->height); Vec2 size = VEC2(t->width, t->height);
Xform xf = XformFromTrs(TRS(.t = crosshair_pos, .s = size)); Xform xf = XformFromTrs(TRS(.t = crosshair_pos, .s = size));
@ -1708,7 +1708,7 @@ internal void user_update(P_Window *window)
P_DisableWindoweCursorClip(G.window); P_DisableWindoweCursorClip(G.window);
P_ShowWindowCursor(G.window); P_ShowWindowCursor(G.window);
} else { } else {
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, sprite_tag_from_path(LIT("sprite/crosshair.ase"))); S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, sprite_tag_from_path(Lit("sprite/crosshair.ase")));
Vec2 size = VEC2(t->width, t->height); Vec2 size = VEC2(t->width, t->height);
Rect cursor_clip = RectFromVec2(G.ui_screen_offset, G.ui_size); Rect cursor_clip = RectFromVec2(G.ui_screen_offset, G.ui_size);
cursor_clip.pos = AddVec2(cursor_clip.pos, MulVec2(size, 0.5f)); cursor_clip.pos = AddVec2(cursor_clip.pos, MulVec2(size, 0.5f));
@ -1902,7 +1902,7 @@ internal void user_update(P_Window *window)
Ent *ent = hovered_ent; Ent *ent = hovered_ent;
Vec2 pos = AddVec2(G.ui_cursor, VEC2(15, 15)); Vec2 pos = AddVec2(G.ui_cursor, VEC2(15, 15));
F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); F_Font *font = font_load_async(Lit("font/fixedsys.ttf"), 12.0f);
if (font) { if (font) {
TempArena temp = BeginTempArena(scratch.arena); TempArena temp = BeginTempArena(scratch.arena);
@ -1927,104 +1927,104 @@ internal void user_update(P_Window *window)
if (G.debug_draw) { if (G.debug_draw) {
__profn("Draw debug info"); __profn("Draw debug info");
F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); F_Font *font = font_load_async(Lit("font/fixedsys.ttf"), 12.0f);
if (font) { if (font) {
TempArena temp = BeginTempArena(scratch.arena); TempArena temp = BeginTempArena(scratch.arena);
String text = ZI; String text = ZI;
text.text = PushDry(temp.arena, u8); text.text = PushDry(temp.arena, u8);
#if BB_DebugIsEnabled #if BB_DebugIsEnabled
text.len += string_copy(temp.arena, LIT("(bitbuff debug enabled)")).len; text.len += CopyString(temp.arena, Lit("(bitbuff debug enabled)")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
#endif #endif
text.len += string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved)).len; text.len += StringFormat(temp.arena, Lit("blended world entities: %F/%F"), FmtUint(G.ss_blended->num_ents_allocated), FmtUint(G.ss_blended->num_ents_reserved)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("blended world tick: %F"), FMT_UINT(G.ss_blended->tick)).len; text.len += StringFormat(temp.arena, Lit("blended world tick: %F"), FmtUint(G.ss_blended->tick)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("blended world time: %F"), FMT_FLOAT(SecondsFromNs(G.ss_blended->sim_time_ns))).len; text.len += StringFormat(temp.arena, Lit("blended world time: %F"), FmtFloat(SecondsFromNs(G.ss_blended->sim_time_ns))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("average local sim publish dt: %F"), FMT_FLOAT(SecondsFromNs(G.average_local_to_user_snapshot_publish_dt_ns))).len; text.len += StringFormat(temp.arena, Lit("average local sim publish dt: %F"), FmtFloat(SecondsFromNs(G.average_local_to_user_snapshot_publish_dt_ns))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("local sim last known tick: %F"), FMT_UINT(G.local_sim_last_known_tick)).len; text.len += StringFormat(temp.arena, Lit("local sim last known tick: %F"), FmtUint(G.local_sim_last_known_tick)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("local sim last known time: %F"), FMT_FLOAT(SecondsFromNs(G.local_sim_last_known_time_ns))).len; text.len += StringFormat(temp.arena, Lit("local sim last known time: %F"), FmtFloat(SecondsFromNs(G.local_sim_last_known_time_ns))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("local sim predicted time: %F"), FMT_FLOAT(SecondsFromNs(G.local_sim_predicted_time_ns))).len; text.len += StringFormat(temp.arena, Lit("local sim predicted time: %F"), FmtFloat(SecondsFromNs(G.local_sim_predicted_time_ns))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("render time target: %F"), FMT_FLOAT(SecondsFromNs(G.render_time_target_ns))).len; text.len += StringFormat(temp.arena, Lit("render time target: %F"), FmtFloat(SecondsFromNs(G.render_time_target_ns))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("render time: %F"), FMT_FLOAT(SecondsFromNs(G.render_time_ns))).len; text.len += StringFormat(temp.arena, Lit("render time: %F"), FmtFloat(SecondsFromNs(G.render_time_ns))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("local player: [%F]"), FMT_UID(local_player->id.uid)).len; text.len += StringFormat(temp.arena, Lit("local player: [%F]"), FmtUid(local_player->id.uid)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
Vec2 world_cursor = G.world_cursor; Vec2 world_cursor = G.world_cursor;
text.len += string_format(temp.arena, LIT("cursor world: %F, %F"), FMT_FLOAT(world_cursor.x), FMT_FLOAT(world_cursor.y)).len; text.len += StringFormat(temp.arena, Lit("cursor world: %F, %F"), FmtFloat(world_cursor.x), FmtFloat(world_cursor.y)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
Vec2I32 world_tile_cursor = sim_world_tile_index_from_pos(world_cursor); Vec2I32 world_tile_cursor = sim_world_tile_index_from_pos(world_cursor);
text.len += string_format(temp.arena, LIT("cursor world tile: %F, %F"), FMT_SINT(world_tile_cursor.x), FMT_SINT(world_tile_cursor.y)).len; text.len += StringFormat(temp.arena, Lit("cursor world tile: %F, %F"), FmtSint(world_tile_cursor.x), FmtSint(world_tile_cursor.y)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
Vec2I32 local_tile_cursor = sim_local_tile_index_from_world_tile_index(world_tile_cursor); Vec2I32 local_tile_cursor = sim_local_tile_index_from_world_tile_index(world_tile_cursor);
text.len += string_format(temp.arena, LIT("cursor local tile: %F, %F"), FMT_SINT(local_tile_cursor.x), FMT_SINT(local_tile_cursor.y)).len; text.len += StringFormat(temp.arena, Lit("cursor local tile: %F, %F"), FmtSint(local_tile_cursor.x), FmtSint(local_tile_cursor.y)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
Vec2I32 tile_chunk_cursor = sim_tile_chunk_index_from_world_tile_index(world_tile_cursor); Vec2I32 tile_chunk_cursor = sim_tile_chunk_index_from_world_tile_index(world_tile_cursor);
text.len += string_format(temp.arena, LIT("cursor tile chunk: %F, %F"), FMT_SINT(tile_chunk_cursor.x), FMT_SINT(tile_chunk_cursor.y)).len; text.len += StringFormat(temp.arena, Lit("cursor tile chunk: %F, %F"), FmtSint(tile_chunk_cursor.x), FmtSint(tile_chunk_cursor.y)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Network read: %F mbit/s"), FMT_FLOAT((f64)G.net_bytes_read.last_second * 8 / 1000 / 1000)).len; text.len += StringFormat(temp.arena, Lit("Network read: %F mbit/s"), FmtFloat((f64)G.net_bytes_read.last_second * 8 / 1000 / 1000)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Network write: %F mbit/s"), FMT_FLOAT((f64)G.net_bytes_sent.last_second * 8 / 1000 / 1000)).len; text.len += StringFormat(temp.arena, Lit("Network write: %F mbit/s"), FmtFloat((f64)G.net_bytes_sent.last_second * 8 / 1000 / 1000)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Ping (real): %F ms"), FMT_FLOAT(SecondsFromNs(local_player->player_last_rtt_ns) * 1000)).len; text.len += StringFormat(temp.arena, Lit("Ping (real): %F ms"), FmtFloat(SecondsFromNs(local_player->player_last_rtt_ns) * 1000)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Ping (average): %F ms"), FMT_FLOAT(local_player->player_average_rtt_seconds * 1000)).len; text.len += StringFormat(temp.arena, Lit("Ping (average): %F ms"), FmtFloat(local_player->player_average_rtt_seconds * 1000)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Memory committed: %F MiB"), FMT_FLOAT((f64)GetGstat(GSTAT_MEMORY_COMMITTED) / 1024 / 1024)).len; text.len += StringFormat(temp.arena, Lit("Memory committed: %F MiB"), FmtFloat((f64)GetGstat(GSTAT_MEMORY_COMMITTED) / 1024 / 1024)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Virtual memory reserved: %F TiB"), FMT_FLOAT((f64)GetGstat(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024)).len; text.len += StringFormat(temp.arena, Lit("Virtual memory reserved: %F TiB"), FmtFloat((f64)GetGstat(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Arenas allocated: %F"), FMT_UINT(GetGstat(GSTAT_NUM_ARENAS))).len; text.len += StringFormat(temp.arena, Lit("Arenas allocated: %F"), FmtUint(GetGstat(GSTAT_NUM_ARENAS))).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Video memory (GPU): %F MiB"), FMT_FLOAT((f64)vram.local_used / 1024 / 1024)).len; text.len += StringFormat(temp.arena, Lit("Video memory (GPU): %F MiB"), FmtFloat((f64)vram.local_used / 1024 / 1024)).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Video memory (shared): %F MiB"), FMT_FLOAT((f64)vram.non_local_used / 1024 / 1024)).len; text.len += StringFormat(temp.arena, Lit("Video memory (shared): %F MiB"), FmtFloat((f64)vram.non_local_used / 1024 / 1024)).len;
//text.len += string_copy(temp.arena, LIT("\n")).len; //text.len += CopyString(temp.arena, Lit("\n")).len;
//text.len += string_copy(temp.arena, LIT("\n")).len; //text.len += CopyString(temp.arena, Lit("\n")).len;
#if RtcIsEnabled #if RtcIsEnabled
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_copy(temp.arena, LIT("\n")).len; text.len += CopyString(temp.arena, Lit("\n")).len;
text.len += string_format(temp.arena, LIT("Debug steps: %F"), FMT_UINT(GetGstat(GSTAT_DEBUG_STEPS))).len; text.len += StringFormat(temp.arena, Lit("Debug steps: %F"), FmtUint(GetGstat(GSTAT_DEBUG_STEPS))).len;
//text.len += string_copy(temp.arena, LIT("\n")).len; //text.len += CopyString(temp.arena, Lit("\n")).len;
#endif #endif
//draw_text(G.render_sig, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved))); //draw_text(G.render_sig, font, pos, StringFormat(temp.arena, Lit("blended world entities: %F/%F"), FmtUint(G.ss_blended->num_ents_allocated), FmtUint(G.ss_blended->num_ents_reserved)));
//draw_text(G.render_sig, font, pos, text); //draw_text(G.render_sig, font, pos, text);
Vec2 pos = VEC2(10, G.ui_size.y); Vec2 pos = VEC2(10, G.ui_size.y);
@ -2184,7 +2184,7 @@ internal P_JobDef(local_sim_job, _)
(UNUSED)_; (UNUSED)_;
#if 0 #if 0
struct host_listen_address local_listen_addr = host_listen_address_from_local_name(LIT("LOCAL_SIM")); struct host_listen_address local_listen_addr = host_listen_address_from_local_name(Lit("LOCAL_SIM"));
struct host_listen_address net_listen_addr = host_listen_address_from_net_port(12345); struct host_listen_address net_listen_addr = host_listen_address_from_net_port(12345);
//N_Host *host = host_alloc(); //N_Host *host = host_alloc();
/* TODO: Host system should allocate & copy string stored in local_listen_addr */ /* TODO: Host system should allocate & copy string stored in local_listen_addr */
@ -2591,19 +2591,19 @@ internal P_JobDef(local_sim_job, _)
#if 0 #if 0
DEBUGBREAKABLE; DEBUGBREAKABLE;
P_LogDebugF("*************************************************"); P_LogDebugF("*************************************************");
P_LogDebugF("local_client->last_tick: %F", FMT_UINT(local_client->last_tick)); P_LogDebugF("local_client->last_tick: %F", FmtUint(local_client->last_tick));
P_LogDebugF("master_sim_predicted_time_ns: %F", FMT_SINT(master_sim_predicted_time_ns)); P_LogDebugF("master_sim_predicted_time_ns: %F", FmtSint(master_sim_predicted_time_ns));
P_LogDebugF("tick_progress: %F", FMT_FLOAT(tick_progress)); P_LogDebugF("tick_progress: %F", FmtFloat(tick_progress));
P_LogDebugF("sim_publish_timescale: %F", FMT_FLOAT(sim_publish_timescale)); P_LogDebugF("sim_publish_timescale: %F", FmtFloat(sim_publish_timescale));
P_LogDebugF("last_tick_from_master_received_at_ns: %F", FMT_SINT(last_tick_from_master_received_at_ns)); P_LogDebugF("last_tick_from_master_received_at_ns: %F", FmtSint(last_tick_from_master_received_at_ns));
P_LogDebugF("average_master_receive_dt_ns: %F", FMT_SINT(average_master_receive_dt_ns)); P_LogDebugF("average_master_receive_dt_ns: %F", FmtSint(average_master_receive_dt_ns));
P_LogDebugF("next_tick_expected_ns: %F", FMT_SINT(next_tick_expected_ns)); P_LogDebugF("next_tick_expected_ns: %F", FmtSint(next_tick_expected_ns));
P_LogDebugF("master_blend_time_target_ns: %F", FMT_SINT(master_blend_time_target_ns)); P_LogDebugF("master_blend_time_target_ns: %F", FmtSint(master_blend_time_target_ns));
P_LogDebugF("blend_time_target_diff_ns: %F", FMT_SINT(blend_time_target_diff_ns)); P_LogDebugF("blend_time_target_diff_ns: %F", FmtSint(blend_time_target_diff_ns));
P_LogDebugF("master_blend_time_ns: %F", FMT_SINT(master_blend_time_ns)); P_LogDebugF("master_blend_time_ns: %F", FmtSint(master_blend_time_ns));
P_LogDebugF("left_snapshot->tick: %F", FMT_UINT(left_snapshot->tick)); P_LogDebugF("left_snapshot->tick: %F", FmtUint(left_snapshot->tick));
P_LogDebugF("right_snapshot->tick: %F", FMT_UINT(right_snapshot->tick)); P_LogDebugF("right_snapshot->tick: %F", FmtUint(right_snapshot->tick));
P_LogDebugF("master_ss->tick: %F", FMT_UINT(master_ss->tick)); P_LogDebugF("master_ss->tick: %F", FmtUint(master_ss->tick));
#endif #endif
} }

View File

@ -31,7 +31,7 @@ internal P_ExitFuncDef(watch_shutdown);
void watch_startup(void) void watch_startup(void)
{ {
G.watch = P_AllocWatch(LIT("./")); G.watch = P_AllocWatch(Lit("./"));
G.watch_events_arena = AllocArena(Gibi(64)); G.watch_events_arena = AllocArena(Gibi(64));
@ -65,7 +65,7 @@ void watch_register_callback(watch_callback *callback)
if (G.num_watch_callbacks < countof(G.watch_callbacks)) { if (G.num_watch_callbacks < countof(G.watch_callbacks)) {
G.watch_callbacks[G.num_watch_callbacks++] = callback; G.watch_callbacks[G.num_watch_callbacks++] = callback;
} else { } else {
P_Panic(LIT("Max resource watch callbacks reached")); P_Panic(Lit("Max resource watch callbacks reached"));
} }
} }
P_Unlock(&lock); P_Unlock(&lock);
@ -77,8 +77,8 @@ internal P_JobDef(watch_monitor_job, _)
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
String ignored[] = { String ignored[] = {
LIT(".vs"), Lit(".vs"),
LIT(".git") Lit(".git")
}; };
while (!Atomic32Fetch(&G.watch_shutdown)) { while (!Atomic32Fetch(&G.watch_shutdown)) {
@ -91,14 +91,14 @@ internal P_JobDef(watch_monitor_job, _)
String name_src = info->name; String name_src = info->name;
b32 ignore = 0; b32 ignore = 0;
for (u32 i = 0; i < countof(ignored); ++i) { for (u32 i = 0; i < countof(ignored); ++i) {
if (string_starts_with(name_src, ignored[i])) { if (StringStartsWith(name_src, ignored[i])) {
ignore = 1; ignore = 1;
break; break;
} }
} }
if (!ignore) { if (!ignore) {
struct watch_event *e = PushStruct(G.watch_events_arena, struct watch_event); struct watch_event *e = PushStruct(G.watch_events_arena, struct watch_event);
e->name = string_copy(G.watch_events_arena, name_src); e->name = CopyString(G.watch_events_arena, name_src);
if (G.last_watch_event) { if (G.last_watch_event) {
G.last_watch_event->next = e; G.last_watch_event->next = e;
} else { } else {
@ -160,7 +160,7 @@ internal P_JobDef(watch_dispatcher_job, _)
P_Lock lock = P_LockE(&G.watch_dispatcher_mutex); P_Lock lock = P_LockE(&G.watch_dispatcher_mutex);
for (struct watch_event *src_event = G.first_watch_event; src_event; src_event = src_event->next) { for (struct watch_event *src_event = G.first_watch_event; src_event; src_event = src_event->next) {
struct watch_event *e = PushStruct(scratch.arena, struct watch_event); struct watch_event *e = PushStruct(scratch.arena, struct watch_event);
e->name = string_copy(scratch.arena, src_event->name); e->name = CopyString(scratch.arena, src_event->name);
if (last_watch_event) { if (last_watch_event) {
last_watch_event->next = e; last_watch_event->next = e;
} else { } else {
@ -189,16 +189,16 @@ internal P_JobDef(watch_dispatcher_job, _)
/* Run callbacks */ /* Run callbacks */
{ {
Dict *dedup_dict = dict_init(scratch.arena, WATCH_DISPATCHER_DEDUP_DICT_BINS); Dict *dedup_dict = InitDict(scratch.arena, WATCH_DISPATCHER_DEDUP_DICT_BINS);
for (struct watch_event *e = first_watch_event; e; e = e->next) { for (struct watch_event *e = first_watch_event; e; e = e->next) {
__profn("Dispatch"); __profn("Dispatch");
/* Do not run callbacks for the same file more than once */ /* Do not run callbacks for the same file more than once */
b32 skip = 0; b32 skip = 0;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, e->name); u64 hash = HashFnv64(Fnv64Basis, e->name);
if (dict_get(dedup_dict, hash) == 1) { if (DictValueFromHash(dedup_dict, hash) == 1) {
skip = 1; skip = 1;
} else { } else {
dict_set(scratch.arena, dedup_dict, hash, 1); SetDictValue(scratch.arena, dedup_dict, hash, 1);
} }
if (!skip) { if (!skip) {
struct watch_callback_job_sig sig = ZI; struct watch_callback_job_sig sig = ZI;