struct typedef progress

This commit is contained in:
jacob 2025-07-28 19:49:46 -05:00
parent 06e69945c9
commit 8f96d89f35
89 changed files with 3063 additions and 2956 deletions

View File

@ -867,7 +867,7 @@ void OnBuild(StringList cli_args)
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/sound/sound.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/draw/draw.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/inc/inc.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/host/host.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/net/net.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/asset_cache/asset_cache.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/mixer/mixer.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/settings/settings.c"), D_TagKind_File));

View File

@ -15,7 +15,7 @@
#include "../asset_cache/asset_cache.h"
#include "../mixer/mixer.h"
#include "../settings/settings.h"
#include "../host/host.h"
#include "../net/net.h"
#include "../resource/resource.h"
#include "../playback/playback.h"

View File

@ -1,20 +1,20 @@
GLOBAL struct {
struct arena *arena;
struct string write_path;
Arena *arena;
String write_path;
} G = ZI, DEBUG_ALIAS(G, G_app);
/* ========================== *
* Write directory
* ========================== */
INTERNAL struct string initialize_write_directory(struct arena *arena, struct string write_dir)
INTERNAL String initialize_write_directory(Arena *arena, String write_dir)
{
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
/* Create write path */
struct string base_write_dir = sys_get_write_path(scratch.arena);
struct string write_path_fmt = base_write_dir.len > 0 ? LIT("%F/%F/") : LIT("%F%F/");
struct string write_path = string_format(
String base_write_dir = sys_get_write_path(scratch.arena);
String write_path_fmt = base_write_dir.len > 0 ? LIT("%F/%F/") : LIT("%F%F/");
String write_path = string_format(
arena,
write_path_fmt,
FMT_STR(base_write_dir),
@ -32,7 +32,7 @@ INTERNAL struct string initialize_write_directory(struct arena *arena, struct st
return write_path;
}
struct string app_write_path_cat(struct arena *arena, struct string filename)
String app_write_path_cat(Arena *arena, String filename)
{
return string_cat(arena, G.write_path, filename);
}
@ -45,7 +45,7 @@ INTERNAL struct sys_window_settings default_window_settings(struct sys_window *w
{
__prof;
struct v2 monitor_size = sys_window_get_monitor_size(window);
V2 monitor_size = sys_window_get_monitor_size(window);
i32 width = 1280;
i32 height = math_round_to_int(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
@ -66,8 +66,8 @@ INTERNAL struct sys_window_settings default_window_settings(struct sys_window *w
* ========================== */
struct app_arg {
struct string key;
struct string value;
String key;
String value;
struct app_arg *next;
};
@ -78,7 +78,7 @@ struct app_arg_list {
};
/* TODO: Remove this and do real argument parsing */
INTERNAL struct app_arg_list parse_args(struct arena *arena, struct string args_str)
INTERNAL struct app_arg_list parse_args(Arena *arena, String args_str)
{
struct app_arg_list res = ZI;
i64 mode = 0;
@ -118,8 +118,8 @@ INTERNAL struct app_arg_list parse_args(struct arena *arena, struct string args_
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) {
struct string key = string_copy(arena, STRING(key_end - key_start, args_str.text + key_start));
struct string value = string_copy(arena, STRING(value_end - value_start, args_str.text + value_start));
String key = string_copy(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));
struct app_arg *arg = arena_push(arena, struct app_arg);
arg->key = key;
arg->value = value;
@ -146,18 +146,18 @@ INTERNAL struct app_arg_list parse_args(struct arena *arena, struct string args_
* Entry point
* ========================== */
void sys_app_startup(struct string args_str)
void sys_app_startup(String args_str)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct app_arg_list args = parse_args(scratch.arena, args_str);
struct string logfile_name = LIT("log.log");
struct string settings_file_name = LIT("settings.txt");
struct string connect_address = ZI;
String logfile_name = LIT("log.log");
String settings_file_name = LIT("settings.txt");
String connect_address = ZI;
for (struct app_arg *arg = args.first; arg; arg = arg->next) {
struct string key = arg->key;
struct string value = arg->value;
String key = arg->key;
String value = arg->value;
if (string_eq(key, LIT("log"))) {
logfile_name = value;
} else if (string_eq(key, LIT("settings"))) {
@ -194,10 +194,10 @@ void sys_app_startup(struct string args_str)
/* Startup logging */
{
struct arena_temp temp = arena_temp_begin(scratch.arena);
TempArena temp = arena_temp_begin(scratch.arena);
struct string logfile_dir = string_cat(temp.arena, G.write_path, LIT("logs/"));
struct string logfile_path = string_cat(temp.arena, logfile_dir, logfile_name);
String logfile_dir = string_cat(temp.arena, G.write_path, LIT("logs/"));
String logfile_path = string_cat(temp.arena, logfile_dir, logfile_name);
sys_mkdir(logfile_dir);
log_startup(logfile_path);
@ -212,22 +212,22 @@ void sys_app_startup(struct string args_str)
#if 0
/* Read window settings from file */
{
struct arena_temp temp = arena_temp_begin(scratch.arena);
TempArena temp = arena_temp_begin(scratch.arena);
struct sys_window_settings window_settings = ZI;
struct string settings_path = app_write_path_cat(temp.arena, settings_file_name);
String settings_path = app_write_path_cat(temp.arena, settings_file_name);
logf_info("Looking for settings file \"%F\"", FMT_STR(settings_path));
if (sys_is_file(settings_path)) {
logf_info("Settings file found");
struct sys_file settings_file = sys_file_open_read(settings_path);
struct string file_data = sys_file_read_all(temp.arena, settings_file);
String file_data = sys_file_read_all(temp.arena, settings_file);
sys_file_close(settings_file);
logf_info("Deserializing settings file data: %F", FMT_STR(file_data));
struct string error = ZI;
String error = ZI;
struct sys_window_settings *res = settings_deserialize(temp.arena, file_data, &error);
if (error.len > 0) {
logf_info("Failed to load settings file with error - %F", FMT_STR(error));
struct string msg = string_format(temp.arena,
String msg = string_format(temp.arena,
LIT(
"Failed to loading settings file \"%F\":\n"
"------------\n"
@ -258,18 +258,18 @@ void sys_app_startup(struct string args_str)
gp_startup();
/* Subsystems */
struct host_startup_receipt host_sr = host_startup();
struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup();
struct ttf_startup_receipt ttf_sr = ttf_startup();
struct font_startup_receipt font_sr = font_startup(&asset_cache_sr, &ttf_sr);
N_StartupReceipt host_sr = host_startup();
AC_StartupReceipt asset_cache_sr = asset_cache_startup();
TTF_StartupReceipt ttf_sr = ttf_startup();
F_StartupReceipt font_sr = font_startup(&asset_cache_sr, &ttf_sr);
struct sprite_startup_receipt sprite_sr = sprite_startup();
struct mixer_startup_receipt mixer_sr = mixer_startup();
M_StartupReceipt mixer_sr = mixer_startup();
struct sound_startup_receipt sound_sr = sound_startup(&asset_cache_sr);
struct draw_startup_receipt draw_sr = draw_startup(&font_sr);
D_StartupReceipt draw_sr = draw_startup(&font_sr);
struct sim_startup_receipt sim_sr = sim_startup();
/* Interface systems */
struct playback_startup_receipt playback_sr = playback_startup(&mixer_sr);
PB_StartupReceipt playback_sr = playback_startup(&mixer_sr);
struct user_startup_receipt user_sr = user_startup(&font_sr, &sprite_sr, &draw_sr, &asset_cache_sr, &sound_sr, &mixer_sr, &host_sr, &sim_sr, connect_address);
(UNUSED)user_sr;
@ -279,12 +279,12 @@ void sys_app_startup(struct string args_str)
/* Write window settings to file */
{
__profn("Write settings file");
struct arena_temp temp = arena_temp_begin(scratch.arena);
TempArena temp = arena_temp_begin(scratch.arena);
struct string window_settings_path = app_write_path_cat(temp.arena, settings_file_name);
String window_settings_path = app_write_path_cat(temp.arena, settings_file_name);
struct sys_window_settings settings = sys_window_get_settings(window);
struct string str = settings_serialize(temp.arena, &settings);
String str = settings_serialize(temp.arena, &settings);
logf_info("Serialized window settings: %F", FMT_STR(str));
logf_info("Writing settings file to path \"%F\"", FMT_STR(window_settings_path));

View File

@ -1 +1 @@
struct string app_write_path_cat(struct arena *arena, struct string filename);
String app_write_path_cat(Arena *arena, String filename);

View File

@ -172,7 +172,7 @@ INTERNAL u32 reverse_bits(u32 v, u32 bit_count)
}
}
INTERNAL struct huffman huffman_init(struct arena *arena, u32 max_code_bits, u32 *bl_counts, u32 bl_counts_count)
INTERNAL struct huffman huffman_init(Arena *arena, u32 max_code_bits, u32 *bl_counts, u32 bl_counts_count)
{
__prof;
@ -231,7 +231,7 @@ INTERNAL u16 huffman_decode(struct huffman *huffman, struct huff_bb *bb)
INTERNAL void inflate(u8 *dst, u8 *encoded)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
__prof;
struct huff_bb bb = { .data = encoded };
@ -271,7 +271,7 @@ INTERNAL void inflate(u8 *dst, u8 *encoded)
case BLOCK_TYPE_COMPRESSED_FIXED:
case BLOCK_TYPE_COMPRESSED_DYNAMIC: {
struct arena_temp temp = arena_temp_begin(scratch.arena);
TempArena temp = arena_temp_begin(scratch.arena);
u32 lit_len_dist_table[512] = ZI;
u32 hlit;
u32 hdist;
@ -440,9 +440,9 @@ PACK(struct frame_header {
u32 chunks_new;
});
INTERNAL void push_error_copy_msg(struct arena *arena, struct ase_error_list *list, struct string msg_src)
INTERNAL void push_error_copy_msg(Arena *arena, Ase_ErrorList *list, String msg_src)
{
struct ase_error *e = arena_push(arena, struct ase_error);
Ase_Error *e = arena_push(arena, Ase_Error);
e->msg = string_copy(arena, msg_src);
if (!list->first) {
list->first = e;
@ -463,7 +463,7 @@ struct layer {
u16 child_level;
u16 blend_mode;
u8 opacity;
struct string name;
String name;
u32 tileset_index;
u32 index;
@ -544,15 +544,15 @@ INTERNAL void make_image_dimensions_squareish(struct ase_header *header, u32 *fr
}
}
struct ase_decode_image_result ase_decode_image(struct arena *arena, struct string encoded)
Ase_DecodedImage ase_decode_image(Arena *arena, String encoded)
{
__prof;
struct arena_temp scratch = scratch_begin(arena);
struct ase_decode_image_result res = ZI;
TempArena scratch = scratch_begin(arena);
Ase_DecodedImage res = ZI;
struct bitbuff bb = bitbuff_from_string(encoded);
struct bitbuff_reader br = br_from_bitbuff_no_debug(&bb);
Bitbuff bb = bitbuff_from_string(encoded);
BitbuffReader br = br_from_bitbuff_no_debug(&bb);
struct ase_header ase_header;
br_read_bytes(&br, STRING_FROM_STRUCT(&ase_header));
@ -562,7 +562,7 @@ struct ase_decode_image_result ase_decode_image(struct arena *arena, struct stri
}
if (ase_header.color_depth != 32) {
struct string msg = string_format(scratch.arena,
String msg = string_format(scratch.arena,
LIT("Only 32 bit rgba color mode is supported (got %F)"),
FMT_UINT(ase_header.color_depth));
push_error_copy_msg(arena, &res.errors, msg);
@ -641,7 +641,7 @@ struct ase_decode_image_result ase_decode_image(struct arena *arena, struct stri
br_seek_bytes(&br, sizeof(u8) * 3);
u16 str_len = br_read_ubits(&br, 16);
layer->name = (struct string) { str_len, arena_push_array_no_zero(scratch.arena, u8, str_len) };
layer->name = (String) { str_len, arena_push_array_no_zero(scratch.arena, u8, str_len) };
br_read_bytes(&br, layer->name);
if (layer->type == 2) {
@ -806,14 +806,14 @@ abort:
* Decode sheet
* ========================== */
struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct string encoded)
Ase_DecodedSheet ase_decode_sheet(Arena *arena, String encoded)
{
__prof;
struct ase_decode_sheet_result res = ZI;
Ase_DecodedSheet res = ZI;
struct bitbuff bb = bitbuff_from_string(encoded);
struct bitbuff_reader br = br_from_bitbuff_no_debug(&bb);
Bitbuff bb = bitbuff_from_string(encoded);
BitbuffReader br = br_from_bitbuff_no_debug(&bb);
struct ase_header ase_header;
br_read_bytes(&br, STRING_FROM_STRUCT(&ase_header));
@ -827,13 +827,13 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
make_image_dimensions_squareish(&ase_header, &frames_x, &frames_y, &image_width, &image_height);
u32 num_frames = 0;
struct ase_frame *frame_head = 0;
Ase_Frame *frame_head = 0;
u32 num_spans = 0;
struct ase_span *span_head = 0;
Ase_Span *span_head = 0;
u32 num_slice_keys = 0;
struct ase_slice_key *slice_key_head = 0;
Ase_SliceKey *slice_key_head = 0;
/* Iterate frames */
for (u16 i = 0; i < ase_header.frames; ++i) {
@ -846,7 +846,7 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
num_chunks = frame_header.chunks_old;
}
struct ase_frame *frame = arena_push(arena, struct ase_frame);
Ase_Frame *frame = arena_push(arena, Ase_Frame);
frame->next = frame_head;
frame_head = frame;
@ -885,7 +885,7 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
br_seek_bytes(&br, 8);
for (u16 k = 0; k < frame_span_count; ++k) {
struct ase_span *span = arena_push(arena, struct ase_span);
Ase_Span *span = arena_push(arena, Ase_Span);
span->next = span_head;
span_head = span;
@ -894,7 +894,7 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
br_seek_bytes(&br, 13);
u16 str_len = br_read_ubits(&br, 16);
span->name = (struct string) { str_len, arena_push_array_no_zero(arena, u8, str_len) };
span->name = (String) { str_len, arena_push_array_no_zero(arena, u8, str_len) };
br_read_bytes(&br, span->name);
++num_spans;
@ -903,7 +903,7 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
} break;
case CHUNK_TYPE_SLICE: {
struct ase_slice_key *slice_key = arena_push(arena, struct ase_slice_key);
Ase_SliceKey *slice_key = arena_push(arena, Ase_SliceKey);
slice_key->next = slice_key_head;
slice_key_head = slice_key;
@ -914,11 +914,11 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
br_seek_bytes(&br, 4);
u16 str_len = br_read_ubits(&br, 16);
slice_key->name = (struct string) { str_len, arena_push_array_no_zero(arena, u8, str_len) };
slice_key->name = (String) { str_len, arena_push_array_no_zero(arena, u8, str_len) };
br_read_bytes(&br, slice_key->name);
for (u32 k = 0; k < num_slices; ++k) {
struct ase_slice *slice = arena_push(arena, struct ase_slice);
Ase_Slice *slice = arena_push(arena, Ase_Slice);
slice->next = slice_key->slice_head;
slice_key->slice_head = slice;
@ -960,8 +960,8 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri
/* ASSERT all data was read */
ASSERT(br_num_bytes_left(&br) == 0);
res.image_size = V2(image_width, image_height);
res.frame_size = V2(frame_width, frame_height);
res.image_size = V2FromXY(image_width, image_height);
res.frame_size = V2FromXY(frame_width, frame_height);
res.num_frames = num_frames;
res.num_spans = num_spans;
res.num_slice_keys = num_slice_keys;

View File

@ -1,65 +1,73 @@
struct ase_error {
struct string msg;
struct ase_error *next;
typedef struct Ase_Error Ase_Error;
struct Ase_Error {
String msg;
Ase_Error *next;
};
struct ase_error_list {
typedef struct Ase_ErrorList Ase_ErrorList;
struct Ase_ErrorList {
u64 count;
struct ase_error *first;
struct ase_error *last;
Ase_Error *first;
Ase_Error *last;
};
struct ase_slice {
typedef struct Ase_Slice Ase_Slice;
struct Ase_Slice {
u32 start;
i32 x1;
i32 y1;
i32 x2;
i32 y2;
struct ase_slice *next;
Ase_Slice *next;
};
struct ase_slice_key {
struct string name;
typedef struct Ase_SliceKey Ase_SliceKey;
struct Ase_SliceKey {
String name;
u32 num_slices;
struct ase_slice *slice_head;
struct ase_slice_key *next;
Ase_Slice *slice_head;
Ase_SliceKey *next;
};
struct ase_span {
struct string name;
typedef struct Ase_Span Ase_Span;
struct Ase_Span {
String name;
u32 start;
u32 end;
struct ase_span *next;
Ase_Span *next;
};
struct ase_frame {
typedef struct Ase_Frame Ase_Frame;
struct Ase_Frame {
u32 index;
u32 x1;
u32 y1;
u32 x2;
u32 y2;
f64 duration;
struct ase_frame *next;
Ase_Frame *next;
};
struct ase_decode_image_result {
struct image_rgba image;
struct ase_error_list errors;
typedef struct Ase_DecodedImage Ase_DecodedImage;
struct Ase_DecodedImage {
ImageDataRgba image;
Ase_ErrorList errors;
b32 success;
};
struct ase_decode_sheet_result {
struct v2 image_size;
struct v2 frame_size;
typedef struct Ase_DecodedSheet Ase_DecodedSheet;
struct Ase_DecodedSheet {
V2 image_size;
V2 frame_size;
u32 num_frames;
u32 num_spans;
u32 num_slice_keys;
struct ase_frame *frame_head;
struct ase_span *span_head;
struct ase_slice_key *slice_key_head;
struct ase_error_list errors;
Ase_Frame *frame_head;
Ase_Span *span_head;
Ase_SliceKey *slice_key_head;
Ase_ErrorList errors;
b32 success;
};
struct ase_decode_image_result ase_decode_image(struct arena *arena, struct string encoded);
struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct string encoded);
Ase_DecodedImage ase_decode_image(Arena *arena, String encoded);
Ase_DecodedSheet ase_decode_sheet(Arena *arena, String encoded);

View File

@ -7,15 +7,15 @@
GLOBAL struct {
struct snc_mutex lookup_mutex;
struct asset lookup[ASSET_LOOKUP_TABLE_CAPACITY];
AC_Asset lookup[ASSET_LOOKUP_TABLE_CAPACITY];
u64 num_assets;
struct snc_mutex store_mutex;
struct arena *store_arena;
Arena *store_arena;
#if RTC
/* Array of len `num_assets` pointing into populated entries of `lookup`. */
struct asset *dbg_table[ASSET_LOOKUP_TABLE_CAPACITY];
AC_Asset *dbg_table[ASSET_LOOKUP_TABLE_CAPACITY];
u64 dbg_table_count;
struct snc_mutex dbg_table_mutex;
#endif
@ -25,12 +25,12 @@ GLOBAL struct {
* Startup
* ========================== */
struct asset_cache_startup_receipt asset_cache_startup(void)
AC_StartupReceipt asset_cache_startup(void)
{
__prof;
/* Init store */
G.store_arena = arena_alloc(GIBI(64));
return (struct asset_cache_startup_receipt) { 0 };
return (AC_StartupReceipt) { 0 };
}
/* ========================== *
@ -44,7 +44,7 @@ INTERNAL void refresh_dbg_table(void)
MEMZERO_ARRAY(G.dbg_table);
G.dbg_table_count = 0;
for (u64 i = 0; i < countof(G.lookup); ++i) {
struct asset *asset = &G.lookup[i];
AC_Asset *asset = &G.lookup[i];
if (asset->hash != 0) {
G.dbg_table[G.dbg_table_count++] = asset;
}
@ -55,14 +55,14 @@ INTERNAL void refresh_dbg_table(void)
/* Returns first matching slot or first empty slot if not found.
* Check returned slot->hash != 0 for presence. */
INTERNAL struct asset *asset_cache_get_slot_locked(struct snc_lock *lock, struct string key, u64 hash)
INTERNAL AC_Asset *asset_cache_get_slot_locked(struct snc_lock *lock, String key, u64 hash)
{
snc_assert_locked_e_or_s(lock, &G.lookup_mutex);
(UNUSED)lock;
u64 index = hash % countof(G.lookup);
for (;;) {
struct asset *slot = &G.lookup[index];
AC_Asset *slot = &G.lookup[index];
if (slot->hash) {
/* Occupied */
if (hash == slot->hash && string_eq(key, slot->key)) {
@ -81,7 +81,7 @@ INTERNAL struct asset *asset_cache_get_slot_locked(struct snc_lock *lock, struct
}
}
u64 asset_cache_hash(struct string key)
u64 asset_cache_hash(String key)
{
/* TODO: Better hash */
return hash_fnv64(HASH_FNV64_BASIS, key);
@ -95,9 +95,9 @@ u64 asset_cache_hash(struct string key)
* inserted the asset into the cache.
*
* */
struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch)
AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch)
{
struct asset *asset = 0;
AC_Asset *asset = 0;
/* Lookup */
{
@ -121,16 +121,16 @@ struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch
if (G.num_assets >= MAX_ASSETS) {
sys_panic(LIT("Max assets reached"));
}
struct string key_stored = ZI;
String key_stored = ZI;
{
/* Copy key to store */
struct asset_cache_store store = asset_cache_store_open();
AC_Store store = asset_cache_store_open();
key_stored = string_copy(store.arena, key);
asset_cache_store_close(&store);
}
/* Initialize asset data */
logf_info("Inserting asset cache entry for \"%F\"", FMT_STR(key));
*asset = (struct asset) {
*asset = (AC_Asset) {
.status = ASSET_STATUS_UNINITIALIZED,
.hash = hash,
.key = key_stored
@ -155,13 +155,13 @@ struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch
* ========================== */
/* Call this once asset job has been created */
void asset_cache_mark_loading(struct asset *asset)
void asset_cache_mark_loading(AC_Asset *asset)
{
asset->status = ASSET_STATUS_LOADING;
}
/* Call this once asset job has finished */
void asset_cache_mark_ready(struct asset *asset, void *store_data)
void asset_cache_mark_ready(AC_Asset *asset, void *store_data)
{
asset->store_data = store_data;
asset->status = ASSET_STATUS_READY;
@ -172,7 +172,7 @@ void asset_cache_mark_ready(struct asset *asset, void *store_data)
* Job
* ========================== */
void asset_cache_wait(struct asset *asset)
void asset_cache_wait(AC_Asset *asset)
{
snc_counter_wait(&asset->counter);
}
@ -184,7 +184,7 @@ void asset_cache_wait(struct asset *asset)
/* NOTE: At the moment only one global asset store exists, however in the
* future there could be more based on asset lifetime. */
void *asset_cache_get_store_data(struct asset *asset)
void *asset_cache_get_store_data(AC_Asset *asset)
{
if (asset->status == ASSET_STATUS_READY) {
return asset->store_data;
@ -194,17 +194,17 @@ void *asset_cache_get_store_data(struct asset *asset)
}
/* Asset store should be opened to allocate memory to the store arena */
struct asset_cache_store asset_cache_store_open(void)
AC_Store asset_cache_store_open(void)
{
struct snc_lock lock = snc_lock_e(&G.store_mutex);
struct asset_cache_store store = {
AC_Store store = {
.lock = lock,
.arena = G.store_arena
};
return store;
}
void asset_cache_store_close(struct asset_cache_store *store)
void asset_cache_store_close(AC_Store *store)
{
snc_unlock(&store->lock);
}

View File

@ -1,45 +1,48 @@
enum asset_status {
typedef enum AC_Status {
ASSET_STATUS_NONE,
ASSET_STATUS_UNINITIALIZED,
/* TODO: ASSET_STATUS_QUEUED? */
ASSET_STATUS_LOADING,
ASSET_STATUS_READY
};
} AC_Status;
struct asset {
typedef struct AC_Asset AC_Asset;
struct AC_Asset {
/* Managed via asset_cache_touch */
u64 hash;
struct string key;
String key;
struct snc_counter counter;
/* Managed via asset_cache_mark_x functions */
enum asset_status status;
AC_Status status;
/* Accessed via asset_cache_get_data */
void *store_data;
};
struct asset_cache_store {
struct arena *arena;
typedef struct AC_Store AC_Store;
struct AC_Store {
Arena *arena;
/* Internal */
struct snc_lock lock;
};
struct asset_cache_startup_receipt { i32 _; };
struct asset_cache_startup_receipt asset_cache_startup(void);
typedef struct AC_StartupReceipt AC_StartupReceipt;
struct AC_StartupReceipt { i32 _; };
AC_StartupReceipt asset_cache_startup(void);
struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch);
AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch);
void asset_cache_mark_loading(struct asset *asset);
void asset_cache_mark_ready(struct asset *asset, void *store_data);
void asset_cache_mark_loading(AC_Asset *asset);
void asset_cache_mark_ready(AC_Asset *asset, void *store_data);
void asset_cache_wait(struct asset *asset);
void asset_cache_wait(AC_Asset *asset);
void *asset_cache_get_store_data(struct asset *asset);
struct asset_cache_store asset_cache_store_open(void);
void asset_cache_store_close(struct asset_cache_store *store);
void *asset_cache_get_store_data(AC_Asset *asset);
AC_Store asset_cache_store_open(void);
void asset_cache_store_close(AC_Store *store);
u64 asset_cache_hash(struct string key);
u64 asset_cache_hash(String key);

View File

@ -1,7 +1,7 @@
struct scratch_shared g_scratch_shared = ZI;
SharedScratchCtx g_scratch_shared = ZI;
/* NOTE: Application will exit if arena fails to reserve or commit initial memory. */
struct arena *arena_alloc(u64 reserve)
Arena *arena_alloc(u64 reserve)
{
__prof;
reserve += ARENA_HEADER_SIZE;
@ -33,22 +33,22 @@ struct arena *arena_alloc(u64 reserve)
ASSERT(((u64)base & 0xFFF) == 0); /* Base should be 4k aligned */
STATIC_ASSERT(ARENA_HEADER_SIZE <= ARENA_BLOCK_SIZE); /* Header must fit in first block */
STATIC_ASSERT(sizeof(struct arena) <= ARENA_HEADER_SIZE); /* Arena struct must fit in header */
STATIC_ASSERT(sizeof(Arena) <= ARENA_HEADER_SIZE); /* Arena struct must fit in header */
__profalloc(base, ARENA_BLOCK_SIZE);
ASAN_POISON(base + sizeof(struct arena), ARENA_BLOCK_SIZE - sizeof(struct arena));
ASAN_POISON(base + sizeof(Arena), ARENA_BLOCK_SIZE - sizeof(Arena));
gstat_add(GSTAT_MEMORY_COMMITTED, ARENA_BLOCK_SIZE);
gstat_add(GSTAT_NUM_ARENAS, 1);
/* Create & return arena header at beginning of block */
struct arena *arena = (struct arena *)base;
Arena *arena = (Arena *)base;
MEMZERO_STRUCT(arena);
arena->committed = ARENA_BLOCK_SIZE - ARENA_HEADER_SIZE;
arena->reserved = reserved;
return arena;
}
void arena_release(struct arena *arena)
void arena_release(Arena *arena)
{
ASAN_UNPOISON(arena, arena->committed + ARENA_HEADER_SIZE);
__prof;
@ -60,7 +60,7 @@ void arena_release(struct arena *arena)
}
/* NOTE: Application will exit if arena fails to commit memory */
void *arena_push_bytes_no_zero(struct arena *arena, u64 size, u64 align)
void *arena_push_bytes_no_zero(Arena *arena, u64 size, u64 align)
{
ASSERT(align > 0);
ASSERT(!arena->readonly);
@ -112,7 +112,7 @@ void *arena_push_bytes_no_zero(struct arena *arena, u64 size, u64 align)
/* Copies the memory from the source arena into the destination arena,
* replacing old contents. Destination arena will be expanded if necessary. */
void arena_copy_replace(struct arena *dst, struct arena *src)
void arena_copy_replace(Arena *dst, Arena *src)
{
arena_reset(dst);
u64 data_size = src->pos;
@ -121,14 +121,14 @@ void arena_copy_replace(struct arena *dst, struct arena *src)
MEMCPY(data_dst, data_src, data_size);
}
void arena_decommit_unused_blocks(struct arena *arena)
void arena_decommit_unused_blocks(Arena *arena)
{
/* Not implemented */
ASSERT(0);
(UNUSED)arena;
}
void arena_set_readonly(struct arena *arena)
void arena_set_readonly(Arena *arena)
{
#if RTC
arena->readonly = 1;
@ -136,7 +136,7 @@ void arena_set_readonly(struct arena *arena)
memory_set_committed_readonly(arena, arena->committed + ARENA_HEADER_SIZE);
}
void arena_set_readwrite(struct arena *arena)
void arena_set_readwrite(Arena *arena)
{
memory_set_committed_readwrite(arena, arena->committed + ARENA_HEADER_SIZE);
#if RTC

View File

@ -18,7 +18,8 @@
* Equivalent to arena_push but without actually allocating anything or modifying the arena. */
#define arena_push_dry(a, type) (type *)(_arena_push_dry((a), alignof(type)))
struct arena {
typedef struct Arena Arena;
struct Arena {
u64 pos;
u64 committed;
u64 reserved;
@ -27,8 +28,9 @@ struct arena {
#endif
};
struct arena_temp {
struct arena *arena;
typedef struct TempArena TempArena;
struct TempArena {
Arena *arena;
u64 start_pos;
#if RTC
@ -36,27 +38,27 @@ struct arena_temp {
#endif
};
struct arena *arena_alloc(u64 reserve);
void arena_release(struct arena *arena);
void *arena_push_bytes_no_zero(struct arena *arena, u64 size, u64 align);
void arena_copy_replace(struct arena *dst, struct arena *src);
void arena_decommit_unused_blocks(struct arena *arena);
void arena_set_readonly(struct arena *arena);
void arena_set_readwrite(struct arena *arena);
Arena *arena_alloc(u64 reserve);
void arena_release(Arena *arena);
void *arena_push_bytes_no_zero(Arena *arena, u64 size, u64 align);
void arena_copy_replace(Arena *dst, Arena *src);
void arena_decommit_unused_blocks(Arena *arena);
void arena_set_readonly(Arena *arena);
void arena_set_readwrite(Arena *arena);
INLINE u8 *arena_base(struct arena *arena)
INLINE u8 *arena_base(Arena *arena)
{
return (u8 *)arena + ARENA_HEADER_SIZE;
}
INLINE void *arena_push_bytes(struct arena *arena, u64 size, u64 align)
INLINE void *arena_push_bytes(Arena *arena, u64 size, u64 align)
{
void *p = arena_push_bytes_no_zero(arena, size, align);
MEMZERO(p, size);
return p;
}
INLINE void arena_pop_to(struct arena *arena, u64 pos)
INLINE void arena_pop_to(Arena *arena, u64 pos)
{
ASSERT(arena->pos >= pos);
ASSERT(!arena->readonly);
@ -65,7 +67,7 @@ INLINE void arena_pop_to(struct arena *arena, u64 pos)
arena->pos = pos;
}
INLINE void arena_pop_struct(struct arena *arena, u64 size, void *copy_dst)
INLINE void arena_pop_struct(Arena *arena, u64 size, void *copy_dst)
{
ASSERT(arena->pos >= size);
ASSERT(!arena->readonly);
@ -78,7 +80,7 @@ INLINE void arena_pop_struct(struct arena *arena, u64 size, void *copy_dst)
arena->pos = new_pos;
}
INLINE void *arena_align(struct arena *arena, u64 align)
INLINE void *arena_align(Arena *arena, u64 align)
{
ASSERT(!arena->readonly);
if (align > 0) {
@ -97,25 +99,25 @@ INLINE void *arena_align(struct arena *arena, u64 align)
}
}
INLINE struct arena_temp arena_temp_begin(struct arena *arena)
INLINE TempArena arena_temp_begin(Arena *arena)
{
struct arena_temp t = ZI;
TempArena t = ZI;
t.arena = arena;
t.start_pos = arena->pos;
return t;
}
INLINE void arena_temp_end(struct arena_temp temp)
INLINE void arena_temp_end(TempArena temp)
{
arena_pop_to(temp.arena, temp.start_pos);
}
INLINE void arena_reset(struct arena *arena)
INLINE void arena_reset(Arena *arena)
{
arena_pop_to(arena, 0);
}
INLINE void *_arena_push_dry(struct arena *arena, u64 align)
INLINE void *_arena_push_dry(Arena *arena, u64 align)
{
u64 aligned_start_pos = (arena->pos + (align - 1));
aligned_start_pos -= aligned_start_pos % align;
@ -129,20 +131,22 @@ INLINE void *_arena_push_dry(struct arena *arena, u64 align)
#define SCRATCH_ARENAS_PER_CTX 2
struct scratch_ctx {
struct arena *arenas[SCRATCH_ARENAS_PER_CTX];
typedef struct ScratchCtx ScratchCtx;
struct ScratchCtx {
Arena *arenas[SCRATCH_ARENAS_PER_CTX];
};
struct scratch_shared {
struct scratch_ctx scratch_contexts[MAX_FIBERS];
typedef struct SharedScratchCtx SharedScratchCtx;
struct SharedScratchCtx {
ScratchCtx scratch_contexts[MAX_FIBERS];
};
extern struct scratch_shared g_scratch_shared;
extern SharedScratchCtx g_scratch_shared;
INLINE struct scratch_ctx *scratch_ctx_from_fiber_id(i16 fiber_id)
INLINE ScratchCtx *scratch_ctx_from_fiber_id(i16 fiber_id)
{
struct scratch_shared *shared = &g_scratch_shared;
struct scratch_ctx *ctx = &shared->scratch_contexts[fiber_id];
SharedScratchCtx *shared = &g_scratch_shared;
ScratchCtx *ctx = &shared->scratch_contexts[fiber_id];
if (!ctx->arenas[0]) {
for (i32 i = 0; i < (i32)countof(ctx->arenas); ++i) {
ctx->arenas[i] = arena_alloc(GIBI(64));
@ -161,7 +165,7 @@ INLINE struct scratch_ctx *scratch_ctx_from_fiber_id(i16 fiber_id)
* scope that could potentially be a scratch arena from another scope. */
#define scratch_begin(potential_conflict) _scratch_begin(potential_conflict)
INLINE struct arena_temp _scratch_begin(struct arena *potential_conflict)
INLINE TempArena _scratch_begin(Arena *potential_conflict)
{
/* This function is currently hard-coded to support 2 scratch arenas */
STATIC_ASSERT(SCRATCH_ARENAS_PER_CTX == 2);
@ -169,12 +173,12 @@ INLINE struct arena_temp _scratch_begin(struct arena *potential_conflict)
/* Use `scratch_begin_no_conflict` if no conflicts are present */
ASSERT(potential_conflict != 0);
struct scratch_ctx *ctx = scratch_ctx_from_fiber_id(FiberId());
struct arena *scratch_arena = ctx->arenas[0];
ScratchCtx *ctx = scratch_ctx_from_fiber_id(FiberId());
Arena *scratch_arena = ctx->arenas[0];
if (potential_conflict && scratch_arena == potential_conflict) {
scratch_arena = ctx->arenas[1];
}
struct arena_temp temp = arena_temp_begin(scratch_arena);
TempArena temp = arena_temp_begin(scratch_arena);
return temp;
}
@ -190,15 +194,15 @@ INLINE struct arena_temp _scratch_begin(struct arena *potential_conflict)
(UNUSED)arena; \
} while (0)
INLINE struct arena_temp _scratch_begin_no_conflict(void)
INLINE TempArena _scratch_begin_no_conflict(void)
{
struct scratch_ctx *ctx = scratch_ctx_from_fiber_id(FiberId());
struct arena *scratch_arena = ctx->arenas[0];
struct arena_temp temp = arena_temp_begin(scratch_arena);
ScratchCtx *ctx = scratch_ctx_from_fiber_id(FiberId());
Arena *scratch_arena = ctx->arenas[0];
TempArena temp = arena_temp_begin(scratch_arena);
return temp;
}
INLINE void scratch_end(struct arena_temp scratch_temp)
INLINE void scratch_end(TempArena scratch_temp)
{
arena_temp_end(scratch_temp);
}

View File

@ -2,21 +2,25 @@
* Atomic types
* ========================== */
/* NOTE: Must be aligned to 32 bit boundary by user */
struct atomic8 {
/* NOTE: Must be aligned to 32 bit boundary by user */
typedef struct Atomic8 Atomic8;
struct Atomic8 {
volatile i8 _v;
};
/* NOTE: Must be aligned to 32 bit boundary by user */
struct atomic16 {
typedef struct Atomic16 Atomic16;
struct Atomic16 {
volatile i16 _v;
};
struct atomic32 {
typedef struct Atomic32 Atomic32;
struct Atomic32 {
volatile i32 _v;
};
struct atomic64 {
typedef struct Atomic64 Atomic64;
struct Atomic64 {
volatile i64 _v;
};
@ -24,29 +28,33 @@ struct atomic64 {
* Cache-line isolated atomic types
* ========================== */
struct alignas(64) atomic8_padded {
struct atomic8 v;
typedef struct Atomic8Padded Atomic8Padded;
struct alignas(64) Atomic8Padded {
Atomic8 v;
u8 _pad[60];
};
STATIC_ASSERT(sizeof(struct atomic8_padded) == 64 && alignof(struct atomic8_padded) == 64);
STATIC_ASSERT(sizeof(Atomic8Padded) == 64 && alignof(Atomic8Padded) == 64);
struct alignas(64) atomic16_padded {
struct atomic16 v;
typedef struct Atomic16Padded Atomic16Padded;
struct alignas(64) Atomic16Padded {
Atomic16 v;
u8 _pad[60];
};
STATIC_ASSERT(sizeof(struct atomic16_padded) == 64 && alignof(struct atomic16_padded) == 64);
STATIC_ASSERT(sizeof(Atomic16Padded) == 64 && alignof(Atomic16Padded) == 64);
struct alignas(64) atomic32_padded {
struct atomic32 v;
typedef struct Atomic32Padded Atomic32Padded;
struct alignas(64) Atomic32Padded {
Atomic32 v;
u8 _pad[60];
};
STATIC_ASSERT(sizeof(struct atomic32_padded) == 64 && alignof(struct atomic32_padded) == 64);
STATIC_ASSERT(sizeof(Atomic32Padded) == 64 && alignof(Atomic32Padded) == 64);
struct alignas(64) atomic64_padded {
struct atomic64 v;
typedef struct Atomic64Padded Atomic64Padded;
struct alignas(64) Atomic64Padded {
Atomic64 v;
u8 _pad[56];
};
STATIC_ASSERT(sizeof(struct atomic64_padded) == 64 && alignof(struct atomic64_padded) == 64);
STATIC_ASSERT(sizeof(Atomic64Padded) == 64 && alignof(Atomic64Padded) == 64);
/* ========================== *
* Atomics impl
@ -54,29 +62,29 @@ STATIC_ASSERT(sizeof(struct atomic64_padded) == 64 && alignof(struct atomic64_pa
#if PLATFORM_WINDOWS
FORCE_INLINE i8 atomic8_fetch(struct atomic8 *x) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, 0, 0); }
FORCE_INLINE i8 atomic8_fetch_set(struct atomic8 *x, i8 e) { return (i8)_InterlockedExchange8((char *)&x->_v, e); }
FORCE_INLINE i8 atomic8_fetch_test_set(struct atomic8 *x, i8 c, i8 e) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, e, c); }
FORCE_INLINE i8 atomic8_fetch_xor(struct atomic8 *x, i8 c) { return (i8)_InterlockedXor8((char *)&x->_v, c); }
FORCE_INLINE i8 atomic8_fetch_add(struct atomic8 *x, i8 a) { return (i8)_InterlockedExchangeAdd8((char *)&x->_v, a); }
FORCE_INLINE i8 atomic8_fetch(Atomic8 *x) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, 0, 0); }
FORCE_INLINE i8 atomic8_fetch_set(Atomic8 *x, i8 e) { return (i8)_InterlockedExchange8((char *)&x->_v, e); }
FORCE_INLINE i8 atomic8_fetch_test_set(Atomic8 *x, i8 c, i8 e) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, e, c); }
FORCE_INLINE i8 atomic8_fetch_xor(Atomic8 *x, i8 c) { return (i8)_InterlockedXor8((char *)&x->_v, c); }
FORCE_INLINE i8 atomic8_fetch_add(Atomic8 *x, i8 a) { return (i8)_InterlockedExchangeAdd8((char *)&x->_v, a); }
FORCE_INLINE i16 atomic16_fetch(struct atomic16 *x) { return (i16)_InterlockedCompareExchange16(&x->_v, 0, 0); }
FORCE_INLINE i16 atomic16_fetch_set(struct atomic16 *x, i16 e) { return (i16)_InterlockedExchange16(&x->_v, e); }
FORCE_INLINE i16 atomic16_fetch_test_set(struct atomic16 *x, i16 c, i16 e) { return (i16)_InterlockedCompareExchange16(&x->_v, e, c); }
FORCE_INLINE i16 atomic16_fetch_xor(struct atomic16 *x, i16 c) { return (i16)_InterlockedXor16(&x->_v, c); }
FORCE_INLINE i16 atomic16_fetch_add(struct atomic16 *x, i16 a) { return (i16)_InterlockedExchangeAdd16(&x->_v, a); }
FORCE_INLINE i16 atomic16_fetch(Atomic16 *x) { return (i16)_InterlockedCompareExchange16(&x->_v, 0, 0); }
FORCE_INLINE i16 atomic16_fetch_set(Atomic16 *x, i16 e) { return (i16)_InterlockedExchange16(&x->_v, e); }
FORCE_INLINE i16 atomic16_fetch_test_set(Atomic16 *x, i16 c, i16 e) { return (i16)_InterlockedCompareExchange16(&x->_v, e, c); }
FORCE_INLINE i16 atomic16_fetch_xor(Atomic16 *x, i16 c) { return (i16)_InterlockedXor16(&x->_v, c); }
FORCE_INLINE i16 atomic16_fetch_add(Atomic16 *x, i16 a) { return (i16)_InterlockedExchangeAdd16(&x->_v, a); }
FORCE_INLINE i32 atomic32_fetch(struct atomic32 *x) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, 0, 0); }
FORCE_INLINE i32 atomic32_fetch_set(struct atomic32 *x, i32 e) { return (i32)_InterlockedExchange((volatile long *)&x->_v, e); }
FORCE_INLINE i32 atomic32_fetch_test_set(struct atomic32 *x, i32 c, i32 e) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, e, c); }
FORCE_INLINE i32 atomic32_fetch_xor(struct atomic32 *x, i32 c) { return (i32)_InterlockedXor((volatile long *)&x->_v,c); }
FORCE_INLINE i32 atomic32_fetch_add(struct atomic32 *x, i32 a) { return (i32)_InterlockedExchangeAdd((volatile long *)&x->_v, a); }
FORCE_INLINE i32 atomic32_fetch(Atomic32 *x) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, 0, 0); }
FORCE_INLINE i32 atomic32_fetch_set(Atomic32 *x, i32 e) { return (i32)_InterlockedExchange((volatile long *)&x->_v, e); }
FORCE_INLINE i32 atomic32_fetch_test_set(Atomic32 *x, i32 c, i32 e) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, e, c); }
FORCE_INLINE i32 atomic32_fetch_xor(Atomic32 *x, i32 c) { return (i32)_InterlockedXor((volatile long *)&x->_v,c); }
FORCE_INLINE i32 atomic32_fetch_add(Atomic32 *x, i32 a) { return (i32)_InterlockedExchangeAdd((volatile long *)&x->_v, a); }
FORCE_INLINE i64 atomic64_fetch(struct atomic64 *x) { return (i64)_InterlockedCompareExchange64(&x->_v, 0, 0); }
FORCE_INLINE i64 atomic64_fetch_set(struct atomic64 *x, i64 e) { return (i64)_InterlockedExchange64(&x->_v, e); }
FORCE_INLINE i64 atomic64_fetch_test_set(struct atomic64 *x, i64 c, i64 e) { return (i64)_InterlockedCompareExchange64(&x->_v, e, c); }
FORCE_INLINE i64 atomic64_fetch_xor(struct atomic64 *x, i64 c) { return (i64)_InterlockedXor64(&x->_v, c); }
FORCE_INLINE i64 atomic64_fetch_add(struct atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_v, a); }
FORCE_INLINE i64 atomic64_fetch(Atomic64 *x) { return (i64)_InterlockedCompareExchange64(&x->_v, 0, 0); }
FORCE_INLINE i64 atomic64_fetch_set(Atomic64 *x, i64 e) { return (i64)_InterlockedExchange64(&x->_v, e); }
FORCE_INLINE i64 atomic64_fetch_test_set(Atomic64 *x, i64 c, i64 e) { return (i64)_InterlockedCompareExchange64(&x->_v, e, c); }
FORCE_INLINE i64 atomic64_fetch_xor(Atomic64 *x, i64 c) { return (i64)_InterlockedXor64(&x->_v, c); }
FORCE_INLINE i64 atomic64_fetch_add(Atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_v, a); }
#else
# error Atomics not implemented

View File

@ -20,8 +20,8 @@ enum dbg_magic {
DBG_MAGIC_STRING = 0x7866,
};
INTERNAL void bw_write_ubits_nomagic(struct bitbuff_writer *bw, u64 value, u8 num_bits);
INTERNAL void _dbg_write_magic(struct bitbuff_writer *bw, enum dbg_magic magic, u8 num_bits)
INTERNAL void bw_write_ubits_nomagic(BitbuffWriter *bw, u64 value, u8 num_bits);
INTERNAL void _dbg_write_magic(BitbuffWriter *bw, enum dbg_magic magic, u8 num_bits)
{
if (bw->debug_enabled) {
if (bw_check_overflow_bits(bw, 24)) {
@ -32,8 +32,8 @@ INTERNAL void _dbg_write_magic(struct bitbuff_writer *bw, enum dbg_magic magic,
}
}
INTERNAL u64 br_read_ubits_nomagic(struct bitbuff_reader *br, u8 num_bits);
INTERNAL void _dbg_read_magic(struct bitbuff_reader *br, enum dbg_magic expected_magic, u8 expected_num_bits)
INTERNAL u64 br_read_ubits_nomagic(BitbuffReader *br, u8 num_bits);
INTERNAL void _dbg_read_magic(BitbuffReader *br, enum dbg_magic expected_magic, u8 expected_num_bits)
{
if (br->debug_enabled) {
if (br_check_overflow_bits(br, 24)) {
@ -83,15 +83,15 @@ INTERNAL i64 sint_from_twos_compliment(u64 tc, u8 num_bits)
* Bitbuff
* ========================== */
struct bitbuff bitbuff_alloc(u64 arena_reserve)
Bitbuff bitbuff_alloc(u64 arena_reserve)
{
struct bitbuff res = ZI;
Bitbuff res = ZI;
res.arena = arena_alloc(arena_reserve);
res.is_backed_by_arena = 1;
return res;
}
void bitbuff_release(struct bitbuff *bb)
void bitbuff_release(Bitbuff *bb)
{
/* Only arena bitbuffs need to be released */
if (bb->is_backed_by_arena) {
@ -99,9 +99,9 @@ void bitbuff_release(struct bitbuff *bb)
}
}
struct bitbuff bitbuff_from_string(struct string s)
Bitbuff bitbuff_from_string(String s)
{
struct bitbuff res = ZI;
Bitbuff res = ZI;
res.fixed_buffer = s;
return res;
}
@ -110,9 +110,9 @@ struct bitbuff bitbuff_from_string(struct string s)
* Writer
* ========================== */
struct bitbuff_writer bw_from_bitbuff(struct bitbuff *bb)
BitbuffWriter bw_from_bitbuff(Bitbuff *bb)
{
struct bitbuff_writer res = ZI;
BitbuffWriter res = ZI;
res.bb = bb;
if (bb->is_backed_by_arena) {
res.base = arena_base(bb->arena);
@ -127,9 +127,9 @@ struct bitbuff_writer bw_from_bitbuff(struct bitbuff *bb)
}
/* Use this when writing external formats that will not verify bitbuff debug symbols / magic numbers */
struct bitbuff_writer bw_from_bitbuff_no_debug(struct bitbuff *bb)
BitbuffWriter bw_from_bitbuff_no_debug(Bitbuff *bb)
{
struct bitbuff_writer res = bw_from_bitbuff(bb);
BitbuffWriter res = bw_from_bitbuff(bb);
#if BITBUFF_DEBUG
res.debug_enabled = 0;
#endif
@ -137,21 +137,21 @@ struct bitbuff_writer bw_from_bitbuff_no_debug(struct bitbuff *bb)
}
/* FIXME: Handle overflowed bw */
u64 bw_num_bits_written(struct bitbuff_writer *bw)
u64 bw_num_bits_written(BitbuffWriter *bw)
{
return bw->cur_bit;
}
/* FIXME: Handle overflowed bw */
u64 bw_num_bytes_written(struct bitbuff_writer *bw)
u64 bw_num_bytes_written(BitbuffWriter *bw)
{
return (bw->cur_bit + 7) >> 3;
}
/* FIXME: Handle overflowed bw */
struct string bw_get_written(struct arena *arena, struct bitbuff_writer *bw)
String bw_get_written(Arena *arena, BitbuffWriter *bw)
{
struct string res = ZI;
String res = ZI;
res.len = (bw->cur_bit + 7) >> 3;
res.text = arena_push_array_no_zero(arena, u8, res.len);
MEMCPY(res.text, bw->base, res.len);
@ -159,22 +159,22 @@ struct string bw_get_written(struct arena *arena, struct bitbuff_writer *bw)
}
/* FIXME: Handle overflowed bw */
u8 *bw_get_written_raw(struct bitbuff_writer *bw)
u8 *bw_get_written_raw(BitbuffWriter *bw)
{
return bw->base;
}
/* Returns 1 if num_bits would cause the writer to overflow its fixed buffer size (if writer is not backed by a dynamic arena bitbuff) */
b32 bw_check_overflow_bits(struct bitbuff_writer *bw, u64 num_bits)
b32 bw_check_overflow_bits(BitbuffWriter *bw, u64 num_bits)
{
b32 res = 0;
struct bitbuff *bb = bw->bb;
Bitbuff *bb = bw->bb;
if (bw->overflowed) {
res = 1;
} else {
u64 bytes_needed = (bw->cur_bit + num_bits + 7) >> 3;
if (bb->is_backed_by_arena) {
struct arena *arena = bb->arena;
Arena *arena = bb->arena;
if (bytes_needed >= arena->pos) {
/* Grow arena */
u64 push_size = (((bytes_needed - arena->pos) / WRITE_OVERFLOW_ARENA_PUSH_SIZE) + 1) * WRITE_OVERFLOW_ARENA_PUSH_SIZE;
@ -195,7 +195,7 @@ b32 bw_check_overflow_bits(struct bitbuff_writer *bw, u64 num_bits)
}
/* Align the pos to the next byte */
void bw_align(struct bitbuff_writer *bw)
void bw_align(BitbuffWriter *bw)
{
#if BITBUFF_DEBUG
if ((bw->cur_bit & 7) != 0) {
@ -206,9 +206,9 @@ void bw_align(struct bitbuff_writer *bw)
}
#if BITBUFF_DEBUG
INTERNAL void bw_write_ubits_nomagic(struct bitbuff_writer *bw, u64 value, u8 num_bits)
INTERNAL void bw_write_ubits_nomagic(BitbuffWriter *bw, u64 value, u8 num_bits)
#else
void bw_write_ubits(struct bitbuff_writer *bw, u64 value, u8 num_bits)
void bw_write_ubits(BitbuffWriter *bw, u64 value, u8 num_bits)
#endif
{
ASSERT(num_bits > 0 && (num_bits == 64 || value <= ~(U64_MAX << num_bits))); /* Bit count must be able to hold value */
@ -236,14 +236,14 @@ void bw_write_ubits(struct bitbuff_writer *bw, u64 value, u8 num_bits)
}
#if BITBUFF_DEBUG
void bw_write_ubits(struct bitbuff_writer *bw, u64 value, u8 num_bits)
void bw_write_ubits(BitbuffWriter *bw, u64 value, u8 num_bits)
{
_dbg_write_magic(bw, DBG_MAGIC_UBITS, num_bits);
bw_write_ubits_nomagic(bw, value, num_bits);
}
#endif
void bw_write_ibits(struct bitbuff_writer *bw, i64 value, u8 num_bits)
void bw_write_ibits(BitbuffWriter *bw, i64 value, u8 num_bits)
{
_dbg_write_magic(bw, DBG_MAGIC_IBITS, num_bits);
u64 ubits;
@ -256,7 +256,7 @@ void bw_write_ibits(struct bitbuff_writer *bw, i64 value, u8 num_bits)
}
/* Returns written bit to make writing delta encoding logic cleaner */
b32 bw_write_bit(struct bitbuff_writer *bw, u8 value)
b32 bw_write_bit(BitbuffWriter *bw, u8 value)
{
bw_write_ubits(bw, value, 1);
return value;
@ -264,7 +264,7 @@ b32 bw_write_bit(struct bitbuff_writer *bw, u8 value)
/* Writes a variable length unsigned integer.
* Value is written in chunks of 7 bits w/ 8th bit signaling continuation. */
void bw_write_uv(struct bitbuff_writer *bw, u64 value)
void bw_write_uv(BitbuffWriter *bw, u64 value)
{
_dbg_write_magic(bw, DBG_MAGIC_UV, 0);
while (value > 0x7F) {
@ -278,7 +278,7 @@ void bw_write_uv(struct bitbuff_writer *bw, u64 value)
/* Writes a variable length signed integer.
* Similar to bw_write_uv, except the 7th bit of the first byte is a sign bit
* indicating that the value is stored in twos compliment. */
void bw_write_iv(struct bitbuff_writer *bw, i64 value)
void bw_write_iv(BitbuffWriter *bw, i64 value)
{
_dbg_write_magic(bw, DBG_MAGIC_IV, 0);
u8 sign_bit;
@ -316,33 +316,33 @@ void bw_write_iv(struct bitbuff_writer *bw, i64 value)
}
}
void bw_write_f32(struct bitbuff_writer *bw, f32 value)
void bw_write_f32(BitbuffWriter *bw, f32 value)
{
_dbg_write_magic(bw, DBG_MAGIC_F32, 0);
bw_write_ubits(bw, *(u32 *)&value, 32);
}
void bw_write_f64(struct bitbuff_writer *bw, f64 value)
void bw_write_f64(BitbuffWriter *bw, f64 value)
{
_dbg_write_magic(bw, DBG_MAGIC_F64, 0);
bw_write_ubits(bw, *(u64 *)&value, 64);
}
void bw_write_uid(struct bitbuff_writer *bw, struct uid value)
void bw_write_uid(BitbuffWriter *bw, UID value)
{
_dbg_write_magic(bw, DBG_MAGIC_UID, 128);
bw_write_ubits(bw, value.hi, 64);
bw_write_ubits(bw, value.lo, 64);
}
void bw_write_string(struct bitbuff_writer *bw, struct string s)
void bw_write_string(BitbuffWriter *bw, String s)
{
_dbg_write_magic(bw, DBG_MAGIC_STRING, 0);
bw_write_uv(bw, s.len);
bw_write_bytes(bw, s);
}
void bw_write_bytes(struct bitbuff_writer *bw, struct string bytes)
void bw_write_bytes(BitbuffWriter *bw, String bytes)
{
/* Align start of bytes */
bw_align(bw);
@ -358,7 +358,7 @@ void bw_write_bytes(struct bitbuff_writer *bw, struct string bytes)
}
#if BITBUFF_DEBUG
void bw_write_dbg_marker(struct bitbuff_writer *bw, struct string name)
void bw_write_dbg_marker(BitbuffWriter *bw, String name)
{
bw->cur_bit += (8 - (bw->cur_bit & 7)) & 7;
for (u64 i = 0; i < name.len; ++i) {
@ -371,14 +371,14 @@ void bw_write_dbg_marker(struct bitbuff_writer *bw, struct string name)
* Reader
* ========================== */
struct bitbuff_reader br_from_bitbuff(struct bitbuff *bb)
BitbuffReader br_from_bitbuff(Bitbuff *bb)
{
struct bitbuff_reader res = ZI;
BitbuffReader res = ZI;
if (!bb->is_backed_by_arena) {
res.base = bb->fixed_buffer.text;
res.base_len = bb->fixed_buffer.len;
} else {
struct arena *arena = bb->arena;
Arena *arena = bb->arena;
res.base = arena_base(arena);
res.base_len = arena->pos;
}
@ -390,9 +390,9 @@ struct bitbuff_reader br_from_bitbuff(struct bitbuff *bb)
}
/* Use this when reading from external formats that will not contain bitbuff debug symbols / magic numbers */
struct bitbuff_reader br_from_bitbuff_no_debug(struct bitbuff *bb)
BitbuffReader br_from_bitbuff_no_debug(Bitbuff *bb)
{
struct bitbuff_reader res = br_from_bitbuff(bb);
BitbuffReader res = br_from_bitbuff(bb);
#if BITBUFF_DEBUG
res.debug_enabled = 0;
#endif
@ -401,33 +401,33 @@ struct bitbuff_reader br_from_bitbuff_no_debug(struct bitbuff *bb)
/* Returns the number of bits read from the bitbuff */
/* FIXME: Handle overflowed br */
u64 br_cur_bit(struct bitbuff_reader *br)
u64 br_cur_bit(BitbuffReader *br)
{
return br->cur_bit;
}
/* Returns the number of *full* bytes read from the bitbuff */
/* FIXME: Handle overflowed br */
u64 br_cur_byte(struct bitbuff_reader *br)
u64 br_cur_byte(BitbuffReader *br)
{
return br->cur_bit >> 3;
}
/* Returns the number of bits left until the bitbuff overflows */
/* FIXME: Handle overflowed br */
u64 br_num_bits_left(struct bitbuff_reader *br)
u64 br_num_bits_left(BitbuffReader *br)
{
return (br->base_len << 3) - br->cur_bit;
}
/* Returns the number of *full* bytes left until the bitbuff overflows */
/* FIXME: Handle overflowed br */
u64 br_num_bytes_left(struct bitbuff_reader *br)
u64 br_num_bytes_left(BitbuffReader *br)
{
return br->base_len - (br->cur_bit >> 3);
}
b32 br_check_overflow_bits(struct bitbuff_reader *br, u64 num_bits)
b32 br_check_overflow_bits(BitbuffReader *br, u64 num_bits)
{
b32 res = 0;
if (br->overflowed) {
@ -447,7 +447,7 @@ b32 br_check_overflow_bits(struct bitbuff_reader *br, u64 num_bits)
}
/* Align the pos to the next byte */
void br_align(struct bitbuff_reader *br)
void br_align(BitbuffReader *br)
{
#if BITBUFF_DEBUG
if ((br->cur_bit & 7) != 0) {
@ -458,9 +458,9 @@ void br_align(struct bitbuff_reader *br)
}
#if BITBUFF_DEBUG
INTERNAL u64 br_read_ubits_nomagic(struct bitbuff_reader *br, u8 num_bits)
INTERNAL u64 br_read_ubits_nomagic(BitbuffReader *br, u8 num_bits)
#else
u64 br_read_ubits(struct bitbuff_reader *br, u8 num_bits)
u64 br_read_ubits(BitbuffReader *br, u8 num_bits)
#endif
{
if (br_check_overflow_bits(br, num_bits)) {
@ -498,14 +498,14 @@ u64 br_read_ubits(struct bitbuff_reader *br, u8 num_bits)
}
#if BITBUFF_DEBUG
u64 br_read_ubits(struct bitbuff_reader *br, u8 num_bits)
u64 br_read_ubits(BitbuffReader *br, u8 num_bits)
{
_dbg_read_magic(br, DBG_MAGIC_UBITS, num_bits);
return br_read_ubits_nomagic(br, num_bits);
}
#endif
i64 br_read_ibits(struct bitbuff_reader *br, u8 num_bits)
i64 br_read_ibits(BitbuffReader *br, u8 num_bits)
{
ASSERT(num_bits > 1);
_dbg_read_magic(br, DBG_MAGIC_IBITS, num_bits);
@ -513,14 +513,14 @@ i64 br_read_ibits(struct bitbuff_reader *br, u8 num_bits)
return sint_from_twos_compliment(tc, num_bits);
}
u8 br_read_bit(struct bitbuff_reader *br)
u8 br_read_bit(BitbuffReader *br)
{
return br_read_ubits(br, 1);
}
/* Read a variable length unsigned integer.
* See bw_write_uv for details. */
u64 br_read_uv(struct bitbuff_reader *br)
u64 br_read_uv(BitbuffReader *br)
{
_dbg_read_magic(br, DBG_MAGIC_UV, 0);
@ -538,7 +538,7 @@ u64 br_read_uv(struct bitbuff_reader *br)
/* Read a variable length signed integer.
* See bw_write_iv for details. */
i64 br_read_iv(struct bitbuff_reader *br)
i64 br_read_iv(BitbuffReader *br)
{
_dbg_read_magic(br, DBG_MAGIC_IV, 0);
u8 first_byte = br_read_ubits(br, 8);
@ -571,32 +571,32 @@ i64 br_read_iv(struct bitbuff_reader *br)
return res;
}
f32 br_read_f32(struct bitbuff_reader *br)
f32 br_read_f32(BitbuffReader *br)
{
_dbg_read_magic(br, DBG_MAGIC_F32, 0);
u32 ubits = br_read_ubits(br, 32);
return *(f32 *)&ubits;
}
f64 br_read_f64(struct bitbuff_reader *br)
f64 br_read_f64(BitbuffReader *br)
{
_dbg_read_magic(br, DBG_MAGIC_F64, 0);
u64 ubits = br_read_ubits(br, 64);
return *(f64 *)&ubits;
}
struct uid br_read_uid(struct bitbuff_reader *br)
UID br_read_uid(BitbuffReader *br)
{
_dbg_read_magic(br, DBG_MAGIC_UID, 128);
u64 hi = br_read_ubits(br, 64);
u64 lo = br_read_ubits(br, 64);
return UID(hi, lo);
return MakeUID(hi, lo);
}
struct string br_read_string(struct arena *arena, struct bitbuff_reader *br)
String br_read_string(Arena *arena, BitbuffReader *br)
{
_dbg_read_magic(br, DBG_MAGIC_STRING, 0);
struct string res = ZI;
String res = ZI;
u64 len = br_read_uv(br);
u8 *src = br_read_bytes_raw(br, len);
if (src != 0) {
@ -608,7 +608,7 @@ struct string br_read_string(struct arena *arena, struct bitbuff_reader *br)
}
/* Will fill dst with zeroes if bitbuff overflows */
void br_read_bytes(struct bitbuff_reader *br, struct string out)
void br_read_bytes(BitbuffReader *br, String out)
{
u8 *src = br_read_bytes_raw(br, out.len);
if (src) {
@ -619,7 +619,7 @@ void br_read_bytes(struct bitbuff_reader *br, struct string out)
}
/* Will return 0 on bitbuff overflow. Result should be checked. */
u8 *br_read_bytes_raw(struct bitbuff_reader *br, u64 num_bytes)
u8 *br_read_bytes_raw(BitbuffReader *br, u64 num_bytes)
{
br_align(br);
@ -634,7 +634,7 @@ u8 *br_read_bytes_raw(struct bitbuff_reader *br, u64 num_bytes)
return raw;
}
void br_seek_bytes(struct bitbuff_reader *br, u64 num_bytes)
void br_seek_bytes(BitbuffReader *br, u64 num_bytes)
{
br_align(br);
@ -646,7 +646,7 @@ void br_seek_bytes(struct bitbuff_reader *br, u64 num_bytes)
br->cur_bit += num_bits;
}
void br_seek_to_byte(struct bitbuff_reader *br, u64 pos)
void br_seek_to_byte(BitbuffReader *br, u64 pos)
{
u64 cur_byte_pos = br->cur_bit >> 3;
if (pos >= cur_byte_pos) {
@ -661,7 +661,7 @@ void br_seek_to_byte(struct bitbuff_reader *br, u64 pos)
}
#if BITBUFF_DEBUG
void br_read_dbg_marker(struct bitbuff_reader *br, struct string name)
void br_read_dbg_marker(BitbuffReader *br, String name)
{
br->cur_bit += (8 - (br->cur_bit & 7)) & 7;
for (u64 i = 0; i < name.len; ++i) {
@ -680,7 +680,7 @@ void br_read_dbg_marker(struct bitbuff_reader *br, struct string name)
void bitbuff_test(void)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u8 kind_ubits = 0;
u8 kind_ibits = 1;
@ -692,7 +692,7 @@ void bitbuff_test(void)
struct test_case_ibits { i64 v; u64 num_bits; };
struct test_case_uv { u64 v; };
struct test_case_iv { i64 v; };
struct test_case_string { struct string v; };
struct test_case_string { String v; };
struct test_case {
u8 kind;
union {
@ -744,10 +744,10 @@ void bitbuff_test(void)
{ kind_string, .s = { LIT("Alriiiiiiiiiiiiiiiiiiighty then") } },
};
struct string encoded = ZI;
String encoded = ZI;
{
struct bitbuff bb = bitbuff_alloc(GIBI(64));
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
Bitbuff bb = bitbuff_alloc(GIBI(64));
BitbuffWriter bw = bw_from_bitbuff(&bb);
for (u64 i = 0; i < countof(cases); ++i) {
struct test_case c = cases[i];
if (c.kind == kind_ubits) {
@ -768,8 +768,8 @@ void bitbuff_test(void)
}
{
struct bitbuff bb = bitbuff_from_string(encoded);
struct bitbuff_reader br = br_from_bitbuff(&bb);
Bitbuff bb = bitbuff_from_string(encoded);
BitbuffReader br = br_from_bitbuff(&bb);
for (u64 i = 0; i < countof(cases); ++i) {
struct test_case c = cases[i];
if (c.kind == kind_ubits) {
@ -789,8 +789,8 @@ void bitbuff_test(void)
i64 r = br_read_iv(&br);
ASSERT(r == w);
} else if (c.kind == kind_string) {
struct string w = c.s.v;
struct string r = br_read_string(scratch.arena, &br);
String w = c.s.v;
String r = br_read_string(scratch.arena, &br);
ASSERT(string_eq(r, w));
} else {
ASSERT(0);

View File

@ -2,29 +2,31 @@
* Bitbuff
* ========================== */
struct bitbuff {
typedef struct Bitbuff Bitbuff;
struct Bitbuff {
b32 is_backed_by_arena;
/* If `is_arena_bitbuff` is 1, this dynamically-sized arena will be used for reading & writing (meaning writing cannot overflow) */
struct arena *arena;
Arena *arena;
/* If `is_arena_bitbuff` is 0, this fixed-sized buffer willl be used for reading & writing */
struct string fixed_buffer;
String fixed_buffer;
};
struct bitbuff bitbuff_alloc(u64 arena_reserve);
void bitbuff_release(struct bitbuff *bitbuff);
Bitbuff bitbuff_alloc(u64 arena_reserve);
void bitbuff_release(Bitbuff *bitbuff);
struct bitbuff bitbuff_from_string(struct string s);
Bitbuff bitbuff_from_string(String s);
/* ========================== *
* Writer
* ========================== */
/* NOTE: base_len is not stored in writer (as it is in the reader) since a dynamic arena-backed bitbuff could grow meaning len needs to be re-checked */
struct bitbuff_writer {
typedef struct BitbuffWriter BitbuffWriter;
struct BitbuffWriter {
b32 overflowed;
struct bitbuff *bb;
Bitbuff *bb;
u8 *base;
u64 cur_bit;
#if BITBUFF_DEBUG
@ -32,36 +34,36 @@ struct bitbuff_writer {
#endif
};
struct bitbuff_writer bw_from_bitbuff(struct bitbuff *bb);
struct bitbuff_writer bw_from_bitbuff_no_debug(struct bitbuff *bb);
BitbuffWriter bw_from_bitbuff(Bitbuff *bb);
BitbuffWriter bw_from_bitbuff_no_debug(Bitbuff *bb);
u64 bw_num_bits_written(struct bitbuff_writer *bw);
u64 bw_num_bytes_written(struct bitbuff_writer *bw);
u64 bw_num_bits_written(BitbuffWriter *bw);
u64 bw_num_bytes_written(BitbuffWriter *bw);
struct string bw_get_written(struct arena *arena, struct bitbuff_writer *bw);
u8 *bw_get_written_raw(struct bitbuff_writer *bw);
String bw_get_written(Arena *arena, BitbuffWriter *bw);
u8 *bw_get_written_raw(BitbuffWriter *bw);
b32 bw_check_overflow_bits(struct bitbuff_writer *bw, u64 num_bits);
b32 bw_check_overflow_bits(BitbuffWriter *bw, u64 num_bits);
void bw_align(struct bitbuff_writer *bw);
void bw_align(BitbuffWriter *bw);
void bw_write_ubits(struct bitbuff_writer *bw, u64 value, u8 num_bits);
void bw_write_ibits(struct bitbuff_writer *bw, i64 value, u8 num_bits);
b32 bw_write_bit(struct bitbuff_writer *bw, u8 value);
void bw_write_ubits(BitbuffWriter *bw, u64 value, u8 num_bits);
void bw_write_ibits(BitbuffWriter *bw, i64 value, u8 num_bits);
b32 bw_write_bit(BitbuffWriter *bw, u8 value);
void bw_write_uv(struct bitbuff_writer *bw, u64 value);
void bw_write_iv(struct bitbuff_writer *bw, i64 value);
void bw_write_uv(BitbuffWriter *bw, u64 value);
void bw_write_iv(BitbuffWriter *bw, i64 value);
void bw_write_f32(struct bitbuff_writer *bw, f32 value);
void bw_write_f64(struct bitbuff_writer *bw, f64 value);
void bw_write_uid(struct bitbuff_writer *bw, struct uid value);
void bw_write_f32(BitbuffWriter *bw, f32 value);
void bw_write_f64(BitbuffWriter *bw, f64 value);
void bw_write_uid(BitbuffWriter *bw, UID value);
void bw_write_string(struct bitbuff_writer *bw, struct string s);
void bw_write_string(BitbuffWriter *bw, String s);
void bw_write_bytes(struct bitbuff_writer *bw, struct string bytes);
void bw_write_bytes(BitbuffWriter *bw, String bytes);
#if BITBUFF_DEBUG
void bw_write_dbg_marker(struct bitbuff_writer *bw, struct string name);
void bw_write_dbg_marker(BitbuffWriter *bw, String name);
#else
#define bw_write_dbg_marker(bw, name)
#endif
@ -70,7 +72,8 @@ void bw_write_dbg_marker(struct bitbuff_writer *bw, struct string name);
* Reader
* ========================== */
struct bitbuff_reader {
typedef struct BitbuffReader BitbuffReader;
struct BitbuffReader {
b32 overflowed;
u64 base_len;
u8 *base;
@ -80,39 +83,39 @@ struct bitbuff_reader {
#endif
};
struct bitbuff_reader br_from_bitbuff(struct bitbuff *bb);
struct bitbuff_reader br_from_bitbuff_no_debug(struct bitbuff *bb);
BitbuffReader br_from_bitbuff(Bitbuff *bb);
BitbuffReader br_from_bitbuff_no_debug(Bitbuff *bb);
u64 br_cur_bit(struct bitbuff_reader *br);
u64 br_cur_byte(struct bitbuff_reader *br);
u64 br_cur_bit(BitbuffReader *br);
u64 br_cur_byte(BitbuffReader *br);
u64 br_num_bits_left(struct bitbuff_reader *br);
u64 br_num_bytes_left(struct bitbuff_reader *br);
u64 br_num_bits_left(BitbuffReader *br);
u64 br_num_bytes_left(BitbuffReader *br);
b32 br_check_overflow_bits(struct bitbuff_reader *br, u64 num_bits);
b32 br_check_overflow_bits(BitbuffReader *br, u64 num_bits);
void br_align(struct bitbuff_reader *br);
void br_align(BitbuffReader *br);
u64 br_read_ubits(struct bitbuff_reader *br, u8 num_bits);
i64 br_read_ibits(struct bitbuff_reader *br, u8 num_bits);
u8 br_read_bit(struct bitbuff_reader *br);
u64 br_read_ubits(BitbuffReader *br, u8 num_bits);
i64 br_read_ibits(BitbuffReader *br, u8 num_bits);
u8 br_read_bit(BitbuffReader *br);
u64 br_read_uv(struct bitbuff_reader *br);
i64 br_read_iv(struct bitbuff_reader *br);
u64 br_read_uv(BitbuffReader *br);
i64 br_read_iv(BitbuffReader *br);
f32 br_read_f32(struct bitbuff_reader *br);
f64 br_read_f64(struct bitbuff_reader *br);
struct uid br_read_uid(struct bitbuff_reader *br);
f32 br_read_f32(BitbuffReader *br);
f64 br_read_f64(BitbuffReader *br);
UID br_read_uid(BitbuffReader *br);
struct string br_read_string(struct arena *arena, struct bitbuff_reader *br);
String br_read_string(Arena *arena, BitbuffReader *br);
void br_read_bytes(struct bitbuff_reader *br, struct string dst);
u8 *br_read_bytes_raw(struct bitbuff_reader *br, u64 num_bytes);
void br_seek_bytes(struct bitbuff_reader *br, u64 num_bytes);
void br_seek_to_byte(struct bitbuff_reader *br, u64 pos);
void br_read_bytes(BitbuffReader *br, String dst);
u8 *br_read_bytes_raw(BitbuffReader *br, u64 num_bytes);
void br_seek_bytes(BitbuffReader *br, u64 num_bytes);
void br_seek_to_byte(BitbuffReader *br, u64 pos);
#if BITBUFF_DEBUG
void br_read_dbg_marker(struct bitbuff_reader *br, struct string name);
void br_read_dbg_marker(BitbuffReader *br, String name);
#else
#define br_read_dbg_marker(br, name)
#endif

View File

@ -4,18 +4,18 @@
* Ctx
* ========================== */
struct buddy_ctx *buddy_ctx_alloc(u64 reserve)
BuddyCtx *buddy_ctx_alloc(u64 reserve)
{
/* TODO: Determine meta reserve dynamically */
struct arena *meta_arena = arena_alloc(GIBI(64));
struct buddy_ctx *ctx = arena_push(meta_arena, struct buddy_ctx);
Arena *meta_arena = arena_alloc(GIBI(64));
BuddyCtx *ctx = arena_push(meta_arena, BuddyCtx);
ctx->meta_arena = meta_arena;
ctx->data_arena = arena_alloc(reserve);
/* TODO: Minimum block size */
ctx->levels = arena_push_array(ctx->meta_arena, struct buddy_level, 64);
ctx->levels = arena_push_array(ctx->meta_arena, BuddyLevel, 64);
for (u64 i = 0; i < 64; ++i) {
struct buddy_level *level = &ctx->levels[i];
BuddyLevel *level = &ctx->levels[i];
level->ctx = ctx;
level->tier = i;
level->size = (u64)1 << i;
@ -24,7 +24,7 @@ struct buddy_ctx *buddy_ctx_alloc(u64 reserve)
return ctx;
}
void buddy_ctx_release(struct buddy_ctx *ctx)
void buddy_ctx_release(BuddyCtx *ctx)
{
arena_release(ctx->data_arena);
arena_release(ctx->meta_arena);
@ -34,25 +34,25 @@ void buddy_ctx_release(struct buddy_ctx *ctx)
* Block
* ========================== */
INTERNAL struct buddy_block *buddy_block_alloc_internal(struct buddy_ctx *ctx)
INTERNAL BuddyBlock *buddy_block_alloc_internal(BuddyCtx *ctx)
{
struct buddy_block *block;
BuddyBlock *block;
if (ctx->first_free_block) {
block = ctx->first_free_block;
ctx->first_free_block = block->next;
} else {
block = arena_push_no_zero(ctx->meta_arena, struct buddy_block);
block = arena_push_no_zero(ctx->meta_arena, BuddyBlock);
}
MEMZERO_STRUCT(block);
return block;
}
INTERNAL void buddy_block_release_internal(struct buddy_ctx *ctx, struct buddy_level *level, struct buddy_block *block)
INTERNAL void buddy_block_release_internal(BuddyCtx *ctx, BuddyLevel *level, BuddyBlock *block)
{
/* Remove from unused list */
{
struct buddy_block *prev = block->prev;
struct buddy_block *next = block->next;
BuddyBlock *prev = block->prev;
BuddyBlock *next = block->next;
if (prev) {
prev->next = next;
} else {
@ -67,9 +67,9 @@ INTERNAL void buddy_block_release_internal(struct buddy_ctx *ctx, struct buddy_l
ctx->first_free_block = block;
}
INTERNAL struct buddy_block *buddy_block_get_unused(struct buddy_ctx *ctx, struct buddy_level *level)
INTERNAL BuddyBlock *buddy_block_get_unused(BuddyCtx *ctx, BuddyLevel *level)
{
struct buddy_block *block = 0;
BuddyBlock *block = 0;
/* TODO: Tier oob check */
if (level->first_unused_block) {
@ -82,18 +82,18 @@ INTERNAL struct buddy_block *buddy_block_get_unused(struct buddy_ctx *ctx, struc
block->next = 0;
} else {
if (level->backed) {
struct buddy_level *parent_level = &ctx->levels[level->tier + 1];
struct buddy_block *parent_block = buddy_block_get_unused(ctx, parent_level);
BuddyLevel *parent_level = &ctx->levels[level->tier + 1];
BuddyBlock *parent_block = buddy_block_get_unused(ctx, parent_level);
/* Create left (used) block from parent block */
struct buddy_block *left = buddy_block_alloc_internal(ctx);
BuddyBlock *left = buddy_block_alloc_internal(ctx);
left->is_used = 1;
left->level = level;
left->parent = parent_block;
left->memory = parent_block->memory;
/* Create right (unused) block from parent block */
struct buddy_block *right = buddy_block_alloc_internal(ctx);
BuddyBlock *right = buddy_block_alloc_internal(ctx);
right->is_used = 0;
right->level = level;
right->parent = parent_block;
@ -108,7 +108,7 @@ INTERNAL struct buddy_block *buddy_block_get_unused(struct buddy_ctx *ctx, struc
right->sibling = left;
block = left;
} else {
struct arena *arena = ctx->data_arena;
Arena *arena = ctx->data_arena;
/* Grow arena */
i64 level_commit_diff = (level->size * 2) - arena->pos;
@ -118,13 +118,13 @@ INTERNAL struct buddy_block *buddy_block_get_unused(struct buddy_ctx *ctx, struc
}
/* Create left (used) block from existing child block memory */
struct buddy_block *left = buddy_block_alloc_internal(ctx);
BuddyBlock *left = buddy_block_alloc_internal(ctx);
left->is_used = 1;
left->level = level;
left->memory = arena_base(arena);
/* Create right (unused) block from new arena memory */
struct buddy_block *right = buddy_block_alloc_internal(ctx);
BuddyBlock *right = buddy_block_alloc_internal(ctx);
right->is_used = 0;
right->level = level;
right->memory = left->memory + level->size;
@ -140,15 +140,15 @@ INTERNAL struct buddy_block *buddy_block_get_unused(struct buddy_ctx *ctx, struc
return block;
}
INTERNAL void buddy_block_mark_unused(struct buddy_block *block)
INTERNAL void buddy_block_mark_unused(BuddyBlock *block)
{
block->is_used = 0;
struct buddy_level *level = block->level;
struct buddy_block *parent = block->parent;
struct buddy_block *sibling = block->sibling;
BuddyLevel *level = block->level;
BuddyBlock *parent = block->parent;
BuddyBlock *sibling = block->sibling;
if (!sibling->is_used && parent != 0) {
/* Merge siblings */
struct buddy_ctx *ctx = level->ctx;
BuddyCtx *ctx = level->ctx;
buddy_block_release_internal(ctx, level, block);
buddy_block_release_internal(ctx, level, sibling);
buddy_block_mark_unused(parent);
@ -161,7 +161,7 @@ INTERNAL void buddy_block_mark_unused(struct buddy_block *block)
}
}
struct buddy_block *buddy_alloc(struct buddy_ctx *ctx, u64 size)
BuddyBlock *buddy_alloc(BuddyCtx *ctx, u64 size)
{
if (size > 0x00FFFFFFFFFFFFFFULL) {
/* TODO: Error */
@ -179,12 +179,12 @@ struct buddy_block *buddy_alloc(struct buddy_ctx *ctx, u64 size)
++desired_level_tier;
}
struct buddy_block *block = buddy_block_get_unused(ctx, &ctx->levels[desired_level_tier]);
BuddyBlock *block = buddy_block_get_unused(ctx, &ctx->levels[desired_level_tier]);
return block;
}
void buddy_release(struct buddy_block *block)
void buddy_release(BuddyBlock *block)
{
buddy_block_mark_unused(block);
}

View File

@ -1,33 +1,38 @@
struct buddy_block {
typedef struct BuddyLevel BuddyLevel;
typedef struct BuddyBlock BuddyBlock;
struct BuddyBlock {
b32 is_used;
struct buddy_level *level;
struct buddy_block *parent;
struct buddy_block *sibling;
BuddyLevel *level;
BuddyBlock *parent;
BuddyBlock *sibling;
/* Links to block in level's unused list or in ctx's free list */
struct buddy_block *prev;
struct buddy_block *next;
BuddyBlock *prev;
BuddyBlock *next;
u8 *memory;
};
struct buddy_level {
struct buddy_ctx *ctx;
typedef struct BuddyCtx BuddyCtx;
typedef struct BuddyLevel BuddyLevel;
struct BuddyLevel {
BuddyCtx *ctx;
b32 backed; /* Signals whether this level is backed by memory in the ctx arena */
u32 tier;
u64 size;
struct buddy_block *first_unused_block;
BuddyBlock *first_unused_block;
};
struct buddy_ctx {
struct arena *meta_arena;
struct arena *data_arena;
struct buddy_level *levels;
struct buddy_block *first_free_block;
typedef struct BuddyCtx BuddyCtx;
struct BuddyCtx {
Arena *meta_arena;
Arena *data_arena;
BuddyLevel *levels;
BuddyBlock *first_free_block;
};
struct buddy_ctx *buddy_ctx_alloc(u64 reserve);
void buddy_ctx_release(struct buddy_ctx *ctx);
BuddyCtx *buddy_ctx_alloc(u64 reserve);
void buddy_ctx_release(BuddyCtx *ctx);
struct buddy_block *buddy_alloc(struct buddy_ctx *ctx, u64 size);
void buddy_release(struct buddy_block *block);
BuddyBlock *buddy_alloc(BuddyCtx *ctx, u64 size);
void buddy_release(BuddyBlock *block);

View File

@ -369,13 +369,15 @@ GLOBAL const f64 *_f64_nan = (f64 *)&_f64_nan_u64;
* Common structs
* ========================== */
struct image_rgba {
typedef struct ImageDataRgba ImageDataRgba;
struct ImageDataRgba {
u32 width;
u32 height;
u32 *pixels; /* Array of [width * height] pixels */
};
struct pcm {
typedef struct PcmData PcmData;
struct PcmData {
u64 count;
i16 *samples;
};

View File

@ -3,12 +3,12 @@
#if GSTAT_ENABLED
struct _gstats {
struct atomic64_padded GSTAT_SOCK_BYTES_SENT;
struct atomic64_padded GSTAT_SOCK_BYTES_RECEIVED;
struct atomic64_padded GSTAT_MEMORY_COMMITTED;
struct atomic64_padded GSTAT_MEMORY_RESERVED;
struct atomic64_padded GSTAT_NUM_ARENAS;
struct atomic64_padded GSTAT_DEBUG_STEPS;
Atomic64Padded GSTAT_SOCK_BYTES_SENT;
Atomic64Padded GSTAT_SOCK_BYTES_RECEIVED;
Atomic64Padded GSTAT_MEMORY_COMMITTED;
Atomic64Padded GSTAT_MEMORY_RESERVED;
Atomic64Padded GSTAT_NUM_ARENAS;
Atomic64Padded GSTAT_DEBUG_STEPS;
};
extern struct _gstats _g_gstats;

View File

@ -10,18 +10,18 @@
struct rc_search_params {
/* In */
struct string name_lower;
String name_lower;
/* Out */
b32 found;
struct string data;
String data;
};
/* Find first resource with `type` and return the data in `udata`. */
INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entry_name, LONG_PTR udata)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct rc_search_params *params = (struct rc_search_params *)udata;
struct string entry_name_lower = string_lower(scratch.arena, string_from_wstr_no_limit(scratch.arena, (LPWSTR)wstr_entry_name));
String entry_name_lower = string_lower(scratch.arena, string_from_wstr_no_limit(scratch.arena, (LPWSTR)wstr_entry_name));
params->found = 0;
params->data = STRING(0, 0);
if (string_eq(entry_name_lower, params->name_lower)) {
@ -39,17 +39,17 @@ INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entr
return !params->found;
}
struct string _incbin_get(struct _incbin_rc_resource *inc)
String _incbin_get(_IncbinRcResource *inc)
{
enum _incbin_state state = atomic32_fetch(&inc->state);
if (state != INCBIN_STATE_SEARCHED) {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
if (state == INCBIN_STATE_UNSEARCHED) {
enum _incbin_state v = atomic32_fetch_test_set(&inc->state, state, INCBIN_STATE_SEARCHING);
if (v == state) {
/* Search RC file for the resource name */
struct string name_lower = string_lower(scratch.arena, inc->rc_name);
String name_lower = string_lower(scratch.arena, inc->rc_name);
struct rc_search_params params = { .name_lower = name_lower };
EnumResourceNamesW(0, RT_RCDATA, &enum_func, (LONG_PTR)&params);
if (!params.found) {

View File

@ -9,7 +9,7 @@
* file).
* ========================== */
#define INCBIN_INCLUDE(var, _rc_name) static struct _incbin_rc_resource _incbin_ ## var = { .rc_name = LIT_NOCAST((_rc_name)) }
#define INCBIN_INCLUDE(var, _rc_name) static _IncbinRcResource _incbin_ ## var = { .rc_name = LIT_NOCAST((_rc_name)) }
#define INCBIN_GET(var) _incbin_get(&_incbin_ ## var)
enum _incbin_state {
@ -18,13 +18,14 @@ enum _incbin_state {
INCBIN_STATE_SEARCHED
};
struct _incbin_rc_resource {
struct atomic32 state;
struct string rc_name;
struct string data;
typedef struct _IncbinRcResource _IncbinRcResource;
struct _IncbinRcResource {
Atomic32 state;
String rc_name;
String data;
};
struct string _incbin_get(struct _incbin_rc_resource *inc);
String _incbin_get(struct _IncbinRcResource *inc);
#else

View File

@ -7,95 +7,110 @@
* Math types
* ========================== */
#define V2(x, y) CPPCOMPAT_INITLIST_TYPE(struct v2) { (x), (y) }
#define V2_FROM_V2I32(v) V2((v).x, (v).y)
struct v2 {
#define V2FromXY(x, y) CPPCOMPAT_INITLIST_TYPE(V2) { (x), (y) }
#define V2FromV2i32(v) V2FromXY((v).x, (v).y)
typedef struct V2 V2;
struct V2 {
f32 x, y;
};
struct v2_array {
struct v2 *points;
typedef struct V2Array V2Array;
struct V2Array {
V2 *points;
u64 count;
};
#define V3(x, y, z) ((struct v3) { (x), (y), (z) })
struct v3 {
#define V3FromXYZ(x, y, z) ((V3) { (x), (y), (z) })
typedef struct V3 V3;
struct V3 {
f32 x, y, z;
};
struct v3_array {
struct v3 *points;
typedef struct V3Array V3Array;
struct V3Array {
V3 *points;
u64 count;
};
#define V4(x, y, z, w) ((struct v4) { (x), (y), (z), (w) })
struct v4 {
#define V4FromXYZW(x, y, z, w) ((V4) { (x), (y), (z), (w) })
typedef struct V4 V4;
struct V4 {
f32 x, y, z, w;
};
struct v4_array {
struct v4 *points;
typedef struct V4Array V4Array;
struct V4Array {
V4 *points;
u64 count;
};
#define V2I32(x, y) CPPCOMPAT_INITLIST_TYPE(struct v2i32) { (x), (y) }
struct v2i32 {
#define V2i32FromXY(x, y) CPPCOMPAT_INITLIST_TYPE(V2i32) { (x), (y) }
typedef struct V2i32 V2i32;
struct V2i32 {
i32 x, y;
};
#define V3I32(x, y, z) CPPCOMPAT_INITLIST_TYPE(struct v3i32) { (x), (y), (z) }
struct v3i32 {
#define V3i32FromXYZ(x, y, z) CPPCOMPAT_INITLIST_TYPE(V3i32) { (x), (y), (z) }
typedef struct V3i32 V3i32;
struct V3i32 {
i32 x, y, z;
};
struct xform {
struct v2 bx; /* X basis vector (x axis) */
struct v2 by; /* Y basis vector (y axis)*/
struct v2 og; /* Translation vector (origin) */
typedef struct Xform Xform;
struct Xform {
V2 bx; /* X basis vector (x axis) */
V2 by; /* Y basis vector (y axis)*/
V2 og; /* Translation vector (origin) */
};
struct mat4x4 {
typedef struct Mat4x4 Mat4x4;
struct Mat4x4 {
union {
struct { struct v4 bx, by, bz, bw; };
struct { V4 bx, by, bz, bw; };
f32 e[4][4];
};
};
#define RECT(_x, _y, _width, _height) (struct rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) }
#define RECT_FROM_V2(_pos, _size) (struct rect) { .pos = (_pos), .size = (_size) }
struct rect {
#define RECT(_x, _y, _width, _height) (Rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) }
#define RECT_FROM_V2(_pos, _size) (Rect) { .pos = (_pos), .size = (_size) }
typedef struct Rect Rect;
struct Rect {
union {
struct { f32 x, y, width, height; };
struct { struct v2 pos, size; };
struct { V2 pos, size; };
};
};
INLINE b32 rect_eq(struct rect r1, struct rect r2) { return r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height == r2.height; }
INLINE b32 rect_eq(Rect r1, Rect r2) { return r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height == r2.height; }
struct aabb {
struct v2 p0, p1;
typedef struct Aabb Aabb;
struct Aabb {
V2 p0, p1;
};
/* Values expected to be normalized 0.0 -> 1.0 */
#define CLIP_ALL ((struct clip_rect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
struct clip_rect {
struct v2 p0, p1;
#define CLIP_ALL ((ClipRect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
typedef struct ClipRect ClipRect;
struct ClipRect {
V2 p0, p1;
};
#define QUAD_UNIT_SQUARE (struct quad) { .p0 = V2(0, 0), .p1 = V2(0, 1), .p2 = V2(1, 1), .p3 = V2(1, 0) }
#define QUAD_UNIT_SQUARE_CENTERED (struct quad) { .p0 = V2(-0.5f, -0.5f), .p1 = V2(0.5f, -0.5f), .p2 = V2(0.5f, 0.5f), .p3 = V2(-0.5f, 0.5f) }
struct quad {
#define QUAD_UNIT_SQUARE (Quad) { .p0 = V2FromXY(0, 0), .p1 = V2FromXY(0, 1), .p2 = V2FromXY(1, 1), .p3 = V2FromXY(1, 0) }
#define QUAD_UNIT_SQUARE_CENTERED (Quad) { .p0 = V2FromXY(-0.5f, -0.5f), .p1 = V2FromXY(0.5f, -0.5f), .p2 = V2FromXY(0.5f, 0.5f), .p3 = V2FromXY(-0.5f, 0.5f) }
typedef struct Quad Quad;
struct Quad {
union {
struct { struct v2 p0, p1, p2, p3; };
struct { struct v2 e[4]; };
struct { V2 p0, p1, p2, p3; };
struct { V2 e[4]; };
};
};
/* (T)ranslation, (R)otation, (S)cale */
#define TRS(...) ((struct trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ })
struct trs {
struct v2 t;
struct v2 s;
#define MakeTrs(...) ((Trs) { .t = V2FromXY(0,0), .s = V2FromXY(1, 1), .r = 0, __VA_ARGS__ })
typedef struct Trs Trs;
struct Trs {
V2 t;
V2 s;
f32 r;
};
@ -751,53 +766,53 @@ INLINE f32 math_lerp_angle(f32 a, f32 b, f32 t) {
* V2
* ========================== */
INLINE struct v2 v2_mul(struct v2 a, f32 s)
INLINE V2 v2_mul(V2 a, f32 s)
{
return V2(a.x * s, a.y * s);
return V2FromXY(a.x * s, a.y * s);
}
INLINE struct v2 v2_mul_v2(struct v2 a, struct v2 b)
INLINE V2 v2_mul_v2(V2 a, V2 b)
{
return V2(a.x * b.x, a.y * b.y);
return V2FromXY(a.x * b.x, a.y * b.y);
}
INLINE struct v2 v2_div(struct v2 a, f32 s)
INLINE V2 v2_div(V2 a, f32 s)
{
f32 d = 1 / s;
return V2(a.x * d, a.y * d);
return V2FromXY(a.x * d, a.y * d);
}
INLINE struct v2 v2_div_v2(struct v2 a, struct v2 b)
INLINE V2 v2_div_v2(V2 a, V2 b)
{
return V2(a.x * (1 / b.x), a.y * (1 / b.y));
return V2FromXY(a.x * (1 / b.x), a.y * (1 / b.y));
}
INLINE struct v2 v2_neg(struct v2 a)
INLINE V2 v2_neg(V2 a)
{
return V2(-a.x, -a.y);
return V2FromXY(-a.x, -a.y);
}
INLINE struct v2 v2_add(struct v2 a, struct v2 b)
INLINE V2 v2_add(V2 a, V2 b)
{
return V2(a.x + b.x, a.y + b.y);
return V2FromXY(a.x + b.x, a.y + b.y);
}
INLINE struct v2 v2_sub(struct v2 a, struct v2 b)
INLINE V2 v2_sub(V2 a, V2 b)
{
return V2(a.x - b.x, a.y - b.y);
return V2FromXY(a.x - b.x, a.y - b.y);
}
INLINE f32 v2_len(struct v2 a)
INLINE f32 v2_len(V2 a)
{
return math_sqrt(a.x * a.x + a.y * a.y);
}
INLINE f32 v2_len_sq(struct v2 a)
INLINE f32 v2_len_sq(V2 a)
{
return a.x * a.x + a.y * a.y;
}
INLINE f32 v2_dot(struct v2 a, struct v2 b)
INLINE f32 v2_dot(V2 a, V2 b)
{
return a.x * b.x + a.y * b.y;
}
@ -805,37 +820,37 @@ INLINE f32 v2_dot(struct v2 a, struct v2 b)
/* Returns signed area between vectors (positive in clockwise direction)
* AKA perpendicular dot product
* AKA 2d cross-product */
INLINE f32 v2_wedge(struct v2 a, struct v2 b)
INLINE f32 v2_wedge(V2 a, V2 b)
{
return a.x * b.y - a.y * b.x;
}
/* Clockwise (right) perpendicular vector */
INLINE struct v2 v2_perp(struct v2 a)
INLINE V2 v2_perp(V2 a)
{
return V2(-a.y, a.x);
return V2FromXY(-a.y, a.x);
}
/* Clockwise (right) perpendicular vector scaled by s */
INLINE struct v2 v2_perp_mul(struct v2 a, f32 s)
INLINE V2 v2_perp_mul(V2 a, f32 s)
{
return V2(s * -a.y, s * a.x);
return V2FromXY(s * -a.y, s * a.x);
}
INLINE struct v2 v2_perp_towards_dir(struct v2 v, struct v2 dir)
INLINE V2 v2_perp_towards_dir(V2 v, V2 dir)
{
f32 wedge = v2_wedge(v, dir);
return v2_perp_mul(v, (wedge >= 0) - (wedge < 0));
}
/* Returns 1 if winding between vectors a & b is clockwise or straight, -1 if counter-clockwise */
INLINE i32 v2_winding(struct v2 a, struct v2 b)
INLINE i32 v2_winding(V2 a, V2 b)
{
f32 w = v2_wedge(a, b);
return (w >= 0) - (w < 0);
}
INLINE struct v2 v2_with_len(struct v2 a, f32 len)
INLINE V2 v2_with_len(V2 a, f32 len)
{
f32 l_sq = a.x * a.x + a.y * a.y;
if (l_sq != 0) {
@ -846,7 +861,7 @@ INLINE struct v2 v2_with_len(struct v2 a, f32 len)
return a;
}
INLINE struct v2 v2_clamp_len(struct v2 a, f32 max)
INLINE V2 v2_clamp_len(V2 a, f32 max)
{
f32 l_sq = a.x * a.x + a.y * a.y;
if (l_sq > max * max) {
@ -857,91 +872,91 @@ INLINE struct v2 v2_clamp_len(struct v2 a, f32 max)
return a;
}
INLINE struct v2 v2_norm(struct v2 a)
INLINE V2 v2_norm(V2 a)
{
return v2_with_len(a, 1.f);
}
INLINE struct v2 v2_round(struct v2 a)
INLINE V2 v2_round(V2 a)
{
return V2(math_round(a.x), math_round(a.y));
return V2FromXY(math_round(a.x), math_round(a.y));
}
INLINE struct v2i32 v2_round_to_int(struct v2 a)
INLINE V2i32 v2_round_to_int(V2 a)
{
return V2I32(math_round_to_int(a.x), math_round_to_int(a.y));
return V2i32FromXY(math_round_to_int(a.x), math_round_to_int(a.y));
}
INLINE struct v2 v2_floor(struct v2 a)
INLINE V2 v2_floor(V2 a)
{
return V2(math_floor(a.x), math_floor(a.y));
return V2FromXY(math_floor(a.x), math_floor(a.y));
}
INLINE struct v2 v2_ceil(struct v2 a)
INLINE V2 v2_ceil(V2 a)
{
return V2(math_ceil(a.x), math_ceil(a.y));
return V2FromXY(math_ceil(a.x), math_ceil(a.y));
}
INLINE f32 v2_distance(struct v2 a, struct v2 b)
INLINE f32 v2_distance(V2 a, V2 b)
{
f32 dx = b.x - a.x;
f32 dy = b.y - a.y;
return math_sqrt(dx * dx + dy * dy);
}
INLINE b32 v2_eq(struct v2 a, struct v2 b)
INLINE b32 v2_eq(V2 a, V2 b)
{
return a.x == b.x && a.y == b.y;
}
INLINE b32 v2_is_zero(struct v2 a)
INLINE b32 v2_is_zero(V2 a)
{
return a.x == 0 && a.y == 0;
}
INLINE struct v2 v2_rotated(struct v2 v, f32 a)
INLINE V2 v2_rotated(V2 v, f32 a)
{
f32 c = math_cos(a);
f32 s = math_sin(a);
return V2(v.x * c - v.y * s, v.x * s + v.y * c);
return V2FromXY(v.x * c - v.y * s, v.x * s + v.y * c);
}
INLINE struct v2 v2_from_angle(f32 a)
INLINE V2 v2_from_angle(f32 a)
{
return V2(math_cos(a), math_sin(a));
return V2FromXY(math_cos(a), math_sin(a));
}
INLINE f32 v2_angle(struct v2 v)
INLINE f32 v2_angle(V2 v)
{
return math_atan2(v.y, v.x);
}
INLINE f32 v2_angle_from_dirs(struct v2 dir1, struct v2 dir2)
INLINE f32 v2_angle_from_dirs(V2 dir1, V2 dir2)
{
return math_atan2(v2_wedge(dir1, dir2), v2_dot(dir1, dir2));
}
INLINE f32 v2_angle_from_points(struct v2 pt1, struct v2 pt2)
INLINE f32 v2_angle_from_points(V2 pt1, V2 pt2)
{
return v2_angle(v2_sub(pt2, pt1));
}
INLINE struct v2 v2_closest_point_ray(struct v2 ray_pos, struct v2 ray_dir_norm, struct v2 p)
INLINE V2 v2_closest_point_ray(V2 ray_pos, V2 ray_dir_norm, V2 p)
{
struct v2 ray_p_dir = v2_sub(p, ray_pos);
V2 ray_p_dir = v2_sub(p, ray_pos);
f32 dot = v2_dot(ray_dir_norm, ray_p_dir);
struct v2 ray_dir_closest = v2_mul(ray_dir_norm, dot);
V2 ray_dir_closest = v2_mul(ray_dir_norm, dot);
return v2_add(ray_pos, ray_dir_closest);
}
/* Interpolate position vectors */
INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
INLINE V2 v2_lerp(V2 val0, V2 val1, f32 t)
{
return V2(math_lerp_f32(val0.x, val1.x, t), math_lerp_f32(val0.y, val1.y, t));
return V2FromXY(math_lerp_f32(val0.x, val1.x, t), math_lerp_f32(val0.y, val1.y, t));
}
/* Interpolate direction vectors (spherical lerp) */
INLINE struct v2 v2_slerp(struct v2 val0, struct v2 val1, f32 t)
INLINE V2 v2_slerp(V2 val0, V2 val1, f32 t)
{
f32 rot = math_lerp_angle(v2_angle(val0), v2_angle(val1), t);
f32 len = math_lerp_f32(v2_len(val0), v2_len(val1), t);
@ -949,36 +964,36 @@ INLINE struct v2 v2_slerp(struct v2 val0, struct v2 val1, f32 t)
}
/* ========================== *
* V2I32
* V2i32
* ========================== */
INLINE b32 v2i32_eq(struct v2i32 a, struct v2i32 b)
INLINE b32 v2i32_eq(V2i32 a, V2i32 b)
{
return a.x == b.x && a.y == b.y;
}
INLINE struct v2i32 v2i32_neg(struct v2i32 a)
INLINE V2i32 v2i32_neg(V2i32 a)
{
return V2I32(-a.x, -a.y);
return V2i32FromXY(-a.x, -a.y);
}
INLINE struct v2i32 v2i32_add(struct v2i32 a, struct v2i32 b)
INLINE V2i32 v2i32_add(V2i32 a, V2i32 b)
{
return V2I32(a.x + b.x, a.y + b.y);
return V2i32FromXY(a.x + b.x, a.y + b.y);
}
INLINE struct v2i32 v2i32_sub(struct v2i32 a, struct v2i32 b)
INLINE V2i32 v2i32_sub(V2i32 a, V2i32 b)
{
return V2I32(a.x - b.x, a.y - b.y);
return V2i32FromXY(a.x - b.x, a.y - b.y);
}
/* ========================== *
* Mat4x4
* ========================== */
INLINE struct mat4x4 mat4x4_from_xform(struct xform xf)
INLINE Mat4x4 mat4x4_from_xform(Xform xf)
{
return CPPCOMPAT_INITLIST_TYPE(struct mat4x4) {
return CPPCOMPAT_INITLIST_TYPE(Mat4x4) {
.e = {
{xf.bx.x, xf.bx.y, 0, 0},
{xf.by.x, xf.by.y, 0, 0},
@ -988,9 +1003,9 @@ INLINE struct mat4x4 mat4x4_from_xform(struct xform xf)
};
}
INLINE struct mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z)
INLINE Mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z)
{
struct mat4x4 m = ZI;
Mat4x4 m = ZI;
f32 rl = 1.0f / (right - left);
f32 tb = 1.0f / (top - bottom);
@ -1007,7 +1022,7 @@ INLINE struct mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top,
return m;
}
INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
INLINE Mat4x4 mat4x4_mul(Mat4x4 m1, Mat4x4 m2)
{
f32 a00 = m1.e[0][0], a01 = m1.e[0][1], a02 = m1.e[0][2], a03 = m1.e[0][3],
a10 = m1.e[1][0], a11 = m1.e[1][1], a12 = m1.e[1][2], a13 = m1.e[1][3],
@ -1019,7 +1034,7 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
b20 = m2.e[2][0], b21 = m2.e[2][1], b22 = m2.e[2][2], b23 = m2.e[2][3],
b30 = m2.e[3][0], b31 = m2.e[3][1], b32 = m2.e[3][2], b33 = m2.e[3][3];
struct mat4x4 res;
Mat4x4 res;
res.e[0][0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;
res.e[0][1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;
res.e[0][2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;
@ -1045,138 +1060,138 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
* ========================== */
/* Construct identity xform */
#define XFORM_IDENT CPPCOMPAT_INITLIST_TYPE(struct xform) { .bx = V2(1, 0), .by = V2(0, 1) }
#define XFORM_IDENT_NOCAST { .bx = V2(1, 0), .by = V2(0, 1) }
#define XFORM_IDENT CPPCOMPAT_INITLIST_TYPE(Xform) { .bx = V2FromXY(1, 0), .by = V2FromXY(0, 1) }
#define XFORM_IDENT_NOCAST { .bx = V2FromXY(1, 0), .by = V2FromXY(0, 1) }
#define XFORM_POS(p) CPPCOMPAT_INITLIST_TYPE(struct xform) { .bx = V2(1, 0), .by = V2(0, 1), .og = (p) }
#define XFORM_POS(p) CPPCOMPAT_INITLIST_TYPE(Xform) { .bx = V2FromXY(1, 0), .by = V2FromXY(0, 1), .og = (p) }
/* Takes a translation, rotation, and scale as optional parameters for constructing an xform */
#define XFORM_TRS(...) xform_from_trs((struct trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ })
#define XFORM_TRS(...) xform_from_trs((Trs) { .t = V2FromXY(0,0), .s = V2FromXY(1, 1), .r = 0, __VA_ARGS__ })
INLINE struct xform xform_mul(struct xform a, struct xform b);
INLINE struct xform xform_rotated(struct xform xf, f32 angle);
INLINE struct xform xform_scaled(struct xform xf, struct v2 v);
INLINE struct v2 xform_basis_mul_v2(struct xform xf, struct v2 v);
INLINE struct v2 xform_mul_v2(struct xform xf, struct v2 v);
INLINE f32 xform_get_determinant(struct xform xf);
INLINE struct v2 xform_get_scale(struct xform xf);
INLINE f32 xform_get_rotation(struct xform xf);
INLINE Xform xform_mul(Xform a, Xform b);
INLINE Xform xform_rotated(Xform xf, f32 angle);
INLINE Xform xform_scaled(Xform xf, V2 v);
INLINE V2 xform_basis_mul_v2(Xform xf, V2 v);
INLINE V2 xform_mul_v2(Xform xf, V2 v);
INLINE f32 xform_get_determinant(Xform xf);
INLINE V2 xform_get_scale(Xform xf);
INLINE f32 xform_get_rotation(Xform xf);
INLINE b32 xform_eq(struct xform xf1, struct xform xf2)
INLINE b32 xform_eq(Xform xf1, Xform xf2)
{
return v2_eq(xf1.og, xf2.og) && v2_eq(xf1.bx, xf2.bx) && v2_eq(xf1.by, xf2.by);
}
INLINE struct xform xform_from_pos(struct v2 v)
INLINE Xform xform_from_pos(V2 v)
{
struct xform xf;
xf.bx = V2(1, 0);
xf.by = V2(0, 1);
Xform xf;
xf.bx = V2FromXY(1, 0);
xf.by = V2FromXY(0, 1);
xf.og = v;
return xf;
}
INLINE struct xform xform_from_rotation(f32 r)
INLINE Xform xform_from_rotation(f32 r)
{
struct xform res;
Xform res;
f32 c = math_cos(r);
f32 s = math_sin(r);
res.bx = V2(c, s);
res.by = V2(-s, c);
res.og = V2(0, 0);
res.bx = V2FromXY(c, s);
res.by = V2FromXY(-s, c);
res.og = V2FromXY(0, 0);
return res;
}
INLINE struct xform xform_from_scale(struct v2 scale)
INLINE Xform xform_from_scale(V2 scale)
{
struct xform res;
res.bx = V2(scale.x, 0);
res.by = V2(0, scale.y);
res.og = V2(0, 0);
Xform res;
res.bx = V2FromXY(scale.x, 0);
res.by = V2FromXY(0, scale.y);
res.og = V2FromXY(0, 0);
return res;
}
INLINE struct xform xform_from_trs(struct trs trs)
INLINE Xform xform_from_trs(Trs trs)
{
struct xform xf = XFORM_POS(trs.t);
Xform xf = XFORM_POS(trs.t);
xf = xform_rotated(xf, trs.r);
xf = xform_scaled(xf, trs.s);
return xf;
}
INLINE struct xform xform_from_rect(struct rect rect)
INLINE Xform xform_from_rect(Rect rect)
{
struct v2 half_size = v2_mul(rect.size, 0.5);
struct xform xf = ZI;
xf.bx = V2(rect.size.x, 0);
xf.by = V2(0, rect.size.y);
V2 half_size = v2_mul(rect.size, 0.5);
Xform xf = ZI;
xf.bx = V2FromXY(rect.size.x, 0);
xf.by = V2FromXY(0, rect.size.y);
xf.og = v2_add(rect.pos, half_size);
return xf;
}
INLINE struct xform xform_translated(struct xform xf, struct v2 v)
INLINE Xform xform_translated(Xform xf, V2 v)
{
xf.og = V2(xf.bx.x * v.x + xf.by.x * v.y + xf.og.x, xf.bx.y * v.x + xf.by.y * v.y + xf.og.y);
xf.og = V2FromXY(xf.bx.x * v.x + xf.by.x * v.y + xf.og.x, xf.bx.y * v.x + xf.by.y * v.y + xf.og.y);
return xf;
}
INLINE struct xform xform_translated_world(struct xform xf, struct v2 v)
INLINE Xform xform_translated_world(Xform xf, V2 v)
{
xf.og = v2_add(xf.og, v);
return xf;
}
INLINE struct xform xform_rotated(struct xform xf, f32 r)
INLINE Xform xform_rotated(Xform xf, f32 r)
{
return xform_mul(xf, xform_from_rotation(r));
}
INLINE struct xform xform_rotated_world(struct xform xf, f32 r)
INLINE Xform xform_rotated_world(Xform xf, f32 r)
{
return xform_mul(xform_from_rotation(r), xf);
}
INLINE struct xform xform_basis_rotated_world(struct xform xf, f32 r)
INLINE Xform xform_basis_rotated_world(Xform xf, f32 r)
{
f32 diff = r;
f32 c = math_cos(diff);
f32 s = math_sin(diff);
xf.bx = V2(xf.bx.x * c - xf.bx.y * s, xf.bx.x * s + xf.bx.y * c);
xf.by = V2(xf.by.x * c - xf.by.y * s, xf.by.x * s + xf.by.y * c);
xf.bx = V2FromXY(xf.bx.x * c - xf.bx.y * s, xf.bx.x * s + xf.bx.y * c);
xf.by = V2FromXY(xf.by.x * c - xf.by.y * s, xf.by.x * s + xf.by.y * c);
return xf;
}
INLINE struct xform xform_basis_with_rotation_world(struct xform xf, f32 r)
INLINE Xform xform_basis_with_rotation_world(Xform xf, f32 r)
{
return xform_basis_rotated_world(xf, r - xform_get_rotation(xf));
}
INLINE struct xform xform_scaled(struct xform xf, struct v2 scale)
INLINE Xform xform_scaled(Xform xf, V2 scale)
{
xf.bx = v2_mul(xf.bx, scale.x);
xf.by = v2_mul(xf.by, scale.y);
return xf;
}
INLINE struct xform xform_scaled_world(struct xform xf, struct v2 scale)
INLINE Xform xform_scaled_world(Xform xf, V2 scale)
{
struct xform res;
Xform res;
res.bx = v2_mul_v2(xf.bx, scale);
res.by = v2_mul_v2(xf.by, scale);
res.og = v2_mul_v2(xf.og, scale);
return res;
}
INLINE struct xform xform_lerp(struct xform a, struct xform b, f32 t)
INLINE Xform xform_lerp(Xform a, Xform b, f32 t)
{
struct xform res;
Xform res;
res.bx = v2_slerp(a.bx, b.bx, t);
res.by = v2_slerp(a.by, b.by, t);
res.og = v2_lerp(a.og, b.og, t);
return res;
}
INLINE struct xform xform_invert(struct xform xf)
INLINE Xform xform_invert(Xform xf)
{
f32 det = xform_get_determinant(xf);
f32 inv_det = 1.0f / det;
@ -1185,17 +1200,17 @@ INLINE struct xform xform_invert(struct xform xf)
xf.bx.x = xf.by.y;
xf.by.y = old_bx_x;
xf.bx = v2_mul_v2(xf.bx, V2(inv_det, -inv_det));
xf.by = v2_mul_v2(xf.by, V2(-inv_det, inv_det));
xf.bx = v2_mul_v2(xf.bx, V2FromXY(inv_det, -inv_det));
xf.by = v2_mul_v2(xf.by, V2FromXY(-inv_det, inv_det));
xf.og = xform_basis_mul_v2(xf, v2_neg(xf.og));
return xf;
}
INLINE struct xform xform_mul(struct xform a, struct xform b)
INLINE Xform xform_mul(Xform a, Xform b)
{
struct xform res;
Xform res;
res.bx.x = a.bx.x * b.bx.x + a.by.x * b.bx.y;
res.bx.y = a.bx.y * b.bx.x + a.by.y * b.bx.y;
res.by.x = a.bx.x * b.by.x + a.by.x * b.by.y;
@ -1204,46 +1219,46 @@ INLINE struct xform xform_mul(struct xform a, struct xform b)
return res;
}
INLINE struct v2 xform_basis_mul_v2(struct xform xf, struct v2 v)
INLINE V2 xform_basis_mul_v2(Xform xf, V2 v)
{
return V2(
return V2FromXY(
xf.bx.x * v.x + xf.by.x * v.y,
xf.bx.y * v.x + xf.by.y * v.y
);
}
INLINE struct v2 xform_mul_v2(struct xform xf, struct v2 v)
INLINE V2 xform_mul_v2(Xform xf, V2 v)
{
struct v2 res = xform_basis_mul_v2(xf, v);
V2 res = xform_basis_mul_v2(xf, v);
res = v2_add(res, xf.og);
return res;
}
INLINE struct xform xform_basis(struct xform xf)
INLINE Xform xform_basis(Xform xf)
{
struct xform res = ZI;
Xform res = ZI;
res.bx = xf.bx;
res.by = xf.by;
return res;
}
INLINE struct v2 xform_basis_invert_mul_v2(struct xform xf, struct v2 v)
INLINE V2 xform_basis_invert_mul_v2(Xform xf, V2 v)
{
struct xform inv = xform_invert(xf);
struct v2 res = xform_basis_mul_v2(inv, v);
Xform inv = xform_invert(xf);
V2 res = xform_basis_mul_v2(inv, v);
return res;
}
/* TODO: Get rid of this? Just force caller to use invert manually since it's expensive. */
INLINE struct v2 xform_invert_mul_v2(struct xform xf, struct v2 v)
INLINE V2 xform_invert_mul_v2(Xform xf, V2 v)
{
struct xform inv = xform_invert(xf);
Xform inv = xform_invert(xf);
return xform_mul_v2(inv, v);
}
INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad)
INLINE Quad xform_mul_quad(Xform xf, Quad quad)
{
struct quad res;
Quad res;
res.p0 = xform_mul_v2(xf, quad.p0);
res.p1 = xform_mul_v2(xf, quad.p1);
res.p2 = xform_mul_v2(xf, quad.p2);
@ -1251,77 +1266,77 @@ INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad)
return res;
}
INLINE f32 xform_get_determinant(struct xform xf)
INLINE f32 xform_get_determinant(Xform xf)
{
return v2_wedge(xf.bx, xf.by);
}
INLINE struct v2 xform_get_right(struct xform xf)
INLINE V2 xform_get_right(Xform xf)
{
return xf.bx;
}
INLINE struct v2 xform_get_left(struct xform xf)
INLINE V2 xform_get_left(Xform xf)
{
return v2_neg(xf.bx);
}
INLINE struct v2 xform_get_up(struct xform xf)
INLINE V2 xform_get_up(Xform xf)
{
return v2_neg(xf.by);
}
INLINE struct v2 xform_get_down(struct xform xf)
INLINE V2 xform_get_down(Xform xf)
{
return xf.by;
}
INLINE f32 xform_get_rotation(struct xform xf)
INLINE f32 xform_get_rotation(Xform xf)
{
return v2_angle(xf.bx);
}
INLINE struct v2 xform_get_scale(struct xform xf)
INLINE V2 xform_get_scale(Xform xf)
{
f32 det_sign = math_fsign(xform_get_determinant(xf));
return V2(v2_len(xf.bx), det_sign * v2_len(xf.by));
return V2FromXY(v2_len(xf.bx), det_sign * v2_len(xf.by));
}
/* ========================== *
* Quad
* ========================== */
INLINE struct quad quad_from_rect(struct rect rect)
INLINE Quad quad_from_rect(Rect rect)
{
struct quad res;
res.p0 = V2(rect.x, rect.y); /* Top left */
res.p1 = V2(rect.x + rect.width, rect.y); /* Top right */
res.p2 = V2(rect.x + rect.width, rect.y + rect.height); /* Bottom right */
res.p3 = V2(rect.x, rect.y + rect.height); /* Bottom left */
Quad res;
res.p0 = V2FromXY(rect.x, rect.y); /* Top left */
res.p1 = V2FromXY(rect.x + rect.width, rect.y); /* Top right */
res.p2 = V2FromXY(rect.x + rect.width, rect.y + rect.height); /* Bottom right */
res.p3 = V2FromXY(rect.x, rect.y + rect.height); /* Bottom left */
return res;
}
INLINE struct quad quad_from_aabb(struct aabb aabb)
INLINE Quad quad_from_aabb(Aabb aabb)
{
struct quad res;
res.p0 = V2(aabb.p0.x, aabb.p0.y); /* Top left */
res.p1 = V2(aabb.p1.x, aabb.p0.y); /* Top right */
res.p2 = V2(aabb.p1.x, aabb.p1.y); /* Bottom right */
res.p3 = V2(aabb.p0.x, aabb.p1.y); /* Bottom left */
Quad res;
res.p0 = V2FromXY(aabb.p0.x, aabb.p0.y); /* Top left */
res.p1 = V2FromXY(aabb.p1.x, aabb.p0.y); /* Top right */
res.p2 = V2FromXY(aabb.p1.x, aabb.p1.y); /* Bottom right */
res.p3 = V2FromXY(aabb.p0.x, aabb.p1.y); /* Bottom left */
return res;
}
INLINE struct quad quad_from_line(struct v2 start, struct v2 end, f32 thickness)
INLINE Quad quad_from_line(V2 start, V2 end, f32 thickness)
{
f32 width = thickness / 2.f;
struct v2 dir = v2_norm(v2_sub(end, start));
struct v2 dir_perp = v2_perp(dir);
V2 dir = v2_norm(v2_sub(end, start));
V2 dir_perp = v2_perp(dir);
struct v2 left = v2_mul(dir_perp, -width);
struct v2 right = v2_mul(dir_perp, width);
V2 left = v2_mul(dir_perp, -width);
V2 right = v2_mul(dir_perp, width);
struct quad res;
Quad res;
res.p0 = v2_add(start, left);
res.p1 = v2_add(start, right);
res.p2 = v2_add(end, right);
@ -1329,13 +1344,13 @@ INLINE struct quad quad_from_line(struct v2 start, struct v2 end, f32 thickness)
return res;
}
INLINE struct quad quad_from_ray(struct v2 pos, struct v2 rel, f32 thickness)
INLINE Quad quad_from_ray(V2 pos, V2 rel, f32 thickness)
{
struct v2 end = v2_add(pos, rel);
V2 end = v2_add(pos, rel);
return quad_from_line(pos, end, thickness);
}
INLINE struct quad quad_scale(struct quad q, f32 s)
INLINE Quad quad_scale(Quad q, f32 s)
{
q.p0 = v2_mul(q.p0, s);
q.p1 = v2_mul(q.p1, s);
@ -1344,9 +1359,9 @@ INLINE struct quad quad_scale(struct quad q, f32 s)
return q;
}
INLINE struct quad quad_round(struct quad quad)
INLINE Quad quad_round(Quad quad)
{
struct quad res;
Quad res;
res.p0 = v2_round(quad.p0);
res.p1 = v2_round(quad.p1);
res.p2 = v2_round(quad.p2);
@ -1354,9 +1369,9 @@ INLINE struct quad quad_round(struct quad quad)
return res;
}
INLINE struct quad quad_floor(struct quad quad)
INLINE Quad quad_floor(Quad quad)
{
struct quad res;
Quad res;
res.p0 = v2_floor(quad.p0);
res.p1 = v2_floor(quad.p1);
res.p2 = v2_floor(quad.p2);
@ -1368,9 +1383,9 @@ INLINE struct quad quad_floor(struct quad quad)
* Convex polygon
* ========================== */
INLINE struct v2 math_poly_center(struct v2_array a)
INLINE V2 math_poly_center(V2Array a)
{
struct v2 sum = V2(0, 0);
V2 sum = V2FromXY(0, 0);
for (u64 i = 0; i < a.count; ++i) {
sum = v2_add(sum, a.points[i]);
}
@ -1378,14 +1393,20 @@ INLINE struct v2 math_poly_center(struct v2_array a)
}
/* ========================== *
* Other
* Spring
* ========================== */
/* https://box2d.org/files/ErinCatto_SoftConstraints_GDC2011.pdf */
struct math_spring { f32 bias_rate; f32 mass_scale; f32 impulse_scale; };
INLINE struct math_spring math_spring_init(f32 hertz, f32 damping_ratio, f32 dt)
typedef struct SoftSpring SoftSpring;
struct SoftSpring {
f32 bias_rate;
f32 mass_scale;
f32 impulse_scale;
};
INLINE SoftSpring math_spring_init(f32 hertz, f32 damping_ratio, f32 dt)
{
struct math_spring res;
SoftSpring res;
if (hertz == 0.0f) {
res.bias_rate = 0;
res.mass_scale = 1;

View File

@ -4,7 +4,7 @@
#if PLATFORM_WINDOWS
# define BCRYPT_RNG_ALG_HANDLE ((void *)0x00000081)
u32 BCryptGenRandom(void *algorithm, u8 *buffer, u32 buffer_size, u32 flags);
void rand_true(struct string buffer)
void rand_true(String buffer)
{
BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (u8 *)buffer.text, buffer.len, 0);
}
@ -16,7 +16,7 @@ void rand_true(struct string buffer)
* Stateful prng
* ========================== */
u64 rand_u64_from_state(struct rand_state *state)
u64 rand_u64_from_state(RandState *state)
{
u64 seed = state->seed;
if (seed == 0) {
@ -26,7 +26,7 @@ u64 rand_u64_from_state(struct rand_state *state)
return seed ^ rand_u64_from_seed(++state->counter);
}
f64 rand_f64_from_state(struct rand_state *state, f64 range_start, f64 range_end)
f64 rand_f64_from_state(RandState *state, f64 range_start, f64 range_end)
{
return range_start + (range_end - range_start) * ((f64)(rand_u64_from_state(state) % F64_RAND_MAX) / (f64)F64_RAND_MAX);
}

View File

@ -1,13 +1,14 @@
struct rand_state {
typedef struct RandState RandState;
struct RandState {
/* If a state's seed == 0 upon a call to a related function, it will be initialized using platform's true rng source */
u64 seed;
u64 counter;
};
void rand_true(struct string buffer);
void rand_true(String buffer);
u64 rand_u64_from_state(struct rand_state *state);
f64 rand_f64_from_state(struct rand_state *state, f64 range_start, f64 range_end);
u64 rand_u64_from_state(RandState *state);
f64 rand_f64_from_state(RandState *state, f64 range_start, f64 range_end);
u64 rand_u64_from_seed(u64 seed);
u64 rand_u64_from_seeds(u64 seed_a, u64 seed_b);

View File

@ -16,22 +16,22 @@
#define INT_CHARS ("0123456789abcdef")
struct string string_from_char(struct arena *arena, char c)
String string_from_char(Arena *arena, char c)
{
u8 *dst = arena_push_no_zero(arena, u8);
*dst = c;
return (struct string) {
return (String) {
.len = 1,
.text = dst
};
}
struct string string_from_uint(struct arena *arena, u64 n, u64 base, u64 zfill)
String string_from_uint(Arena *arena, u64 n, u64 base, u64 zfill)
{
/* Base too large */
ASSERT(base <= (countof(INT_CHARS) - 1));
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
/* Build backwards text starting from least significant digit */
u64 len = 0;
@ -55,13 +55,13 @@ struct string string_from_uint(struct arena *arena, u64 n, u64 base, u64 zfill)
scratch_end(scratch);
return (struct string) {
return (String) {
.len = len,
.text = final_text
};
}
struct string string_from_int(struct arena *arena, i64 n, u64 base, u64 zfill)
String string_from_int(Arena *arena, i64 n, u64 base, u64 zfill)
{
u8 *final_text = arena_push_dry(arena, u8);
u8 len = 0;
@ -72,26 +72,26 @@ struct string string_from_int(struct arena *arena, i64 n, u64 base, u64 zfill)
n = -n;
}
/* Push unsigned number */
struct string uint_str = string_from_uint(arena, n, base, zfill);
return (struct string) {
String uint_str = string_from_uint(arena, n, base, zfill);
return (String) {
.len = len + uint_str.len,
.text = final_text
};
}
struct string string_from_ptr(struct arena *arena, void *ptr)
String string_from_ptr(Arena *arena, void *ptr)
{
struct string prepend = string_copy(arena, LIT("0x"));
struct string uint_str = string_from_uint(arena, (u64)ptr, 16, sizeof(ptr));
return (struct string) {
String prepend = string_copy(arena, LIT("0x"));
String uint_str = string_from_uint(arena, (u64)ptr, 16, sizeof(ptr));
return (String) {
.len = prepend.len + uint_str.len,
.text = prepend.text
};
}
struct string string_from_float(struct arena *arena, f64 f, u32 precision)
String string_from_float(Arena *arena, f64 f, u32 precision)
{
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
u8 *final_text = arena_push_dry(arena, u8);
u64 final_len = 0;
@ -148,15 +148,15 @@ struct string string_from_float(struct arena *arena, f64 f, u32 precision)
scratch_end(scratch);
return (struct string) {
return (String) {
.len = final_len,
.text = final_text
};
}
struct string string_from_handle(struct arena *arena, u64 v0, u64 v1)
String string_from_handle(Arena *arena, u64 v0, u64 v1)
{
struct string res = ZI;
String res = ZI;
res.text = arena_push_dry(arena, u8);
res.len += string_copy(arena, LIT("h")).len;
res.len += string_from_uint(arena, v0, 16, 0).len;
@ -165,9 +165,9 @@ struct string string_from_handle(struct arena *arena, u64 v0, u64 v1)
return res;
}
struct string string_from_uid(struct arena *arena, struct uid uid)
String string_from_uid(Arena *arena, UID uid)
{
struct string res = ZI;
String res = ZI;
res.text = arena_push_dry(arena, u8);
res.len += string_from_uint(arena, (uid.hi >> 32), 16, 8).len;
return res;
@ -177,9 +177,9 @@ struct string string_from_uid(struct arena *arena, struct uid uid)
* String operations
* ========================== */
struct string string_copy(struct arena *arena, struct string src)
String string_copy(Arena *arena, String src)
{
struct string str = {
String str = {
.len = src.len,
.text = arena_push_array_no_zero(arena, u8, src.len)
};
@ -187,31 +187,31 @@ struct string string_copy(struct arena *arena, struct string src)
return str;
}
struct string string_copy_to_string(struct string dst, struct string src)
String string_copy_to_string(String dst, String src)
{
struct string res = ZI;
String res = ZI;
res.len = min_u64(dst.len, src.len);
res.text = dst.text;
MEMCPY(res.text, src.text, res.len);
return res;
}
struct string string_repeat(struct arena *arena, struct string src, u64 count)
String string_repeat(Arena *arena, String src, u64 count)
{
u64 final_len = src.len * count;
u8 *final_text = arena_push_array_no_zero(arena, u8, final_len);
for (u64 i = 0; i < count; ++i) {
MEMCPY(final_text + (src.len * i), src.text, src.len);
}
return (struct string) {
return (String) {
.text = final_text,
.len = final_len
};
}
struct string string_cat(struct arena *arena, struct string str1, struct string str2)
String string_cat(Arena *arena, String str1, String str2)
{
struct string new_str = ZI;
String new_str = ZI;
new_str.len = str1.len + str2.len;
new_str.text = arena_push_array_no_zero(arena, u8, new_str.len);
MEMCPY(new_str.text, str1.text, str1.len);
@ -221,50 +221,50 @@ struct string string_cat(struct arena *arena, struct string str1, struct string
/* `arena` is where pieces will be allocated. These strings point
* into the existing string and do not allocate any new text. */
struct string_array string_split(struct arena *arena, struct string str, struct string delim)
StringArray string_split(Arena *arena, String str, String delim)
{
struct string_array pieces = ZI;
pieces.strings = arena_push_dry(arena, struct string);
StringArray pieces = ZI;
pieces.strings = arena_push_dry(arena, String);
i64 piece_start = 0;
for (i64 i = 0; i < (i64)str.len - (i64)delim.len; ++i) {
struct string cmp = ZI;
String cmp = ZI;
cmp.text = &str.text[i];
cmp.len = min_i64(str.len - i, delim.len);
b32 is_delimiter = string_eq(cmp, delim);
if (is_delimiter) {
struct string piece = ZI;
String piece = ZI;
piece.text = &str.text[piece_start];
piece.len = i - piece_start;
i += delim.len;
piece_start = i;
if (piece.len > 0) {
*arena_push_no_zero(arena, struct string) = piece;
*arena_push_no_zero(arena, String) = piece;
++pieces.count;
}
}
}
if (piece_start < (i64)str.len) {
struct string piece = ZI;
String piece = ZI;
piece.text = &str.text[piece_start];
piece.len = str.len - piece_start;
*arena_push_no_zero(arena, struct string) = piece;
*arena_push_no_zero(arena, String) = piece;
++pieces.count;
}
return pieces;
}
/* NOTE: Really slow */
struct string string_indent(struct arena *arena, struct string str, u32 indent)
String string_indent(Arena *arena, String str, u32 indent)
{
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
u64 final_len = 0;
u8 *final_text = arena_push_dry(arena, u8);
struct string_array split = string_split(scratch.arena, str, LIT("\n"));
StringArray split = string_split(scratch.arena, str, LIT("\n"));
for (u64 i = 0; i < split.count; ++i) {
struct string piece = split.strings[i];
String piece = split.strings[i];
for (u32 j = 0; j < indent; ++j) {
string_from_char(arena, ' ');
++final_len;
@ -279,15 +279,15 @@ struct string string_indent(struct arena *arena, struct string str, u32 indent)
scratch_end(scratch);
return (struct string) {
return (String) {
.len = final_len,
.text = final_text
};
}
struct string string_lower(struct arena *arena, struct string str)
String string_lower(Arena *arena, String str)
{
struct string res = ZI;
String res = ZI;
res.text = arena_push_array_no_zero(arena, u8, str.len);
res.len = str.len;
@ -302,7 +302,7 @@ struct string string_lower(struct arena *arena, struct string str)
return res;
}
b32 string_eq(struct string str1, struct string str2)
b32 string_eq(String str1, String str2)
{
b32 eq = 1;
if (str1.len == str2.len) {
@ -318,7 +318,7 @@ b32 string_eq(struct string str1, struct string str2)
return eq;
}
i32 string_cmp(struct string str1, struct string str2)
i32 string_cmp(String str1, String str2)
{
i32 res = 0;
for (u64 i = 0; i < min_u64(str1.len, str2.len); ++i) {
@ -337,7 +337,7 @@ i32 string_cmp(struct string str1, struct string str2)
return res;
}
b32 string_contains(struct string str, struct string substring)
b32 string_contains(String str, String substring)
{
if (substring.len > str.len) {
return 0;
@ -359,7 +359,7 @@ b32 string_contains(struct string str, struct string substring)
return 0;
}
b32 string_starts_with(struct string str, struct string substring)
b32 string_starts_with(String str, String substring)
{
if (str.len >= substring.len) {
for (u64 i = 0; i < substring.len; ++i) {
@ -372,7 +372,7 @@ b32 string_starts_with(struct string str, struct string substring)
return 0;
}
b32 string_ends_with(struct string str, struct string substring)
b32 string_ends_with(String str, String substring)
{
if (str.len >= substring.len) {
u64 start = str.len - substring.len;
@ -421,7 +421,7 @@ b32 string_ends_with(struct string str, struct string substring)
* %e/%E equivalent? (scientific notation of floats)
* %o equivalent? (octal representation)
*/
struct string string_formatv(struct arena *arena, struct string fmt, va_list args)
String string_formatv(Arena *arena, String fmt, va_list args)
{
__prof;
@ -441,7 +441,7 @@ struct string string_formatv(struct arena *arena, struct string fmt, va_list arg
}
if (!no_more_args && !escape && *c == '%' && *next == 'F') {
struct string parsed_str = ZI;
String parsed_str = ZI;
/* Detect arg type and parse to string */
struct fmt_arg arg = va_arg(args, struct fmt_arg);
switch (arg.type) {
@ -514,17 +514,17 @@ struct string string_formatv(struct arena *arena, struct string fmt, va_list arg
}
#endif
return (struct string) {
return (String) {
.len = final_len,
.text = final_text
};
}
struct string _string_format(struct arena *arena, struct string fmt, ...)
String _string_format(Arena *arena, String fmt, ...)
{
va_list args;
va_start(args, fmt);
struct string new_str = string_formatv(arena, fmt, args);
String new_str = string_formatv(arena, fmt, args);
va_end(args);
return new_str;
}
@ -535,7 +535,7 @@ struct string _string_format(struct arena *arena, struct string fmt, ...)
/* Codepoint iteration */
struct string_codepoint_iter string_codepoint_iter_begin(struct string str)
struct string_codepoint_iter string_codepoint_iter_begin(String str)
{
return (struct string_codepoint_iter) {
.src = str
@ -546,8 +546,8 @@ struct string_codepoint_iter string_codepoint_iter_begin(struct string str)
b32 string_codepoint_iter_next(struct string_codepoint_iter *iter)
{
if (iter->pos < iter->src.len) {
struct string str_remaining = { .len = (iter->src.len - iter->pos), .text = iter->src.text + iter->pos };
struct uni_decode_utf8_result decoded = uni_decode_utf8(str_remaining);
String str_remaining = { .len = (iter->src.len - iter->pos), .text = iter->src.text + iter->pos };
Utf8DecodeResult decoded = uni_decode_utf8(str_remaining);
iter->pos += decoded.advance8;
iter->codepoint = decoded.codepoint;
return 1;
@ -563,18 +563,18 @@ void string_codepoint_iter_end(struct string_codepoint_iter *iter)
}
/* utf8 <- utf16 */
struct string string_from_string16(struct arena *arena, struct string16 str16)
String string_from_string16(Arena *arena, String16 str16)
{
struct string res = {
String res = {
.len = 0,
.text = arena_push_dry(arena, u8)
};
u64 pos16 = 0;
while (pos16 < str16.len) {
struct string16 str16_remaining = { .len = (str16.len - pos16), .text = str16.text + pos16 };
struct uni_decode_utf16_result decoded = uni_decode_utf16(str16_remaining);
struct uni_encode_utf8_result encoded = uni_encode_utf8(decoded.codepoint);
String16 str16_remaining = { .len = (str16.len - pos16), .text = str16.text + pos16 };
Utf16DecodeResult decoded = uni_decode_utf16(str16_remaining);
Utf8EncodeResult encoded = uni_encode_utf8(decoded.codepoint);
u8 *dst = arena_push_array_no_zero(arena, u8, encoded.count8);
MEMCPY(dst, encoded.chars8, encoded.count8);
@ -587,18 +587,18 @@ struct string string_from_string16(struct arena *arena, struct string16 str16)
}
/* utf8 <- utf32 */
struct string string_from_string32(struct arena *arena, struct string32 str32)
String string_from_string32(Arena *arena, String32 str32)
{
struct string res = {
String res = {
.len = 0,
.text = arena_push_dry(arena, u8)
};
u64 pos32 = 0;
while (pos32 < str32.len) {
struct string32 str32_remaining = { .len = (str32.len - pos32), .text = str32.text + pos32 };
struct uni_decode_utf32_result decoded = uni_decode_utf32(str32_remaining);
struct uni_encode_utf8_result encoded = uni_encode_utf8(decoded.codepoint);
String32 str32_remaining = { .len = (str32.len - pos32), .text = str32.text + pos32 };
Utf32DecodeResult decoded = uni_decode_utf32(str32_remaining);
Utf8EncodeResult encoded = uni_encode_utf8(decoded.codepoint);
u8 *dst = arena_push_array_no_zero(arena, u8, encoded.count8);
MEMCPY(dst, &encoded.chars8, encoded.count8);
@ -611,18 +611,18 @@ struct string string_from_string32(struct arena *arena, struct string32 str32)
}
/* utf16 <- utf8 */
struct string16 string16_from_string(struct arena *arena, struct string str8)
String16 string16_from_string(Arena *arena, String str8)
{
struct string16 res = {
String16 res = {
.len = 0,
.text = arena_push_dry(arena, u16)
};
u64 pos8 = 0;
while (pos8 < str8.len) {
struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining);
struct uni_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint);
String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
Utf8DecodeResult decoded = uni_decode_utf8(str8_remaining);
Utf16EncodeResult encoded = uni_encode_utf16(decoded.codepoint);
u16 *dst = arena_push_array_no_zero(arena, u16, encoded.count16);
MEMCPY(dst, encoded.chars16, (encoded.count16 << 1));
@ -635,18 +635,18 @@ struct string16 string16_from_string(struct arena *arena, struct string str8)
}
/* utf32 <- utf8 */
struct string32 string32_from_string(struct arena *arena, struct string str8)
String32 string32_from_string(Arena *arena, String str8)
{
struct string32 res = {
String32 res = {
.len = 0,
.text = arena_push_dry(arena, u32)
};
u64 pos8 = 0;
while (pos8 < str8.len) {
struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining);
struct uni_encode_utf32_result encoded = uni_encode_utf32(decoded.codepoint);
String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
Utf8DecodeResult decoded = uni_decode_utf8(str8_remaining);
Utf32EncodeResult encoded = uni_encode_utf32(decoded.codepoint);
u32 *dst = arena_push_no_zero(arena, u32);
*dst = encoded.chars32;
@ -688,7 +688,7 @@ u64 cstr_len(char *cstr, u64 limit)
return end - cstr;
}
char *cstr_from_string(struct arena *arena, struct string src)
char *cstr_from_string(Arena *arena, String src)
{
u8 *text = arena_push_array_no_zero(arena, u8, src.len + 1);
MEMCPY(text, src.text, src.len);
@ -696,7 +696,7 @@ char *cstr_from_string(struct arena *arena, struct string src)
return (char *)text;
}
char *cstr_buff_from_string(struct string dst_buff, struct string src)
char *cstr_buff_from_string(String dst_buff, String src)
{
if (dst_buff.len > 0) {
u64 len = min_u64(src.len, dst_buff.len - 1);
@ -706,19 +706,19 @@ char *cstr_buff_from_string(struct string dst_buff, struct string src)
return (char *)dst_buff.text;
}
struct string string_from_cstr_no_limit(char *cstr)
String string_from_cstr_no_limit(char *cstr)
{
u64 len = cstr_len_no_limit(cstr);
return (struct string) {
return (String) {
.len = len,
.text = (u8 *)cstr
};
}
struct string string_from_cstr(char *cstr, u64 limit)
String string_from_cstr(char *cstr, u64 limit)
{
u64 len = cstr_len(cstr, limit);
return (struct string) {
return (String) {
.text = (u8 *)cstr,
.len = len
};
@ -754,45 +754,45 @@ u64 wstr_len(wchar_t *wstr, u64 limit)
return end - wstr;
}
wchar_t *wstr_from_string(struct arena *arena, struct string src)
wchar_t *wstr_from_string(Arena *arena, String src)
{
struct string16 str16 = string16_from_string(arena, src);
String16 str16 = string16_from_string(arena, src);
*arena_push_no_zero(arena, u16) = 0;
return (wchar_t *)str16.text;
}
wchar_t *wstr_from_string16(struct arena *arena, struct string16 src)
wchar_t *wstr_from_string16(Arena *arena, String16 src)
{
u16 *text = arena_push_array_no_zero(arena, u16, src.len + 1);
text[src.len] = 0;
return (wchar_t *)text;
}
struct string string_from_wstr_no_limit(struct arena *arena, wchar_t *wstr)
String string_from_wstr_no_limit(Arena *arena, wchar_t *wstr)
{
struct string16 str16 = string16_from_wstr_no_limit(wstr);
String16 str16 = string16_from_wstr_no_limit(wstr);
return string_from_string16(arena, str16);
}
struct string string_from_wstr(struct arena *arena, wchar_t *wstr, u64 limit)
String string_from_wstr(Arena *arena, wchar_t *wstr, u64 limit)
{
struct string16 str16 = string16_from_wstr(wstr, limit);
String16 str16 = string16_from_wstr(wstr, limit);
return string_from_string16(arena, str16);
}
struct string16 string16_from_wstr_no_limit(wchar_t *wstr)
String16 string16_from_wstr_no_limit(wchar_t *wstr)
{
u64 len = wstr_len_no_limit(wstr);
return (struct string16) {
return (String16) {
.len = len,
.text = (u16 *)wstr
};
}
struct string16 string16_from_wstr(wchar_t *wstr, u64 limit)
String16 string16_from_wstr(wchar_t *wstr, u64 limit)
{
u64 len = wstr_len(wstr, limit);
return (struct string16)
return (String16)
{
.len = len,
.text = (u16 *)wstr

View File

@ -1,21 +1,25 @@
struct string {
typedef struct String String;
struct String {
u64 len;
u8 *text;
};
struct string16 {
typedef struct String16 String16;
struct String16 {
u64 len;
u16 *text;
};
struct string32 {
typedef struct String32 String32;
struct String32 {
u64 len;
u32 *text;
};
struct string_array {
typedef struct StringArray StringArray;
struct StringArray {
u64 count;
struct string *strings;
String *strings;
};
/* ========================== *
@ -23,16 +27,16 @@ struct string_array {
* ========================== */
/* Expand C string literal with size for string initialization */
#define LIT(cstr_lit) CPPCOMPAT_INITLIST_TYPE(struct string) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) }
#define LIT(cstr_lit) CPPCOMPAT_INITLIST_TYPE(String) { (sizeof((cstr_lit)) - 1), (u8 *)(cstr_lit) }
/* Same as `STR`, but works with static variable initialization */
#define LIT_NOCAST(cstr_lit) { .len = (sizeof((cstr_lit)) - 1), .text = (u8 *)(cstr_lit) }
#define STRING(size, data) (CPPCOMPAT_INITLIST_TYPE(struct string) { (size), (data) })
#define STRING(size, data) (CPPCOMPAT_INITLIST_TYPE(String) { (size), (data) })
#define STRING_FROM_POINTERS(p0, p1) (CPPCOMPAT_INITLIST_TYPE(struct string) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 })
#define STRING_FROM_POINTERS(p0, p1) (CPPCOMPAT_INITLIST_TYPE(String) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 })
#define STRING_FROM_STRUCT(ptr) (CPPCOMPAT_INITLIST_TYPE(struct string) { sizeof(*(ptr)), (u8 *)(ptr) })
#define STRING_FROM_STRUCT(ptr) (CPPCOMPAT_INITLIST_TYPE(String) { sizeof(*(ptr)), (u8 *)(ptr) })
#define STRING_FROM_ARENA(arena) (STRING((arena)->pos, arena_base(arena)))
@ -41,7 +45,7 @@ struct string_array {
( \
/* Must be array */ \
ASSERT(IS_ARRAY(a)), \
((struct string) { .len = sizeof(a), .text = (u8 *)(a) }) \
((String) { .len = sizeof(a), .text = (u8 *)(a) }) \
)
@ -49,30 +53,30 @@ struct string_array {
* Conversion
* ========================== */
struct string string_from_char(struct arena *arena, char c);
struct string string_from_uint(struct arena *arena, u64 n, u64 base, u64 zfill);
struct string string_from_int(struct arena *arena, i64 n, u64 base, u64 zfill);
struct string string_from_ptr(struct arena *arena, void *ptr);
struct string string_from_float(struct arena *arena, f64 f, u32 precision);
struct string string_from_handle(struct arena *arena, u64 v0, u64 v1);
struct string string_from_uid(struct arena *arena, struct uid uid);
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
* ========================== */
struct string string_copy(struct arena *arena, struct string src);
struct string string_copy_to_string(struct string dst, struct string src);
struct string string_repeat(struct arena *arena, struct string src, u64 count);
struct string string_cat(struct arena *arena, struct string str1, struct string str2);
struct string_array string_split(struct arena *arena, struct string str, struct string delim);
struct string string_indent(struct arena *arena, struct string str, u32 indent);
struct string string_lower(struct arena *arena, struct string str);
b32 string_eq(struct string str1, struct string str2);
i32 string_cmp(struct string str1, struct string str2);
b32 string_contains(struct string str, struct string substring);
b32 string_starts_with(struct string str, struct string substring);
b32 string_ends_with(struct string str, struct string substring);
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
@ -103,7 +107,7 @@ struct fmt_arg {
u32 zfill;
union {
u8 c;
struct string string;
String string;
u64 uint;
i64 sint;
void *ptr;
@ -111,7 +115,7 @@ struct fmt_arg {
struct {
u64 h64[2];
} handle;
struct uid uid;
UID uid;
} value;
};
@ -130,8 +134,8 @@ struct fmt_arg {
#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)
struct string _string_format(struct arena *arena, struct string fmt, ...);
struct string string_formatv(struct arena *arena, struct string fmt, va_list args);
String _string_format(Arena *arena, String fmt, ...);
String string_formatv(Arena *arena, String fmt, va_list args);
/* ========================== *
* Unicode
@ -141,19 +145,19 @@ struct string_codepoint_iter {
u32 codepoint;
/* Internal */
struct string src;
String src;
u64 pos;
};
struct string_codepoint_iter string_codepoint_iter_begin(struct string str);
struct string_codepoint_iter string_codepoint_iter_begin(String str);
b32 string_codepoint_iter_next(struct string_codepoint_iter *iter);
void string_codepoint_iter_end(struct string_codepoint_iter *iter);
struct string string_from_string16(struct arena *arena, struct string16 str16);
struct string string_from_string32(struct arena *arena, struct string32 str32);
String string_from_string16(Arena *arena, String16 str16);
String string_from_string32(Arena *arena, String32 str32);
struct string16 string16_from_string(struct arena *arena, struct string str8);
struct string32 string32_from_string(struct arena *arena, struct string str8);
String16 string16_from_string(Arena *arena, String str8);
String32 string32_from_string(Arena *arena, String str8);
/* ========================== *
* Legacy strings
@ -161,16 +165,16 @@ struct string32 string32_from_string(struct arena *arena, struct string str8);
u64 cstr_len_no_limit(char *cstr);
u64 cstr_len(char *cstr, u64 limit);
char *cstr_from_string(struct arena *arena, struct string src);
char *cstr_buff_from_string(struct string dest_buff, struct string src);
struct string string_from_cstr_no_limit(char *cstr);
struct string string_from_cstr(char *cstr, u64 limit);
char *cstr_from_string(Arena *arena, String src);
char *cstr_buff_from_string(String dest_buff, String src);
String string_from_cstr_no_limit(char *cstr);
String string_from_cstr(char *cstr, u64 limit);
u64 wstr_len_no_limit(wchar_t *wstr);
u64 wstr_len(wchar_t *wstr, u64 limit);
wchar_t *wstr_from_string(struct arena *arena, struct string src);
wchar_t *wstr_from_string16(struct arena *arena, struct string16 src);
struct string string_from_wstr_no_limit(struct arena *arena, wchar_t *wstr);
struct string string_from_wstr(struct arena *arena, wchar_t *wstr, u64 limit);
struct string16 string16_from_wstr_no_limit(wchar_t *wstr);
struct string16 string16_from_wstr(wchar_t *wstr, u64 limit);
wchar_t *wstr_from_string(Arena *arena, String src);
wchar_t *wstr_from_string16(Arena *arena, String16 src);
String string_from_wstr_no_limit(Arena *arena, wchar_t *wstr);
String string_from_wstr(Arena *arena, wchar_t *wstr, u64 limit);
String16 string16_from_wstr_no_limit(wchar_t *wstr);
String16 string16_from_wstr(wchar_t *wstr, u64 limit);

View File

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

View File

@ -1,13 +1,14 @@
#define UID(hi64, lo64) ((struct uid) { .hi = (hi64), .lo = (lo64) })
struct uid {
#define MakeUID(hi64, lo64) ((UID) { .hi = (hi64), .lo = (lo64) })
typedef struct UID UID;
struct UID {
u64 hi;
u64 lo;
};
INLINE b32 uid_eq(struct uid a, struct uid b) { return a.hi == b.hi && a.lo == b.lo; }
INLINE b32 uid_eq(UID a, UID b) { return a.hi == b.hi && a.lo == b.lo; }
INLINE b32 uid_is_zero(struct uid v) { return v.hi == 0 && v.lo == 0; }
INLINE b32 uid_is_zero(UID v) { return v.hi == 0 && v.lo == 0; }
struct uid uid_true_rand(void);
UID uid_true_rand(void);
struct uid uid_combine(struct uid a, struct uid b);
UID uid_combine(UID a, UID b);

View File

@ -2,7 +2,7 @@
* utf8
* ========================== */
struct uni_decode_utf8_result uni_decode_utf8(struct string str)
Utf8DecodeResult uni_decode_utf8(String str)
{
LOCAL_PERSIST 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
@ -66,15 +66,15 @@ struct uni_decode_utf8_result uni_decode_utf8(struct string str)
}
}
return (struct uni_decode_utf8_result) {
return (Utf8DecodeResult) {
.advance8 = advance,
.codepoint = codepoint
};
}
struct uni_encode_utf8_result uni_encode_utf8(u32 codepoint)
Utf8EncodeResult uni_encode_utf8(u32 codepoint)
{
struct uni_encode_utf8_result res = ZI;
Utf8EncodeResult res = ZI;
if (codepoint <= 0x7F) {
res.count8 = 1;
@ -107,7 +107,7 @@ struct uni_encode_utf8_result uni_encode_utf8(u32 codepoint)
* utf16
* ========================== */
struct uni_decode_utf16_result uni_decode_utf16(struct string16 str)
Utf16DecodeResult uni_decode_utf16(String16 str)
{
u32 codepoint = U32_MAX;
u32 advance = 0;
@ -126,15 +126,15 @@ struct uni_decode_utf16_result uni_decode_utf16(struct string16 str)
}
}
return (struct uni_decode_utf16_result) {
return (Utf16DecodeResult) {
.advance16 = advance,
.codepoint = codepoint
};
}
struct uni_encode_utf16_result uni_encode_utf16(u32 codepoint)
Utf16EncodeResult uni_encode_utf16(u32 codepoint)
{
struct uni_encode_utf16_result res = ZI;
Utf16EncodeResult res = ZI;
if (codepoint <= 0xFFFF) {
res.count16 = 1;
@ -166,7 +166,7 @@ b32 uni_is_utf16_low_surrogate(u16 c)
* utf32
* ========================== */
struct uni_decode_utf32_result uni_decode_utf32(struct string32 str)
Utf32DecodeResult uni_decode_utf32(String32 str)
{
u32 codepoint = U32_MAX;
u32 advance = 0;
@ -179,15 +179,15 @@ struct uni_decode_utf32_result uni_decode_utf32(struct string32 str)
}
}
return (struct uni_decode_utf32_result) {
return (Utf32DecodeResult) {
.advance32 = advance,
.codepoint = codepoint
};
}
struct uni_encode_utf32_result uni_encode_utf32(u32 codepoint)
Utf32EncodeResult uni_encode_utf32(u32 codepoint)
{
struct uni_encode_utf32_result res = ZI;
Utf32EncodeResult res = ZI;
if (codepoint <= 0x10FFFF) {
res.chars32 = codepoint;

View File

@ -2,35 +2,39 @@
* utf8
* ========================== */
struct uni_decode_utf8_result {
typedef struct Utf8DecodeResult Utf8DecodeResult;
struct Utf8DecodeResult {
u32 advance8;
u32 codepoint;
};
struct uni_encode_utf8_result {
typedef struct Utf8EncodeResult Utf8EncodeResult;
struct Utf8EncodeResult {
u32 count8;
u8 chars8[4];
};
struct uni_decode_utf8_result uni_decode_utf8(struct string str);
struct uni_encode_utf8_result uni_encode_utf8(u32 codepoint);
Utf8DecodeResult uni_decode_utf8(String str);
Utf8EncodeResult uni_encode_utf8(u32 codepoint);
/* ========================== *
* utf16
* ========================== */
struct uni_decode_utf16_result {
typedef struct Utf16DecodeResult Utf16DecodeResult;
struct Utf16DecodeResult {
u32 advance16;
u32 codepoint;
};
struct uni_encode_utf16_result {
typedef struct Utf16EncodeResult Utf16EncodeResult;
struct Utf16EncodeResult {
u32 count16;
u16 chars16[2];
};
struct uni_decode_utf16_result uni_decode_utf16(struct string16 str);
struct uni_encode_utf16_result uni_encode_utf16(u32 codepoint);
Utf16DecodeResult uni_decode_utf16(String16 str);
Utf16EncodeResult uni_encode_utf16(u32 codepoint);
b32 uni_is_utf16_high_surrogate(u16 c);
b32 uni_is_utf16_low_surrogate(u16 c);
@ -38,14 +42,16 @@ b32 uni_is_utf16_low_surrogate(u16 c);
* utf32
* ========================== */
struct uni_decode_utf32_result {
typedef struct Utf32DecodeResult Utf32DecodeResult;
struct Utf32DecodeResult {
u32 advance32;
u32 codepoint;
};
struct uni_encode_utf32_result {
typedef struct Utf32EncodeResult Utf32EncodeResult;
struct Utf32EncodeResult {
u32 chars32;
};
struct uni_decode_utf32_result uni_decode_utf32(struct string32 str);
struct uni_encode_utf32_result uni_encode_utf32(u32 codepoint);
Utf32DecodeResult uni_decode_utf32(String32 str);
Utf32EncodeResult uni_encode_utf32(u32 codepoint);

View File

@ -9,7 +9,7 @@
*/
#define HASH_FNV64_BASIS 0xCBF29CE484222325
INLINE u64 hash_fnv64(u64 seed, struct string s)
INLINE u64 hash_fnv64(u64 seed, String s)
{
u64 hash = seed;
for (u64 i = 0; i < s.len; ++i) {
@ -69,7 +69,7 @@ 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)
{
if (item_count > 1) {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u64 left_count = item_count / 2;
u64 right_count = item_count - left_count;
@ -94,38 +94,41 @@ INLINE void merge_sort(void *items, u64 item_count, u64 item_size, sort_compare_
* Simple chaining hash -> 64 bit value table for generic use
* ========================== */
struct dict_entry {
typedef struct DictEntry DictEntry;
struct DictEntry {
u64 hash;
u64 value;
struct dict_entry *prev_in_bin;
struct dict_entry *next_in_bin;
struct dict_entry *prev;
struct dict_entry *next;
DictEntry *prev_in_bin;
DictEntry *next_in_bin;
DictEntry *prev;
DictEntry *next;
};
struct dict_bin {
struct dict_entry *first;
struct dict_entry *last;
typedef struct DictBin DictBin;
struct DictBin {
DictEntry *first;
DictEntry *last;
};
struct dict {
typedef struct Dict Dict;
struct Dict {
u64 bins_count;
struct dict_bin *bins;
struct dict_entry *first_free;
struct dict_entry *first;
struct dict_entry *last;
DictBin *bins;
DictEntry *first_free;
DictEntry *first;
DictEntry *last;
};
INLINE struct dict *dict_init(struct arena *arena, u64 bins_count)
INLINE Dict *dict_init(Arena *arena, u64 bins_count)
{
__prof;
struct dict *dict = arena_push(arena, struct dict);
Dict *dict = arena_push(arena, Dict);
dict->bins_count = max_u64(bins_count, 1); /* Ensure at least 1 bin */
dict->bins = arena_push_array(arena, struct dict_bin, dict->bins_count);
dict->bins = arena_push_array(arena, DictBin, dict->bins_count);
return dict;
}
INLINE void dict_reset(struct dict *dict)
INLINE void dict_reset(Dict *dict)
{
MEMZERO(dict->bins, sizeof(*dict->bins) * dict->bins_count);
if (dict->first) {
@ -134,12 +137,12 @@ INLINE void dict_reset(struct dict *dict)
}
}
INLINE struct dict_entry *dict_ensure_entry(struct arena *arena, struct dict *dict, u64 hash)
INLINE DictEntry *dict_ensure_entry(Arena *arena, Dict *dict, u64 hash)
{
__prof;
struct dict_bin *bin = &dict->bins[hash % dict->bins_count];
DictBin *bin = &dict->bins[hash % dict->bins_count];
struct dict_entry *entry = bin->first;
DictEntry *entry = bin->first;
while (entry) {
if (hash == entry->hash) {
/* Existing match found */
@ -154,7 +157,7 @@ INLINE struct dict_entry *dict_ensure_entry(struct arena *arena, struct dict *di
entry = dict->first_free;
dict->first_free = entry->next;
} else {
entry = arena_push_no_zero(arena, struct dict_entry);
entry = arena_push_no_zero(arena, DictEntry);
}
MEMZERO_STRUCT(entry);
entry->hash = hash;
@ -177,19 +180,19 @@ INLINE struct dict_entry *dict_ensure_entry(struct arena *arena, struct dict *di
return entry;
}
INLINE void dict_set(struct arena *arena, struct dict *dict, u64 hash, u64 value)
INLINE void dict_set(Arena *arena, Dict *dict, u64 hash, u64 value)
{
__prof;
struct dict_entry *entry = dict_ensure_entry(arena, dict, hash);
DictEntry *entry = dict_ensure_entry(arena, dict, hash);
entry->value = value;
}
INLINE struct dict_entry *dict_get_entry(struct dict *dict, u64 hash)
INLINE DictEntry *dict_get_entry(Dict *dict, u64 hash)
{
__prof;
struct dict_entry *result = 0;
struct dict_bin *bin = &dict->bins[hash % dict->bins_count];
for (struct dict_entry *entry = bin->first; entry; entry = entry->next_in_bin) {
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;
@ -199,20 +202,20 @@ INLINE struct dict_entry *dict_get_entry(struct dict *dict, u64 hash)
return result;
}
INLINE u64 dict_get(struct dict *dict, u64 hash)
INLINE u64 dict_get(Dict *dict, u64 hash)
{
__prof;
struct dict_entry *entry = dict_get_entry(dict, hash);
DictEntry *entry = dict_get_entry(dict, hash);
return entry ? entry->value : 0;
}
INLINE void dict_remove_entry(struct dict *dict, struct dict_entry *entry)
INLINE void dict_remove_entry(Dict *dict, DictEntry *entry)
{
/* Remove from bin */
{
struct dict_bin *bin = &dict->bins[entry->hash % dict->bins_count];
struct dict_entry *prev_in_bin = entry->prev_in_bin;
struct dict_entry *next_in_bin = entry->next_in_bin;
DictBin *bin = &dict->bins[entry->hash % dict->bins_count];
DictEntry *prev_in_bin = entry->prev_in_bin;
DictEntry *next_in_bin = entry->next_in_bin;
if (prev_in_bin) {
prev_in_bin->next_in_bin = next_in_bin;
} else {
@ -226,8 +229,8 @@ INLINE void dict_remove_entry(struct dict *dict, struct dict_entry *entry)
}
/* Remove from list */
{
struct dict_entry *prev = entry->prev;
struct dict_entry *next = entry->next;
DictEntry *prev = entry->prev;
DictEntry *next = entry->next;
if (prev) {
prev->next = next;
} else {

View File

@ -26,9 +26,9 @@ INTERNAL void _dbgbreakable(void)
#define DBGSTEP
#endif
INTERNAL struct collider_support_point collider_get_support_point_internal(struct collider_shape *shape, struct xform xf, struct v2 dir, i32 ignore)
INTERNAL CLD_SupportPoint collider_get_support_point_internal(CLD_Shape *shape, Xform xf, V2 dir, i32 ignore)
{
struct v2 *points = shape->points;
V2 *points = shape->points;
u32 count = shape->count;
f32 radius = shape->radius;
@ -40,14 +40,14 @@ INTERNAL struct collider_support_point collider_get_support_point_internal(struc
ignore = -1;
}
struct v2 furthest = ZI;
V2 furthest = ZI;
u32 furthest_index = 0;
f32 furthest_dot = -F32_INFINITY;
for (u32 i = 0; i < count; ++i) {
if ((i32)i == ignore) {
continue;
}
struct v2 p = points[i];
V2 p = points[i];
f32 dot = v2_dot(dir, p);
if (dot > furthest_dot) {
furthest = p;
@ -63,15 +63,15 @@ INTERNAL struct collider_support_point collider_get_support_point_internal(struc
furthest = xform_mul_v2(xf, furthest);
struct collider_support_point res;
CLD_SupportPoint res;
res.p = furthest;
res.i = furthest_index;
return res;
}
struct collider_shape collider_from_quad(struct quad quad)
CLD_Shape collider_from_quad(Quad quad)
{
struct collider_shape res;
CLD_Shape res;
res.points[0] = quad.p0;
res.points[1] = quad.p1;
res.points[2] = quad.p2;
@ -81,14 +81,14 @@ struct collider_shape collider_from_quad(struct quad quad)
return res;
}
struct collider_support_point collider_get_support_point(struct collider_shape *shape, struct xform xf, struct v2 dir)
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, V2 dir)
{
return collider_get_support_point_internal(shape, xf, dir, -1);
}
INTERNAL struct collider_menkowski_point get_menkowski_point(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, struct v2 dir)
INTERNAL CLD_MenkowskiPoint get_menkowski_point(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, V2 dir)
{
struct collider_menkowski_point res;
CLD_MenkowskiPoint res;
res.s0 = collider_get_support_point(shape0, xf0, dir);
res.s1 = collider_get_support_point(shape1, xf1, v2_neg(dir));
res.p = v2_sub(res.s0.p, res.s1.p);
@ -99,19 +99,19 @@ INTERNAL struct collider_menkowski_point get_menkowski_point(struct collider_sha
* AABB
* ========================== */
struct aabb collider_aabb_from_collider(struct collider_shape *shape, struct xform xf)
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf)
{
struct aabb res;
res.p0.x = collider_get_support_point(shape, xf, V2(-1, 0)).p.x - COLLISION_TOLERANCE;
res.p0.y = collider_get_support_point(shape, xf, V2(0, -1)).p.y - COLLISION_TOLERANCE;
res.p1.x = collider_get_support_point(shape, xf, V2(1, 0)).p.x + COLLISION_TOLERANCE;
res.p1.y = collider_get_support_point(shape, xf, V2(0, 1)).p.y + COLLISION_TOLERANCE;
Aabb res;
res.p0.x = collider_get_support_point(shape, xf, V2FromXY(-1, 0)).p.x - COLLISION_TOLERANCE;
res.p0.y = collider_get_support_point(shape, xf, V2FromXY(0, -1)).p.y - COLLISION_TOLERANCE;
res.p1.x = collider_get_support_point(shape, xf, V2FromXY(1, 0)).p.x + COLLISION_TOLERANCE;
res.p1.y = collider_get_support_point(shape, xf, V2FromXY(0, 1)).p.y + COLLISION_TOLERANCE;
return res;
}
struct aabb collider_aabb_from_combined_aabb(struct aabb b0, struct aabb b1)
Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1)
{
struct aabb res;
Aabb res;
res.p0.x = min_f32(min_f32(b0.p0.x, b0.p1.x), min_f32(b1.p0.x, b1.p1.x));
res.p0.y = min_f32(min_f32(b0.p0.y, b0.p1.y), min_f32(b1.p0.y, b1.p1.y));
res.p1.x = max_f32(max_f32(b0.p0.x, b0.p1.x), max_f32(b1.p0.x, b1.p1.x));
@ -119,7 +119,7 @@ struct aabb collider_aabb_from_combined_aabb(struct aabb b0, struct aabb b1)
return res;
}
b32 collider_test_aabb(struct aabb box0, struct aabb box1)
b32 collider_test_aabb(Aabb box0, Aabb box1)
{
f32 b0_x0 = box0.p0.x;
f32 b0_x1 = box0.p1.x;
@ -142,8 +142,8 @@ b32 collider_test_aabb(struct aabb box0, struct aabb box1)
* ========================== */
struct gjk_result {
struct collider_menkowski_simplex simplex;
struct v2 final_dir;
CLD_MenkowskiSimplex simplex;
V2 final_dir;
/* If 1, simplex represents triangle inside of menkowski difference
* encapsulating the origin. If 0, simplex represents the closest
@ -156,24 +156,24 @@ struct gjk_result {
};
#if COLLIDER_DEBUG
INTERNAL struct gjk_result gjk_get_simplex(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, f32 min_unique_pt_dist_sq, u32 dbg_step)
INTERNAL struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq, u32 dbg_step)
#else
INTERNAL struct gjk_result gjk_get_simplex(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, f32 min_unique_pt_dist_sq)
INTERNAL struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq)
#endif
{
b32 overlapping = 0;
struct collider_menkowski_simplex s = ZI;
struct v2 dir = ZI;
struct collider_menkowski_point m = ZI;
CLD_MenkowskiSimplex s = ZI;
V2 dir = ZI;
CLD_MenkowskiPoint m = ZI;
/* First point is support point in shape's general directions to eachother */
dir = v2_sub(xf1.og, xf0.og);
if (v2_is_zero(dir)) dir = V2(1, 0);
if (v2_is_zero(dir)) dir = V2FromXY(1, 0);
s.a = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
s.len = 1;
struct v2 removed_a = ZI;
struct v2 removed_b = ZI;
V2 removed_a = ZI;
V2 removed_b = ZI;
u32 num_removed = 0;
for (;;) {
if (s.len == 1) {
@ -226,13 +226,13 @@ INTERNAL struct gjk_result gjk_get_simplex(struct collider_shape *shape0, struct
/* Determine region of the simplex in which the origin lies */
DBGSTEP;
struct v2 vab = v2_sub(s.b.p, s.a.p);
struct v2 vac = v2_sub(s.c.p, s.a.p);
struct v2 vbc = v2_sub(s.c.p, s.b.p);
V2 vab = v2_sub(s.b.p, s.a.p);
V2 vac = v2_sub(s.c.p, s.a.p);
V2 vbc = v2_sub(s.c.p, s.b.p);
struct v2 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac));
struct v2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
struct v2 rbc_dir = v2_perp_towards_dir(vbc, vab);
V2 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac));
V2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
V2 rbc_dir = v2_perp_towards_dir(vbc, vab);
f32 rab_dot = v2_dot(rab_dir, v2_neg(s.a.p));
f32 rac_dot = v2_dot(rac_dir, v2_neg(s.a.p));
@ -313,34 +313,34 @@ INTERNAL struct gjk_result gjk_get_simplex(struct collider_shape *shape0, struct
* ========================== */
struct epa_result {
struct v2 normal;
struct collider_menkowski_feature closest_feature; /* Represents closest feature (edge or point) to origin on menkowski difference */
V2 normal;
CLD_MenkowskiFeature closest_feature; /* Represents closest feature (edge or point) to origin on menkowski difference */
#if COLLIDER_DEBUG
struct collider_prototype prototype;
CLD_Prototype prototype;
u32 dbg_step;
#endif
};
#if COLLIDER_DEBUG
INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, struct gjk_result gjk_res, f32 min_unique_pt_dist_sq, u32 max_iterations, u32 dbg_step)
INTERNAL struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, struct gjk_result gjk_res, f32 min_unique_pt_dist_sq, u32 max_iterations, u32 dbg_step)
#else
INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, struct gjk_result gjk_res, f32 min_unique_pt_dist_sq, u32 max_iterations)
INTERNAL struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, struct gjk_result gjk_res, f32 min_unique_pt_dist_sq, u32 max_iterations)
#endif
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct collider_menkowski_feature closest_feature = ZI;
struct v2 normal = ZI;
CLD_MenkowskiFeature closest_feature = ZI;
V2 normal = ZI;
struct collider_menkowski_point *proto = 0;
CLD_MenkowskiPoint *proto = 0;
u32 proto_count = 0;
if (gjk_res.overlapping) {
struct collider_menkowski_simplex s = gjk_res.simplex;
proto = arena_push_dry(scratch.arena, struct collider_menkowski_point);
CLD_MenkowskiSimplex s = gjk_res.simplex;
proto = arena_push_dry(scratch.arena, CLD_MenkowskiPoint);
{
ASSERT(s.len == 3);
struct collider_menkowski_point *tmp = arena_push_array_no_zero(scratch.arena, struct collider_menkowski_point, 3);
CLD_MenkowskiPoint *tmp = arena_push_array_no_zero(scratch.arena, CLD_MenkowskiPoint, 3);
tmp[0] = s.a;
tmp[1] = s.b;
tmp[2] = s.c;
@ -356,20 +356,20 @@ INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0
/* Find dir from origin to closest edge */
/* FIXME: Winding order of ps & pe index */
f32 closest_len_sq = F32_INFINITY;
struct collider_menkowski_point closest_a = ZI;
struct collider_menkowski_point closest_b = ZI;
CLD_MenkowskiPoint closest_a = ZI;
CLD_MenkowskiPoint closest_b = ZI;
u32 closest_b_index = 0;
for (u32 i = 0; i < proto_count; ++i) {
u32 a_index = i;
u32 b_index = (i < proto_count - 1) ? (i + 1) : 0;
struct collider_menkowski_point a = proto[a_index];
struct collider_menkowski_point b = proto[b_index];
CLD_MenkowskiPoint a = proto[a_index];
CLD_MenkowskiPoint b = proto[b_index];
struct v2 vab = v2_sub(b.p, a.p);
struct v2 vao = v2_neg(a.p);
V2 vab = v2_sub(b.p, a.p);
V2 vao = v2_neg(a.p);
f32 proj_ratio = clamp_f32(v2_dot(vao, vab) / v2_len_sq(vab), 0, 1);
struct v2 proj = v2_add(a.p, v2_mul(vab, proj_ratio));
V2 proj = v2_add(a.p, v2_mul(vab, proj_ratio));
f32 proj_len_sq = v2_len_sq(proj);
if (proj_len_sq < closest_len_sq - min_unique_pt_dist_sq) {
@ -379,11 +379,11 @@ INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0
closest_len_sq = proj_len_sq;
}
}
struct v2 vab = v2_sub(closest_b.p, closest_a.p);
V2 vab = v2_sub(closest_b.p, closest_a.p);
/* Find new point in dir */
struct v2 dir = v2_mul(v2_perp(vab), winding);
struct collider_menkowski_point m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
V2 dir = v2_mul(v2_perp(vab), winding);
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
#if COLLIDER_DEBUG
{
@ -406,8 +406,8 @@ INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0
//const f32 validity_epsilon = 0.00000000001f; /* Arbitrary */
const f32 validity_epsilon = min_unique_pt_dist_sq; /* Arbitrary */
struct v2 vam = v2_sub(m.p, closest_a.p);
struct v2 vbm = v2_sub(closest_b.p, closest_a.p);
V2 vam = v2_sub(m.p, closest_a.p);
V2 vbm = v2_sub(closest_b.p, closest_a.p);
f32 dot = v2_dot(vab, vam) / v2_len_sq(vab);
@ -430,7 +430,7 @@ INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0
}
/* Expand prototype */
arena_push_no_zero(scratch.arena, struct collider_menkowski_point);
arena_push_no_zero(scratch.arena, CLD_MenkowskiPoint);
++proto_count;
/* Shift points in prototype to make room */
@ -477,16 +477,16 @@ INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0
* ========================== */
struct clip_line_to_line_result {
struct v2 a0_clipped, b0_clipped;
struct v2 a1_clipped, b1_clipped;
V2 a0_clipped, b0_clipped;
V2 a1_clipped, b1_clipped;
};
INTERNAL struct clip_line_to_line_result clip_line_to_line(struct v2 a0, struct v2 b0, struct v2 a1, struct v2 b1, struct v2 normal)
INTERNAL struct clip_line_to_line_result clip_line_to_line(V2 a0, V2 b0, V2 a1, V2 b1, V2 normal)
{
struct v2 vab0 = v2_sub(b0, a0);
struct v2 vab1 = v2_sub(b1, a1);
struct v2 va0a1 = v2_sub(a1, a0);
struct v2 vb0b1 = v2_sub(b1, b0);
V2 vab0 = v2_sub(b0, a0);
V2 vab1 = v2_sub(b1, a1);
V2 va0a1 = v2_sub(a1, a0);
V2 vb0b1 = v2_sub(b1, b0);
f32 vab0_w = v2_wedge(vab0, normal);
f32 vab1_w = v2_wedge(vab1, normal);
f32 va0a1_w = v2_wedge(va0a1, normal);
@ -516,10 +516,10 @@ INTERNAL struct clip_line_to_line_result clip_line_to_line(struct v2 a0, struct
return res;
}
INTERNAL struct v2 clip_point_to_line(struct v2 a, struct v2 b, struct v2 p, struct v2 normal)
INTERNAL V2 clip_point_to_line(V2 a, V2 b, V2 p, V2 normal)
{
struct v2 vab = v2_sub(b, a);
struct v2 vap = v2_sub(p, a);
V2 vab = v2_sub(b, a);
V2 vap = v2_sub(p, a);
f32 vab_w = v2_wedge(vab, normal);
f32 vap_w = v2_wedge(vap, normal);
@ -530,7 +530,7 @@ INTERNAL struct v2 clip_point_to_line(struct v2 a, struct v2 b, struct v2 p, str
t = clamp_f32(vap_w * w, 0, 1);
}
struct v2 res = v2_add(a, v2_mul(vab, t));
V2 res = v2_add(a, v2_mul(vab, t));
return res;
}
@ -538,18 +538,18 @@ INTERNAL struct v2 clip_point_to_line(struct v2 a, struct v2 b, struct v2 p, str
* Collision points
* ========================== */
struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1)
CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
{
struct collider_collision_points_result res = ZI;
CLD_CollisionResult res = ZI;
const f32 tolerance = COLLISION_TOLERANCE;
const f32 min_unique_pt_dist_sq = MIN_UNIQUE_PT_DIST_SQ;
const u32 max_epa_iterations = MAX_EPA_ITERATIONS;
struct collider_collision_point points[2] = ZI;
CLD_CollisionPoint points[2] = ZI;
u32 num_points = 0;
b32 colliding = 0;
struct v2 normal = ZI;
V2 normal = ZI;
#if COLLIDER_DEBUG
u32 dbg_step = 0;
@ -581,20 +581,20 @@ struct collider_collision_points_result collider_collision_points(struct collide
if (gjk_res.overlapping) {
colliding = 1;
} else {
struct collider_menkowski_feature f = epa_res.closest_feature;
CLD_MenkowskiFeature f = epa_res.closest_feature;
/* Shapes not overlapping, determine if distance between shapes within tolerance */
if (f.len == 1) {
struct v2 p = v2_neg(f.a.p);
V2 p = v2_neg(f.a.p);
if (v2_len_sq(p) <= (tolerance * tolerance)) {
colliding = 1;
}
} else {
/* Project origin to determine if distance is within tolerance. */
ASSERT(f.len == 2);
struct v2 vab = v2_sub(f.b.p, f.a.p);
struct v2 vao = v2_neg(f.a.p);
V2 vab = v2_sub(f.b.p, f.a.p);
V2 vao = v2_neg(f.a.p);
f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
struct v2 p = v2_add(f.a.p, v2_mul(vab, ratio));
V2 p = v2_add(f.a.p, v2_mul(vab, ratio));
if (v2_len_sq(p) <= (tolerance * tolerance)) {
colliding = 1;
}
@ -606,16 +606,16 @@ struct collider_collision_points_result collider_collision_points(struct collide
/* Max vertices must be < 16 to fit in 4 bit ids */
STATIC_ASSERT(countof(shape0->points) <= 16);
struct collider_menkowski_feature f = epa_res.closest_feature;
CLD_MenkowskiFeature f = epa_res.closest_feature;
{
b32 collapse0 = 0;
b32 collapse1 = 0;
struct collider_support_point a0 = f.a.s0;
struct collider_support_point a1 = f.a.s1;
struct collider_support_point b0 = f.b.s0;
struct collider_support_point b1 = f.b.s1;
CLD_SupportPoint a0 = f.a.s0;
CLD_SupportPoint a1 = f.a.s1;
CLD_SupportPoint b0 = f.b.s0;
CLD_SupportPoint b1 = f.b.s1;
/* FIXME: Manually account for shapes w/ 1 & 2 points */
if (f.len == 2) {
if (a0.i == b0.i) {
@ -641,20 +641,20 @@ struct collider_collision_points_result collider_collision_points(struct collide
b1 = a1;
}
struct v2 vab0 = v2_sub(b0.p, a0.p);
struct v2 vab1 = v2_sub(b1.p, a1.p);
struct v2 vab0_norm = v2_norm(vab0);
struct v2 vab1_norm = v2_norm(vab1);
V2 vab0 = v2_sub(b0.p, a0.p);
V2 vab1 = v2_sub(b1.p, a1.p);
V2 vab0_norm = v2_norm(vab0);
V2 vab1_norm = v2_norm(vab1);
/* Swap points based on normal direction for consistent clipping */
if (v2_wedge(normal, vab0) < 0) {
struct collider_support_point tmp = a0;
CLD_SupportPoint tmp = a0;
a0 = b0;
b0 = tmp;
vab0 = v2_neg(vab0);
}
if (v2_wedge(normal, vab1) < 0) {
struct collider_support_point tmp = a1;
CLD_SupportPoint tmp = a1;
a1 = b1;
b1 = tmp;
vab1 = v2_neg(vab1);
@ -685,27 +685,27 @@ struct collider_collision_points_result collider_collision_points(struct collide
f32 a_sep = F32_INFINITY;
f32 b_sep = F32_INFINITY;
struct v2 a_midpoint = ZI;
struct v2 b_midpoint = ZI;
V2 a_midpoint = ZI;
V2 b_midpoint = ZI;
b32 ignore_a = 1;
b32 ignore_b = 1;
if (!collapse0 && !collapse1) {
/* Clip line to line */
struct clip_line_to_line_result clip_res = clip_line_to_line(a0.p, b0.p, a1.p, b1.p, normal);
struct v2 a0_clipped = clip_res.a0_clipped;
struct v2 a1_clipped = clip_res.a1_clipped;
struct v2 b0_clipped = clip_res.b0_clipped;
struct v2 b1_clipped = clip_res.b1_clipped;
V2 a0_clipped = clip_res.a0_clipped;
V2 a1_clipped = clip_res.a1_clipped;
V2 b0_clipped = clip_res.b0_clipped;
V2 b1_clipped = clip_res.b1_clipped;
/* Calc midpoint between clipped a & b */
struct v2 va0a1_clipped = v2_sub(a1_clipped, a0_clipped);
struct v2 vb0b1_clipped = v2_sub(b1_clipped, b0_clipped);
V2 va0a1_clipped = v2_sub(a1_clipped, a0_clipped);
V2 vb0b1_clipped = v2_sub(b1_clipped, b0_clipped);
a_sep = v2_dot(va0a1_clipped, normal);
b_sep = v2_dot(vb0b1_clipped, normal);
a_midpoint = v2_add(a0_clipped, v2_mul(va0a1_clipped, 0.5f));
b_midpoint = v2_add(b0_clipped, v2_mul(vb0b1_clipped, 0.5f));
ignore_a = 0;
ignore_b = 0;
struct v2 vfin = v2_sub(b_midpoint, a_midpoint);
V2 vfin = v2_sub(b_midpoint, a_midpoint);
if (v2_len_sq(vfin) < (0.005 * 0.005)) {
if (a_sep > b_sep) {
ignore_a = 1;
@ -718,8 +718,8 @@ struct collider_collision_points_result collider_collision_points(struct collide
res.b0_clipped = b0_clipped;
res.b1_clipped = b1_clipped;
} else {
struct v2 p0 = a0.p;
struct v2 p1 = a1.p;
V2 p0 = a0.p;
V2 p1 = a1.p;
/* TODO: Choose ID based on closest clipped point */
if (collapse1 && !collapse0) {
/* Project a1 onto vab0 */
@ -730,7 +730,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
p1 = clip_point_to_line(a1.p, b1.p, a0.p, normal);
}
/* Calc midpoint */
struct v2 vsep = v2_sub(p1, p0);
V2 vsep = v2_sub(p1, p0);
a_midpoint = v2_add(p0, v2_mul(vsep, 0.5f));
a_sep = v2_dot(normal, p1) - v2_dot(normal, p0);
ignore_a = 0;
@ -742,13 +742,13 @@ struct collider_collision_points_result collider_collision_points(struct collide
/* Insert points */
if (!ignore_a && a_sep < tolerance) {
struct collider_collision_point *point = &points[num_points++];
CLD_CollisionPoint *point = &points[num_points++];
point->id = a0.i | (a1.i << 4);
point->separation = a_sep;
point->point = a_midpoint;
}
if (!ignore_b && b_sep < tolerance) {
struct collider_collision_point *point = &points[num_points++];
CLD_CollisionPoint *point = &points[num_points++];
point->id = b0.i | (b1.i << 4);
point->separation = b_sep;
point->point = b_midpoint;
@ -781,16 +781,16 @@ struct collider_collision_points_result collider_collision_points(struct collide
/* TODO: De-duplicate code between collider_closest_points & collider_collision_points */
struct collider_closest_points_result collider_closest_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1)
CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
{
struct collider_closest_points_result res = ZI;
CLD_ClosestResult res = ZI;
const f32 tolerance = COLLISION_TOLERANCE;
const f32 min_unique_pt_dist_sq = MIN_UNIQUE_PT_DIST_SQ;
const u32 max_epa_iterations = MAX_EPA_ITERATIONS;
struct v2 p0 = ZI;
struct v2 p1 = ZI;
V2 p0 = ZI;
V2 p1 = ZI;
b32 colliding = 0;
#if COLLIDER_DEBUG
@ -823,7 +823,7 @@ struct collider_closest_points_result collider_closest_points(struct collider_sh
* ========================== */
colliding = gjk_res.overlapping;
struct collider_menkowski_feature f = epa_res.closest_feature;
CLD_MenkowskiFeature f = epa_res.closest_feature;
if (f.len == 1) {
p0 = f.a.s0.p;
p1 = f.a.s1.p;
@ -834,8 +834,8 @@ struct collider_closest_points_result collider_closest_points(struct collider_sh
f32 ratio;
{
/* Determine ratio between edge a & b that projected origin lies */
struct v2 vab = v2_sub(f.b.p, f.a.p);
struct v2 vao = v2_neg(f.a.p);
V2 vab = v2_sub(f.b.p, f.a.p);
V2 vao = v2_neg(f.a.p);
ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
}
/* Shape 0 */
@ -869,9 +869,9 @@ struct collider_closest_points_result collider_closest_points(struct collider_sh
/* Takes 2 shapes and their xforms at t=0 and t=1.
* Returns time of impact in range [0, 1]. */
f32 collider_time_of_impact(struct collider_shape *c0, struct collider_shape *c1,
struct xform xf0_t0, struct xform xf1_t0,
struct xform xf0_t1, struct xform xf1_t1,
f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
Xform xf0_t0, Xform xf1_t0,
Xform xf0_t1, Xform xf1_t1,
f32 tolerance, u32 max_iterations)
{
f32 t0 = 0;
@ -882,10 +882,10 @@ f32 collider_time_of_impact(struct collider_shape *c0, struct collider_shape *c1
f32 t_sep = F32_INFINITY;
/* Find direction p0 -> p1 at t=0 */
struct v2 dir;
struct v2 dir_neg;
V2 dir;
V2 dir_neg;
{
struct collider_closest_points_result closest_points_res = collider_closest_points(c0, c1, xf0_t0, xf1_t0);
CLD_ClosestResult closest_points_res = collider_closest_points(c0, c1, xf0_t0, xf1_t0);
if (closest_points_res.colliding) {
/* Shapes are penetrating at t=0 */
return 0;
@ -897,8 +897,8 @@ f32 collider_time_of_impact(struct collider_shape *c0, struct collider_shape *c1
}
{
struct v2 p0 = collider_get_support_point(c0, xf0_t1, dir).p;
struct v2 p1 = collider_get_support_point(c1, xf1_t1, dir_neg).p;
V2 p0 = collider_get_support_point(c0, xf0_t1, dir).p;
V2 p1 = collider_get_support_point(c1, xf1_t1, dir_neg).p;
t1_sep = v2_dot(dir, v2_sub(p1, p0));
if (t1_sep > 0) {
/* Shapes are not penetrating at t=1 */
@ -919,11 +919,11 @@ f32 collider_time_of_impact(struct collider_shape *c0, struct collider_shape *c1
t = (-t1_sep / m) + t1;
}
struct xform xf0 = xform_lerp(xf0_t0, xf0_t1, t);
struct xform xf1 = xform_lerp(xf1_t0, xf1_t1, t);
Xform xf0 = xform_lerp(xf0_t0, xf0_t1, t);
Xform xf1 = xform_lerp(xf1_t0, xf1_t1, t);
struct v2 p0 = collider_get_support_point(c0, xf0, dir).p;
struct v2 p1 = collider_get_support_point(c1, xf1, dir_neg).p;
V2 p0 = collider_get_support_point(c0, xf0, dir).p;
V2 p1 = collider_get_support_point(c1, xf1, dir_neg).p;
t_sep = v2_dot(dir, v2_sub(p1, p0));
/* Update bracket */
@ -947,15 +947,15 @@ f32 collider_time_of_impact(struct collider_shape *c0, struct collider_shape *c1
* ========================== */
/* TODO: Remove this (debugging) */
struct v2_array menkowski(struct arena *arena, struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, u32 detail)
V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail)
{
struct v2_array res = { .points = arena_push_dry(arena, struct v2) };
V2Array res = { .points = arena_push_dry(arena, V2) };
for (u64 i = 0; i < detail; ++i) {
f32 angle = ((f32)i / detail) * (2 * PI);
struct v2 dir = v2_from_angle(angle);
struct collider_menkowski_point m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
V2 dir = v2_from_angle(angle);
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
if (res.count == 0 || !v2_eq(m.p, res.points[res.count - 1])) {
*arena_push_no_zero(arena, struct v2) = m.p;
*arena_push_no_zero(arena, V2) = m.p;
++res.count;
}
}
@ -963,19 +963,19 @@ struct v2_array menkowski(struct arena *arena, struct collider_shape *shape0, st
}
/* TODO: Remove this (debugging) */
struct v2_array cloud(struct arena *arena, struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1)
V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
{
/* FIXME: Account for radius */
struct v2_array res = { .points = arena_push_dry(arena, struct v2) };
struct v2 *points0 = shape0->points;
struct v2 *points1 = shape1->points;
V2Array res = { .points = arena_push_dry(arena, V2) };
V2 *points0 = shape0->points;
V2 *points1 = shape1->points;
u32 count0 = shape0->count;
u32 count1 = shape1->count;
for (u64 i = 0; i < count0; ++i) {
struct v2 p0 = xform_mul_v2(xf0, points0[i]);
V2 p0 = xform_mul_v2(xf0, points0[i]);
for (u64 j = 0; j < count1; ++j) {
struct v2 p1 = xform_mul_v2(xf1, points1[j]);
*arena_push_no_zero(arena, struct v2) = v2_sub(p0, p1);
V2 p1 = xform_mul_v2(xf1, points1[j]);
*arena_push_no_zero(arena, V2) = v2_sub(p0, p1);
++res.count;
}
}
@ -987,16 +987,16 @@ struct v2_array cloud(struct arena *arena, struct collider_shape *shape0, struct
* ========================== */
#if 0
b32 collider_collision_boolean(struct collider_shape *shape0, struct collider_shape *shape1)
b32 collider_collision_boolean(CLD_Shape *shape0, CLD_Shape *shape1)
{
struct { struct v2 a, b, c; } s = ZI;
struct { V2 a, b, c; } s = ZI;
/* FIXME: Infinite loop when shapes exactly overlap same space? */
struct v2 dir, p;
V2 dir, p;
/* First point is support point in shape's general directions to eachother */
dir = v2_sub(starting_point(shape1), starting_point(shape0));
if (v2_is_zero(dir)) dir = V2(1, 0);
if (v2_is_zero(dir)) dir = V2FromXY(1, 0);
s.a = get_menkowski_point(shape0, shape1, dir);
/* Second point is support point towards origin */
@ -1018,9 +1018,9 @@ b32 collider_collision_boolean(struct collider_shape *shape0, struct collider_sh
s.b = s.a;
s.a = p;
struct v2 vab = v2_sub(s.b, s.a);
struct v2 vac = v2_sub(s.c, s.a);
struct v2 a_to_origin = v2_neg(s.a);
V2 vab = v2_sub(s.b, s.a);
V2 vac = v2_sub(s.c, s.a);
V2 a_to_origin = v2_neg(s.a);
dir = v2_perp_towards_dir(vab, v2_neg(vac)); /* Normal of ab pointing away from c */
if (v2_dot(dir, a_to_origin) >= 0) {

View File

@ -1,77 +1,90 @@
struct collider_shape {
struct v2 points[8];
typedef struct CLD_Shape CLD_Shape;
struct CLD_Shape {
V2 points[8];
u32 count;
f32 radius;
};
struct collider_support_point {
struct v2 p;
typedef struct CLD_SupportPoint CLD_SupportPoint;
struct CLD_SupportPoint {
V2 p;
u32 i; /* Index of original point in shape */
};
struct collider_menkowski_point {
struct v2 p; /* Menkowski difference point */
struct collider_support_point s0; /* Support point of first shape in dir */
struct collider_support_point s1; /* Support point of second shape in -dir */
typedef struct CLD_MenkowskiPoint CLD_MenkowskiPoint;
struct CLD_MenkowskiPoint {
V2 p; /* Menkowski difference point */
CLD_SupportPoint s0; /* Support point of first shape in dir */
CLD_SupportPoint s1; /* Support point of second shape in -dir */
};
struct collider_menkowski_simplex {
typedef struct CLD_MenkowskiSimplex CLD_MenkowskiSimplex;
struct CLD_MenkowskiSimplex {
u32 len;
struct collider_menkowski_point a, b, c;
CLD_MenkowskiPoint a, b, c;
};
struct collider_menkowski_feature {
typedef struct CLD_MenkowskiFeature CLD_MenkowskiFeature;
struct CLD_MenkowskiFeature {
u32 len;
struct collider_menkowski_point a, b;
CLD_MenkowskiPoint a, b;
};
struct collider_collision_point {
struct v2 point;
typedef struct CLD_CollisionPoint CLD_CollisionPoint;
struct CLD_CollisionPoint {
V2 point;
f32 separation;
u32 id; /* Based on polygon edge-to-edge */
};
struct collider_prototype { struct v2 points[64]; u32 len; };
struct collider_collision_points_result {
struct v2 normal;
struct collider_collision_point points[2];
typedef struct CLD_Prototype CLD_Prototype;
struct CLD_Prototype {
V2 points[64];
u32 len;
};
typedef struct CLD_CollisionResult CLD_CollisionResult;
struct CLD_CollisionResult {
V2 normal;
CLD_CollisionPoint points[2];
u32 num_points;
/* For debugging */
b32 solved;
struct collider_menkowski_simplex simplex;
struct collider_prototype prototype;
CLD_MenkowskiSimplex simplex;
CLD_Prototype prototype;
/* For debugging */
struct v2 a0, b0, a1, b1;
struct v2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
V2 a0, b0, a1, b1;
V2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
};
struct collider_closest_points_result {
struct v2 p0, p1;
typedef struct CLD_ClosestResult CLD_ClosestResult;
struct CLD_ClosestResult {
V2 p0, p1;
b32 colliding;
/* For debugging */
b32 solved;
struct collider_menkowski_simplex simplex;
struct collider_prototype prototype;
CLD_MenkowskiSimplex simplex;
CLD_Prototype prototype;
};
struct collider_shape collider_from_quad(struct quad quad);
CLD_Shape collider_from_quad(Quad quad);
struct collider_support_point collider_get_support_point(struct collider_shape *shape, struct xform xf, struct v2 dir);
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, V2 dir);
struct aabb collider_aabb_from_collider(struct collider_shape *shape, struct xform xf);
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf);
struct aabb collider_aabb_from_combined_aabb(struct aabb b0, struct aabb b1);
Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1);
b32 collider_test_aabb(struct aabb box0, struct aabb box1);
b32 collider_test_aabb(Aabb box0, Aabb box1);
struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1);
CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
struct collider_closest_points_result collider_closest_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1);
CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
f32 collider_time_of_impact(struct collider_shape *c0, struct collider_shape *c1, struct xform xf0_t0, struct xform xf1_t0, struct xform xf0_t1, struct xform xf1_t1, f32 tolerance, u32 max_iterations);
f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, Xform xf0_t1, Xform xf1_t1, f32 tolerance, u32 max_iterations);
struct v2_array menkowski(struct arena *arena, struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, u32 detail);
struct v2_array cloud(struct arena *arena, struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1);
V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail);
V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);

View File

@ -1,27 +1,27 @@
GLOBAL struct {
struct gp_resource *solid_white_texture;
G_Resource *solid_white_texture;
} G = ZI, DEBUG_ALIAS(G, G_draw);
/* ========================== *
* Startup
* ========================== */
struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr)
D_StartupReceipt draw_startup(F_StartupReceipt *font_sr)
{
__prof;
(UNUSED)font_sr;
u32 pixel_white = 0xFFFFFFFF;
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white);
return (struct draw_startup_receipt) { 0 };
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2i32FromXY(1, 1), &pixel_white);
return (D_StartupReceipt) { 0 };
}
/* ========================== *
* Material
* ========================== */
void draw_material(struct gp_render_sig *sig, struct draw_material_params params)
void draw_material(G_RenderSig *sig, D_MaterialParams params)
{
struct gp_render_cmd_desc cmd = ZI;
G_RenderCmdDesc cmd = ZI;
cmd.kind = GP_RENDER_CMD_KIND_DRAW_MATERIAL;
cmd.material.xf = params.xf;
cmd.material.texture = params.texture;
@ -36,9 +36,9 @@ void draw_material(struct gp_render_sig *sig, struct draw_material_params params
* Fill shapes
* ========================== */
void draw_poly_ex(struct gp_render_sig *sig, struct v2_array vertices, struct gp_indices indices, u32 color)
void draw_poly_ex(G_RenderSig *sig, V2Array vertices, G_Indices indices, u32 color)
{
struct gp_render_cmd_desc cmd = ZI;
G_RenderCmdDesc cmd = ZI;
cmd.kind = GP_RENDER_CMD_KIND_DRAW_UI_SHAPE;
cmd.ui_shape.vertices = vertices;
cmd.ui_shape.indices = indices;
@ -47,16 +47,16 @@ void draw_poly_ex(struct gp_render_sig *sig, struct v2_array vertices, struct gp
}
/* Draws a filled polygon using triangles in a fan pattern */
void draw_poly(struct gp_render_sig *sig, struct v2_array vertices, u32 color)
void draw_poly(G_RenderSig *sig, V2Array vertices, u32 color)
{
if (vertices.count >= 3) {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u32 num_tris = vertices.count - 2;
u32 num_indices = num_tris * 3;
/* Generate indices in a fan pattern */
struct gp_indices indices = {
G_Indices indices = {
.count = num_indices,
.indices = arena_push_array_no_zero(scratch.arena, u32, num_indices)
};
@ -73,21 +73,21 @@ void draw_poly(struct gp_render_sig *sig, struct v2_array vertices, u32 color)
}
}
void draw_circle(struct gp_render_sig *sig, struct v2 pos, f32 radius, u32 color, u32 detail)
void draw_circle(G_RenderSig *sig, V2 pos, f32 radius, u32 color, u32 detail)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct v2 *points = arena_push_array_no_zero(scratch.arena, struct v2, detail);
V2 *points = arena_push_array_no_zero(scratch.arena, V2, detail);
for (u32 i = 0; i < detail; ++i) {
f32 angle = ((f32)i / (f32)detail) * TAU;
struct v2 p = V2(
V2 p = V2FromXY(
radius * math_cos(angle),
radius * math_sin(angle)
);
points[i] = v2_add(pos, p);
}
struct v2_array vertices = {
V2Array vertices = {
.points = points,
.count = detail
};
@ -96,14 +96,14 @@ void draw_circle(struct gp_render_sig *sig, struct v2 pos, f32 radius, u32 color
scratch_end(scratch);
}
void draw_quad(struct gp_render_sig *sig, struct quad quad, u32 color)
void draw_quad(G_RenderSig *sig, Quad quad, u32 color)
{
LOCAL_PERSIST u32 indices_array[6] = {
0, 1, 2,
0, 2, 3
};
struct v2_array vertices = { .count = 4, .points = quad.e };
struct gp_indices indices = { .count = 6, .indices = indices_array };
V2Array vertices = { .count = 4, .points = quad.e };
G_Indices indices = { .count = 6, .indices = indices_array };
draw_poly_ex(sig, vertices, indices, color);
}
@ -111,64 +111,64 @@ void draw_quad(struct gp_render_sig *sig, struct quad quad, u32 color)
* Line shapes
* ========================== */
void draw_gradient_line(struct gp_render_sig *sig, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color)
void draw_gradient_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 start_color, u32 end_color)
{
#if 0
struct quad quad = quad_from_line(start, end, thickness);
Quad quad = quad_from_line(start, end, thickness);
draw_material(sig, DRAW_MATERIAL_PARAMS(.texture = G.solid_white_texture, .tint0 = start_color, .tint1 = end_color, .quad = quad));
#else
/* Placeholder */
(UNUSED)end_color;
struct quad quad = quad_from_line(start, end, thickness);
Quad quad = quad_from_line(start, end, thickness);
draw_quad(sig, quad, start_color);
#endif
}
void draw_line(struct gp_render_sig *sig, struct v2 start, struct v2 end, f32 thickness, u32 color)
void draw_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 color)
{
struct quad quad = quad_from_line(start, end, thickness);
Quad quad = quad_from_line(start, end, thickness);
draw_quad(sig, quad, color);
}
void draw_ray(struct gp_render_sig *sig, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
void draw_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, u32 color)
{
struct quad quad = quad_from_ray(pos, rel, thickness);
Quad quad = quad_from_ray(pos, rel, thickness);
draw_quad(sig, quad, color);
}
void draw_poly_line(struct gp_render_sig *sig, struct v2_array points, b32 loop, f32 thickness, u32 color)
void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u32 color)
{
if (points.count >= 2) {
for (u64 i = 1; i < points.count; ++i) {
struct v2 p1 = points.points[i - 1];
struct v2 p2 = points.points[i];
struct quad q = quad_from_line(p1, p2, thickness);
V2 p1 = points.points[i - 1];
V2 p2 = points.points[i];
Quad q = quad_from_line(p1, p2, thickness);
draw_quad(sig, q, color);
}
if (loop && points.count > 2) {
struct v2 p1 = points.points[points.count - 1];
struct v2 p2 = points.points[0];
struct quad q = quad_from_line(p1, p2, thickness);
V2 p1 = points.points[points.count - 1];
V2 p2 = points.points[0];
Quad q = quad_from_line(p1, p2, thickness);
draw_quad(sig, q, color);
}
}
}
void draw_circle_line(struct gp_render_sig *sig, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
void draw_circle_line(G_RenderSig *sig, V2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct v2 *points = arena_push_array_no_zero(scratch.arena, struct v2, detail);
V2 *points = arena_push_array_no_zero(scratch.arena, V2, detail);
for (u32 i = 0; i < detail; ++i) {
f32 angle = ((f32)i / (f32)detail) * TAU;
struct v2 p = V2(
V2 p = V2FromXY(
radius * math_cos(angle),
radius * math_sin(angle)
);
points[i] = v2_add(pos, p);
}
struct v2_array a = {
V2Array a = {
.points = points,
.count = detail
};
@ -177,67 +177,67 @@ void draw_circle_line(struct gp_render_sig *sig, struct v2 pos, f32 radius, f32
scratch_end(scratch);
}
void draw_quad_line(struct gp_render_sig *sig, struct quad quad, f32 thickness, u32 color)
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color)
{
struct v2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
struct v2_array a = { .points = points, .count = countof(points) };
V2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
V2Array a = { .points = points, .count = countof(points) };
draw_poly_line(sig, a, 1, thickness, color);
}
void draw_arrow_line(struct gp_render_sig *sig, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color)
void draw_arrow_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, f32 arrowhead_height, u32 color)
{
const f32 head_width_ratio = 0.5f; /* Width of arrowhead relative to its length */
const f32 max_height_to_line_ratio = 0.9f; /* Maximum length of arrowhead relative to total line length */
arrowhead_height = min_f32(arrowhead_height, v2_len(v2_sub(end, start)) * max_height_to_line_ratio);
struct v2 head_start_dir = v2_sub(start, end);
V2 head_start_dir = v2_sub(start, end);
head_start_dir = v2_norm(head_start_dir);
head_start_dir = v2_mul(head_start_dir, arrowhead_height);
struct v2 head_start = v2_add(end, head_start_dir);
V2 head_start = v2_add(end, head_start_dir);
struct v2 head_p1_dir = v2_perp_mul(head_start_dir, head_width_ratio);
struct v2 head_p2_dir = v2_neg(head_p1_dir);
V2 head_p1_dir = v2_perp_mul(head_start_dir, head_width_ratio);
V2 head_p2_dir = v2_neg(head_p1_dir);
struct v2 head_p1 = v2_add(head_start, head_p1_dir);
struct v2 head_p2 = v2_add(head_start, head_p2_dir);
V2 head_p1 = v2_add(head_start, head_p1_dir);
V2 head_p2 = v2_add(head_start, head_p2_dir);
struct v2 head_points[] = { end, head_p1, head_p2 };
struct v2_array head_points_v2_array = {
V2 head_points[] = { end, head_p1, head_p2 };
V2Array head_points_v2_array = {
.points = head_points,
.count = countof(head_points)
};
draw_poly(sig, head_points_v2_array, color);
struct quad line_quad = quad_from_line(start, head_start, thickness);
Quad line_quad = quad_from_line(start, head_start, thickness);
draw_quad(sig, line_quad, color);
}
void draw_arrow_ray(struct gp_render_sig *sig, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color)
void draw_arrow_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, f32 arrowhead_height, u32 color)
{
struct v2 end = v2_add(pos, rel);
V2 end = v2_add(pos, rel);
draw_arrow_line(sig, pos, end, thickness, arrowhead_height, color);
}
void draw_collider_line(struct gp_render_sig *sig, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail)
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail)
{
struct arena_temp scratch = scratch_begin_no_conflict();
struct v2_array poly = ZI;
TempArena scratch = scratch_begin_no_conflict();
V2Array poly = ZI;
if (shape.radius == 0) {
poly.count = shape.count;
poly.points = arena_push_array_no_zero(scratch.arena, struct v2, shape.count);
poly.points = arena_push_array_no_zero(scratch.arena, V2, shape.count);
for (u32 i = 0; i < shape.count; ++i) {
struct v2 p = xform_mul_v2(shape_xf, shape.points[i]);
V2 p = xform_mul_v2(shape_xf, shape.points[i]);
poly.points[i] = p;
}
} else {
poly.count = detail;
poly.points = arena_push_array_no_zero(scratch.arena, struct v2, detail);
poly.points = arena_push_array_no_zero(scratch.arena, V2, detail);
for (u32 i = 0; i < detail; ++i) {
f32 angle = ((f32)i / (f32)detail) * TAU;
struct v2 dir = V2(math_cos(angle), math_sin(angle));
struct v2 p = collider_get_support_point(&shape, shape_xf, dir).p;
V2 dir = V2FromXY(math_cos(angle), math_sin(angle));
V2 p = collider_get_support_point(&shape, shape_xf, dir).p;
poly.points[i] = p;
}
}
@ -249,11 +249,11 @@ void draw_collider_line(struct gp_render_sig *sig, struct collider_shape shape,
* Grid
* ========================== */
void draw_grid(struct gp_render_sig *sig, struct xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, struct v2 offset)
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, V2 offset)
{
i32 grid_id = 0;
{
struct gp_render_cmd_desc cmd = ZI;
G_RenderCmdDesc cmd = ZI;
cmd.kind = GP_RENDER_CMD_KIND_PUSH_GRID;
cmd.grid.bg0_color = bg0_color;
cmd.grid.bg1_color = bg1_color;
@ -266,7 +266,7 @@ void draw_grid(struct gp_render_sig *sig, struct xform xf, u32 bg0_color, u32 bg
grid_id = gp_push_render_cmd(sig, &cmd);
}
struct gp_render_cmd_desc cmd = ZI;
G_RenderCmdDesc cmd = ZI;
cmd.kind = GP_RENDER_CMD_KIND_DRAW_MATERIAL;
cmd.material.xf = xf;
cmd.material.tint = COLOR_WHITE;
@ -278,9 +278,9 @@ void draw_grid(struct gp_render_sig *sig, struct xform xf, u32 bg0_color, u32 bg
* UI
* ========================== */
void draw_ui_rect(struct gp_render_sig *sig, struct draw_ui_rect_params params)
void draw_ui_rect(G_RenderSig *sig, D_UiRectParams params)
{
struct gp_render_cmd_desc cmd = ZI;
G_RenderCmdDesc cmd = ZI;
cmd.kind = GP_RENDER_CMD_KIND_DRAW_UI_RECT;
cmd.ui_rect.xf = params.xf;
cmd.ui_rect.texture = params.texture;
@ -294,9 +294,9 @@ void draw_ui_rect(struct gp_render_sig *sig, struct draw_ui_rect_params params)
* ========================== */
/* Returns the rect of the text area */
struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params)
Rect draw_text(G_RenderSig *sig, D_TextParams params)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
f32 inv_font_image_width = 1.0 / (f32)params.font->image_width;
f32 inv_font_image_height = 1.0 / (f32)params.font->image_height;
@ -312,7 +312,7 @@ struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params)
f32 width;
f32 height;
f32 advance;
struct clip_rect clip;
ClipRect clip;
};
struct drawable_line {
@ -352,14 +352,14 @@ struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params)
} else {
struct drawable_glyph *tg = arena_push(scratch.arena, struct drawable_glyph);
++num_line_glyphs;
struct font_glyph *glyph = font_get_glyph(params.font, codepoint);
F_Glyph *glyph = font_get_glyph(params.font, codepoint);
tg->off_x = glyph->off_x * params.scale;
tg->off_y = glyph->off_y * params.scale;
tg->width = glyph->width * params.scale;
tg->height = glyph->height * params.scale;
tg->advance = glyph->advance * params.scale;
struct rect glyph_atlas_rect = glyph->atlas_rect;
tg->clip = (struct clip_rect) {
Rect glyph_atlas_rect = glyph->atlas_rect;
tg->clip = (ClipRect) {
{
glyph_atlas_rect.x * inv_font_image_width,
glyph_atlas_rect.y * inv_font_image_height
@ -400,7 +400,7 @@ struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params)
* Determine text bounds
* ========================== */
struct rect bounds = ZI;
Rect bounds = ZI;
bounds.x = params.pos.x;
bounds.y = params.pos.y;
bounds.width = widest_line;
@ -440,7 +440,7 @@ struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params)
u64 line_number = 0;
for (struct drawable_line *line = first_line; line; line = line->next) {
struct v2 draw_pos = bounds.pos;
V2 draw_pos = bounds.pos;
draw_pos.y += line_number * line_spacing - first_line_top_offset;
/* Alignment */
@ -459,9 +459,9 @@ struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params)
/* Draw glyphs */
for (u64 i = 0; i < line->num_glyphs; ++i) {
struct drawable_glyph *tg = &line->glyphs[i];
struct v2 pos = V2(draw_pos.x + tg->off_x, draw_pos.y + tg->off_y);
struct v2 size = V2(tg->width, tg->height);
struct xform xf = xform_from_rect(RECT_FROM_V2(pos, size));
V2 pos = V2FromXY(draw_pos.x + tg->off_x, draw_pos.y + tg->off_y);
V2 size = V2FromXY(tg->width, tg->height);
Xform xf = xform_from_rect(RECT_FROM_V2(pos, size));
draw_ui_rect(sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = params.font->texture, .tint = params.color, .clip = tg->clip));
draw_pos.x += tg->advance;

View File

@ -1,94 +1,94 @@
struct font;
struct font_startup_receipt;
struct draw_startup_receipt { i32 _; };
struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr);
typedef struct D_StartupReceipt D_StartupReceipt;
struct D_StartupReceipt { i32 _; };
D_StartupReceipt draw_startup(F_StartupReceipt *font_sr);
/* ========================== *
* Material
* ========================== */
#define DRAW_MATERIAL_PARAMS(...) ((struct draw_material_params) { \
#define DRAW_MATERIAL_PARAMS(...) ((D_MaterialParams) { \
.tint = COLOR_WHITE, \
.clip = CLIP_ALL, \
__VA_ARGS__ \
})
struct draw_material_params {
struct xform xf;
struct gp_resource *texture;
struct clip_rect clip;
typedef struct D_MaterialParams D_MaterialParams;
struct D_MaterialParams {
Xform xf;
G_Resource *texture;
ClipRect clip;
u32 tint;
b32 is_light;
struct v3 light_emittance;
V3 light_emittance;
};
void draw_material(struct gp_render_sig *sig, struct draw_material_params params);
void draw_material(G_RenderSig *sig, D_MaterialParams params);
/* ========================== *
* Fill shapes
* ========================== */
void draw_poly_ex(struct gp_render_sig *sig, struct v2_array vertices, struct gp_indices indices, u32 color);
void draw_poly_ex(G_RenderSig *sig, V2Array vertices, G_Indices indices, u32 color);
void draw_poly(struct gp_render_sig *sig, struct v2_array points, u32 color);
void draw_poly(G_RenderSig *sig, V2Array points, u32 color);
void draw_circle(struct gp_render_sig *sig, struct v2 pos, f32 radius, u32 color, u32 detail);
void draw_circle(G_RenderSig *sig, V2 pos, f32 radius, u32 color, u32 detail);
void draw_quad(struct gp_render_sig *sig, struct quad quad, u32 color);
void draw_quad(G_RenderSig *sig, Quad quad, u32 color);
/* ========================== *
* Line shapes
* ========================== */
void draw_gradient_line(struct gp_render_sig *sig, struct v2 start, struct v2 end, f32 thickness, u32 start_color, u32 end_color);
void draw_gradient_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 start_color, u32 end_color);
void draw_line(struct gp_render_sig *sig, struct v2 start, struct v2 end, f32 thickness, u32 color);
void draw_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 color);
void draw_ray(struct gp_render_sig *sig, struct v2 pos, struct v2 rel, f32 thickness, u32 color);
void draw_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, u32 color);
void draw_poly_line(struct gp_render_sig *sig, struct v2_array points, b32 loop, f32 thickness, u32 color);
void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u32 color);
void draw_circle_line(struct gp_render_sig *sig, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
void draw_circle_line(G_RenderSig *sig, V2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
void draw_quad_line(struct gp_render_sig *sig, struct quad quad, f32 thickness, u32 color);
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color);
void draw_arrow_line(struct gp_render_sig *sig, struct v2 start, struct v2 end, f32 thickness, f32 arrowhead_height, u32 color);
void draw_arrow_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, f32 arrowhead_height, u32 color);
void draw_arrow_ray(struct gp_render_sig *sig, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color);
void draw_arrow_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, f32 arrowhead_height, u32 color);
void draw_collider_line(struct gp_render_sig *sig, struct collider_shape shape, struct xform shape_xf, f32 thickness, u32 color, u32 detail);
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail);
/* ========================== *
* Grid
* ========================== */
void draw_grid(struct gp_render_sig *sig, struct xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, struct v2 offset);
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, V2 offset);
/* ========================== *
* UI
* ========================== */
#define DRAW_UI_RECT_PARAMS(...) ((struct draw_ui_rect_params) { \
#define DRAW_UI_RECT_PARAMS(...) ((D_UiRectParams) { \
.tint = COLOR_WHITE, \
.clip = CLIP_ALL, \
__VA_ARGS__ \
})
struct draw_ui_rect_params {
struct xform xf;
struct gp_resource *texture;
struct clip_rect clip;
typedef struct D_UiRectParams D_UiRectParams;
struct D_UiRectParams {
Xform xf;
G_Resource *texture;
ClipRect clip;
u32 tint;
};
void draw_ui_rect(struct gp_render_sig *sig, struct draw_ui_rect_params params);
void draw_ui_rect(G_RenderSig *sig, D_UiRectParams params);
/* ========================== *
* Text
* ========================== */
#define DRAW_TEXT_PARAMS(...) ((struct draw_text_params) { \
#define DRAW_TEXT_PARAMS(...) ((D_TextParams) { \
.scale = 1.0, \
.alignment = DRAW_TEXT_ALIGNMENT_LEFT, \
.offset_x = DRAW_TEXT_OFFSET_X_LEFT, \
@ -98,36 +98,37 @@ void draw_ui_rect(struct gp_render_sig *sig, struct draw_ui_rect_params params);
})
/* How is text aligned within its area */
enum draw_text_alignment {
typedef enum D_TextAlignment {
DRAW_TEXT_ALIGNMENT_LEFT, /* Default */
DRAW_TEXT_ALIGNMENT_CENTER,
DRAW_TEXT_ALIGNMENT_RIGHT
};
} D_TextAlignment;
/* How does the specified text position relate to the text area.
* E.g. BOTTOM & RIGHT means the bottom-right of the text area will snap to
* the specified position. */
enum draw_text_offset_x {
typedef enum D_TextOffsetX {
DRAW_TEXT_OFFSET_X_LEFT, /* Default */
DRAW_TEXT_OFFSET_X_CENTER,
DRAW_TEXT_OFFSET_X_RIGHT
};
} D_TextOffsetX;
enum draw_text_offset_y {
typedef enum D_TextOffsetY {
DRAW_TEXT_OFFSET_Y_TOP, /* Default */
DRAW_TEXT_OFFSET_Y_CENTER,
DRAW_TEXT_OFFSET_Y_BOTTOM
};
} D_TextOffsetY;
struct draw_text_params {
struct font *font;
struct v2 pos;
typedef struct D_TextParams D_TextParams;
struct D_TextParams {
F_Font *font;
V2 pos;
f32 scale;
u32 color;
enum draw_text_alignment alignment;
enum draw_text_offset_x offset_x;
enum draw_text_offset_y offset_y;
struct string str;
D_TextAlignment alignment;
D_TextOffsetX offset_x;
D_TextOffsetY offset_y;
String str;
};
struct rect draw_text(struct gp_render_sig *sig, struct draw_text_params params);
Rect draw_text(G_RenderSig *sig, D_TextParams params);

View File

@ -1,7 +1,8 @@
struct dxc_compile_result {
struct string dxc;
struct string errors;
typedef struct DXC_Result DXC_Result;
struct DXC_Result {
String dxc;
String errors;
b32 success;
};
struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_source, i32 num_args, struct string *args);
DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String *args);

View File

@ -1,12 +1,12 @@
#if !RESOURCE_RELOADING
struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_source, i32 num_args, struct string *args)
DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String *args)
{
(UNUSED)arena;
(UNUSED)shader_source;
(UNUSED)num_args;
(UNUSED)args;
struct dxc_compile_result res = ZI;
DXC_Result res = ZI;
return res;
}
@ -33,11 +33,11 @@ struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_
#pragma comment(lib, "dxcompiler")
/* https://github.com/microsoft/DirectXShaderCompiler/wiki/Using-dxc.exe-and-dxcompiler.dll */
struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_source, i32 num_args, struct string *args)
DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String *args)
{
__prof;
struct arena_temp scratch = scratch_begin(arena);
struct dxc_compile_result res = ZI;
TempArena scratch = scratch_begin(arena);
DXC_Result res = ZI;
wchar_t **wstr_args = arena_push_array(scratch.arena, wchar_t *, num_args);
for (i32 i = 0; i < num_args; ++i) {
@ -65,7 +65,7 @@ struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_
CComPtr<IDxcBlobUtf8> dxc_errors = 0;
compile_results->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&dxc_errors), 0);
if (dxc_errors != 0) {
struct string blob_str = ZI;
String blob_str = ZI;
blob_str.len = dxc_errors->GetBufferSize();
blob_str.text = (u8 *)dxc_errors->GetBufferPointer();
res.errors = string_copy(arena, blob_str);
@ -81,7 +81,7 @@ struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_
CComPtr<IDxcBlob> dxc_shader = 0;
compile_results->GetOutput(DXC_OUT_OBJECT, IID_PPV_ARGS(&dxc_shader), 0);
if (dxc_shader != 0) {
struct string blob_str = ZI;
String blob_str = ZI;
blob_str.len = dxc_shader->GetBufferSize();
blob_str.text = (u8 *)dxc_shader->GetBufferPointer();
res.dxc = string_copy(arena, blob_str);

View File

@ -6,7 +6,7 @@ GLOBAL u32 g_font_codes[] = {
struct font_task_params {
struct font_task_params *next_free;
struct asset *asset;
AC_Asset *asset;
f32 point_size;
u64 path_len;
char path_cstr[1024];
@ -14,7 +14,7 @@ struct font_task_params {
struct font_task_params_store {
struct font_task_params *head_free;
struct arena *arena;
Arena *arena;
struct snc_mutex mutex;
};
@ -24,20 +24,20 @@ struct font_task_params_store {
GLOBAL struct {
struct font_task_params_store params;
} G = ZI, DEBUG_ALIAS(G, L_font);
} G = ZI, DEBUG_ALIAS(G, G_font);
/* ========================== *
* Startup
* ========================== */
struct font_startup_receipt font_startup(struct asset_cache_startup_receipt *asset_cache_sr,
struct ttf_startup_receipt *ttf_sr)
F_StartupReceipt font_startup(AC_StartupReceipt *asset_cache_sr,
TTF_StartupReceipt *ttf_sr)
{
__prof;
(UNUSED)asset_cache_sr;
(UNUSED)ttf_sr;
G.params.arena = arena_alloc(GIBI(64));
return (struct font_startup_receipt) { 0 };
return (F_StartupReceipt) { 0 };
}
/* ========================== *
@ -75,12 +75,12 @@ INTERNAL void font_task_params_release(struct font_task_params *p)
INTERNAL SYS_JOB_DEF(font_load_asset_job, job)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct font_task_params *params = job.sig;
struct string path = STRING(params->path_len, (u8 *)params->path_cstr);
String path = STRING(params->path_len, (u8 *)params->path_cstr);
f32 point_size = params->point_size;
struct asset *asset = params->asset;
AC_Asset *asset = params->asset;
logf_info("Loading font \"%F\" (point size %F)", FMT_STR(path), FMT_FLOAT((f64)point_size));
i64 start_ns = sys_time_ns();
@ -89,25 +89,25 @@ INTERNAL SYS_JOB_DEF(font_load_asset_job, job)
ASSERT(countof(g_font_codes) < LOOKUP_TABLE_SIZE);
/* Decode */
struct resource res = resource_open(path);
R_Resource res = resource_open(path);
if (!resource_exists(&res)) {
/* FIME: Load baked font instead of panicking */
sys_panic(string_format(scratch.arena,
LIT("Font \"%F\" not found"),
FMT_STR(path)));
}
struct ttf_decode_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);
/* Send texture to GPU */
struct gp_resource *texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_data.width, result.image_data.height), result.image_data.pixels);
G_Resource *texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2i32FromXY(result.image_data.width, result.image_data.height), result.image_data.pixels);
/* Allocate store memory */
struct font *font = 0;
F_Font *font = 0;
{
struct asset_cache_store store = asset_cache_store_open();
font = arena_push(store.arena, struct font);
font->glyphs = arena_push_array_no_zero(store.arena, struct font_glyph, result.glyphs_count);
AC_Store store = asset_cache_store_open();
font = arena_push(store.arena, F_Font);
font->glyphs = arena_push_array_no_zero(store.arena, F_Glyph, result.glyphs_count);
font->lookup = arena_push_array(store.arena, u16, LOOKUP_TABLE_SIZE);
asset_cache_store_close(&store);
}
@ -127,6 +127,7 @@ INTERNAL SYS_JOB_DEF(font_load_asset_job, job)
}
/* Copy glyphs from decode result */
STATIC_ASSERT(sizeof(*font->glyphs) == sizeof(*result.glyphs)); /* Font glyph size must match TTF glyph size for memcpy */
MEMCPY(font->glyphs, result.glyphs, sizeof(*font->glyphs) * result.glyphs_count);
/* Build lookup table */
@ -144,19 +145,19 @@ INTERNAL SYS_JOB_DEF(font_load_asset_job, job)
}
/* Returns the asset from the asset cache */
struct asset *font_load_asset(struct string path, f32 point_size, b32 wait)
AC_Asset *font_load_asset(String path, f32 point_size, b32 wait)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
/* Concatenate point_size to path for key */
struct string key = string_format(scratch.arena,
String key = string_format(scratch.arena,
LIT("%F%F_font"),
FMT_STR(path),
FMT_FLOAT_P((f64)point_size, 1));
u64 hash = asset_cache_hash(key);
b32 is_first_touch;
struct asset *asset = asset_cache_touch(key, hash, &is_first_touch);
AC_Asset *asset = asset_cache_touch(key, hash, &is_first_touch);
if (is_first_touch) {
/* Assemble task params */
@ -183,20 +184,20 @@ struct asset *font_load_asset(struct string path, f32 point_size, b32 wait)
return asset;
}
struct font *font_load_async(struct string path, f32 point_size)
F_Font *font_load_async(String path, f32 point_size)
{
__prof;
struct asset *asset = font_load_asset(path, point_size, 0);
struct font *f = (struct font *)asset_cache_get_store_data(asset);
AC_Asset *asset = font_load_asset(path, point_size, 0);
F_Font *f = (F_Font *)asset_cache_get_store_data(asset);
return f;
}
struct font *font_load(struct string path, f32 point_size)
F_Font *font_load(String path, f32 point_size)
{
__prof;
struct asset *asset = font_load_asset(path, point_size, 1);
AC_Asset *asset = font_load_asset(path, point_size, 1);
asset_cache_wait(asset);
struct font *f = (struct font *)asset_cache_get_store_data(asset);
F_Font *f = (F_Font *)asset_cache_get_store_data(asset);
return f;
}
@ -204,7 +205,7 @@ struct font *font_load(struct string path, f32 point_size)
* Other
* ========================== */
struct font_glyph *font_get_glyph(struct font *font, u32 codepoint)
F_Glyph *font_get_glyph(F_Font *font, u32 codepoint)
{
if (codepoint < LOOKUP_TABLE_SIZE) {
u16 index = font->lookup[codepoint];

View File

@ -1,32 +1,30 @@
struct asset;
struct asset_cache_startup_receipt;
struct ttf_startup_receipt;
struct font_glyph {
typedef struct F_Glyph F_Glyph;
struct F_Glyph {
f32 off_x;
f32 off_y;
i32 advance;
f32 width;
f32 height;
struct rect atlas_rect;
Rect atlas_rect;
};
struct font {
struct gp_resource *texture;
typedef struct F_Font F_Font;
struct F_Font {
G_Resource *texture;
u32 image_width;
u32 image_height;
f32 point_size;
u16 glyphs_count;
struct font_glyph *glyphs;
F_Glyph *glyphs;
u16 *lookup;
};
struct font_startup_receipt { i32 _; };
struct font_startup_receipt font_startup(struct asset_cache_startup_receipt *asset_cache_sr,
struct ttf_startup_receipt *ttf_sr);
typedef struct F_StartupReceipt F_StartupReceipt;
struct F_StartupReceipt { i32 _; };
F_StartupReceipt font_startup(AC_StartupReceipt *asset_cache_sr, TTF_StartupReceipt *ttf_sr);
struct asset *font_load_asset(struct string path, f32 point_size, b32 wait);
struct font *font_load_async(struct string path, f32 point_size);
struct font *font_load(struct string path, f32 point_size);
AC_Asset *font_load_asset(String path, f32 point_size, b32 wait);
F_Font *font_load_async(String path, f32 point_size);
F_Font *font_load(String path, f32 point_size);
struct font_glyph *font_get_glyph(struct font *font, u32 codepoint);
F_Glyph *font_get_glyph(F_Font *font, u32 codepoint);

View File

@ -1,7 +1,8 @@
struct sys_window;
struct snc_counter;
struct gp_indices {
typedef struct G_Indices G_Indices;
struct G_Indices {
u32 count;
u32 *indices;
};
@ -16,20 +17,20 @@ void gp_startup(void);
* Resource
* ========================== */
struct gp_resource;
typedef struct G_Resource G_Resource;
/* NOTE: Internally, the layer will make sure to not release any resources
* until after any in-flight GPU runs finish using them. However, it is up to
* the caller to make sure the released resources aren't then referenced in
* any runs
*/
void gp_resource_release(struct gp_resource *resource);
void gp_resource_release(G_Resource *resource);
/* ========================== *
* Texture
* ========================== */
enum gp_texture_format {
typedef enum G_TextureFormat {
GP_TEXTURE_FORMAT_NONE,
GP_TEXTURE_FORMAT_R8_UNORM,
GP_TEXTURE_FORMAT_R8G8B8A8_UNORM,
@ -37,22 +38,22 @@ enum gp_texture_format {
GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT,
NUM_GP_TEXTURE_FORMATS
};
} G_TextureFormat;
enum gp_texture_flag {
typedef enum G_TextureFlag {
GP_TEXTURE_FLAG_NONE = (0),
GP_TEXTURE_FLAG_TARGETABLE = (1 << 0)
};
} G_TextureFlag;
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data);
G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2i32 size, void *initial_data);
struct v2i32 gp_texture_get_size(struct gp_resource *texture);
V2i32 gp_texture_get_size(G_Resource *texture);
/* ========================== *
* Render
* ========================== */
enum gp_render_cmd_kind {
typedef enum G_RenderCmdKind {
GP_RENDER_CMD_KIND_NONE,
GP_RENDER_CMD_KIND_DRAW_MATERIAL,
GP_RENDER_CMD_KIND_DRAW_UI_RECT,
@ -60,35 +61,36 @@ enum gp_render_cmd_kind {
GP_RENDER_CMD_KIND_PUSH_GRID,
NUM_GP_RENDER_CMD_KINDS
};
} G_RenderCmdKind;
struct gp_render_cmd_desc {
enum gp_render_cmd_kind kind;
typedef struct G_RenderCmdDesc G_RenderCmdDesc;
struct G_RenderCmdDesc {
G_RenderCmdKind kind;
union {
struct {
struct xform xf;
struct gp_resource *texture;
struct clip_rect clip;
Xform xf;
G_Resource *texture;
ClipRect clip;
u32 tint;
b32 is_light;
struct v3 light_emittance;
V3 light_emittance;
u32 grid_cmd_id;
} material;
struct {
struct xform xf;
struct gp_resource *texture;
struct clip_rect clip;
Xform xf;
G_Resource *texture;
ClipRect clip;
u32 tint;
} ui_rect;
struct {
struct v2_array vertices;
struct gp_indices indices;
V2Array vertices;
G_Indices indices;
u32 color;
} ui_shape;
struct {
f32 line_thickness;
f32 line_spacing;
struct v2 offset;
V2 offset;
u32 bg0_color;
u32 bg1_color;
u32 line_color;
@ -98,45 +100,51 @@ struct gp_render_cmd_desc {
};
};
struct gp_render_params {
struct v2i32 ui_size;
struct v2i32 render_size;
struct xform world_to_render_xf;
struct xform render_to_ui_xf;
typedef struct G_RenderParams G_RenderParams;
struct G_RenderParams {
V2i32 ui_size;
V2i32 render_size;
Xform world_to_render_xf;
Xform render_to_ui_xf;
b32 effects_disabled;
};
struct gp_render_sig *gp_render_sig_alloc(void);
typedef struct G_RenderSig G_RenderSig;
G_RenderSig *gp_render_sig_alloc(void);
/* Returns a cmd id internal to the sig */
u32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_desc *desc);
u32 gp_push_render_cmd(G_RenderSig *render_sig, G_RenderCmdDesc *desc);
struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp_render_params render_params);
G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams render_params);
/* ========================== *
* Memory info
* ========================== */
struct gp_memory_info {
typedef struct G_MemoryInfo G_MemoryInfo;
struct G_MemoryInfo {
u64 local_used;
u64 local_budget;
u64 non_local_used;
u64 non_local_budget;
};
struct gp_memory_info gp_query_memory_info(void);
G_MemoryInfo gp_query_memory_info(void);
/* ========================== *
* Swapchain
* ========================== */
struct gp_swapchain *gp_swapchain_alloc(struct sys_window *window, struct v2i32 resolution);
typedef struct G_Swapchain G_Swapchain;
void gp_swapchain_release(struct gp_swapchain *gp_swapchain);
G_Swapchain *gp_swapchain_alloc(struct sys_window *window, V2i32 resolution);
void gp_swapchain_release(G_Swapchain *gp_swapchain);
/* Waits until a new backbuffer is ready to be written to.
* This should be called before rendering for minimum latency. */
void gp_swapchain_wait(struct gp_swapchain *gp_swapchain);
void gp_swapchain_wait(G_Swapchain *gp_swapchain);
/* ========================== *
* Present
@ -145,4 +153,4 @@ void gp_swapchain_wait(struct gp_swapchain *gp_swapchain);
/* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution`
* 2. Blits `texture` to the backbuffer using `texture_xf`
* 3. Presents the backbuffer */
void gp_present(struct gp_swapchain *gp_swapchain, struct v2i32 backbuffer_resolution, struct gp_resource *texture, struct xform texture_xf, i32 vsync);
void gp_present(G_Swapchain *gp_swapchain, V2i32 backbuffer_resolution, G_Resource *texture, Xform texture_xf, i32 vsync);

View File

@ -58,8 +58,8 @@
* ========================== */
struct shader_desc {
struct string file;
struct string func;
String file;
String func;
};
struct pipeline_rtv_desc {
@ -68,22 +68,22 @@ struct pipeline_rtv_desc {
};
struct pipeline_desc {
struct string name;
String name;
/* If a dxc string is set, then it will be used directly instead of looking up dxc from archive using pipeline name */
struct string vs_dxc;
struct string ps_dxc;
struct string cs_dxc;
String vs_dxc;
String ps_dxc;
String cs_dxc;
struct pipeline_rtv_desc rtvs[8];
};
struct pipeline {
struct string name;
String name;
u64 hash;
b32 success;
b32 is_gfx;
struct string error;
String error;
i64 compilation_time_ns;
/* Lock global pipelines mutex when accessing */
@ -97,32 +97,32 @@ struct pipeline {
};
struct pipeline_error {
struct string msg;
String msg;
struct pipeline_error *next;
};
struct pipeline_include {
struct string name;
String name;
u64 name_hash;
struct pipeline_include *next;
};
struct pipeline_scope {
struct arena *arena;
struct dict *refs;
Arena *arena;
Dict *refs;
struct pipeline_scope *next_free;
};
struct command_queue_desc {
enum D3D12_COMMAND_LIST_TYPE type;
enum D3D12_COMMAND_QUEUE_PRIORITY priority;
struct string dbg_name;
String dbg_name;
};
struct command_queue {
struct command_queue_desc desc;
ID3D12CommandQueue *cq;
struct arena *arena;
Arena *arena;
struct snc_mutex submit_fence_mutex;
u64 submit_fence_target;
@ -137,7 +137,7 @@ struct command_queue {
struct command_list_pool {
struct command_queue *cq;
struct arena *arena;
Arena *arena;
struct snc_mutex mutex;
struct command_list *first_submitted_command_list;
struct command_list *last_submitted_command_list;
@ -214,7 +214,7 @@ struct dx12_resource {
D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */
struct v2i32 texture_size;
V2i32 texture_size;
struct dx12_resource *next_free;
};
@ -229,7 +229,7 @@ struct swapchain {
IDXGISwapChain3 *swapchain;
HWND hwnd;
HANDLE waitable;
struct v2i32 resolution;
V2i32 resolution;
struct swapchain_buffer buffers[DX12_SWAPCHAIN_BUFFER_COUNT];
struct swapchain *next_free;
@ -237,7 +237,7 @@ struct swapchain {
struct cpu_descriptor_heap {
enum D3D12_DESCRIPTOR_HEAP_TYPE type;
struct arena *arena;
Arena *arena;
struct snc_mutex mutex;
u32 descriptor_size;
@ -305,27 +305,27 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name);
* ========================== */
GLOBAL struct {
struct atomic32 initialized;
Atomic32 initialized;
/* Descriptor heaps pool */
struct snc_mutex command_descriptor_heaps_mutex;
struct arena *command_descriptor_heaps_arena;
Arena *command_descriptor_heaps_arena;
struct command_descriptor_heap *first_submitted_command_descriptor_heap;
struct command_descriptor_heap *last_submitted_command_descriptor_heap;
/* Command buffers pool */
struct snc_mutex command_buffers_mutex;
struct arena *command_buffers_arena;
struct dict *command_buffers_dict;
Arena *command_buffers_arena;
Dict *command_buffers_dict;
/* Resources pool */
struct snc_mutex resources_mutex;
struct arena *resources_arena;
Arena *resources_arena;
struct dx12_resource *first_free_resource;
/* Swapchains pool */
struct snc_mutex swapchains_mutex;
struct arena *swapchains_arena;
Arena *swapchains_arena;
struct swapchain *first_free_swapchain;
/* Shader bytecode archive */
@ -333,16 +333,16 @@ GLOBAL struct {
/* Pipeline cache */
struct snc_mutex pipelines_mutex;
struct arena *pipelines_arena;
Arena *pipelines_arena;
struct pipeline *first_free_pipeline;
struct dict *pipeline_descs;
struct dict *top_pipelines; /* Latest pipelines */
struct dict *top_successful_pipelines; /* Latest pipelines that successfully compiled */
Dict *pipeline_descs;
Dict *top_pipelines; /* Latest pipelines */
Dict *top_successful_pipelines; /* Latest pipelines that successfully compiled */
struct pipeline_scope *first_free_pipeline_scope;
/* Fenced release queue */
struct snc_mutex fenced_releases_mutex;
struct arena *fenced_releases_arena;
Arena *fenced_releases_arena;
u64 fenced_release_targets[DX12_NUM_QUEUES];
/* Factory */
@ -409,7 +409,7 @@ void gp_startup(void)
G.fenced_releases_arena = arena_alloc(GIBI(64));
/* Initialize embedded shader archive */
struct string embedded_data = inc_dxc_tar();
String embedded_data = inc_dxc_tar();
if (embedded_data.len <= 0) {
sys_panic(LIT("No embedded shaders found"));
}
@ -460,10 +460,10 @@ INTERNAL SYS_EXIT_FUNC(gp_shutdown)
* Dx12 device initialization
* ========================== */
INTERNAL void dx12_init_error(struct string error)
INTERNAL void dx12_init_error(String error)
{
struct arena_temp scratch = scratch_begin_no_conflict();
struct string msg = string_format(scratch.arena, LIT("Failed to initialize DirectX 12.\n\n%F"), FMT_STR(error));
TempArena scratch = scratch_begin_no_conflict();
String msg = string_format(scratch.arena, LIT("Failed to initialize DirectX 12.\n\n%F"), FMT_STR(error));
sys_panic(msg);
scratch_end(scratch);
}
@ -471,7 +471,7 @@ INTERNAL void dx12_init_error(struct string error)
INTERNAL void dx12_init_device(void)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
HRESULT hr = 0;
/* Enable debug layer */
@ -516,8 +516,8 @@ INTERNAL void dx12_init_device(void)
__profn("Create device");
IDXGIAdapter1 *adapter = 0;
ID3D12Device *device = 0;
struct string error = LIT("Could not initialize GPU device.");
struct string first_gpu_name = ZI;
String error = LIT("Could not initialize GPU device.");
String first_gpu_name = ZI;
u32 adapter_index = 0;
b32 skip = 0; /* For debugging iGPU */
for (;;) {
@ -548,7 +548,7 @@ INTERNAL void dx12_init_device(void)
}
if (!device) {
if (first_gpu_name.len > 0) {
struct 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));
}
dx12_init_error(error);
@ -668,7 +668,7 @@ INTERNAL void dx12_init_objects(void)
__profn("Initialize command queue profiling contexts");
for (i32 i = 0; i < DX12_NUM_QUEUES; ++i) {
struct command_queue *cq = G.command_queues[i];
struct string dbg_name = params[i].dbg_name;
String dbg_name = params[i].dbg_name;
__prof_dx12_ctx_alloc(cq->prof, G.device, cq->cq, dbg_name.text, dbg_name.len);
(UNUSED)dbg_name;
}
@ -686,7 +686,7 @@ INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines);
INTERNAL void dx12_init_pipelines(void)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
/* Register pipeline descs */
{
@ -741,7 +741,7 @@ INTERNAL void dx12_init_pipelines(void)
/* Compile pipelines */
u32 num_pipelines = 0;
struct pipeline_desc *descs = arena_push_dry(scratch.arena, struct pipeline_desc);
for (struct dict_entry *entry = G.pipeline_descs->first; entry; entry = entry->next) {
for (DictEntry *entry = G.pipeline_descs->first; entry; entry = entry->next) {
struct pipeline_desc *desc = (struct pipeline_desc *)entry->value;
*arena_push(scratch.arena, struct pipeline_desc) = *desc;
++num_pipelines;
@ -761,12 +761,12 @@ INTERNAL void dx12_init_pipelines(void)
if (pipeline->success) {
logf_success("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns)));
if (pipeline->error.len) {
struct string msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error));
String msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error));
log_warning(msg);
}
} else {
struct string error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error");
struct string msg = string_format(scratch.arena, LIT("Error initializing pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(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));
log_error(msg);
sys_message_box(SYS_MESSAGE_BOX_KIND_WARNING, msg);
}
@ -782,16 +782,16 @@ INTERNAL void dx12_init_pipelines(void)
INTERNAL void dx12_init_noise(void)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
{
struct string noise_res_name = LIT("noise_128x128x64_16.dat");
struct resource noise_res = resource_open(noise_res_name);
String noise_res_name = LIT("noise_128x128x64_16.dat");
R_Resource noise_res = resource_open(noise_res_name);
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;
if (resource_exists(&noise_res)) {
struct string data = resource_get_data(&noise_res);
String data = resource_get_data(&noise_res);
if (data.len != expected_size) {
sys_panic(string_format(scratch.arena,
LIT("Noise texture has unexpected size for a %Fx%Fx%F texture (expected %F, got %F)"),
@ -848,21 +848,21 @@ INTERNAL void dx12_init_noise(void)
#if RESOURCE_RELOADING
struct shader_compile_desc {
struct string src;
struct string friendly_name;
struct string entry;
struct string target;
String src;
String friendly_name;
String entry;
String target;
};
struct shader_compile_result {
i64 elapsed_ns;
struct string dxc;
struct string errors;
String dxc;
String errors;
b32 success;
};
struct shader_compile_job_sig {
struct arena *arena;
Arena *arena;
struct shader_compile_desc *descs;
struct shader_compile_result *results;
};
@ -871,28 +871,28 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job)
{
__prof;
struct shader_compile_job_sig *sig = job.sig;
struct arena *arena = sig->arena;
Arena *arena = sig->arena;
struct shader_compile_desc *desc = &sig->descs[job.id];
struct shader_compile_result *result = &sig->results[job.id];
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
{
i64 start_ns = sys_time_ns();
struct dxc_compile_result dxc_result = ZI;
DXC_Result dxc_result = ZI;
{
__profn("Compile shader");
logf_info("Compiling shader \"%F:%F\"", FMT_STR(desc->friendly_name), FMT_STR(desc->entry));
/* NOTE: `DXC_ARGS` is supplied by build system at compile time */
char *dxc_args_cstr = STRINGIZE(DXC_ARGS);
struct string dxc_args_str = string_from_cstr_no_limit(dxc_args_cstr);
struct string_array dxc_args_array = string_split(scratch.arena, dxc_args_str, LIT(" "));
struct string shader_args[] = {
String dxc_args_str = string_from_cstr_no_limit(dxc_args_cstr);
StringArray dxc_args_array = string_split(scratch.arena, dxc_args_str, LIT(" "));
String shader_args[] = {
desc->friendly_name,
LIT("-E"), desc->entry,
LIT("-T"), desc->target,
};
u32 num_args = countof(shader_args) + dxc_args_array.count;
struct string *args = arena_push_array(scratch.arena, struct string, num_args);
String *args = arena_push_array(scratch.arena, String, num_args);
for (u32 i = 0; i < countof(shader_args); ++i) {
args[i] = shader_args[i];
}
@ -940,19 +940,19 @@ INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
pipeline->name = desc->name;
pipeline->hash = hash_fnv64(HASH_FNV64_BASIS, pipeline->name);
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
{
i64 start_ns = sys_time_ns();
struct string pipeline_name = pipeline->name;
String pipeline_name = pipeline->name;
logf_info("Loading pipeline \"%F\"", FMT_STR(pipeline_name));
b32 success = 1;
HRESULT hr = 0;
struct string error_str = ZI;
String error_str = ZI;
struct 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;
struct 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;
struct 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 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 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 cs_dxc = desc->cs_dxc.len > 0 ? desc->cs_dxc : tar_get(&G.dxc_archive, string_cat(scratch.arena, pipeline_name, LIT(".cs")))->data;
if (success && vs_dxc.len > 0 && ps_dxc.len <= 0) {
error_str = LIT("Pipeline has vertex shader without pixel shader");
success = 0;
@ -1216,7 +1216,7 @@ INTERNAL struct pipeline_scope *pipeline_scope_begin(void)
}
snc_unlock(&lock);
}
struct arena *arena = 0;
Arena *arena = 0;
if (scope) {
arena = scope->arena;
} else {
@ -1234,7 +1234,7 @@ INTERNAL void pipeline_scope_end(struct pipeline_scope *scope)
__prof;
struct snc_lock lock = snc_lock_e(&G.pipelines_mutex);
{
for (struct dict_entry *entry = scope->refs->first; entry; entry = entry->next) {
for (DictEntry *entry = scope->refs->first; entry; entry = entry->next) {
struct pipeline *pipeline = (struct pipeline *)entry->value;
if (--pipeline->refcount <= 0) {
fenced_release(pipeline, FENCED_RELEASE_KIND_PIPELINE);
@ -1247,7 +1247,7 @@ INTERNAL void pipeline_scope_end(struct pipeline_scope *scope)
}
INTERNAL READONLY struct pipeline g_nil_pipeline = ZI;
INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, struct string name)
INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, String name)
{
__prof;
struct pipeline *res = &g_nil_pipeline;
@ -1309,10 +1309,10 @@ INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines)
INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct string rst_extension = LIT(".rst");
struct string knl_extension = LIT(".knl");
String rst_extension = LIT(".rst");
String knl_extension = LIT(".knl");
b32 is_src = string_starts_with(name, LIT("src/"));
b32 is_rs = is_src && string_ends_with(name, rst_extension);
@ -1320,8 +1320,8 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
b32 success = 0;
/* Recompile shaders */
struct string pipeline_name = ZI;
struct string friendly_name = ZI;
String pipeline_name = ZI;
String friendly_name = ZI;
i32 num_shaders = 0;
struct shader_compile_desc *shader_descs = 0;
struct shader_compile_result *shader_results = 0;
@ -1329,15 +1329,15 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
logf_debug("Change detected in shader source file \"%F\", recompiling...", FMT_STR(name));
success = 1;
struct sys_file file = sys_file_open_read_wait(name);
struct string data = sys_file_read_all(scratch.arena, file);
String data = sys_file_read_all(scratch.arena, file);
{
friendly_name = name;
struct string_array split = string_split(scratch.arena, friendly_name, LIT("src/"));
StringArray split = string_split(scratch.arena, friendly_name, LIT("src/"));
friendly_name = split.count > 0 ? string_cat(scratch.arena, LIT("src/"), split.strings[split.count - 1]) : friendly_name;
}
{
pipeline_name = name;
struct string_array split = string_split(scratch.arena, pipeline_name, LIT("/"));
StringArray split = string_split(scratch.arena, pipeline_name, LIT("/"));
pipeline_name = split.count > 0 ? split.strings[split.count - 1] : pipeline_name;
split = string_split(scratch.arena, pipeline_name, LIT("."));
pipeline_name = split.count > 1 ? split.strings[split.count - 2] : pipeline_name;
@ -1386,11 +1386,11 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
if (result->success) {
logf_success("Finished compiling shader \"%F:%F\" in %F seconds", FMT_STR(desc->friendly_name), FMT_STR(desc->entry), FMT_FLOAT(SECONDS_FROM_NS(result->elapsed_ns)));
if (result->errors.len > 0) {
struct string msg = result->errors;
String msg = result->errors;
log_warning(msg);
}
} else {
struct string msg = result->errors;
String msg = result->errors;
log_error(msg);
success = 0;
}
@ -1400,7 +1400,7 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
/* Create pipeline descs */
u32 num_pipelines = 0;
struct pipeline_desc *pipeline_descs = arena_push_dry(scratch.arena, struct pipeline_desc);
for (struct dict_entry *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 new_pipeline_desc = *pipeline_desc;
if (string_eq(pipeline_desc->name, pipeline_name)) {
@ -1434,20 +1434,20 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name)
if (pipeline->success) {
logf_success("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns)));
if (pipeline->error.len > 0) {
struct string msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error));
String msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error));
log_warning(msg);
}
} else {
{
struct string error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error");
struct string msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(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));
log_error(msg);
}
struct pipeline *old_pipeline = (struct pipeline *)dict_get(G.top_successful_pipelines, pipeline->hash);
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 */
struct string error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error");
struct string msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(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));
sys_message_box(SYS_MESSAGE_BOX_KIND_WARNING, msg);
}
@ -1517,7 +1517,7 @@ INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRI
__prof;
struct cpu_descriptor_heap *dh = 0;
{
struct arena *arena = arena_alloc(MEBI(64));
Arena *arena = arena_alloc(MEBI(64));
dh = arena_push(arena, struct cpu_descriptor_heap);
dh->arena = arena;
}
@ -1663,7 +1663,7 @@ INTERNAL void dx12_resource_release_now(struct dx12_resource *t)
snc_unlock(&lock);
}
void gp_resource_release(struct gp_resource *resource)
void gp_resource_release(G_Resource *resource)
{
struct dx12_resource *r = (struct dx12_resource *)resource;
fenced_release(r, FENCED_RELEASE_KIND_RESOURCE);
@ -1682,7 +1682,7 @@ struct dx12_resource_barrier_desc {
INTERNAL void dx12_resource_barriers(ID3D12GraphicsCommandList *cl, i32 num_descs, struct dx12_resource_barrier_desc *descs)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
i32 num_rbs = 0;
struct D3D12_RESOURCE_BARRIER *rbs = arena_push_array_no_zero(scratch.arena, struct D3D12_RESOURCE_BARRIER, num_descs);
@ -1737,7 +1737,7 @@ INTERNAL SYS_JOB_DEF(command_queue_alloc_job, job)
{
struct command_queue *cq = 0;
{
struct arena *arena = arena_alloc(GIBI(64));
Arena *arena = arena_alloc(GIBI(64));
cq = arena_push(arena, struct command_queue);
cq->arena = arena;
}
@ -1779,7 +1779,7 @@ INTERNAL struct command_list_pool *command_list_pool_alloc(struct command_queue
{
struct command_list_pool *pool = 0;
{
struct arena *arena = arena_alloc(GIBI(64));
Arena *arena = arena_alloc(GIBI(64));
pool = arena_push(arena, struct command_list_pool);
pool->arena = arena;
}
@ -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);
struct dict_entry *cb_group_entry = dict_ensure_entry(G.command_buffers_arena, G.command_buffers_dict, group_hash);
DictEntry *cb_group_entry = dict_ensure_entry(G.command_buffers_arena, G.command_buffers_dict, group_hash);
cb_group = (struct command_buffer_group *)cb_group_entry->value;
if (!cb_group) {
/* Create group */
@ -2204,7 +2204,7 @@ INTERNAL SYS_JOB_DEF(dx12_wait_fence_job, job)
* Texture
* ========================== */
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data)
G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2i32 size, void *initial_data)
{
__prof;
if (size.x <= 0 || size.y <= 0) {
@ -2268,10 +2268,10 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
snc_counter_wait(&counter);
}
return (struct gp_resource *)r;
return (G_Resource *)r;
}
struct v2i32 gp_texture_get_size(struct gp_resource *resource)
V2i32 gp_texture_get_size(G_Resource *resource)
{
struct dx12_resource *r = (struct dx12_resource *)resource;
return r->texture_size;
@ -2418,7 +2418,7 @@ INTERNAL void command_list_set_sig(struct command_list *cl, void *src, u32 size)
}
}
INTERNAL struct D3D12_VIEWPORT viewport_from_rect(struct rect r)
INTERNAL struct D3D12_VIEWPORT viewport_from_rect(Rect r)
{
struct D3D12_VIEWPORT viewport = ZI;
viewport.TopLeftX = r.x;
@ -2430,7 +2430,7 @@ INTERNAL struct D3D12_VIEWPORT viewport_from_rect(struct rect r)
return viewport;
}
INTERNAL D3D12_RECT scissor_from_rect(struct rect r)
INTERNAL D3D12_RECT scissor_from_rect(Rect r)
{
D3D12_RECT scissor = ZI;
scissor.left = r.x;
@ -2458,7 +2458,7 @@ INTERNAL D3D12_INDEX_BUFFER_VIEW ibv_from_command_buffer(struct command_buffer *
return ibv;
}
INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size, D3D12_RESOURCE_STATES initial_state)
INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, V2i32 size, D3D12_RESOURCE_STATES initial_state)
{
__prof;
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
@ -2493,10 +2493,10 @@ INTERNAL struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, struct v2i32 size
}
/* Calculate the view projection matrix */
INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 viewport_height)
INLINE Mat4x4 calculate_vp(Xform view, f32 viewport_width, f32 viewport_height)
{
struct mat4x4 projection = mat4x4_from_ortho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0);
struct mat4x4 view4x4 = mat4x4_from_xform(view);
Mat4x4 projection = mat4x4_from_ortho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0);
Mat4x4 view4x4 = mat4x4_from_xform(view);
return mat4x4_mul(projection, view4x4);
}
@ -2512,25 +2512,25 @@ INTERNAL D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_from_descriptor(struct descripto
* ========================== */
struct render_sig {
struct arena *arena;
struct rand_state rand;
Arena *arena;
RandState rand;
u32 frame_index;
/* Material instances */
u32 num_material_instance_descs;
struct arena *material_instance_descs_arena;
Arena *material_instance_descs_arena;
/* Ui instances */
u32 num_ui_rect_instance_descs;
struct arena *ui_rect_instance_descs_arena;
Arena *ui_rect_instance_descs_arena;
/* UI shapes */
struct arena *ui_shape_verts_arena;
struct arena *ui_shape_indices_arena;
Arena *ui_shape_verts_arena;
Arena *ui_shape_indices_arena;
/* Grids */
u32 num_material_grid_descs;
struct arena *material_grid_descs_arena;
Arena *material_grid_descs_arena;
/* Resources */
struct dx12_resource *albedo;
@ -2543,26 +2543,26 @@ struct render_sig {
};
struct material_instance_desc {
struct xform xf;
Xform xf;
u32 texture_id;
struct clip_rect clip;
ClipRect clip;
u32 tint;
b32 is_light;
struct v3 light_emittance;
V3 light_emittance;
u32 grid_id;
};
struct ui_rect_instance_desc {
struct xform xf;
Xform xf;
u32 texture_id;
struct clip_rect clip;
ClipRect clip;
u32 tint;
};
struct material_grid_desc {
f32 line_thickness;
f32 line_spacing;
struct v2 offset;
V2 offset;
u32 bg0_color;
u32 bg1_color;
u32 line_color;
@ -2575,7 +2575,7 @@ INTERNAL struct render_sig *render_sig_alloc(void)
__prof;
struct render_sig *sig = 0;
{
struct arena *arena = arena_alloc(MEBI(64));
Arena *arena = arena_alloc(MEBI(64));
sig = arena_push(arena, struct render_sig);
sig->arena = arena;
}
@ -2610,14 +2610,14 @@ INTERNAL void render_sig_reset(struct render_sig *sig)
arena_reset(sig->material_grid_descs_arena);
}
struct gp_render_sig *gp_render_sig_alloc(void)
G_RenderSig *gp_render_sig_alloc(void)
{
__prof;
struct render_sig *sig = render_sig_alloc();
return (struct gp_render_sig *)sig;
return (G_RenderSig *)sig;
}
u32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_desc *cmd_desc)
u32 gp_push_render_cmd(G_RenderSig *render_sig, G_RenderCmdDesc *cmd_desc)
{
u32 ret = 0;
struct render_sig *sig = (struct render_sig *)render_sig;
@ -2657,8 +2657,8 @@ u32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_de
u32 *indices = arena_push_array_no_zero(sig->ui_shape_indices_arena, u32, cmd_desc->ui_shape.indices.count);
for (u32 i = 0; i < cmd_desc->ui_shape.vertices.count; ++i) {
struct k_shape_vert *v = &verts[i];
v->pos = k_float2_from_v2(cmd_desc->ui_shape.vertices.points[i]);
v->color_srgb = k_uint_from_u32(color);
v->pos = K_Float2FromV2(cmd_desc->ui_shape.vertices.points[i]);
v->color_srgb = K_UintFromU32(color);
}
u32 vert_offset = verts - (struct k_shape_vert *)arena_base(sig->ui_shape_verts_arena);
for (u32 i = 0; i < cmd_desc->ui_shape.indices.count; ++i) {
@ -2688,20 +2688,20 @@ u32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_de
* Render
* ========================== */
struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp_render_params params)
G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams params)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct render_sig *rsig = (struct render_sig *)gp_render_sig;
++rsig->frame_index;
struct v2i32 ui_size = V2I32(max_i32(params.ui_size.x, 1), max_i32(params.ui_size.y, 1));
struct v2i32 render_size = V2I32(max_i32(params.render_size.x, 1), max_i32(params.render_size.y, 1));
struct xform world_to_render_xf = params.world_to_render_xf;
struct xform render_to_ui_xf = params.render_to_ui_xf;
V2i32 ui_size = V2i32FromXY(max_i32(params.ui_size.x, 1), max_i32(params.ui_size.y, 1));
V2i32 render_size = V2i32FromXY(max_i32(params.render_size.x, 1), max_i32(params.render_size.y, 1));
Xform world_to_render_xf = params.world_to_render_xf;
Xform render_to_ui_xf = params.render_to_ui_xf;
struct rect ui_viewport = RECT_FROM_V2(V2(0, 0), V2(ui_size.x, ui_size.y));
struct rect render_viewport = RECT_FROM_V2(V2(0, 0), V2(render_size.x, render_size.y));
Rect ui_viewport = RECT_FROM_V2(V2FromXY(0, 0), V2FromXY(ui_size.x, ui_size.y));
Rect render_viewport = RECT_FROM_V2(V2FromXY(0, 0), V2FromXY(render_size.x, render_size.y));
/* Allocate render buffers */
@ -2746,13 +2746,13 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
{
__profn("Run render");
__profnc_dx12(cl->cq->prof, cl->cl, "Run render", RGB32_F(0.5, 0.2, 0.2));
struct mat4x4 world_to_render_vp_matrix = calculate_vp(world_to_render_xf, render_viewport.width, render_viewport.height);
struct mat4x4 ui_vp_matrix = calculate_vp(XFORM_IDENT, ui_viewport.width, ui_viewport.height);
struct mat4x4 blit_vp_matrix = ZI;
Mat4x4 world_to_render_vp_matrix = calculate_vp(world_to_render_xf, render_viewport.width, render_viewport.height);
Mat4x4 ui_vp_matrix = calculate_vp(XFORM_IDENT, ui_viewport.width, ui_viewport.height);
Mat4x4 blit_vp_matrix = ZI;
{
struct xform xf = render_to_ui_xf;
xf = xform_scaled(xf, V2(render_size.x, render_size.y));
xf = xform_translated(xf, V2(0.5, 0.5));
Xform xf = render_to_ui_xf;
xf = xform_scaled(xf, V2FromXY(render_size.x, render_size.y));
xf = xform_translated(xf, V2FromXY(0.5, 0.5));
blit_vp_matrix = calculate_vp(xf, ui_viewport.width, ui_viewport.height);
}
@ -2776,14 +2776,14 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
for (u32 i = 0; i < rsig->num_material_instance_descs; ++i) {
struct material_instance_desc *desc = &((struct material_instance_desc *)arena_base(rsig->material_instance_descs_arena))[i];
struct k_material_instance *instance = &material_instances[i];
instance->tex_nurid = k_uint_from_u32(desc->texture_id);
instance->grid_id = k_uint_from_u32(desc->grid_id);
instance->xf = k_float2x3_from_xform(desc->xf);
instance->uv0 = k_float2_from_v2(desc->clip.p0);
instance->uv1 = k_float2_from_v2(desc->clip.p1);
instance->tint_srgb = k_uint_from_u32(desc->tint);
instance->is_light = k_uint_from_u32(desc->is_light);
instance->light_emittance_srgb = k_float3_from_v3(desc->light_emittance);
instance->tex_nurid = K_UintFromU32(desc->texture_id);
instance->grid_id = K_UintFromU32(desc->grid_id);
instance->xf = K_Float2x3FromXform(desc->xf);
instance->uv0 = K_Float2FromV2(desc->clip.p0);
instance->uv1 = K_Float2FromV2(desc->clip.p1);
instance->tint_srgb = K_UintFromU32(desc->tint);
instance->is_light = K_UintFromU32(desc->is_light);
instance->light_emittance_srgb = K_Float3FromV3(desc->light_emittance);
}
}
@ -2793,11 +2793,11 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
for (u32 i = 0; i < rsig->num_ui_rect_instance_descs; ++i) {
struct ui_rect_instance_desc *desc = &((struct ui_rect_instance_desc *)arena_base(rsig->ui_rect_instance_descs_arena))[i];
struct k_ui_instance *instance = &ui_rect_instances[i];
instance->tex_nurid = k_uint_from_u32(desc->texture_id);
instance->xf = k_float2x3_from_xform(desc->xf);
instance->uv0 = k_float2_from_v2(desc->clip.p0);
instance->uv1 = k_float2_from_v2(desc->clip.p1);
instance->tint_srgb = k_uint_from_u32(desc->tint);
instance->tex_nurid = K_UintFromU32(desc->texture_id);
instance->xf = K_Float2x3FromXform(desc->xf);
instance->uv0 = K_Float2FromV2(desc->clip.p0);
instance->uv1 = K_Float2FromV2(desc->clip.p1);
instance->tint_srgb = K_UintFromU32(desc->tint);
}
}
@ -2807,14 +2807,14 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
for (u32 i = 0; i < rsig->num_material_grid_descs; ++i) {
struct material_grid_desc *desc = &((struct material_grid_desc *)arena_base(rsig->material_grid_descs_arena))[i];
struct k_material_grid *grid = &grids[i];
grid->line_thickness = k_float_from_f32(desc->line_thickness);
grid->line_spacing = k_float_from_f32(desc->line_spacing);
grid->offset = k_float2_from_v2(desc->offset);
grid->bg0_srgb = k_uint_from_u32(desc->bg0_color);
grid->bg1_srgb = k_uint_from_u32(desc->bg1_color);
grid->line_srgb = k_uint_from_u32(desc->line_color);
grid->x_srgb = k_uint_from_u32(desc->x_color);
grid->y_srgb = k_uint_from_u32(desc->y_color);
grid->line_thickness = K_FloatFromF32(desc->line_thickness);
grid->line_spacing = K_FloatFromF32(desc->line_spacing);
grid->offset = K_Float2FromV2(desc->offset);
grid->bg0_srgb = K_UintFromU32(desc->bg0_color);
grid->bg1_srgb = K_UintFromU32(desc->bg1_color);
grid->line_srgb = K_UintFromU32(desc->line_color);
grid->x_srgb = K_UintFromU32(desc->x_color);
grid->y_srgb = K_UintFromU32(desc->y_color);
}
}
}
@ -2874,9 +2874,9 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
/* Set sig */
struct k_material_sig sig = ZI;
sig.projection = k_float4x4_from_mat4x4(world_to_render_vp_matrix);
sig.instances_urid = k_uint_from_u32(material_instance_buffer->resource->srv_descriptor->index);
sig.grids_urid = k_uint_from_u32(grid_buffer->resource->srv_descriptor->index);
sig.projection = K_Float4x4FromMat4x4(world_to_render_vp_matrix);
sig.instances_urid = K_UintFromU32(material_instance_buffer->resource->srv_descriptor->index);
sig.grids_urid = K_UintFromU32(grid_buffer->resource->srv_descriptor->index);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Draw */
@ -2932,12 +2932,12 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
/* Set sig */
struct k_flood_sig sig = ZI;
sig.step_len = k_int_from_i32(step_length);
sig.emittance_tex_urid = k_uint_from_u32(rsig->emittance->srv_descriptor->index);
sig.read_flood_tex_urid = k_uint_from_u32(rsig->emittance_flood_read->uav_descriptor->index);
sig.target_flood_tex_urid = k_uint_from_u32(rsig->emittance_flood_target->uav_descriptor->index);
sig.tex_width = k_uint_from_u32(render_size.x);
sig.tex_height = k_uint_from_u32(render_size.y);
sig.step_len = K_IntFromI32(step_length);
sig.emittance_tex_urid = K_UintFromU32(rsig->emittance->srv_descriptor->index);
sig.read_flood_tex_urid = K_UintFromU32(rsig->emittance_flood_read->uav_descriptor->index);
sig.target_flood_tex_urid = K_UintFromU32(rsig->emittance_flood_target->uav_descriptor->index);
sig.tex_width = K_UintFromU32(render_size.x);
sig.tex_height = K_UintFromU32(render_size.y);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Dispatch */
@ -3000,20 +3000,20 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
/* Set sig */
struct k_shade_sig sig = ZI;
sig.flags = k_uint_from_u32(shade_flags);
sig.tex_width = k_uint_from_u32(render_size.x);
sig.tex_height = k_uint_from_u32(render_size.y);
sig.frame_seed = k_uint4_from_u32((u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF),
(u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF),
(u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF),
(u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF));
sig.frame_index = k_uint_from_u32(rsig->frame_index);
sig.camera_offset = k_float2_from_v2(world_to_render_xf.og);
sig.albedo_tex_urid = k_uint_from_u32(rsig->albedo->srv_descriptor->index);
sig.emittance_tex_urid = k_uint_from_u32(rsig->emittance->srv_descriptor->index);
sig.emittance_flood_tex_urid = k_uint_from_u32(rsig->emittance_flood_read->srv_descriptor->index);
sig.read_tex_urid = k_uint_from_u32(rsig->shade_read->uav_descriptor->index);
sig.target_tex_urid = k_uint_from_u32(rsig->shade_target->uav_descriptor->index);
sig.flags = K_UintFromU32(shade_flags);
sig.tex_width = K_UintFromU32(render_size.x);
sig.tex_height = K_UintFromU32(render_size.y);
sig.frame_seed = K_Uint4FromU32((u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF),
(u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF),
(u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF),
(u32)(rand_u64_from_state(&rsig->rand) & 0xFFFFFFFF));
sig.frame_index = K_UintFromU32(rsig->frame_index);
sig.camera_offset = K_Float2FromV2(world_to_render_xf.og);
sig.albedo_tex_urid = K_UintFromU32(rsig->albedo->srv_descriptor->index);
sig.emittance_tex_urid = K_UintFromU32(rsig->emittance->srv_descriptor->index);
sig.emittance_flood_tex_urid = K_UintFromU32(rsig->emittance_flood_read->srv_descriptor->index);
sig.read_tex_urid = K_UintFromU32(rsig->shade_read->uav_descriptor->index);
sig.target_tex_urid = K_UintFromU32(rsig->shade_target->uav_descriptor->index);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Dispatch */
@ -3062,11 +3062,11 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
/* Set sig */
struct k_blit_sig sig = ZI;
sig.projection = k_float4x4_from_mat4x4(blit_vp_matrix);
sig.flags = k_uint_from_u32(K_BLIT_FLAG_TONE_MAP | K_BLIT_FLAG_GAMMA_CORRECT);
sig.exposure = k_float_from_f32(2.0);
sig.gamma = k_float_from_f32((f32)2.2);
sig.tex_urid = k_uint_from_u32(rsig->shade_read->uav_descriptor->index);
sig.projection = K_Float4x4FromMat4x4(blit_vp_matrix);
sig.flags = K_UintFromU32(K_BLIT_FLAG_TONE_MAP | K_BLIT_FLAG_GAMMA_CORRECT);
sig.exposure = K_FloatFromF32(2.0);
sig.gamma = K_FloatFromF32((f32)2.2);
sig.tex_urid = K_UintFromU32(rsig->shade_read->uav_descriptor->index);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Draw */
@ -3094,8 +3094,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
/* Set sig */
struct k_ui_sig sig = ZI;
sig.projection = k_float4x4_from_mat4x4(ui_vp_matrix);
sig.instances_urid = k_uint_from_u32(ui_rect_instance_buffer->resource->srv_descriptor->index);
sig.projection = K_Float4x4FromMat4x4(ui_vp_matrix);
sig.instances_urid = K_UintFromU32(ui_rect_instance_buffer->resource->srv_descriptor->index);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Draw */
@ -3124,8 +3124,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
/* Set sig */
struct k_shape_sig sig = ZI;
sig.projection = k_float4x4_from_mat4x4(ui_vp_matrix);
sig.verts_urid = k_uint_from_u32(ui_shape_verts_buffer->resource->srv_descriptor->index);
sig.projection = K_Float4x4FromMat4x4(ui_vp_matrix);
sig.verts_urid = K_UintFromU32(ui_shape_verts_buffer->resource->srv_descriptor->index);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Draw */
@ -3144,16 +3144,16 @@ struct gp_resource *gp_run_render(struct gp_render_sig *gp_render_sig, struct gp
render_sig_reset(rsig);
scratch_end(scratch);
return (struct gp_resource *)rsig->ui_target;
return (G_Resource *)rsig->ui_target;
}
/* ========================== *
* Memory info
* ========================== */
struct gp_memory_info gp_query_memory_info(void)
G_MemoryInfo gp_query_memory_info(void)
{
struct gp_memory_info res = ZI;
G_MemoryInfo res = ZI;
HRESULT hr = 0;
IDXGIAdapter3 *dxgiAdapter3 = 0;
@ -3201,7 +3201,7 @@ INTERNAL void swapchain_init_resources(struct swapchain *swapchain)
}
}
struct gp_swapchain *gp_swapchain_alloc(struct sys_window *window, struct v2i32 resolution)
G_Swapchain *gp_swapchain_alloc(struct sys_window *window, V2i32 resolution)
{
HRESULT hr = 0;
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
@ -3261,16 +3261,16 @@ struct gp_swapchain *gp_swapchain_alloc(struct sys_window *window, struct v2i32
swapchain_init_resources(swapchain);
return (struct gp_swapchain *)swapchain;
return (G_Swapchain *)swapchain;
}
void gp_swapchain_release(struct gp_swapchain *gp_swapchain)
void gp_swapchain_release(G_Swapchain *gp_swapchain)
{
/* TODO */
(UNUSED)gp_swapchain;
}
void gp_swapchain_wait(struct gp_swapchain *gp_swapchain)
void gp_swapchain_wait(G_Swapchain *gp_swapchain)
{
#if DX12_WAIT_FRAME_LATENCY > 0
struct swapchain *swapchain = (struct swapchain *)gp_swapchain;
@ -3282,7 +3282,7 @@ void gp_swapchain_wait(struct gp_swapchain *gp_swapchain)
#endif
}
INTERNAL struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, struct v2i32 resolution)
INTERNAL struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, V2i32 resolution)
{
__prof;
resolution.x = max_i32(resolution.x, 1);
@ -3335,7 +3335,7 @@ INTERNAL struct swapchain_buffer *update_swapchain(struct swapchain *swapchain,
* Present
* ========================== */
INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *src, struct xform src_xf)
INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *src, Xform src_xf)
{
__prof;
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
@ -3360,15 +3360,15 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
struct rect viewport_rect = RECT_FROM_V2(V2(0, 0), V2(swapchain->resolution.x, swapchain->resolution.y));
Rect viewport_rect = RECT_FROM_V2(V2FromXY(0, 0), V2FromXY(swapchain->resolution.x, swapchain->resolution.y));
D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect);
D3D12_RECT scissor = scissor_from_rect(viewport_rect);
struct mat4x4 vp_matrix = ZI;
Mat4x4 vp_matrix = ZI;
{
struct xform xf = src_xf;
xf = xform_scaled(xf, V2(src->texture_size.x, src->texture_size.y));
xf = xform_translated(xf, V2(0.5, 0.5));
Xform xf = src_xf;
xf = xform_scaled(xf, V2FromXY(src->texture_size.x, src->texture_size.y));
xf = xform_translated(xf, V2FromXY(0.5, 0.5));
vp_matrix = calculate_vp(xf, viewport.Width, viewport.Height);
}
@ -3401,9 +3401,9 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
/* Set sig */
struct k_blit_sig sig = ZI;
sig.projection = k_float4x4_from_mat4x4(vp_matrix);
sig.flags = k_uint_from_u32(K_BLIT_FLAG_NONE);
sig.tex_urid = k_uint_from_u32(src->srv_descriptor->index);
sig.projection = K_Float4x4FromMat4x4(vp_matrix);
sig.flags = K_UintFromU32(K_BLIT_FLAG_NONE);
sig.tex_urid = K_UintFromU32(src->srv_descriptor->index);
command_list_set_sig(cl, &sig, sizeof(sig));
/* Draw */
@ -3434,7 +3434,7 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
pipeline_scope_end(pipeline_scope);
}
void gp_present(struct gp_swapchain *gp_swapchain, struct v2i32 backbuffer_resolution, struct gp_resource *texture, struct xform texture_xf, i32 vsync)
void gp_present(G_Swapchain *gp_swapchain, V2i32 backbuffer_resolution, G_Resource *texture, Xform texture_xf, i32 vsync)
{
__prof;
struct swapchain *swapchain = (struct swapchain *)gp_swapchain;
@ -3497,7 +3497,7 @@ INTERNAL SYS_JOB_DEF(dx12_evictor_job, _)
while (!shutdown) {
{
__profn("Dx12 evictor run");
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u64 targets[countof(completed_targets)] = ZI;
/* Copy queued data */

View File

@ -1,3 +0,0 @@
#include "host.h"
#include "host_core.c"

View File

@ -1,138 +0,0 @@
#define HOST_CHANNEL_ID_NIL (struct host_channel_id) { .gen = 0, .idx = 0 }
#define HOST_CHANNEL_ID_ALL (struct host_channel_id) { .gen = U32_MAX, .idx = U32_MAX }
struct buddy_ctx;
struct host_snd_packet;
struct host_channel_lookup_bin;
struct host_rcv_buffer;
enum host_cmd_kind {
HOST_CMD_KIND_NONE,
HOST_CMD_KIND_TRY_CONNECT,
HOST_CMD_KIND_CONNECT_SUCCESS,
HOST_CMD_KIND_DISCONNECT,
HOST_CMD_KIND_HEARTBEAT,
HOST_CMD_KIND_WRITE
};
enum host_event_kind {
HOST_EVENT_KIND_NONE,
HOST_EVENT_KIND_CHANNEL_OPENED,
HOST_EVENT_KIND_CHANNEL_CLOSED,
HOST_EVENT_KIND_MSG
};
enum host_write_flag {
HOST_WRITE_FLAG_NONE = 0,
HOST_WRITE_FLAG_RELIABLE = (1 << 0)
};
struct host_channel_id {
u32 gen;
u32 idx;
};
struct host_cmd {
enum host_cmd_kind kind;
struct host_channel_id channel_id;
u16 heartbeat_id;
u16 heartbeat_ack_id;
b32 write_reliable;
struct string write_msg;
struct host_cmd *next;
};
struct host_event {
enum host_event_kind kind;
struct host_channel_id channel_id;
struct string msg;
struct host_event *next;
};
struct host_event_list {
struct host_event *first;
struct host_event *last;
};
struct host {
struct arena *arena;
struct sys_sock *sock;
struct buddy_ctx *buddy; /* For storing msg assembler data */
struct arena *cmd_arena;
struct host_cmd *first_cmd;
struct host_cmd *last_cmd;
struct host_cmd *first_free_cmd;
struct arena *channel_arena;
struct host_channel *channels;
struct host_channel *first_free_channel;
u64 num_channels_reserved;
struct host_snd_packet *first_free_packet; /* Allocated in `arena` */
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
struct host_channel_lookup_bin *channel_lookup_bins; /* Allocated in `arena` */
u64 num_channel_lookup_bins;
struct host_msg_assembler_lookup_bin *msg_assembler_lookup_bins; /* Allocated in `arena` */
u64 num_msg_assembler_lookup_bins;
/* Double buffer for incoming data */
struct snc_mutex rcv_buffer_write_mutex;
struct host_rcv_buffer *rcv_buffer_read;
struct host_rcv_buffer *rcv_buffer_write;
u64 bytes_received;
u64 bytes_sent;
};
/* ========================== *
* Startup
* ========================== */
struct host_startup_receipt { i32 _; };
struct host_startup_receipt host_startup(void);
/* ========================== *
* Host
* ========================== */
struct host *host_alloc(u16 listen_port);
void host_release(struct host *host);
/* ========================== *
* Queue
* ========================== */
void host_queue_connect_to_address(struct host *host, struct sys_address connect_address);
void host_queue_disconnect(struct host *host, struct host_channel_id channel_id);
void host_queue_write(struct host *host, struct host_channel_id channel_id, struct string msg, u32 flags);
/* ========================== *
* Info
* ========================== */
i64 host_get_channel_last_rtt_ns(struct host *host, struct host_channel_id channel_id);
INLINE b32 host_channel_id_eq(struct host_channel_id a, struct host_channel_id b) { return a.idx == b.idx && a.gen == b.gen; }
INLINE b32 host_channel_id_is_nil(struct host_channel_id id) { return id.gen == 0 && id.idx == 0; }
/* ========================== *
* Update
* ========================== */
struct host_event_list host_update_begin(struct arena *arena, struct host *host);
void host_update_end(struct host *host);

View File

@ -5,7 +5,7 @@
#if RESOURCES_EMBEDDED
INCBIN_INCLUDE(res_tar, INCBIN_DIR "res.tar");
struct string inc_res_tar(void)
String inc_res_tar(void)
{
return INCBIN_GET(res_tar);
}
@ -13,7 +13,7 @@ struct string inc_res_tar(void)
INCBIN_INCLUDE(dxc_tar, INCBIN_DIR "dxc.tar");
struct string inc_dxc_tar(void)
String inc_dxc_tar(void)
{
return INCBIN_GET(dxc_tar);
}

View File

@ -1,5 +1,5 @@
#if RESOURCES_EMBEDDED
struct string inc_res_tar(void);
String inc_res_tar(void);
#endif
struct string inc_dxc_tar(void);
String inc_dxc_tar(void);

View File

@ -63,7 +63,7 @@ enum lex_number_state {
LEX_NUMBER_STATE_EXPONENT
};
GLOBAL READONLY struct string g_keyword_strings[] = {
GLOBAL READONLY String g_keyword_strings[] = {
['t'] = LIT_NOCAST("true"),
['f'] = LIT_NOCAST("false"),
['n'] = LIT_NOCAST("null")
@ -75,7 +75,7 @@ GLOBAL READONLY enum token_type g_keyword_types[] = {
['n'] = TOKEN_TYPE_KEYWORD_NULL
};
INTERNAL struct token *push_token(struct arena *arena, struct token_list *list)
INTERNAL struct token *push_token(Arena *arena, struct token_list *list)
{
struct token *t = arena_push(arena, struct token);
if (!list->token_first) {
@ -87,7 +87,7 @@ INTERNAL struct token *push_token(struct arena *arena, struct token_list *list)
return t;
}
INTERNAL struct token_list lex(struct arena *arena, struct string src)
INTERNAL struct token_list lex(Arena *arena, String src)
{
struct token_list res = ZI;
@ -286,7 +286,7 @@ INTERNAL struct token_list lex(struct arena *arena, struct string src)
case 't':
case 'f':
case 'n': {
struct string keyword = g_keyword_strings[src.text[pos]];
String keyword = g_keyword_strings[src.text[pos]];
b32 match = 1;
if ((pos + keyword.len - 1) < src.len) {
@ -304,7 +304,7 @@ INTERNAL struct token_list lex(struct arena *arena, struct string src)
}
}
if (match) {
struct string cmp_str = {
String cmp_str = {
.len = keyword.len,
.text = &src.text[pos]
};
@ -354,13 +354,13 @@ INTERNAL struct token_list lex(struct arena *arena, struct string src)
* Interpret
* ========================== */
INTERNAL void append_char(struct arena *arena, struct string *str, u8 c)
INTERNAL void append_char(Arena *arena, String *str, u8 c)
{
*arena_push_no_zero(arena, u8) = c;
++str->len;
}
INTERNAL f64 interpret_number(struct string src)
INTERNAL f64 interpret_number(String src)
{
b32 whole_present = 0;
u64 whole_left = 0;
@ -522,9 +522,9 @@ INTERNAL f64 interpret_number(struct string src)
return res;
}
INTERNAL struct string interpret_string(struct arena *arena, struct string src, struct string *error)
INTERNAL String interpret_string(Arena *arena, String src, String *error)
{
struct string res = {
String res = {
.len = 0,
.text = arena_push_dry(arena, u8)
};
@ -634,22 +634,22 @@ INTERNAL struct string interpret_string(struct arena *arena, struct string src,
struct parser {
/* Input */
struct string src;
String src;
struct token *at;
/* Output */
struct json *root;
struct json_error_list errors;
JSON_Blob *root;
JSON_ErrorList errors;
};
INTERNAL void push_error(struct arena *arena, struct parser *p, struct token *t, struct string msg)
INTERNAL void push_error(Arena *arena, struct parser *p, struct token *t, String msg)
{
struct json_error *error = arena_push(arena, struct json_error);
JSON_Error *error = arena_push(arena, JSON_Error);
error->msg = msg;
error->start = t->start;
error->end = t->end;
struct json_error_list *list = &p->errors;
JSON_ErrorList *list = &p->errors;
if (!list->first) {
list->first = error;
} else {
@ -659,28 +659,28 @@ INTERNAL void push_error(struct arena *arena, struct parser *p, struct token *t,
++list->count;
}
INTERNAL void parse(struct arena *arena, struct parser *p)
INTERNAL void parse(Arena *arena, struct parser *p)
{
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
struct json *root = arena_push(arena, struct json);
JSON_Blob *root = arena_push(arena, JSON_Blob);
struct token *at = p->at;
struct string src = p->src;
String src = p->src;
if (at->type == TOKEN_TYPE_BOF) {
at = at->next;
}
/* Depth first stack */
*arena_push_no_zero(scratch.arena, struct json *) = root;
*arena_push_no_zero(scratch.arena, JSON_Blob *) = root;
u64 stack_count = 1;
while (stack_count > 0) {
struct json *json = 0;
arena_pop(scratch.arena, struct json *, &json);
JSON_Blob *json = 0;
arena_pop(scratch.arena, JSON_Blob *, &json);
--stack_count;
struct json *parent_json = json->parent;
JSON_Blob *parent_json = json->parent;
b32 is_new_parent = 0;
if (json->type == JSON_TYPE_OBJECT || json->type == JSON_TYPE_ARRAY) {
/* No more children to parse for object/array, check for closing brace. */
@ -697,9 +697,9 @@ INTERNAL void parse(struct arena *arena, struct parser *p)
if (parent_json->type == JSON_TYPE_OBJECT) {
/* Parse key */
if (at->type == TOKEN_TYPE_STRING) {
struct string t_text = (struct string) { .len = at->end - at->start, .text = &src.text[at->start] };
struct string error = ZI;
struct string key = interpret_string(arena, t_text, &error);
String t_text = (String) { .len = at->end - at->start, .text = &src.text[at->start] };
String error = ZI;
String key = interpret_string(arena, t_text, &error);
if (error.len > 0) {
push_error(arena, p, at, error);
goto abort;
@ -732,7 +732,7 @@ INTERNAL void parse(struct arena *arena, struct parser *p)
/* Parse value */
switch (at->type) {
case TOKEN_TYPE_NUMBER: {
struct string t_text = (struct string) { .len = at->end - at->start, .text = &src.text[at->start] };
String t_text = (String) { .len = at->end - at->start, .text = &src.text[at->start] };
f64 value = interpret_number(t_text);
json->type = JSON_TYPE_NUMBER;
json->value.number = value;
@ -740,9 +740,9 @@ INTERNAL void parse(struct arena *arena, struct parser *p)
} break;
case TOKEN_TYPE_STRING: {
struct string t_text = (struct string) { .len = at->end - at->start, .text = &src.text[at->start] };
struct string error = ZI;
struct string value = interpret_string(arena, t_text, &error);
String t_text = (String) { .len = at->end - at->start, .text = &src.text[at->start] };
String error = ZI;
String value = interpret_string(arena, t_text, &error);
if (error.len > 0) {
push_error(arena, p, at, error);
goto abort;
@ -792,21 +792,21 @@ INTERNAL void parse(struct arena *arena, struct parser *p)
if (is_new_parent) {
/* Push self back to stack to re-check for closing brace later */
*arena_push_no_zero(scratch.arena, struct json *) = json;
*arena_push_no_zero(scratch.arena, JSON_Blob *) = json;
++stack_count;
/* Create child & push to stack */
struct json *child = arena_push(arena, struct json);
JSON_Blob *child = arena_push(arena, JSON_Blob);
child->parent = json;
*arena_push_no_zero(scratch.arena, struct json *) = child;
*arena_push_no_zero(scratch.arena, JSON_Blob *) = child;
++stack_count;
} else if (parent_json) {
/* Check for comma */
if (at->type == TOKEN_TYPE_COMMA) {
/* Create sibling & push to stack */
struct json *sibling = arena_push(arena, struct json);
JSON_Blob *sibling = arena_push(arena, JSON_Blob);
sibling->parent = parent_json;
*arena_push_no_zero(scratch.arena, struct json *) = sibling;
*arena_push_no_zero(scratch.arena, JSON_Blob *) = sibling;
++stack_count;
at = at->next;
}
@ -825,9 +825,9 @@ INTERNAL void parse(struct arena *arena, struct parser *p)
* Interface
* ========================== */
struct json_parse_result json_from_string(struct arena *arena, struct string src)
JSON_Result json_from_string(Arena *arena, String src)
{
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
struct token_list tl = lex(scratch.arena, src);
@ -845,7 +845,7 @@ struct json_parse_result json_from_string(struct arena *arena, struct string src
scratch_end(scratch);
return (struct json_parse_result) {
return (JSON_Result) {
.root = p.root,
.errors = p.errors
};

View File

@ -1,44 +1,49 @@
enum json_type {
typedef enum JSON_Type {
JSON_TYPE_NULL,
JSON_TYPE_BOOL,
JSON_TYPE_NUMBER,
JSON_TYPE_STRING,
JSON_TYPE_ARRAY,
JSON_TYPE_OBJECT
};
} JSON_Type;
struct json {
enum json_type type;
struct string key;
typedef struct JSON_Blob JSON_Blob;
struct JSON_Blob {
JSON_Type type;
String key;
struct json *parent;
struct json *next;
struct json *child_first;
struct json *child_last;
JSON_Blob *parent;
JSON_Blob *next;
JSON_Blob *child_first;
JSON_Blob *child_last;
union {
struct string string;
String string;
f64 number;
b32 boolean;
} value;
};
struct json_error {
struct string msg;
typedef struct JSON_Error JSON_Error;
struct JSON_Error {
String msg;
u64 start;
u64 end;
struct json_error *next;
JSON_Error *next;
};
struct json_error_list {
typedef struct JSON_ErrorList JSON_ErrorList;
struct JSON_ErrorList {
u64 count;
struct json_error *first;
struct json_error *last;
JSON_Error *first;
JSON_Error *last;
};
struct json_parse_result {
struct json *root;
struct json_error_list errors;
typedef struct JSON_Result JSON_Result;
struct JSON_Result {
JSON_Blob *root;
JSON_ErrorList errors;
};
struct json_parse_result json_from_string(struct arena *arena, struct string src);
JSON_Result json_from_string(Arena *arena, String src);

View File

@ -8,71 +8,80 @@
#if K_IS_CPU
#define K_STRUCT(s) PACK(struct s)
#define K_DECL(t, n) struct CAT(k_, t) n
#define K_DECL(t, n) struct CAT(K_, t) n
#define K_DECLS(t, n) K_DECL(t, n)
#define K_STATIC_ASSERT(c) STATIC_ASSERT(c)
struct k_uint { u32 v; };
INLINE struct k_uint k_uint_from_u32(u32 v)
typedef struct K_uint K_uint;
struct K_uint { u32 v; };
INLINE struct K_uint K_UintFromU32(u32 v)
{
return (struct k_uint) { .v = v };
return (struct K_uint) { .v = v };
}
struct k_int { i32 v; };
INLINE struct k_int k_int_from_i32(i32 v)
typedef struct K_int K_int;
struct K_int { i32 v; };
INLINE struct K_int K_IntFromI32(i32 v)
{
return (struct k_int) { .v = v };
return (struct K_int) { .v = v };
}
struct k_uint2 { u32 v[2]; };
INLINE struct k_uint2 k_uint2_from_u32(u32 x, u32 y)
typedef struct K_uint2 K_uint2;
struct K_uint2 { u32 v[2]; };
INLINE struct K_uint2 K_Uint2FromU32(u32 x, u32 y)
{
return (struct k_uint2) { .v[0] = x, .v[1] = y };
return (struct K_uint2) { .v[0] = x, .v[1] = y };
}
struct k_uint3 { u32 v[3]; };
INLINE struct k_uint3 k_uint3_from_u32(u32 x, u32 y, u32 z)
typedef struct K_uint3 K_uint3;
struct K_uint3 { u32 v[3]; };
INLINE struct K_uint3 K_Uint3FromU32(u32 x, u32 y, u32 z)
{
return (struct k_uint3) { .v[0] = x, .v[1] = y, .v[2] = z };
return (struct K_uint3) { .v[0] = x, .v[1] = y, .v[2] = z };
}
struct k_uint4 { u32 v[4]; };
INLINE struct k_uint4 k_uint4_from_u32(u32 x, u32 y, u32 z, u32 w)
typedef struct K_uint4 K_uint4;
struct K_uint4 { u32 v[4]; };
INLINE struct K_uint4 K_Uint4FromU32(u32 x, u32 y, u32 z, u32 w)
{
return (struct k_uint4) { .v[0] = x, .v[1] = y, .v[2] = z, .v[3] = w };
return (struct K_uint4) { .v[0] = x, .v[1] = y, .v[2] = z, .v[3] = w };
}
struct k_float { f32 v; };
INLINE struct k_float k_float_from_f32(f32 v)
typedef struct K_float K_float;
struct K_float { f32 v; };
INLINE struct K_float K_FloatFromF32(f32 v)
{
return (struct k_float) { .v = v };
return (struct K_float) { .v = v };
}
struct k_float2 { f32 v[2]; };
INLINE struct k_float2 k_float2_from_v2(struct v2 v)
typedef struct K_float2 K_float2;
struct K_float2 { f32 v[2]; };
INLINE struct K_float2 K_Float2FromV2(V2 v)
{
return (struct k_float2) { .v[0] = v.x, .v[1] = v.y };
return (struct K_float2) { .v[0] = v.x, .v[1] = v.y };
}
struct k_float3 { f32 v[3]; };
INLINE struct k_float3 k_float3_from_v3(struct v3 v)
typedef struct K_float3 K_float3;
struct K_float3 { f32 v[3]; };
INLINE struct K_float3 K_Float3FromV3(V3 v)
{
return (struct k_float3) { .v[0] = v.x, .v[1] = v.y, .v[2] = v.z };
return (struct K_float3) { .v[0] = v.x, .v[1] = v.y, .v[2] = v.z };
}
struct k_float4x4 { f32 v[4][4]; };
INLINE struct k_float4x4 k_float4x4_from_mat4x4(struct mat4x4 v)
typedef struct K_float4x4 K_float4x4;
struct K_float4x4 { f32 v[4][4]; };
INLINE struct K_float4x4 K_Float4x4FromMat4x4(Mat4x4 v)
{
struct k_float4x4 res;
struct K_float4x4 res;
STATIC_ASSERT(sizeof(res) == sizeof(v));
MEMCPY(&res, v.e, sizeof(res));
return res;
}
struct k_float2x3 { f32 v[2][3]; };
INLINE struct k_float2x3 k_float2x3_from_xform(struct xform v)
struct K_float2x3 { f32 v[2][3]; };
INLINE struct K_float2x3 K_Float2x3FromXform(Xform v)
{
struct k_float2x3 res;
struct K_float2x3 res;
STATIC_ASSERT(sizeof(res) == sizeof(v));
MEMCPY(&res, &v, sizeof(res));
return res;

View File

@ -21,10 +21,10 @@ struct effect_data {
};
struct mix {
struct mixer_track_handle track_handle;
M_Handle track_handle;
b32 track_finished;
struct mixer_desc desc;
M_TrackDesc desc;
struct effect_data effect_data;
struct sound *source;
u64 source_pos;
@ -35,7 +35,7 @@ struct track {
/* Controlled via interface */
struct sound *sound;
struct mixer_desc desc;
M_TrackDesc desc;
/* Internal */
struct mix mix;
@ -48,11 +48,11 @@ GLOBAL struct {
struct snc_mutex mutex;
/* Listener */
struct v2 listener_pos;
struct v2 listener_dir;
V2 listener_pos;
V2 listener_dir;
/* Track list */
struct arena *track_arena;
Arena *track_arena;
struct track *track_first_playing;
struct track *track_last_playing;
u64 track_playing_count;
@ -63,28 +63,28 @@ GLOBAL struct {
* Startup
* ========================== */
struct mixer_startup_receipt mixer_startup(void)
M_StartupReceipt mixer_startup(void)
{
__prof;
G.track_arena = arena_alloc(GIBI(64));
G.listener_pos = V2(0, 0);
G.listener_dir = V2(0, -1);
return (struct mixer_startup_receipt) { 0 };
G.listener_pos = V2FromXY(0, 0);
G.listener_dir = V2FromXY(0, -1);
return (M_StartupReceipt) { 0 };
}
/* ========================== *
* Track
* ========================== */
INTERNAL struct mixer_track_handle track_to_handle(struct track *track)
INTERNAL M_Handle track_to_handle(struct track *track)
{
return (struct mixer_track_handle) {
return (M_Handle) {
.gen = track->gen,
.data = track
};
}
INTERNAL struct track *track_from_handle(struct mixer_track_handle handle)
INTERNAL struct track *track_from_handle(M_Handle handle)
{
struct track *track = (struct track *)handle.data;
if (track && track->gen == handle.gen) {
@ -172,12 +172,12 @@ INTERNAL void track_release_locked(struct snc_lock *lock, struct track *track)
/* TODO: Rework interface to take "mixer_cmd"s instead of
* directly modifying tracks. */
struct mixer_track_handle mixer_play(struct sound *sound)
M_Handle mixer_play(struct sound *sound)
{
return mixer_play_ex(sound, MIXER_DESC());
}
struct mixer_track_handle mixer_play_ex(struct sound *sound, struct mixer_desc desc)
M_Handle mixer_play_ex(struct sound *sound, M_TrackDesc desc)
{
struct track *track;
{
@ -192,9 +192,9 @@ struct mixer_track_handle mixer_play_ex(struct sound *sound, struct mixer_desc d
}
/* NOTE: This is quite inefficient. */
struct mixer_desc mixer_track_get(struct mixer_track_handle handle)
M_TrackDesc mixer_track_get(M_Handle handle)
{
struct mixer_desc res = ZI;
M_TrackDesc res = ZI;
struct track *track = track_from_handle(handle);
if (track) {
@ -214,7 +214,7 @@ struct mixer_desc mixer_track_get(struct mixer_track_handle handle)
}
/* NOTE: This is quite inefficient. */
void mixer_track_set(struct mixer_track_handle handle, struct mixer_desc desc)
void mixer_track_set(M_Handle handle, M_TrackDesc desc)
{
struct track *track = track_from_handle(handle);
if (track) {
@ -231,7 +231,7 @@ void mixer_track_set(struct mixer_track_handle handle, struct mixer_desc desc)
}
}
void mixer_set_listener(struct v2 pos, struct v2 dir)
void mixer_set_listener(V2 pos, V2 dir)
{
struct snc_lock lock = snc_lock_e(&G.mutex);
{
@ -257,18 +257,18 @@ INTERNAL i16 sample_sound(struct sound *sound, u64 sample_pos, b32 wrap)
}
/* To be called once per audio playback interval */
struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
M_PcmF32 mixer_update(Arena *arena, u64 frame_count)
{
__prof;
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
struct mixed_pcm_f32 res = ZI;
M_PcmF32 res = ZI;
res.count = frame_count * 2;
res.samples = arena_push_array(arena, f32, res.count);
struct v2 listener_pos = V2(0, 0);
struct v2 listener_dir = V2(0, 0);
V2 listener_pos = V2FromXY(0, 0);
V2 listener_dir = V2FromXY(0, 0);
/* Create temp array of mixes */
struct mix **mixes = 0;
@ -302,7 +302,7 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
}
struct sound *source = mix->source;
struct mixer_desc desc = mix->desc;
M_TrackDesc desc = mix->desc;
struct effect_data *effect_data = &mix->effect_data;
b32 source_is_stereo = source->flags & SOUND_FLAG_STEREO;
f32 speed = max_f32(0, desc.speed);
@ -335,7 +335,7 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
mix->source_pos = source_sample_pos_end;
struct mixed_pcm_f32 mix_pcm = {
M_PcmF32 mix_pcm = {
.count = res.count,
.samples = arena_push_array(scratch.arena, f32, res.count)
};
@ -407,14 +407,14 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
const f32 rolloff_scale = 6.0f;
const f32 pan_scale = 0.75;
struct v2 pos = desc.pos;
V2 pos = desc.pos;
/* If sound pos = listener pos, pretend sound is close in front of listener. */
if (v2_eq(listener_pos, pos)) {
pos = v2_add(listener_pos, v2_mul(listener_dir, 0.001f));
}
struct v2 sound_rel = v2_sub(pos, listener_pos);
struct v2 sound_rel_dir = v2_norm(sound_rel);
V2 sound_rel = v2_sub(pos, listener_pos);
V2 sound_rel_dir = v2_norm(sound_rel);
/* Calculate volume */
f32 volume_start = effect_data->spatial_volume;

View File

@ -3,47 +3,52 @@ struct sound;
#define MIXER_FLAG_NONE 0x0
#define MIXER_FLAG_SPATIALIZE 0x1
#define MIXER_DESC(...) ((struct mixer_desc) { \
#define MIXER_DESC(...) ((M_TrackDesc) { \
.flags = 0, \
\
.volume = 1.0, \
.speed = 1.0, \
.looping = 0, \
\
.pos = V2(0, 0), \
.pos = V2FromXY(0, 0), \
\
__VA_ARGS__ \
})
struct mixer_desc {
typedef struct M_TrackDesc M_TrackDesc;
struct M_TrackDesc {
u32 flags;
f32 volume; /* 0 -> 1.0+ */
f32 speed; /* 0 -> 1.0+ */
b32 looping;
/* MIXER_FLAG_SPATIALIZE */
struct v2 pos;
V2 pos;
};
struct mixer_track_handle {
typedef struct M_Handle M_Handle;
struct M_Handle {
u64 gen;
void *data;
};
/* Stereo mix of 32 bit float samples */
struct mixed_pcm_f32 {
typedef struct M_PcmF32 M_PcmF32;
struct M_PcmF32 {
u64 count;
f32 *samples;
};
struct mixer_startup_receipt { i32 _; };
struct mixer_startup_receipt mixer_startup(void);
typedef struct M_StartupReceipt M_StartupReceipt;
struct M_StartupReceipt { i32 _; };
M_StartupReceipt mixer_startup(void);
/* Interface */
struct mixer_track_handle mixer_play(struct sound *sound);
struct mixer_track_handle mixer_play_ex(struct sound *sound, struct mixer_desc desc);
struct mixer_desc mixer_track_get(struct mixer_track_handle handle);
void mixer_track_set(struct mixer_track_handle handle, struct mixer_desc desc);
void mixer_set_listener(struct v2 pos, struct v2 dir);
M_Handle mixer_play(struct sound *sound);
M_Handle mixer_play_ex(struct sound *sound, M_TrackDesc desc);
M_TrackDesc mixer_track_get(M_Handle handle);
void mixer_track_set(M_Handle handle, M_TrackDesc desc);
void mixer_set_listener(V2 pos, V2 dir);
/* Mixing */
struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_request_count);
M_PcmF32 mixer_update(Arena *arena, u64 frame_request_count);

View File

@ -1,9 +1,10 @@
#define MP3_DECODE_FLAG_NONE 0x00
#define MP3_DECODE_FLAG_STEREO 0x01
struct mp3_decode_result {
struct pcm pcm;
typedef struct MP3_Result MP3_Result;
struct MP3_Result {
PcmData pcm;
b32 success;
};
struct mp3_decode_result mp3_decode(struct arena *arena, struct string encoded, u32 sample_rate, u32 flags);
MP3_Result mp3_decode(Arena *arena, String encoded, u32 sample_rate, u32 flags);

View File

@ -18,9 +18,9 @@
#pragma comment(lib, "mfreadwrite")
#pragma comment(lib, "shlwapi")
struct mp3_decode_result mp3_decode(struct arena *arena, struct string encoded, u32 sample_rate, u32 flags)
MP3_Result mp3_decode(Arena *arena, String encoded, u32 sample_rate, u32 flags)
{
struct mp3_decode_result res = ZI;
MP3_Result res = ZI;
u64 bytes_per_sample = 2;
u64 channel_count;

3
src/net/net.c Normal file
View File

@ -0,0 +1,3 @@
#include "net.h"
#include "net_core.c"

View File

@ -1,9 +1,9 @@
#ifndef HOST_H
#define HOST_H
#ifndef NET_H
#define NET_H
#include "../base/base.h"
#include "../sys/sys.h"
#include "host_core.h"
#include "net_core.h"
#endif

View File

@ -12,13 +12,6 @@
* Challenges to verify receiving address.
*/
#define PACKET_MAGIC 0xd9e3b8b6
#define PACKET_MSG_CHUNK_MAX_LEN 1024
#define PACKET_DATA_MAX_LEN 1280 /* Give enough space for msg chunk + header */
#define NUM_CHANNEL_LOOKUP_BINS 512
#define NUM_MSG_ASSEMBLER_LOOKUP_BINS 16384
enum host_packet_kind {
HOST_PACKET_KIND_NONE,
HOST_PACKET_KIND_TRY_CONNECT,
@ -33,19 +26,11 @@ enum host_packet_flag {
HOST_PACKET_FLAG_RELIABLE = (1 << 0)
};
struct host_snd_packet {
struct host_snd_packet *next;
u64 seq;
u64 data_len;
u8 data[PACKET_DATA_MAX_LEN];
};
struct host_channel {
struct host_channel_id id;
N_ChannelId id;
b32 valid;
b32 connected;
struct host *host;
N_Host *host;
struct host_channel *next_free;
@ -55,10 +40,10 @@ struct host_channel {
struct host_channel *prev_address_hash;
/* NOTE: Packets are allocated in host's `arena` */
struct host_snd_packet *first_reliable_packet;
struct host_snd_packet *last_reliable_packet;
struct host_snd_packet *first_unreliable_packet;
struct host_snd_packet *last_unreliable_packet;
N_SndPacket *first_reliable_packet;
N_SndPacket *last_reliable_packet;
N_SndPacket *first_unreliable_packet;
N_SndPacket *last_unreliable_packet;
u64 num_reliable_packets;
u64 num_unreliable_packets;
@ -89,24 +74,13 @@ struct host_channel_list {
struct host_channel_node *last;
};
struct host_channel_lookup_bin {
struct host_channel *first;
struct host_channel *last;
};
struct host_rcv_packet {
struct sock *sock;
struct sys_address address;
struct string data;
String data;
struct host_rcv_packet *next;
};
struct host_rcv_buffer {
struct arena *arena;
struct host_rcv_packet *first_packet;
struct host_rcv_packet *last_packet;
};
struct host_msg_assembler {
struct host_channel *channel;
b32 is_reliable;
@ -131,7 +105,7 @@ struct host_msg_assembler {
i64 touched_ns;
struct buddy_block *buddy_block;
BuddyBlock *buddy_block;
u8 *chunk_bitmap;
u8 *chunk_data;
};
@ -153,36 +127,36 @@ INTERNAL void host_msg_assembler_release(struct host_msg_assembler *ma);
* Startup
* ========================== */
struct host_startup_receipt host_startup(void)
N_StartupReceipt host_startup(void)
{
__prof;
return (struct host_startup_receipt) { 0 };
return (N_StartupReceipt) { 0 };
}
/* ========================== *
* Host
* ========================== */
struct host *host_alloc(u16 listen_port)
N_Host *host_alloc(u16 listen_port)
{
struct arena *arena = arena_alloc(GIBI(64));
struct host *host = arena_push(arena, struct host);
Arena *arena = arena_alloc(GIBI(64));
N_Host *host = arena_push(arena, N_Host);
host->arena = arena;
host->cmd_arena = arena_alloc(GIBI(64));
host->channel_arena = arena_alloc(GIBI(64));
host->rcv_buffer_read = arena_push(host->arena, struct host_rcv_buffer);
host->rcv_buffer_write = arena_push(host->arena, struct host_rcv_buffer);
host->rcv_buffer_read = arena_push(host->arena, N_RcvBuffer);
host->rcv_buffer_write = arena_push(host->arena, N_RcvBuffer);
host->rcv_buffer_read->arena = arena_alloc(GIBI(64));
host->rcv_buffer_write->arena = arena_alloc(GIBI(64));
host->buddy = buddy_ctx_alloc(GIBI(64));
host->channels = arena_push_dry(host->channel_arena, struct host_channel);
host->num_channel_lookup_bins = NUM_CHANNEL_LOOKUP_BINS;
host->channel_lookup_bins = arena_push_array(host->arena, struct host_channel_lookup_bin, host->num_channel_lookup_bins);
host->num_channel_lookup_bins = N_NumChannelLookupBins;
host->channel_lookup_bins = arena_push_array(host->arena, N_ChannelLookupBin, host->num_channel_lookup_bins);
host->num_msg_assembler_lookup_bins = NUM_MSG_ASSEMBLER_LOOKUP_BINS;
host->num_msg_assembler_lookup_bins = N_NumMsgAssemblerLookupBins;
host->msg_assembler_lookup_bins = arena_push_array(host->arena, struct host_msg_assembler_lookup_bin, host->num_msg_assembler_lookup_bins);
host->sock = sys_sock_alloc(listen_port, MEBI(2), MEBI(2));
@ -190,7 +164,7 @@ struct host *host_alloc(u16 listen_port)
return host;
}
void host_release(struct host *host)
void host_release(N_Host *host)
{
sys_sock_release(host->sock);
@ -211,10 +185,10 @@ INTERNAL u64 hash_from_address(struct sys_address address)
return hash_fnv64(HASH_FNV64_BASIS, STRING_FROM_STRUCT(&address));
}
INTERNAL struct host_channel *host_channel_from_address(struct host *host, struct sys_address address)
INTERNAL struct host_channel *host_channel_from_address(N_Host *host, struct sys_address address)
{
u64 hash = hash_from_address(address);
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[hash % host->num_channel_lookup_bins];
N_ChannelLookupBin *bin = &host->channel_lookup_bins[hash % host->num_channel_lookup_bins];
for (struct host_channel *channel = bin->first; channel; channel = channel->next_address_hash) {
if (channel->address_hash == hash && sys_address_eq(channel->address, address)) {
return channel;
@ -224,7 +198,7 @@ INTERNAL struct host_channel *host_channel_from_address(struct host *host, struc
}
/* Returns nil channel if id = HOST_CHANNEL_ID_ALL */
INTERNAL struct host_channel *host_single_channel_from_id(struct host *host, struct host_channel_id channel_id)
INTERNAL struct host_channel *host_single_channel_from_id(N_Host *host, N_ChannelId channel_id)
{
if (channel_id.gen > 0 && channel_id.idx < host->num_channels_reserved) {
struct host_channel *channel = &host->channels[channel_id.idx];
@ -235,7 +209,7 @@ INTERNAL struct host_channel *host_single_channel_from_id(struct host *host, str
return &_g_host_channel_nil;
}
INTERNAL struct host_channel_list host_channels_from_id(struct arena *arena, struct host *host, struct host_channel_id channel_id)
INTERNAL struct host_channel_list host_channels_from_id(Arena *arena, N_Host *host, N_ChannelId channel_id)
{
struct host_channel_list res = ZI;
if (host_channel_id_eq(channel_id, HOST_CHANNEL_ID_ALL)) {
@ -264,9 +238,9 @@ INTERNAL struct host_channel_list host_channels_from_id(struct arena *arena, str
return res;
}
INTERNAL struct host_channel *host_channel_alloc(struct host *host, struct sys_address address)
INTERNAL struct host_channel *host_channel_alloc(N_Host *host, struct sys_address address)
{
struct host_channel_id id = ZI;
N_ChannelId id = ZI;
struct host_channel *channel;
if (host->first_free_channel) {
channel = host->first_free_channel;
@ -288,7 +262,7 @@ INTERNAL struct host_channel *host_channel_alloc(struct host *host, struct sys_a
channel->address_hash = address_hash;
u64 bin_index = address_hash % host->num_channel_lookup_bins;
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[bin_index];
N_ChannelLookupBin *bin = &host->channel_lookup_bins[bin_index];
if (bin->last) {
channel->prev_address_hash = bin->last;
bin->last->next_address_hash = channel;
@ -302,11 +276,11 @@ INTERNAL struct host_channel *host_channel_alloc(struct host *host, struct sys_a
INTERNAL void host_channel_release(struct host_channel *channel)
{
struct host *host = channel->host;
N_Host *host = channel->host;
/* Release from lookup table */
{
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[channel->address_hash % host->num_channel_lookup_bins];
N_ChannelLookupBin *bin = &host->channel_lookup_bins[channel->address_hash % host->num_channel_lookup_bins];
struct host_channel *prev = channel->prev_address_hash;
struct host_channel *next = channel->next_address_hash;
if (prev) {
@ -348,7 +322,7 @@ INTERNAL void host_channel_release(struct host_channel *channel)
* Msg assembler
* ========================== */
INTERNAL u64 hash_from_channel_msg(struct host_channel_id channel_id, u64 msg_id)
INTERNAL u64 hash_from_channel_msg(N_ChannelId channel_id, u64 msg_id)
{
u64 res = HASH_FNV64_BASIS;
res = hash_fnv64(res, STRING_FROM_STRUCT(&channel_id));
@ -356,7 +330,7 @@ INTERNAL u64 hash_from_channel_msg(struct host_channel_id channel_id, u64 msg_id
return res;
}
INTERNAL struct host_msg_assembler *host_get_msg_assembler(struct host *host, struct host_channel_id channel_id, u64 msg_id)
INTERNAL struct host_msg_assembler *host_get_msg_assembler(N_Host *host, N_ChannelId channel_id, u64 msg_id)
{
u64 hash = hash_from_channel_msg(channel_id, msg_id);
struct host_msg_assembler_lookup_bin *bin = &host->msg_assembler_lookup_bins[hash % host->num_msg_assembler_lookup_bins];
@ -370,7 +344,7 @@ INTERNAL struct host_msg_assembler *host_get_msg_assembler(struct host *host, st
INTERNAL struct host_msg_assembler *host_msg_assembler_alloc(struct host_channel *channel, u64 msg_id, u64 chunk_count, u64 now_ns, b32 is_reliable)
{
struct host *host = channel->host;
N_Host *host = channel->host;
struct host_msg_assembler *ma;
if (host->first_free_msg_assembler) {
ma = host->first_free_msg_assembler;
@ -389,7 +363,7 @@ INTERNAL struct host_msg_assembler *host_msg_assembler_alloc(struct host_channel
/* Align chunk bitmap to 16 so msg data is aligned */
chunk_bitmap_size += 16 - (chunk_bitmap_size % 16);
}
u64 chunk_data_size = chunk_count * PACKET_MSG_CHUNK_MAX_LEN;
u64 chunk_data_size = chunk_count * N_MaxPacketChunkLen;
/* Allocate msg data using buddy allocator since the assembler has
* arbitrary lifetime and data needs to stay contiguous for random
@ -430,7 +404,7 @@ INTERNAL struct host_msg_assembler *host_msg_assembler_alloc(struct host_channel
INTERNAL void host_msg_assembler_release(struct host_msg_assembler *ma)
{
struct host_channel *channel = ma->channel;
struct host *host = channel->host;
N_Host *host = channel->host;
buddy_release(ma->buddy_block);
/* Release from channel list */
@ -523,15 +497,15 @@ INTERNAL void host_msg_assembler_set_chunk_received(struct host_msg_assembler *m
* Packet
* ========================== */
INTERNAL struct host_snd_packet *host_channel_snd_packet_alloc(struct host_channel *channel, b32 is_reliable)
INTERNAL N_SndPacket *host_channel_snd_packet_alloc(struct host_channel *channel, b32 is_reliable)
{
struct host *host = channel->host;
struct host_snd_packet *packet = 0;
N_Host *host = channel->host;
N_SndPacket *packet = 0;
if (host->first_free_packet) {
packet = host->first_free_packet;
host->first_free_packet = packet->next;
} else {
packet = arena_push_no_zero(host->arena, struct host_snd_packet);
packet = arena_push_no_zero(host->arena, N_SndPacket);
}
MEMZERO_STRUCT(packet);
@ -560,9 +534,9 @@ INTERNAL struct host_snd_packet *host_channel_snd_packet_alloc(struct host_chann
* Cmd interface
* ========================== */
INTERNAL struct host_cmd *host_cmd_alloc_and_append(struct host *host)
INTERNAL N_Cmd *host_cmd_alloc_and_append(N_Host *host)
{
struct host_cmd *cmd = arena_push(host->cmd_arena, struct host_cmd);
N_Cmd *cmd = arena_push(host->cmd_arena, N_Cmd);
if (host->last_cmd) {
host->last_cmd->next = cmd;
} else {
@ -572,7 +546,7 @@ INTERNAL struct host_cmd *host_cmd_alloc_and_append(struct host *host)
return cmd;
}
void host_queue_connect_to_address(struct host *host, struct sys_address connect_address)
void host_queue_connect_to_address(N_Host *host, struct sys_address connect_address)
{
struct host_channel *channel = host_channel_from_address(host, connect_address);
if (!channel->valid) {
@ -580,16 +554,16 @@ void host_queue_connect_to_address(struct host *host, struct sys_address connect
}
}
void host_queue_disconnect(struct host *host, struct host_channel_id channel_id)
void host_queue_disconnect(N_Host *host, N_ChannelId channel_id)
{
struct host_cmd *cmd = host_cmd_alloc_and_append(host);
N_Cmd *cmd = host_cmd_alloc_and_append(host);
cmd->kind = HOST_CMD_KIND_DISCONNECT;
cmd->channel_id = channel_id;
}
void host_queue_write(struct host *host, struct host_channel_id channel_id, struct string msg, u32 flags)
void host_queue_write(N_Host *host, N_ChannelId channel_id, String msg, u32 flags)
{
struct host_cmd *cmd = host_cmd_alloc_and_append(host);
N_Cmd *cmd = host_cmd_alloc_and_append(host);
cmd->kind = HOST_CMD_KIND_WRITE;
cmd->channel_id = channel_id;
cmd->write_msg = string_copy(host->cmd_arena, msg);
@ -600,7 +574,7 @@ void host_queue_write(struct host *host, struct host_channel_id channel_id, stru
* Info
* ========================== */
i64 host_get_channel_last_rtt_ns(struct host *host, struct host_channel_id channel_id)
i64 host_get_channel_last_rtt_ns(N_Host *host, N_ChannelId channel_id)
{
struct host_channel *channel = host_single_channel_from_id(host, channel_id);
return channel->last_heartbeat_rtt_ns;
@ -610,9 +584,9 @@ i64 host_get_channel_last_rtt_ns(struct host *host, struct host_channel_id chann
* Update
* ========================== */
INTERNAL struct host_event *push_event(struct arena *arena, struct host_event_list *list)
INTERNAL N_Event *push_event(Arena *arena, N_EventList *list)
{
struct host_event *event = arena_push(arena, struct host_event);
N_Event *event = arena_push(arena, N_Event);
if (list->last) {
list->last->next = event;
} else {
@ -623,11 +597,11 @@ INTERNAL struct host_event *push_event(struct arena *arena, struct host_event_li
}
/* Read incoming packets, update channels, and return events */
struct host_event_list host_update_begin(struct arena *arena, struct host *host)
N_EventList host_update_begin(Arena *arena, N_Host *host)
{
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
struct host_event_list events = ZI;
N_EventList events = ZI;
i64 now_ns = sys_time_ns();
{
__profn("Read packets");
@ -641,7 +615,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
struct sys_sock_read_result res = ZI;
while ((res = sys_sock_read(scratch.arena, sock)).valid) {
struct sys_address address = res.address;
struct string data = res.data;
String data = res.data;
if (data.len > 0) {
struct host_rcv_packet *packet = arena_push(scratch.arena, struct host_rcv_packet);
packet->address = address;
@ -662,10 +636,10 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
for (struct host_rcv_packet *packet = first_packet; packet; packet = packet->next) {
//struct sock *sock = packet->sock;
struct sys_address address = packet->address;
struct bitbuff bb = bitbuff_from_string(packet->data);
struct bitbuff_reader br = br_from_bitbuff(&bb);
Bitbuff bb = bitbuff_from_string(packet->data);
BitbuffReader br = br_from_bitbuff(&bb);
u32 magic = br_read_ubits(&br, 32); /* TODO: implicitly encode magic into crc32 */
if (magic == PACKET_MAGIC) {
if (magic == N_PacketMagic) {
/* TODO: Combine kind byte with flags byte */
struct host_channel *channel = host_channel_from_address(host, address);
enum host_packet_kind host_packet_kind = br_read_ibits(&br, 8);
@ -702,7 +676,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
/* 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);
}
struct host_cmd *cmd = host_cmd_alloc_and_append(host);
N_Cmd *cmd = host_cmd_alloc_and_append(host);
cmd->kind = HOST_CMD_KIND_CONNECT_SUCCESS;
cmd->channel_id = channel->id;
} break;
@ -712,7 +686,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
/* We successfully connected to a foreign host and they are ready to receive messages */
if (channel->valid && !channel->connected) {
logf_info("Host received connection from %F", FMT_STR(sys_string_from_address(scratch.arena, address)));
struct host_event *event = push_event(arena, &events);
N_Event *event = push_event(arena, &events);
event->kind = HOST_EVENT_KIND_CHANNEL_OPENED;
event->channel_id = channel->id;
channel->connected = 1;
@ -724,7 +698,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
/* A foreign host disconnected from us */
if (channel->valid) {
logf_info("Host received disconnection from %F", FMT_STR(sys_string_from_address(scratch.arena, address)));
struct host_event *event = push_event(arena, &events);
N_Event *event = push_event(arena, &events);
event->kind = HOST_EVENT_KIND_CHANNEL_CLOSED;
event->channel_id = channel->id;
host_channel_release(channel);
@ -758,7 +732,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
u64 chunk_id = br_read_uv(&br);
u64 chunk_count = br_read_uv(&br);
b32 is_last_chunk = (chunk_id + 1) == chunk_count;
u64 chunk_len = is_last_chunk ? br_read_uv(&br) : PACKET_MSG_CHUNK_MAX_LEN;
u64 chunk_len = is_last_chunk ? br_read_uv(&br) : N_MaxPacketChunkLen;
struct host_msg_assembler *ma = host_get_msg_assembler(host, channel->id, msg_id);
if (!ma) {
@ -769,7 +743,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
if (!host_msg_assembler_is_chunk_filled(ma, chunk_id)) {
u8 *src = br_read_bytes_raw(&br, chunk_len);
if (src) {
u8 *dst = &ma->chunk_data[chunk_id * PACKET_MSG_CHUNK_MAX_LEN];
u8 *dst = &ma->chunk_data[chunk_id * N_MaxPacketChunkLen];
MEMCPY(dst, src, chunk_len);
if (is_last_chunk) {
ma->last_chunk_len = chunk_len;
@ -780,9 +754,9 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
if (ma->num_chunks_received == chunk_count) {
/* All chunks filled, message has finished assembling */
/* TODO: Message ordering */
struct host_event *event = push_event(arena, &events);
struct string data = ZI;
data.len = ((chunk_count - 1) * PACKET_MSG_CHUNK_MAX_LEN) + ma->last_chunk_len;
N_Event *event = push_event(arena, &events);
String data = ZI;
data.len = ((chunk_count - 1) * N_MaxPacketChunkLen) + ma->last_chunk_len;
data.text = arena_push_array_no_zero(arena, u8, data.len);
MEMCPY(data.text, ma->chunk_data, data.len);
event->kind = HOST_EVENT_KIND_MSG;
@ -822,14 +796,14 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
if (channel->valid) {
/* Send / resend handshake if not connected */
if (!channel->connected) {
struct host_cmd *cmd = host_cmd_alloc_and_append(host);
N_Cmd *cmd = host_cmd_alloc_and_append(host);
cmd->kind = HOST_CMD_KIND_TRY_CONNECT;
cmd->channel_id = channel->id;
}
/* Send heartbeat */
/* TODO: Send this less frequently (once per second or half of timeout or something) */
{
struct host_cmd *cmd = host_cmd_alloc_and_append(host);
N_Cmd *cmd = host_cmd_alloc_and_append(host);
cmd->kind = HOST_CMD_KIND_HEARTBEAT;
cmd->heartbeat_id = channel->last_heartbeat_acked_id + 1;
cmd->heartbeat_ack_id = channel->last_heartbeat_received_id;
@ -838,9 +812,9 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
/* Release acked reliable packets */
{
u64 acked_seq = channel->their_acked_seq;
struct host_snd_packet *packet = channel->first_reliable_packet;
N_SndPacket *packet = channel->first_reliable_packet;
while (packet) {
struct host_snd_packet *next = packet->next;
N_SndPacket *next = packet->next;
u64 seq = packet->seq;
if (seq < acked_seq) {
packet->next = host->first_free_packet;
@ -882,18 +856,18 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
}
/* Process host cmds & send outgoing packets */
void host_update_end(struct host *host)
void host_update_end(N_Host *host)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
/* Process cmds into sendable packets */
/* TODO: Unreliable packets don't need to be allocated into unreliable packet queue, should just send them and forget */
{
__profn("Process host cmds");
for (struct host_cmd *cmd = host->first_cmd; cmd; cmd = cmd->next) {
enum host_cmd_kind kind = cmd->kind;
struct host_channel_id channel_id = cmd->channel_id;
for (N_Cmd *cmd = host->first_cmd; cmd; cmd = cmd->next) {
N_CmdKind kind = cmd->kind;
N_ChannelId channel_id = cmd->channel_id;
struct host_channel_list channels = host_channels_from_id(scratch.arena, host, channel_id);
for (struct host_channel_node *node = channels.first; node; node = node->next) {
struct host_channel *channel = node->channel;
@ -901,10 +875,10 @@ void host_update_end(struct host *host)
case HOST_CMD_KIND_TRY_CONNECT:
{
u8 packet_flags = 0;
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, 0);
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
Bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
BitbuffWriter bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
bw_write_ibits(&bw, HOST_PACKET_KIND_TRY_CONNECT, 8);
bw_write_ubits(&bw, packet_flags, 8);
bw_write_uv(&bw, channel->our_acked_seq);
@ -914,10 +888,10 @@ void host_update_end(struct host *host)
case HOST_CMD_KIND_CONNECT_SUCCESS:
{
u8 packet_flags = 0;
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, 0);
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
Bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
BitbuffWriter bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
bw_write_ibits(&bw, HOST_PACKET_KIND_CONNECT_SUCCESS, 8);
bw_write_ubits(&bw, packet_flags, 8);
bw_write_uv(&bw, channel->our_acked_seq);
@ -927,10 +901,10 @@ void host_update_end(struct host *host)
case HOST_CMD_KIND_DISCONNECT:
{
u8 packet_flags = 0;
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, 0);
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
Bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
BitbuffWriter bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
bw_write_ibits(&bw, HOST_PACKET_KIND_DISCONNECT, 8);
bw_write_ubits(&bw, packet_flags, 8);
bw_write_uv(&bw, channel->our_acked_seq);
@ -940,10 +914,10 @@ void host_update_end(struct host *host)
case HOST_CMD_KIND_HEARTBEAT:
{
u8 packet_flags = 0;
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, 0);
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, 0);
Bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
BitbuffWriter bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
bw_write_ibits(&bw, HOST_PACKET_KIND_HEARTBEAT, 8);
bw_write_ubits(&bw, packet_flags, 8);
bw_write_uv(&bw, channel->our_acked_seq);
@ -956,28 +930,28 @@ void host_update_end(struct host *host)
{
b32 is_reliable = cmd->write_reliable;
u8 packet_flags = (is_reliable * HOST_PACKET_FLAG_RELIABLE);
struct string msg = cmd->write_msg;
String msg = cmd->write_msg;
u64 chunk_count = 0;
if (msg.len > 0) {
chunk_count = (msg.len - 1) / PACKET_MSG_CHUNK_MAX_LEN;
chunk_count = (msg.len - 1) / N_MaxPacketChunkLen;
}
chunk_count += 1;
u64 msg_id = ++channel->last_sent_msg_id;
for (u64 i = 0; i < chunk_count; ++i) {
u64 chunk_len = PACKET_MSG_CHUNK_MAX_LEN;
u64 chunk_len = N_MaxPacketChunkLen;
b32 is_last_chunk = i + 1 == chunk_count;
if (is_last_chunk) {
chunk_len = msg.len % PACKET_MSG_CHUNK_MAX_LEN;
chunk_len = msg.len % N_MaxPacketChunkLen;
if (chunk_len == 0) {
chunk_len = PACKET_MSG_CHUNK_MAX_LEN;
chunk_len = N_MaxPacketChunkLen;
}
}
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, is_reliable);
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
N_SndPacket *packet = host_channel_snd_packet_alloc(channel, is_reliable);
Bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
BitbuffWriter bw = bw_from_bitbuff(&bb);
bw_write_ubits(&bw, N_PacketMagic, 32); /* TODO: implicitly encode magic into crc32 */
bw_write_ibits(&bw, HOST_PACKET_KIND_MSG_CHUNK, 8);
bw_write_ubits(&bw, packet_flags, 8);
bw_write_uv(&bw, channel->our_acked_seq);
@ -990,7 +964,7 @@ void host_update_end(struct host *host)
if (is_last_chunk) {
bw_write_uv(&bw, chunk_len);
}
u8 *chunk_data = msg.text + (i * PACKET_MSG_CHUNK_MAX_LEN);
u8 *chunk_data = msg.text + (i * N_MaxPacketChunkLen);
bw_write_bytes(&bw, STRING(chunk_len, chunk_data));
packet->data_len = bw_num_bytes_written(&bw);
}
@ -1013,12 +987,12 @@ void host_update_end(struct host *host)
if (channel->valid) {
struct sys_address address = channel->address;
/* Send reliable packets to channel */
for (struct host_snd_packet *packet = channel->first_reliable_packet; packet; packet = packet->next) {
for (N_SndPacket *packet = channel->first_reliable_packet; packet; packet = packet->next) {
sys_sock_write(sock, address, STRING(packet->data_len, packet->data));
total_sent += packet->data_len;
}
/* Send unreliable packets to channel */
for (struct host_snd_packet *packet = channel->first_unreliable_packet; packet; packet = packet->next) {
for (N_SndPacket *packet = channel->first_unreliable_packet; packet; packet = packet->next) {
sys_sock_write(sock, address, STRING(packet->data_len, packet->data));
total_sent += packet->data_len;
}

168
src/net/net_core.h Normal file
View File

@ -0,0 +1,168 @@
#define HOST_CHANNEL_ID_NIL (N_ChannelId) { .gen = 0, .idx = 0 }
#define HOST_CHANNEL_ID_ALL (N_ChannelId) { .gen = U32_MAX, .idx = U32_MAX }
#define N_PacketMagic 0xd9e3b8b6
#define N_MaxPacketChunkLen 1024
#define N_MaxPacketLen 1280 /* Give enough space for msg chunk + header */
#define N_NumChannelLookupBins 512
#define N_NumMsgAssemblerLookupBins 16384
typedef enum N_CmdKind {
HOST_CMD_KIND_NONE,
HOST_CMD_KIND_TRY_CONNECT,
HOST_CMD_KIND_CONNECT_SUCCESS,
HOST_CMD_KIND_DISCONNECT,
HOST_CMD_KIND_HEARTBEAT,
HOST_CMD_KIND_WRITE
} N_CmdKind;
typedef enum N_EventKind {
HOST_EVENT_KIND_NONE,
HOST_EVENT_KIND_CHANNEL_OPENED,
HOST_EVENT_KIND_CHANNEL_CLOSED,
HOST_EVENT_KIND_MSG
} N_EventKind;
typedef enum N_WriteFlag {
HOST_WRITE_FLAG_NONE = 0,
HOST_WRITE_FLAG_RELIABLE = (1 << 0)
} N_WriteFlag;
typedef struct N_ChannelId N_ChannelId;
struct N_ChannelId {
u32 gen;
u32 idx;
};
typedef struct N_Cmd N_Cmd;
struct N_Cmd {
N_CmdKind kind;
N_ChannelId channel_id;
u16 heartbeat_id;
u16 heartbeat_ack_id;
b32 write_reliable;
String write_msg;
N_Cmd *next;
};
typedef struct N_Event N_Event;
struct N_Event {
N_EventKind kind;
N_ChannelId channel_id;
String msg;
N_Event *next;
};
typedef struct N_EventList N_EventList;
struct N_EventList {
N_Event *first;
N_Event *last;
};
typedef struct N_ChannelLookupBin N_ChannelLookupBin;
struct N_ChannelLookupBin {
struct host_channel *first;
struct host_channel *last;
};
typedef struct N_RcvBuffer N_RcvBuffer;
struct N_RcvBuffer {
Arena *arena;
struct host_rcv_packet *first_packet;
struct host_rcv_packet *last_packet;
};
typedef struct N_SndPacket N_SndPacket;
struct N_SndPacket {
N_SndPacket *next;
u64 seq;
u64 data_len;
u8 data[N_MaxPacketLen];
};
typedef struct N_Host N_Host;
struct N_Host {
Arena *arena;
struct sys_sock *sock;
BuddyCtx *buddy; /* For storing msg assembler data */
Arena *cmd_arena;
N_Cmd *first_cmd;
N_Cmd *last_cmd;
N_Cmd *first_free_cmd;
Arena *channel_arena;
struct host_channel *channels;
struct host_channel *first_free_channel;
u64 num_channels_reserved;
N_SndPacket *first_free_packet; /* Allocated in `arena` */
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
N_ChannelLookupBin *channel_lookup_bins; /* Allocated in `arena` */
u64 num_channel_lookup_bins;
struct host_msg_assembler_lookup_bin *msg_assembler_lookup_bins; /* Allocated in `arena` */
u64 num_msg_assembler_lookup_bins;
/* Double buffer for incoming data */
struct snc_mutex rcv_buffer_write_mutex;
N_RcvBuffer *rcv_buffer_read;
N_RcvBuffer *rcv_buffer_write;
u64 bytes_received;
u64 bytes_sent;
};
/* ========================== *
* Startup
* ========================== */
typedef struct N_StartupReceipt N_StartupReceipt;
struct N_StartupReceipt { i32 _; };
N_StartupReceipt host_startup(void);
/* ========================== *
* Host
* ========================== */
N_Host *host_alloc(u16 listen_port);
void host_release(N_Host *host);
/* ========================== *
* Queue
* ========================== */
void host_queue_connect_to_address(N_Host *host, struct sys_address connect_address);
void host_queue_disconnect(N_Host *host, N_ChannelId channel_id);
void host_queue_write(N_Host *host, N_ChannelId channel_id, String msg, u32 flags);
/* ========================== *
* Info
* ========================== */
i64 host_get_channel_last_rtt_ns(N_Host *host, N_ChannelId channel_id);
INLINE b32 host_channel_id_eq(N_ChannelId a, N_ChannelId b) { return a.idx == b.idx && a.gen == b.gen; }
INLINE b32 host_channel_id_is_nil(N_ChannelId id) { return id.gen == 0 && id.idx == 0; }
/* ========================== *
* Update
* ========================== */
N_EventList host_update_begin(Arena *arena, N_Host *host);
void host_update_end(N_Host *host);

View File

@ -1,4 +1,3 @@
struct mixer_startup_receipt;
struct playback_startup_receipt { i32 _; };
struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *mixer_sr);
typedef struct PB_StartupReceipt PB_StartupReceipt;
struct PB_StartupReceipt { i32 _; };
PB_StartupReceipt playback_startup(M_StartupReceipt *mixer_sr);

View File

@ -33,7 +33,7 @@ struct wasapi_buffer {
};
GLOBAL struct {
struct atomic32 shutdown;
Atomic32 shutdown;
IAudioClient *client;
HANDLE event;
IAudioRenderClient *playback;
@ -50,7 +50,7 @@ INTERNAL void wasapi_initialize(void);
INTERNAL SYS_EXIT_FUNC(playback_shutdown);
INTERNAL SYS_JOB_DEF(playback_job, _);
struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *mixer_sr)
PB_StartupReceipt playback_startup(M_StartupReceipt *mixer_sr)
{
__prof;
(UNUSED)mixer_sr;
@ -59,7 +59,7 @@ struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *m
sys_run(1, playback_job, 0, SYS_POOL_AUDIO, SYS_PRIORITY_HIGH, &G.playback_job_counter);
sys_on_exit(&playback_shutdown);
return (struct playback_startup_receipt) { 0 };
return (PB_StartupReceipt) { 0 };
}
INTERNAL SYS_EXIT_FUNC(playback_shutdown)
@ -185,7 +185,7 @@ INTERNAL struct wasapi_buffer wasapi_update_begin(void)
return wspbuf;
}
INTERNAL void wasapi_update_end(struct wasapi_buffer *wspbuf, struct mixed_pcm_f32 src)
INTERNAL void wasapi_update_end(struct wasapi_buffer *wspbuf, M_PcmF32 src)
{
__prof;
u32 frames_in_source = src.count / 2;
@ -228,7 +228,7 @@ INTERNAL SYS_JOB_DEF(playback_job, _)
* need to halt mixer to prevent memory leak when sounds are played. */
/* TODO: Signal counter that running job wiats on, rather than scheduling job manually */
while (!atomic32_fetch(&G.shutdown)) {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
{
__profn("Wasapi wait");
WaitForSingleObject(G.event, INFINITE);
@ -236,7 +236,7 @@ INTERNAL SYS_JOB_DEF(playback_job, _)
{
__profn("Fill sample buffer");
struct wasapi_buffer wspbuf = wasapi_update_begin();
struct mixed_pcm_f32 pcm = mixer_update(scratch.arena, wspbuf.frames_count);
M_PcmF32 pcm = mixer_update(scratch.arena, wspbuf.frames_count);
wasapi_update_end(&wspbuf, pcm);
}
scratch_end(scratch);

View File

@ -5,7 +5,7 @@
/* Add resource data to binary */
GLOBAL struct {
struct arena *arena;
Arena *arena;
#if RESOURCES_EMBEDDED
struct tar_archive archive;
@ -16,13 +16,13 @@ GLOBAL struct {
* Startup
* ========================== */
struct resource_startup_receipt resource_startup(void)
R_StartupReceipt resource_startup(void)
{
__prof;
G.arena = arena_alloc(GIBI(64));
#if RESOURCES_EMBEDDED
struct string embedded_data = inc_res_tar();
String embedded_data = inc_res_tar();
if (embedded_data.len <= 0) {
sys_panic(LIT("No embedded resources found"));
}
@ -34,28 +34,28 @@ struct resource_startup_receipt resource_startup(void)
}
#endif
return (struct resource_startup_receipt) { 0 };
return (R_StartupReceipt) { 0 };
}
/* ========================== *
* Open / close
* ========================== */
struct resource resource_open(struct string name)
R_Resource resource_open(String name)
{
__prof;
#if RESOURCES_EMBEDDED
struct resource res = ZI;
R_Resource res = ZI;
struct tar_entry *entry = tar_get(&G.archive, name);
res._data = entry->data;
res._name = entry->file_name;
res._exists = entry->valid;
return res;
#else
struct resource res = ZI;
R_Resource res = ZI;
if (name.len < countof(res._name_text)) {
u8 path_text[RESOURCE_NAME_LEN_MAX + (sizeof("res/") - 1)];
struct string path = ZI;
String path = ZI;
{
path_text[0] = 'r';
path_text[1] = 'e';
@ -69,7 +69,7 @@ struct resource resource_open(struct string name)
struct sys_file file = sys_file_open_read_wait(path);
struct sys_file_map file_map = ZI;
struct string data = ZI;
String data = ZI;
if (file.valid) {
file_map = sys_file_map_open_read(file);
if (file_map.valid) {
@ -95,7 +95,7 @@ struct resource resource_open(struct string name)
}
#if !RESOURCES_EMBEDDED
void resource_close(struct resource *res_ptr)
void resource_close(R_Resource *res_ptr)
{
sys_file_map_close(res_ptr->_file_map);
sys_file_close(res_ptr->_file);

View File

@ -3,11 +3,12 @@
/* A resource contains data that can be retrieved globally by name.
* If enabled during compilation, resource data is embedded in the
* executable. Otherwise each resource represents a file on disk. */
struct resource {
struct string _data;
typedef struct R_Resource R_Resource;
struct R_Resource {
String _data;
b32 _exists;
#if RESOURCES_EMBEDDED
struct string _name;
String _name;
#else
struct sys_file _file;
struct sys_file_map _file_map;
@ -20,19 +21,20 @@ struct resource {
* Startup
* ========================== */
struct resource_startup_receipt { i32 _; };
struct resource_startup_receipt resource_startup(void);
typedef struct R_StartupReceipt R_StartupReceipt;
struct R_StartupReceipt { i32 _; };
R_StartupReceipt resource_startup(void);
/* ========================== *
* Open / close
* ========================== */
struct resource resource_open(struct string name);
R_Resource resource_open(String name);
#if RESOURCES_EMBEDDED
#define resource_close(res_ptr) (UNUSED)res_ptr
#else
void resource_close(struct resource *res_ptr);
void resource_close(R_Resource *res_ptr);
#endif
/* ========================== *

View File

@ -1,16 +1,16 @@
struct string settings_serialize(struct arena *arena, const struct sys_window_settings *settings)
String settings_serialize(Arena *arena, const struct sys_window_settings *settings)
{
__prof;
struct string minimized = settings->flags & SYS_WINDOW_SETTINGS_FLAG_MINIMIZED ? LIT("true") : LIT("false");
struct string maximized = settings->flags & SYS_WINDOW_SETTINGS_FLAG_MAXIMIZED ? LIT("true") : LIT("false");
struct string fullscreen = settings->flags & SYS_WINDOW_SETTINGS_FLAG_FULLSCREEN ? LIT("true") : LIT("false");
String minimized = settings->flags & SYS_WINDOW_SETTINGS_FLAG_MINIMIZED ? LIT("true") : LIT("false");
String maximized = settings->flags & SYS_WINDOW_SETTINGS_FLAG_MAXIMIZED ? LIT("true") : LIT("false");
String fullscreen = settings->flags & SYS_WINDOW_SETTINGS_FLAG_FULLSCREEN ? LIT("true") : LIT("false");
i32 x = settings->floating_x;
i32 y = settings->floating_y;
i32 width = settings->floating_width;
i32 height = settings->floating_height;
struct string fmt = LIT(
String fmt = LIT(
"{\n"
" \"window\": {\n"
" \"minimized\": %F,\n"
@ -24,7 +24,7 @@ struct string settings_serialize(struct arena *arena, const struct sys_window_se
"}\n"
);
struct string formatted = string_format(arena,
String formatted = string_format(arena,
fmt,
FMT_STR(minimized),
FMT_STR(maximized),
@ -37,29 +37,29 @@ struct string settings_serialize(struct arena *arena, const struct sys_window_se
return formatted;
}
struct sys_window_settings *settings_deserialize(struct arena *arena, struct string src, struct string *error_out)
struct sys_window_settings *settings_deserialize(Arena *arena, String src, String *error_out)
{
__prof;
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
struct string error = ZI;
struct json_error json_error = ZI;
String error = ZI;
JSON_Error json_error = ZI;
struct sys_window_settings *settings = arena_push(arena, struct sys_window_settings);
struct json_parse_result parse_res = json_from_string(scratch.arena, src);
JSON_Result parse_res = json_from_string(scratch.arena, src);
if (parse_res.errors.count > 0) {
json_error = *parse_res.errors.first;
goto abort;
}
struct json *root = parse_res.root;
JSON_Blob *root = parse_res.root;
if (!root) {
error = LIT("Root object not found.");
goto abort;
}
struct json *window = root->child_first;
JSON_Blob *window = root->child_first;
if (!window || window->type != JSON_TYPE_OBJECT || !string_eq(window->key, LIT("window"))) {
error = LIT("\"window\" object not found");
goto abort;
@ -71,8 +71,8 @@ struct sys_window_settings *settings_deserialize(struct arena *arena, struct str
b32 found_y = 0;
b32 found_width = 0;
b32 found_height = 0;
for (struct json *child = window->child_first; child; child = child->next) {
struct string key = child->key;
for (JSON_Blob *child = window->child_first; child; child = child->next) {
String key = child->key;
if (string_eq(key, LIT("maximized"))) {
if (child->type != JSON_TYPE_BOOL) {

View File

@ -1,5 +1,3 @@
struct sys_window_settings;
String settings_serialize(Arena *arena, const struct sys_window_settings *settings);
struct string settings_serialize(struct arena *arena, const struct sys_window_settings *settings);
struct sys_window_settings *settings_deserialize(struct arena *arena, struct string src, struct string *error_out);
struct sys_window_settings *settings_deserialize(Arena *arena, String src, String *error_out);

View File

@ -4,7 +4,7 @@
#include "../base/base.h"
#include "../sprite/sprite.h"
#include "../collider/collider.h"
#include "../host/host.h"
#include "../net/net.h"
#include "../mixer/mixer.h"
#include "sim_core.h"

View File

@ -33,7 +33,7 @@
* ========================== */
GLOBAL struct {
struct arena *nil_arena;
Arena *nil_arena;
struct sim_client_store *nil_client_store;
struct sim_client *nil_client;
struct sim_snapshot *nil_snapshot;
@ -99,7 +99,7 @@ struct sim_client_store *sim_client_store_alloc(void)
__prof;
struct sim_client_store *store;
{
struct arena *arena = arena_alloc(GIBI(64));
Arena *arena = arena_alloc(GIBI(64));
store = arena_push(arena, struct sim_client_store);
store->arena = arena;
}
@ -187,15 +187,15 @@ void sim_client_release(struct sim_client *client)
* Client lookup
* ========================== */
INTERNAL u64 hash_from_channel_id(struct host_channel_id channel_id)
INTERNAL u64 hash_from_channel_id(N_ChannelId channel_id)
{
return hash_fnv64(HASH_FNV64_BASIS, STRING_FROM_STRUCT(&channel_id));
}
void sim_client_set_channel_id(struct sim_client *client, struct host_channel_id channel_id)
void sim_client_set_channel_id(struct sim_client *client, N_ChannelId channel_id)
{
struct sim_client_store *store = client->store;
struct host_channel_id old_channel_id = client->channel_id;
N_ChannelId old_channel_id = client->channel_id;
/* Remove old channel id from channel lookup */
if (!host_channel_id_is_nil(old_channel_id)) {
@ -236,7 +236,7 @@ void sim_client_set_channel_id(struct sim_client *client, struct host_channel_id
}
}
struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id)
struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, N_ChannelId channel_id)
{
struct sim_client *res = sim_client_nil();
u64 channel_hash = hash_from_channel_id(channel_id);
@ -275,8 +275,8 @@ struct sim_snapshot *sim_snapshot_alloc(struct sim_client *client, struct sim_sn
struct sim_snapshot *ss;
{
struct arena *arena = ZI;
struct arena *ents_arena = 0;
Arena *arena = ZI;
Arena *ents_arena = 0;
{
ss = client->first_free_snapshot;
if (ss) {
@ -540,26 +540,26 @@ struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *clien
* Tile
* ========================== */
struct v2i32 sim_world_tile_index_from_pos(struct v2 pos)
V2i32 sim_world_tile_index_from_pos(V2 pos)
{
struct v2i32 res = V2I32(pos.x * SIM_TILES_PER_UNIT_SQRT, pos.y * SIM_TILES_PER_UNIT_SQRT);
V2i32 res = V2i32FromXY(pos.x * SIM_TILES_PER_UNIT_SQRT, pos.y * SIM_TILES_PER_UNIT_SQRT);
res.x -= pos.x < 0;
res.y -= pos.y < 0;
return res;
}
struct v2 sim_pos_from_world_tile_index(struct v2i32 world_tile_index)
V2 sim_pos_from_world_tile_index(V2i32 world_tile_index)
{
struct v2 res = ZI;
V2 res = ZI;
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
res.x = (f32)world_tile_index.x * tile_size;
res.y = (f32)world_tile_index.y * tile_size;
return res;
}
struct v2i32 sim_local_tile_index_from_world_tile_index(struct v2i32 world_tile_index)
V2i32 sim_local_tile_index_from_world_tile_index(V2i32 world_tile_index)
{
struct v2i32 res = world_tile_index;
V2i32 res = world_tile_index;
res.x += res.x < 0;
res.y += res.y < 0;
res.x = res.x % SIM_TILES_PER_CHUNK_SQRT;
@ -569,17 +569,17 @@ struct v2i32 sim_local_tile_index_from_world_tile_index(struct v2i32 world_tile_
return res;
}
struct v2i32 sim_world_tile_index_from_local_tile_index(struct v2i32 tile_chunk_index, struct v2i32 local_tile_index)
V2i32 sim_world_tile_index_from_local_tile_index(V2i32 tile_chunk_index, V2i32 local_tile_index)
{
struct v2i32 res = ZI;
V2i32 res = ZI;
res.x = (tile_chunk_index.x * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.x;
res.y = (tile_chunk_index.y * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.y;
return res;
}
struct v2i32 sim_tile_chunk_index_from_world_tile_index(struct v2i32 world_tile_index)
V2i32 sim_tile_chunk_index_from_world_tile_index(V2i32 world_tile_index)
{
struct v2i32 res = world_tile_index;
V2i32 res = world_tile_index;
res.x += res.x < 0;
res.y += res.y < 0;
res.x = res.x / SIM_TILES_PER_CHUNK_SQRT;
@ -589,9 +589,9 @@ struct v2i32 sim_tile_chunk_index_from_world_tile_index(struct v2i32 world_tile_
return res;
}
void sim_snapshot_set_tile(struct sim_snapshot *ss, struct v2i32 world_tile_index, enum sim_tile_kind tile_kind)
void sim_snapshot_set_tile(struct sim_snapshot *ss, V2i32 world_tile_index, enum sim_tile_kind tile_kind)
{
struct v2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
V2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
struct sim_ent_id chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
struct sim_ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
@ -602,7 +602,7 @@ void sim_snapshot_set_tile(struct sim_snapshot *ss, struct v2i32 world_tile_inde
chunk_ent->tile_chunk_index = chunk_index;
}
struct v2i32 local_index = sim_local_tile_index_from_world_tile_index(world_tile_index);
V2i32 local_index = sim_local_tile_index_from_world_tile_index(world_tile_index);
chunk_ent->tile_chunk_tiles[local_index.x + (local_index.y * SIM_TILES_PER_CHUNK_SQRT)] = tile_kind;
}
@ -720,7 +720,7 @@ void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *
* Snapshot encode
* ========================== */
void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1)
void sim_snapshot_encode(BitbuffWriter *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1)
{
__prof;
@ -789,7 +789,7 @@ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver,
* Snapshot decode
* ========================== */
void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss)
void sim_snapshot_decode(BitbuffReader *br, struct sim_snapshot *ss)
{
__prof;
@ -869,7 +869,7 @@ void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss)
* Snapshot encode
* ========================== */
void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1)
void sim_snapshot_encode(BitbuffWriter *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1)
{
__prof;
@ -928,7 +928,7 @@ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver,
* ========================== */
struct sim_ent_decode_node {
struct string tmp_encoded;
String tmp_encoded;
};
struct sim_ent_decode_queue {
@ -936,10 +936,10 @@ struct sim_ent_decode_queue {
struct sim_ent_decode_node *last;
};
void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss)
void sim_snapshot_decode(BitbuffReader *br, struct sim_snapshot *ss)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
ss->sim_dt_ns = br_read_iv(br);
ss->sim_time_ns = br_read_iv(br);
@ -995,7 +995,7 @@ void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss)
if (!released) {
u64 num_ent_bits = br_read_uv(br);
struct bitbuff_reader ent_br = br_from_seek_bits(br, num_ent_bits);
BitbuffReader ent_br = br_from_seek_bits(br, num_ent_bits);
if (br_num_bits_left(&ent_br) > 0) {
struct sim_ent_decode_node *n = arena_push(scratch.arena, struct sim_ent_decode_node);
n->is_new = allocation_changed && !released;
@ -1036,7 +1036,7 @@ void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss)
/* Decode ent data from decode queue */
for (struct sim_ent_decode_node *n = queue.first; n; n = n->next) {
struct bitbuff_reader ent_br = n->br;
BitbuffReader ent_br = n->br;
u32 index = n->index;
struct sim_ent *e = sim_ent_from_index(ss, index);
if (e->valid) {

View File

@ -12,7 +12,7 @@
#define SIM_LAYER_RELATIVE_WEAPON (1)
struct sim_ent_id {
struct uid uid;
UID uid;
};
struct sim_client_handle {
@ -38,14 +38,14 @@ struct sim_client_lookup_bin {
struct sim_client_store {
b32 valid;
struct arena *arena;
Arena *arena;
/* Client lookup */
struct sim_client_lookup_bin *client_lookup_bins;
u64 num_client_lookup_bins;
/* Clients */
struct arena *clients_arena;
Arena *clients_arena;
struct sim_client *clients;
struct sim_client_handle first_free_client;
u64 num_clients_allocated;
@ -77,12 +77,12 @@ struct sim_client {
struct sim_client_handle handle;
struct sim_client_store *store;
struct arena *snapshots_arena;
Arena *snapshots_arena;
/* Round trip time of the client (if networked) */
i64 last_rtt_ns;
struct host_channel_id channel_id;
N_ChannelId channel_id;
u64 channel_hash;
struct sim_client_handle next_free;
@ -128,8 +128,8 @@ INLINE b32 sim_client_handle_eq(struct sim_client_handle a, struct sim_client_ha
struct sim_client *sim_client_alloc(struct sim_client_store *store);
void sim_client_release(struct sim_client *client);
struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id);
void sim_client_set_channel_id(struct sim_client *client, struct host_channel_id channel_id);
struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, N_ChannelId channel_id);
void sim_client_set_channel_id(struct sim_client *client, N_ChannelId channel_id);
struct sim_client *sim_client_from_handle(struct sim_client_store *store, struct sim_client_handle handle);
/* ========================== *
@ -159,9 +159,9 @@ enum sim_control_flag {
};
struct sim_control {
struct v2 move; /* Movement direction vector (speed of 0 -> 1) */
struct v2 focus; /* Focus direction vector (where does the controller want to look) */
struct v2 dbg_cursor; /* Where is the user's cursor in the world (used for things like editing the world) */
V2 move; /* Movement direction vector (speed of 0 -> 1) */
V2 focus; /* Focus direction vector (where does the controller want to look) */
V2 dbg_cursor; /* Where is the user's cursor in the world (used for things like editing the world) */
u32 flags;
};
@ -192,7 +192,7 @@ struct sim_snapshot {
u64 prev_tick;
u64 next_tick;
struct arena *arena;
Arena *arena;
/* Sim time (guaranteed to increase by sim_dt_ns each step) */
i64 sim_dt_ns;
@ -212,7 +212,7 @@ struct sim_snapshot {
u64 num_id_bins;
/* Entities */
struct arena *ents_arena;
Arena *ents_arena;
struct sim_ent *ents;
u32 first_free_ent;
u32 num_ents_allocated;
@ -225,9 +225,6 @@ INLINE struct sim_snapshot *sim_snapshot_nil(void)
return *_g_sim_snapshot_nil;
}
struct bitbuff_writer;
struct bitbuff_reader;
/* Alloc */
struct sim_snapshot *sim_snapshot_alloc(struct sim_client *client, struct sim_snapshot *src, u64 tick);
void sim_snapshot_release(struct sim_snapshot *sim_snapshot);
@ -239,12 +236,12 @@ struct sim_snapshot *sim_snapshot_from_closest_tick_lte(struct sim_client *clien
struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *client, u64 tick);
/* Tile */
struct v2i32 sim_world_tile_index_from_pos(struct v2 pos);
struct v2 sim_pos_from_world_tile_index(struct v2i32 world_tile_index);
struct v2i32 sim_local_tile_index_from_world_tile_index(struct v2i32 world_tile_index);
struct v2i32 sim_world_tile_index_from_local_tile_index(struct v2i32 tile_chunk_index, struct v2i32 local_tile_index);
struct v2i32 sim_tile_chunk_index_from_world_tile_index(struct v2i32 world_tile_index);
void sim_snapshot_set_tile(struct sim_snapshot *ss, struct v2i32 world_tile_index, enum sim_tile_kind tile_kind);
V2i32 sim_world_tile_index_from_pos(V2 pos);
V2 sim_pos_from_world_tile_index(V2i32 world_tile_index);
V2i32 sim_local_tile_index_from_world_tile_index(V2i32 world_tile_index);
V2i32 sim_world_tile_index_from_local_tile_index(V2i32 tile_chunk_index, V2i32 local_tile_index);
V2i32 sim_tile_chunk_index_from_world_tile_index(V2i32 world_tile_index);
void sim_snapshot_set_tile(struct sim_snapshot *ss, V2i32 world_tile_index, enum sim_tile_kind tile_kind);
/* Lerp */
struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, struct sim_snapshot *ss0, struct sim_snapshot *ss1, f64 blend);
@ -253,5 +250,5 @@ struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, str
void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss, struct sim_ent_id remote_player, u32 sync_flags);
/* Encode / decode */
void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1);
void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss);
void sim_snapshot_encode(BitbuffWriter *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1);
void sim_snapshot_decode(BitbuffReader *br, struct sim_snapshot *ss);

View File

@ -1,7 +1,7 @@
/* Id magic number constants (to be used in conjunction with ent ids in deterministic id combinations) */
#define SIM_ENT_CONTACT_BASIS_UID (UID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af))
#define SIM_ENT_COLLISION_DEBUG_BASIS_UID (UID(0x302c01182013bb02, 0x570bd270399d11a5))
#define SIM_ENT_TILE_CHUNK_BASIS_UID (UID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
#define SIM_ENT_CONTACT_BASIS_UID (MakeUID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af))
#define SIM_ENT_COLLISION_DEBUG_BASIS_UID (MakeUID(0x302c01182013bb02, 0x570bd270399d11a5))
#define SIM_ENT_TILE_CHUNK_BASIS_UID (MakeUID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
INTERNAL u32 index_from_ent(struct sim_snapshot *ss, struct sim_ent *ent)
{
@ -128,7 +128,7 @@ void sim_ent_release(struct sim_ent *ent)
void sim_ent_release_all_with_prop(struct sim_snapshot *ss, enum sim_ent_prop prop)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sim_ent **ents_to_release = arena_push_dry(scratch.arena, struct sim_ent *);
u64 ents_to_release_count = 0;
@ -289,11 +289,11 @@ struct sim_ent_id sim_ent_collision_debug_id_from_ids(struct sim_ent_id player_i
}
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
struct sim_ent_id sim_ent_tile_chunk_id_from_tile_chunk_index(struct v2i32 chunk_index)
struct sim_ent_id sim_ent_tile_chunk_id_from_tile_chunk_index(V2i32 chunk_index)
{
struct sim_ent_id res = ZI;
res.uid = SIM_ENT_TILE_CHUNK_BASIS_UID;
res.uid = uid_combine(res.uid, UID(rand_u64_from_seed(chunk_index.x), rand_u64_from_seed(chunk_index.y)));
res.uid = uid_combine(res.uid, MakeUID(rand_u64_from_seed(chunk_index.x), rand_u64_from_seed(chunk_index.y)));
return res;
}
@ -412,9 +412,9 @@ INTERNAL void sim_ent_mark_child_xforms_dirty(struct sim_snapshot *ss, struct si
}
}
INTERNAL struct xform sim_ent_get_xform_internal(struct sim_snapshot *ss, struct sim_ent *ent)
INTERNAL Xform sim_ent_get_xform_internal(struct sim_snapshot *ss, struct sim_ent *ent)
{
struct xform xf;
Xform xf;
if (ent->_is_xform_dirty) {
if (ent->is_top) {
xf = ent->_local_xform;
@ -433,9 +433,9 @@ INTERNAL struct xform sim_ent_get_xform_internal(struct sim_snapshot *ss, struct
return xf;
}
struct xform sim_ent_get_xform(struct sim_ent *ent)
Xform sim_ent_get_xform(struct sim_ent *ent)
{
struct xform xf;
Xform xf;
if (ent->_is_xform_dirty) {
if (ent->is_top) {
xf = ent->_local_xform;
@ -455,12 +455,12 @@ struct xform sim_ent_get_xform(struct sim_ent *ent)
return xf;
}
struct xform sim_ent_get_local_xform(struct sim_ent *ent)
Xform sim_ent_get_local_xform(struct sim_ent *ent)
{
return ent->_local_xform;
}
void sim_ent_set_xform(struct sim_ent *ent, struct xform xf)
void sim_ent_set_xform(struct sim_ent *ent, Xform xf)
{
if (!xform_eq(xf, ent->_xform)) {
struct sim_snapshot *ss = ent->ss;
@ -469,7 +469,7 @@ void sim_ent_set_xform(struct sim_ent *ent, struct xform xf)
ent->_local_xform = xf;
} else {
struct sim_ent *parent = sim_ent_from_id(ss, ent->parent);
struct xform parent_global = sim_ent_get_xform_internal(ss, parent);
Xform parent_global = sim_ent_get_xform_internal(ss, parent);
ent->_local_xform = xform_mul(xform_invert(parent_global), xf);
}
ent->_xform = xf;
@ -478,7 +478,7 @@ void sim_ent_set_xform(struct sim_ent *ent, struct xform xf)
}
}
void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf)
void sim_ent_set_local_xform(struct sim_ent *ent, Xform xf)
{
if (!xform_eq(xf, ent->_local_xform)) {
ent->_local_xform = xf;
@ -491,7 +491,7 @@ void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf)
* Ent movement
* ========================== */
void sim_ent_set_linear_velocity(struct sim_ent *ent, struct v2 velocity)
void sim_ent_set_linear_velocity(struct sim_ent *ent, V2 velocity)
{
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY);
@ -505,25 +505,25 @@ void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity)
}
}
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 point)
void sim_ent_apply_linear_impulse(struct sim_ent *ent, V2 impulse, V2 point)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
struct xform xf = sim_ent_get_xform(ent);
struct v2 center = xf.og;
Xform xf = sim_ent_get_xform(ent);
V2 center = xf.og;
f32 scale = math_fabs(xform_get_determinant(xf));
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
struct v2 vcp = v2_sub(point, center);
V2 vcp = v2_sub(point, center);
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
sim_ent_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
}
}
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse)
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, V2 impulse)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
f32 scale = math_fabs(xform_get_determinant(xf));
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
@ -531,7 +531,7 @@ void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impul
}
}
void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force)
void sim_ent_apply_force_to_center(struct sim_ent *ent, V2 force)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
ent->force = v2_add(ent->force, force);
@ -541,7 +541,7 @@ void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force)
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
f32 scale = math_fabs(xform_get_determinant(xf));
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
@ -559,21 +559,21 @@ void sim_ent_apply_torque(struct sim_ent *ent, f32 torque)
* Tile
* ========================== */
struct sim_ent *sim_tile_chunk_from_chunk_index(struct sim_snapshot *ss, struct v2i32 chunk_index)
struct sim_ent *sim_tile_chunk_from_chunk_index(struct sim_snapshot *ss, V2i32 chunk_index)
{
struct sim_ent_id chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
struct sim_ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
return chunk_ent;
}
struct sim_ent *sim_tile_chunk_from_world_tile_index(struct sim_snapshot *ss, struct v2i32 world_tile_index)
struct sim_ent *sim_tile_chunk_from_world_tile_index(struct sim_snapshot *ss, V2i32 world_tile_index)
{
struct v2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
V2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
struct sim_ent *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index);
return chunk_ent;
}
enum sim_tile_kind sim_get_chunk_tile(struct sim_ent *chunk_ent, struct v2i32 local_tile_index)
enum sim_tile_kind sim_get_chunk_tile(struct sim_ent *chunk_ent, V2i32 local_tile_index)
{
enum sim_tile_kind res = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
return res;
@ -592,8 +592,8 @@ void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64
if (e->is_top) {
/* TODO: Cache parent & child xforms in sim */
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
sim_ent_set_xform(e, xform_lerp(e0_xf, e1_xf, blend));
}
@ -687,7 +687,7 @@ void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote)
* Ent encode
* ========================== */
void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_ent *e1)
void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1)
{
struct sim_snapshot *ss = e1->ss;
/* FIXME: Things like xforms need to be retreived manually rather than memcopied. */
@ -714,7 +714,7 @@ void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_en
* Ent decode
* ========================== */
void sim_ent_decode(struct bitbuff_reader *br, struct sim_ent *e)
void sim_ent_decode(BitbuffReader *br, struct sim_ent *e)
{
struct sim_snapshot *old_ss = e->ss;
{
@ -739,7 +739,7 @@ void sim_ent_decode(struct bitbuff_reader *br, struct sim_ent *e)
* Ent encode
* ========================== */
void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_ent *e1)
void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1)
{
struct sim_snapshot *ss = e1->ss;
@ -772,7 +772,7 @@ void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_en
* Ent decode
* ========================== */
void sim_ent_decode(struct bitbuff_reader *br, struct sim_ent *e)
void sim_ent_decode(BitbuffReader *br, struct sim_ent *e)
{
struct sim_ent decoded = *e;
{

View File

@ -1,8 +1,5 @@
#define SIM_ENT_NIL_ID ((struct sim_ent_id) { UID(0, 0) })
#define SIM_ENT_ROOT_ID ((struct sim_ent_id) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
struct bitbuff_writer;
struct bitbuff_reader;
#define SIM_ENT_NIL_ID ((struct sim_ent_id) { MakeUID(0, 0) })
#define SIM_ENT_ROOT_ID ((struct sim_ent_id) { MakeUID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
enum sim_ent_prop {
SEPROP_ACTIVE,
@ -111,8 +108,8 @@ struct sim_ent {
/* Position */
/* Use xform getters & setters to access. */
struct xform _local_xform; /* Transform in relation to parent ent (or the world if ent has no parent) */
struct xform _xform; /* Calculated from ent tree */
Xform _local_xform; /* Transform in relation to parent ent (or the world if ent has no parent) */
Xform _xform; /* Calculated from ent tree */
b32 _is_xform_dirty;
/* ====================================================================== */
@ -142,7 +139,7 @@ struct sim_ent {
struct sim_ent_id cmd_control_hovered_ent;
/* Chat cmd */
//struct string cmd_chat_msg;
//String cmd_chat_msg;
/* ====================================================================== */
/* Chat */
@ -150,7 +147,7 @@ struct sim_ent {
/* SEPROP_CHAT */
struct sim_ent_id chat_player;
//struct string chat_msg;
//String chat_msg;
/* ====================================================================== */
@ -160,7 +157,7 @@ struct sim_ent {
/* FIXME: Move out of here */
u8 tile_chunk_tiles[SIM_TILES_PER_CHUNK_SQRT * SIM_TILES_PER_CHUNK_SQRT];
struct v2i32 tile_chunk_index;
V2i32 tile_chunk_index;
/* ====================================================================== */
/* Client */
@ -172,7 +169,7 @@ struct sim_ent {
struct sim_client_handle player_client_handle; /* The client handle on the master sim's machine */
struct sim_control player_control;
struct v2 player_cursor_pos;
V2 player_cursor_pos;
struct sim_ent_id player_hovered_ent;
struct sim_ent_id player_control_ent;
@ -189,8 +186,8 @@ struct sim_ent {
/* ====================================================================== */
/* Collider */
struct v2 collision_dir; /* If set, then only collisions coming from this direction will generate contacts (used for walls to prevent ghost collisions) */
struct collider_shape local_collider;
V2 collision_dir; /* If set, then only collisions coming from this direction will generate contacts (used for walls to prevent ghost collisions) */
CLD_Shape local_collider;
#if COLLIDER_DEBUG
struct phys_collision_debug collision_debug_data;
@ -247,10 +244,10 @@ struct sim_ent {
f32 angular_ground_friction;
/* Use sim_ent_set_linear_velocity & sim_ent_set_angular_velocity to set */
struct v2 linear_velocity; /* m/s */
V2 linear_velocity; /* m/s */
f32 angular_velocity; /* rad/s */
struct v2 force;
V2 force;
f32 torque;
f32 linear_damping;
@ -260,13 +257,13 @@ struct sim_ent {
/* Sprite */
struct sprite_tag sprite;
struct string sprite_span_name;
String sprite_span_name;
u32 sprite_tint;
struct v3 sprite_emittance;
V3 sprite_emittance;
struct string sprite_collider_slice; /* Collider will sync to bounds of this slice if set */
String sprite_collider_slice; /* Collider will sync to bounds of this slice if set */
struct xform sprite_local_xform; /* Sprite transform in relation to ent */
Xform sprite_local_xform; /* Sprite transform in relation to ent */
/* ====================================================================== */
/* Animation */
@ -280,7 +277,7 @@ struct sim_ent {
/* SEPROP_ATTACHED */
/* Slice name on the parent ent's sprite to attach to */
struct string attach_slice;
String attach_slice;
/* ====================================================================== */
/* Equip */
@ -330,8 +327,8 @@ struct sim_ent {
struct sim_ent_id bullet_src;
struct sim_ent_id bullet_tracer;
struct v2 bullet_src_pos;
struct v2 bullet_src_dir;
V2 bullet_src_pos;
V2 bullet_src_dir;
f32 bullet_launch_velocity;
f32 bullet_knockback;
f32 bullet_explosion_strength;
@ -349,13 +346,13 @@ struct sim_ent {
/* SEPROP_TRACER */
struct v2 tracer_start;
struct v2 tracer_start_velocity;
V2 tracer_start;
V2 tracer_start_velocity;
f32 tracer_fade_duration; /* Time for tracer to fade from opacity of 1 to 0 */
/* calculated each frame */
struct v2 tracer_gradient_start;
struct v2 tracer_gradient_end;
V2 tracer_gradient_start;
V2 tracer_gradient_end;
/* ====================================================================== */
/* Quake */
@ -371,24 +368,24 @@ struct sim_ent {
/* SEPROP_TEST */
b32 test_initialized;
struct xform test_start_local_xform;
struct xform test_start_sprite_xform;
Xform test_start_local_xform;
Xform test_start_sprite_xform;
/* SEPROP_TEST_SOUND_EMITTER */
struct string sound_name;
struct mixer_desc sound_desc;
struct mixer_track_handle sound_handle;
String sound_name;
M_TrackDesc sound_desc;
M_Handle sound_handle;
/* ====================================================================== */
/* Camera */
/* SEPROP_CAMERA */
struct sim_ent_id camera_follow;
struct xform camera_quad_xform;
Xform camera_quad_xform;
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
u32 camera_lerp_continuity_gen;
struct xform camera_xform_target; /* Calculated from camera_follow */
Xform camera_xform_target; /* Calculated from camera_follow */
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
f32 shake;
@ -511,7 +508,7 @@ struct sim_ent *sim_ent_from_id(struct sim_snapshot *ss, struct sim_ent_id id);
struct sim_ent_id sim_ent_random_id(void);
struct sim_ent_id sim_ent_contact_constraint_id_from_contacting_ids(struct sim_ent_id player_id, struct sim_ent_id id0, struct sim_ent_id id1);
struct sim_ent_id sim_ent_collision_debug_id_from_ids(struct sim_ent_id player_id, struct sim_ent_id id0, struct sim_ent_id id1);
struct sim_ent_id sim_ent_tile_chunk_id_from_tile_chunk_index(struct v2i32 chunk_start);
struct sim_ent_id sim_ent_tile_chunk_id_from_tile_chunk_index(V2i32 chunk_start);
/* Query */
struct sim_ent *sim_ent_find_first_match_one(struct sim_snapshot *ss, enum sim_ent_prop prop);
@ -522,24 +519,24 @@ void sim_ent_link_parent(struct sim_ent *parent, struct sim_ent *child);
void sim_ent_unlink_from_parent(struct sim_ent *ent);
/* Xform */
struct xform sim_ent_get_xform(struct sim_ent *ent);
struct xform sim_ent_get_local_xform(struct sim_ent *ent);
void sim_ent_set_xform(struct sim_ent *ent, struct xform xf);
void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf);
Xform sim_ent_get_xform(struct sim_ent *ent);
Xform sim_ent_get_local_xform(struct sim_ent *ent);
void sim_ent_set_xform(struct sim_ent *ent, Xform xf);
void sim_ent_set_local_xform(struct sim_ent *ent, Xform xf);
/* Movement */
void sim_ent_set_linear_velocity(struct sim_ent *ent, struct v2 velocity);
void sim_ent_set_linear_velocity(struct sim_ent *ent, V2 velocity);
void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity);
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 world_point);
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse);
void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force);
void sim_ent_apply_linear_impulse(struct sim_ent *ent, V2 impulse, V2 world_point);
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, V2 impulse);
void sim_ent_apply_force_to_center(struct sim_ent *ent, V2 force);
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse);
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque);
/* Tile */
struct sim_ent *sim_tile_chunk_from_chunk_index(struct sim_snapshot *ss, struct v2i32 chunk_index);
struct sim_ent *sim_tile_chunk_from_world_tile_index(struct sim_snapshot *ss, struct v2i32 world_tile_index);
enum sim_tile_kind sim_get_chunk_tile(struct sim_ent *chunk_ent, struct v2i32 local_tile_index);
struct sim_ent *sim_tile_chunk_from_chunk_index(struct sim_snapshot *ss, V2i32 chunk_index);
struct sim_ent *sim_tile_chunk_from_world_tile_index(struct sim_snapshot *ss, V2i32 world_tile_index);
enum sim_tile_kind sim_get_chunk_tile(struct sim_ent *chunk_ent, V2i32 local_tile_index);
/* Lerp */
void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64 blend);
@ -549,5 +546,5 @@ void sim_ent_sync_alloc_tree(struct sim_ent *local_parent, struct sim_ent *remot
void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote);
/* Encode / decode */
void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_ent *e1);
void sim_ent_decode(struct bitbuff_reader *br, struct sim_ent *e);
void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1);
void sim_ent_decode(BitbuffReader *br, struct sim_ent *e);

View File

@ -32,9 +32,9 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
if (!(sim_ent_has_prop(check0, SEPROP_SOLID) || sim_ent_has_prop(check0, SEPROP_SENSOR))) continue;
if (check0->local_collider.count <= 0) continue;
struct xform check0_xf = sim_ent_get_xform(check0);
struct collider_shape check0_collider = check0->local_collider;
struct aabb aabb = collider_aabb_from_collider(&check0_collider, check0_xf);
Xform check0_xf = sim_ent_get_xform(check0);
CLD_Shape check0_collider = check0->local_collider;
Aabb aabb = collider_aabb_from_collider(&check0_collider, check0_xf);
struct space_iter iter = space_iter_begin_aabb(space, aabb);
struct space_entry *space_entry;
@ -48,10 +48,10 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
/* Deterministic order based on entity id */
struct sim_ent *e0;
struct sim_ent *e1;
struct xform e0_xf;
struct xform e1_xf;
struct collider_shape e0_collider;
struct collider_shape e1_collider;
Xform e0_xf;
Xform e1_xf;
CLD_Shape e0_collider;
CLD_Shape e1_collider;
if (check0->id.uid.hi < check1->id.uid.hi) {
e0 = check0;
e1 = check1;
@ -81,7 +81,7 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
}
/* Calculate collision */
struct collider_collision_points_result collider_res = collider_collision_points(&e0_collider, &e1_collider, e0_xf, e1_xf);
CLD_CollisionResult collider_res = collider_collision_points(&e0_collider, &e1_collider, e0_xf, e1_xf);
/* Parts of algorithm are hard-coded to support 2 contact points */
STATIC_ASSERT(countof(constraint_ent->contact_constraint_data.points) == 2);
@ -129,8 +129,8 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
/* Update / insert returned contacts */
for (u32 i = 0; i < collider_res.num_points; ++i) {
struct collider_collision_point *res_point = &collider_res.points[i];
struct v2 point = res_point->point;
CLD_CollisionPoint *res_point = &collider_res.points[i];
V2 point = res_point->point;
f32 sep = res_point->separation;
u32 id = res_point->id;
struct phys_contact_point *contact = 0;
@ -162,9 +162,9 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
/* Skip solve based on collision direction */
{
struct v2 normal = collider_res.normal;
struct v2 dir0 = e0->collision_dir;
struct v2 dir1 = e1->collision_dir;
V2 normal = collider_res.normal;
V2 dir0 = e0->collision_dir;
V2 dir1 = e1->collision_dir;
f32 threshold = 0.5;
b32 is_wrong_dir = 0;
if (!v2_is_zero(dir0)) {
@ -186,23 +186,23 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
data.dt = elapsed_dt;
/* Calculate point */
struct v2 midpoint = collider_res.points[0].point;
V2 midpoint = collider_res.points[0].point;
if (collider_res.num_points > 1) {
midpoint = v2_add(midpoint, v2_mul(v2_sub(collider_res.points[1].point, midpoint), 0.5f));
}
data.point = midpoint;
/* Calculate relative velocity */
struct v2 vrel;
V2 vrel;
{
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
V2 v0 = e0->linear_velocity;
V2 v1 = e1->linear_velocity;
f32 w0 = e0->angular_velocity;
f32 w1 = e1->angular_velocity;
struct v2 vcp1 = v2_sub(midpoint, e1_xf.og);
struct v2 vcp0 = v2_sub(midpoint, e0_xf.og);
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
V2 vcp1 = v2_sub(midpoint, e1_xf.og);
V2 vcp0 = v2_sub(midpoint, e0_xf.og);
V2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
V2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
vrel = v2_sub(vel0, vel1);
}
data.vrel = vrel;
@ -254,7 +254,7 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt,
/* Update closest points */
{
struct collider_closest_points_result closest_points_res = collider_closest_points(&e0_collider, &e1_collider, e0_xf, e1_xf);
CLD_ClosestResult closest_points_res = collider_closest_points(&e0_collider, &e1_collider, e0_xf, e1_xf);
dbg->closest0 = closest_points_res.p0;
dbg->closest1 = closest_points_res.p1;
}
@ -281,11 +281,11 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1);
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
struct v2 normal = constraint->normal;
struct v2 tangent = v2_perp(normal);
V2 normal = constraint->normal;
V2 tangent = v2_perp(normal);
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
/* TODO: Cache this */
/* Calculate masses */
@ -319,8 +319,8 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
/* Update / insert returned contacts */
for (u32 i = 0; i < num_points; ++i) {
struct phys_contact_point *contact = &constraint->points[i];
struct v2 vcp0 = contact->vcp0;
struct v2 vcp1 = contact->vcp1;
V2 vcp0 = contact->vcp0;
V2 vcp1 = contact->vcp1;
/* Normal mass */
{
@ -396,21 +396,21 @@ void phys_warm_start_contacts(struct phys_step_ctx *ctx)
f32 inv_i0 = constraint->inv_i0;
f32 inv_i1 = constraint->inv_i1;
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
V2 v0 = e0->linear_velocity;
V2 v1 = e1->linear_velocity;
f32 w0 = e0->angular_velocity;
f32 w1 = e1->angular_velocity;
/* Warm start */
struct v2 normal = constraint->normal;
struct v2 tangent = v2_perp(normal);
V2 normal = constraint->normal;
V2 tangent = v2_perp(normal);
f32 inv_num_points = 1.f / num_points;
for (u32 i = 0; i < num_points; ++i) {
struct phys_contact_point *point = &constraint->points[i];
struct v2 vcp0 = point->vcp0;
struct v2 vcp1 = point->vcp1;
V2 vcp0 = point->vcp0;
V2 vcp1 = point->vcp1;
struct v2 impulse = v2_add(v2_mul(normal, point->normal_impulse), v2_mul(tangent, point->tangent_impulse));
V2 impulse = v2_add(v2_mul(normal, point->normal_impulse), v2_mul(tangent, point->tangent_impulse));
impulse = v2_mul(impulse, inv_num_points);
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
@ -441,15 +441,15 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1);
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
V2 v0 = e0->linear_velocity;
V2 v1 = e1->linear_velocity;
f32 w0 = e0->angular_velocity;
f32 w1 = e1->angular_velocity;
u32 num_points = constraint->num_points;
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve && !constraint->wrong_dir) {
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = constraint->inv_m0;
f32 inv_m1 = constraint->inv_m1;
@ -457,13 +457,13 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
f32 inv_i1 = constraint->inv_i1;
/* Normal impulse */
struct v2 normal = constraint->normal;
V2 normal = constraint->normal;
for (u32 point_index = 0; point_index < num_points; ++point_index) {
struct phys_contact_point *point = &constraint->points[point_index];
struct v2 vcp0 = point->vcp0;
struct v2 vcp1 = point->vcp1;
struct v2 p0 = v2_add(e0_xf.og, vcp0);
struct v2 p1 = v2_add(e1_xf.og, vcp1);
V2 vcp0 = point->vcp0;
V2 vcp1 = point->vcp1;
V2 p0 = v2_add(e0_xf.og, vcp0);
V2 p1 = v2_add(e1_xf.og, vcp1);
/* FIXME: Should separation use the rotated contact points? */
f32 separation = v2_dot(v2_sub(p1, p0), normal) + point->starting_separation;
@ -477,16 +477,16 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
velocity_bias = separation / dt;
} else if (apply_bias) {
/* Soft constraint */
struct math_spring softness = math_spring_init(CONTACT_SPRING_HZ, CONTACT_SPRING_DAMP, dt);
SoftSpring softness = math_spring_init(CONTACT_SPRING_HZ, CONTACT_SPRING_DAMP, dt);
f32 pushout_velocity = constraint->pushout_velocity;
mass_scale = softness.mass_scale;
impulse_scale = softness.impulse_scale;
velocity_bias = max_f32(softness.bias_rate * separation, -pushout_velocity);
}
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
struct v2 vrel = v2_sub(vel0, vel1);
V2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
V2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
V2 vrel = v2_sub(vel0, vel1);
f32 k = point->inv_normal_mass;
@ -499,7 +499,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
f32 delta = new_impulse - old_impulse;
point->normal_impulse = new_impulse;
struct v2 impulse = v2_mul(normal, delta);
V2 impulse = v2_mul(normal, delta);
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
@ -507,15 +507,15 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
}
/* Tangent impulse */
struct v2 tangent = v2_perp(normal);
V2 tangent = v2_perp(normal);
for (u32 point_index = 0; point_index < num_points; ++point_index) {
struct phys_contact_point *point = &constraint->points[point_index];
struct v2 vcp0 = point->vcp0;
struct v2 vcp1 = point->vcp1;
V2 vcp0 = point->vcp0;
V2 vcp1 = point->vcp1;
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
struct v2 vrel = v2_sub(vel0, vel1);
V2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
V2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
V2 vrel = v2_sub(vel0, vel1);
f32 k = point->inv_tangent_mass;
@ -529,7 +529,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
f32 delta = new_impulse - old_impulse;
point->tangent_impulse = new_impulse;
struct v2 impulse = v2_mul(tangent, delta);
V2 impulse = v2_mul(tangent, delta);
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
@ -580,8 +580,8 @@ void phys_prepare_motor_joints(struct phys_step_ctx *ctx)
struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
/* TODO: Cache this */
/* Calculate masses */
@ -602,13 +602,13 @@ void phys_prepare_motor_joints(struct phys_step_ctx *ctx)
joint->inv_i0 = inv_i0;
joint->inv_i1 = inv_i1;
joint->point_local_e0 = V2(0, 0);
joint->point_local_e1 = V2(0, 0);
joint->point_local_e0 = V2FromXY(0, 0);
joint->point_local_e1 = V2FromXY(0, 0);
struct v2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
struct v2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
V2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
V2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
struct xform linear_mass_xf = ZI;
Xform linear_mass_xf = ZI;
linear_mass_xf.bx.x = inv_m0 + inv_m1 + vcp0.y * vcp0.y * inv_i0 + vcp1.y * vcp1.y * inv_i1;
linear_mass_xf.bx.y = -vcp0.y * vcp0.x * inv_i0 - vcp1.y * vcp1.x * inv_i1;
linear_mass_xf.by.x = linear_mass_xf.bx.y;
@ -618,7 +618,7 @@ void phys_prepare_motor_joints(struct phys_step_ctx *ctx)
joint->angular_mass = 1.f / (inv_i0 + inv_i1);
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
joint->linear_impulse = V2(0, 0);
joint->linear_impulse = V2FromXY(0, 0);
joint->angular_impulse = 0;
#endif
} else {
@ -643,16 +643,16 @@ void phys_warm_start_motor_joints(struct phys_step_ctx *ctx)
struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1);
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = joint->inv_m0;
f32 inv_m1 = joint->inv_m1;
f32 inv_i0 = joint->inv_i0;
f32 inv_i1 = joint->inv_i1;
struct v2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
struct v2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
V2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
V2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
sim_ent_set_linear_velocity(e0, v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)));
sim_ent_set_linear_velocity(e1, v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)));
@ -675,16 +675,16 @@ void phys_solve_motor_joints(struct phys_step_ctx *ctx, f32 dt)
struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1);
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = joint->inv_m0;
f32 inv_m1 = joint->inv_m1;
f32 inv_i0 = joint->inv_i0;
f32 inv_i1 = joint->inv_i1;
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
V2 v0 = e0->linear_velocity;
V2 v1 = e1->linear_velocity;
f32 w0 = e0->angular_velocity;
f32 w1 = e1->angular_velocity;
@ -709,22 +709,22 @@ void phys_solve_motor_joints(struct phys_step_ctx *ctx, f32 dt)
/* Linear constraint */
{
struct v2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
struct v2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
V2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
V2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
f32 max_impulse = joint->max_force * dt;
struct v2 linear_separation = v2_sub(v2_add(e1_xf.og, vcp1), v2_add(e0_xf.og, vcp0));
struct v2 linear_bias = v2_mul(linear_separation, correction_rate * inv_dt);
V2 linear_separation = v2_sub(v2_add(e1_xf.og, vcp1), v2_add(e0_xf.og, vcp0));
V2 linear_bias = v2_mul(linear_separation, correction_rate * inv_dt);
struct v2 vrel = v2_sub(v2_add(v1, v2_perp_mul(vcp1, w1)), v2_add(v0, v2_perp_mul(vcp0, w0)));
struct v2 impulse = v2_neg(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vrel, linear_bias)));
V2 vrel = v2_sub(v2_add(v1, v2_perp_mul(vcp1, w1)), v2_add(v0, v2_perp_mul(vcp0, w0)));
V2 impulse = v2_neg(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vrel, linear_bias)));
struct v2 old_impulse = joint->linear_impulse;
struct v2 new_impulse = v2_clamp_len(v2_add(old_impulse, impulse), max_impulse);
V2 old_impulse = joint->linear_impulse;
V2 new_impulse = v2_clamp_len(v2_add(old_impulse, impulse), max_impulse);
joint->linear_impulse = new_impulse;
struct v2 delta = v2_sub(new_impulse, old_impulse);
V2 delta = v2_sub(new_impulse, old_impulse);
v0 = v2_sub(v0, v2_mul(delta, inv_m0));
v1 = v2_add(v1, v2_mul(delta, inv_m1));
w0 -= v2_wedge(vcp0, delta) * inv_i0;
@ -779,7 +779,7 @@ void phys_prepare_mouse_joints(struct phys_step_ctx *ctx)
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
struct sim_ent *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
/* TODO: Cache this */
/* Calculate masses */
@ -793,9 +793,9 @@ void phys_prepare_mouse_joints(struct phys_step_ctx *ctx)
joint->inv_m = inv_m;
joint->inv_i = inv_i;
struct v2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
V2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
struct xform linear_mass_xf = ZI;
Xform linear_mass_xf = ZI;
linear_mass_xf.bx.x = inv_m + inv_i * vcp.y * vcp.y;
linear_mass_xf.bx.y = -inv_i * vcp.x * vcp.y;
linear_mass_xf.by.x = linear_mass_xf.bx.y;
@ -803,7 +803,7 @@ void phys_prepare_mouse_joints(struct phys_step_ctx *ctx)
joint->linear_mass_xf = xform_invert(linear_mass_xf);
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
joint->linear_impulse = V2(0, 0);
joint->linear_impulse = V2FromXY(0, 0);
joint->angular_impulse = 0;
#endif
} else {
@ -828,8 +828,8 @@ void phys_warm_start_mouse_joints(struct phys_step_ctx *ctx)
if (sim_ent_should_simulate(ent)) {
f32 inv_m = joint->inv_m;
f32 inv_i = joint->inv_i;
struct xform xf = sim_ent_get_xform(ent);
struct v2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
Xform xf = sim_ent_get_xform(ent);
V2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
sim_ent_set_angular_velocity(ent, ent->angular_velocity + ((v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i));
}
@ -848,7 +848,7 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt)
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
struct sim_ent *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
struct v2 v = ent->linear_velocity;
V2 v = ent->linear_velocity;
f32 w = ent->angular_velocity;
f32 inv_m = joint->inv_m;
@ -856,7 +856,7 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt)
/* Angular impulse */
{
struct math_spring softness = math_spring_init(joint->angular_spring_hz, joint->angular_spring_damp, dt);
SoftSpring softness = math_spring_init(joint->angular_spring_hz, joint->angular_spring_damp, dt);
f32 mass_scale = softness.mass_scale;
f32 impulse_scale = softness.impulse_scale;
f32 impulse = mass_scale * (-w / inv_i) - impulse_scale * joint->angular_impulse;
@ -868,27 +868,27 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt)
{
f32 max_impulse = joint->max_force / dt;
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
struct v2 point_start = xform_mul_v2(xf, joint->point_local_start);
struct v2 point_end = joint->point_end;
V2 point_start = xform_mul_v2(xf, joint->point_local_start);
V2 point_end = joint->point_end;
struct v2 vcp = v2_sub(point_start, xf.og);
struct v2 separation = v2_sub(point_start, point_end);
V2 vcp = v2_sub(point_start, xf.og);
V2 separation = v2_sub(point_start, point_end);
struct math_spring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
SoftSpring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
f32 bias_rate = softness.bias_rate;
f32 mass_scale = softness.mass_scale;
f32 impulse_scale = softness.impulse_scale;
struct v2 bias = v2_mul(separation, bias_rate);
struct v2 vel = v2_add(v, v2_perp_mul(vcp, w));
struct v2 b = xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias));
V2 bias = v2_mul(separation, bias_rate);
V2 vel = v2_add(v, v2_perp_mul(vcp, w));
V2 b = xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias));
struct v2 impulse = v2_mul(b, -mass_scale);
V2 impulse = v2_mul(b, -mass_scale);
impulse = v2_sub(impulse, v2_mul(joint->linear_impulse, impulse_scale));
struct v2 old_impulse = joint->linear_impulse;
V2 old_impulse = joint->linear_impulse;
joint->linear_impulse = v2_add(joint->linear_impulse, impulse);
joint->linear_impulse = v2_clamp_len(joint->linear_impulse, max_impulse);
@ -947,8 +947,8 @@ void phys_prepare_weld_joints(struct phys_step_ctx *ctx)
struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0;
f32 inv_m1;
@ -968,8 +968,8 @@ void phys_prepare_weld_joints(struct phys_step_ctx *ctx)
joint->inv_i1 = inv_i1;
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
joint->linear_impulse0 = V2(0, 0);
joint->linear_impulse1 = V2(0, 0);
joint->linear_impulse0 = V2FromXY(0, 0);
joint->linear_impulse1 = V2FromXY(0, 0);
joint->angular_impulse0 = 0;
joint->angular_impulse1 = 0;
#endif
@ -997,8 +997,8 @@ void phys_warm_start_weld_joints(struct phys_step_ctx *ctx)
if (sim_ent_should_simulate(e0)) {
f32 inv_m = joint->inv_m0;
f32 inv_i = joint->inv_i0;
struct xform xf = sim_ent_get_xform(e1);
struct v2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
Xform xf = sim_ent_get_xform(e1);
V2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
ent->angular_velocity += (v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i;
}
@ -1031,17 +1031,17 @@ void phys_solve_weld_joints(struct phys_step_ctx *ctx, f32 dt)
struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
struct xform xf0 = sim_ent_get_xform(e0);
struct xform xf1 = sim_ent_get_xform(e1);
Xform xf0 = sim_ent_get_xform(e0);
Xform xf1 = sim_ent_get_xform(e1);
struct xform target_xf1 = xform_mul(xf0, joint->xf0_to_xf1);
Xform target_xf1 = xform_mul(xf0, joint->xf0_to_xf1);
struct v2 v1 = e1->linear_velocity;
V2 v1 = e1->linear_velocity;
f32 w1 = e1->angular_velocity;
/* Angular constraint */
{
struct math_spring softness = math_spring_init(joint->angular_spring_hz, joint->angular_spring_damp, dt);
SoftSpring softness = math_spring_init(joint->angular_spring_hz, joint->angular_spring_damp, dt);
f32 inv_i1 = joint->inv_i1;
f32 k = 1 / inv_i1;
f32 separation = math_unwind_angle(xform_get_rotation(target_xf1) - xform_get_rotation(xf1));
@ -1054,20 +1054,20 @@ void phys_solve_weld_joints(struct phys_step_ctx *ctx, f32 dt)
/* Linear constraint */
{
struct math_spring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
SoftSpring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
f32 inv_m1 = joint->inv_m1;
struct v2 separation = v2_sub(xf1.og, target_xf1.og);
V2 separation = v2_sub(xf1.og, target_xf1.og);
f32 k = 1 / inv_m1;
struct v2 bias = v2_mul(separation, softness.bias_rate);
struct v2 b = v2_mul(v2_add(v1, bias), k);
V2 bias = v2_mul(separation, softness.bias_rate);
V2 b = v2_mul(v2_add(v1, bias), k);
struct v2 impulse = v2_mul(b, -softness.mass_scale);
V2 impulse = v2_mul(b, -softness.mass_scale);
impulse = v2_sub(impulse, v2_mul(joint->linear_impulse1, softness.impulse_scale));
struct v2 old_impulse = joint->linear_impulse1;
V2 old_impulse = joint->linear_impulse1;
joint->linear_impulse1 = v2_add(joint->linear_impulse1, impulse);
impulse = v2_sub(joint->linear_impulse1, old_impulse);
@ -1086,11 +1086,11 @@ void phys_solve_weld_joints(struct phys_step_ctx *ctx, f32 dt)
* Integration
* ========================== */
INTERNAL struct xform get_derived_xform(struct sim_ent *ent, f32 dt)
INTERNAL Xform get_derived_xform(struct sim_ent *ent, f32 dt)
{
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
struct v2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
V2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
f32 step_angular_velocity = ent->angular_velocity * dt;
xf.og = v2_add(xf.og, step_linear_velocity);
@ -1109,18 +1109,18 @@ void phys_integrate_forces(struct phys_step_ctx *ctx, f32 dt)
b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_DYNAMIC);
b32 is_kinematic = sim_ent_has_prop(ent, SEPROP_KINEMATIC);
if (is_dynamic || is_kinematic) {
struct v2 linear_velocity = ent->linear_velocity;
V2 linear_velocity = ent->linear_velocity;
f32 angular_velocity = ent->angular_velocity;
f32 linear_damping_factor = max_f32(1.0f - (ent->linear_damping * dt), 0);
f32 angular_damping_factor = max_f32(1.0f - (ent->angular_damping * dt), 0);
/* Integrate forces */
if (is_dynamic) {
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
f32 det_abs = math_fabs(xform_get_determinant(xf));
f32 mass = ent->mass_unscaled * det_abs;
f32 inertia = ent->inertia_unscaled * det_abs;
struct v2 force_accel = v2_mul(v2_div(ent->force, mass), dt);
V2 force_accel = v2_mul(v2_div(ent->force, mass), dt);
f32 torque_accel = (ent->torque / inertia) * dt;
linear_velocity = v2_add(linear_velocity, force_accel);
angular_velocity += torque_accel;
@ -1133,7 +1133,7 @@ void phys_integrate_forces(struct phys_step_ctx *ctx, f32 dt)
/* Update entity */
sim_ent_set_linear_velocity(ent, linear_velocity);
sim_ent_set_angular_velocity(ent, angular_velocity);
ent->force = V2(0, 0);
ent->force = V2FromXY(0, 0);
ent->torque = 0;
}
@ -1149,7 +1149,7 @@ void phys_integrate_velocities(struct phys_step_ctx *ctx, f32 dt)
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC) && !sim_ent_has_prop(ent, SEPROP_KINEMATIC)) continue;
struct xform xf = get_derived_xform(ent, dt);
Xform xf = get_derived_xform(ent, dt);
sim_ent_set_xform(ent, xf);
}
}
@ -1172,14 +1172,14 @@ f32 phys_determine_earliest_toi(struct phys_step_ctx *ctx, f32 step_dt, f32 tole
if (!sim_ent_has_prop(e0, SEPROP_TOI)) continue;
if (e0->local_collider.count <= 0) continue;
struct collider_shape e0_collider = e0->local_collider;
struct xform e0_xf_t0 = sim_ent_get_xform(e0);
struct xform e0_xf_t1 = get_derived_xform(e0, step_dt);
CLD_Shape e0_collider = e0->local_collider;
Xform e0_xf_t0 = sim_ent_get_xform(e0);
Xform e0_xf_t1 = get_derived_xform(e0, step_dt);
/* TODO: Use swept aabb rather than combined aabb. This should prevent spikes from bullets returning 0 positive TOIs with irrelevant entities. */
struct aabb aabb_t0 = collider_aabb_from_collider(&e0_collider, e0_xf_t0);
struct aabb aabb_t1 = collider_aabb_from_collider(&e0_collider, e0_xf_t1);
struct aabb combined_aabb = collider_aabb_from_combined_aabb(aabb_t0, aabb_t1);
Aabb aabb_t0 = collider_aabb_from_collider(&e0_collider, e0_xf_t0);
Aabb aabb_t1 = collider_aabb_from_collider(&e0_collider, e0_xf_t1);
Aabb combined_aabb = collider_aabb_from_combined_aabb(aabb_t0, aabb_t1);
struct space_iter iter = space_iter_begin_aabb(space, combined_aabb);
struct space_entry *entry;
@ -1190,9 +1190,9 @@ f32 phys_determine_earliest_toi(struct phys_step_ctx *ctx, f32 step_dt, f32 tole
if (e1->local_collider.count <= 0) continue;
if (!can_contact(e0, e1)) continue;
struct collider_shape e1_collider = e1->local_collider;
struct xform e1_xf_t0 = sim_ent_get_xform(e1);
struct xform e1_xf_t1 = get_derived_xform(e1, step_dt);
CLD_Shape e1_collider = e1->local_collider;
Xform e1_xf_t0 = sim_ent_get_xform(e1);
Xform e1_xf_t1 = get_derived_xform(e1, step_dt);
f32 t = collider_time_of_impact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations);
if (t != 0 && t < smallest_t) {
@ -1218,13 +1218,13 @@ void phys_update_aabbs(struct phys_step_ctx *ctx)
struct sim_ent *ent = &ss->ents[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (ent->local_collider.count > 0) {
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle);
if (!space_entry->valid) {
space_entry = space_entry_alloc(space, ent->id);
ent->space_handle = space_entry->handle;
}
struct aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf);
Aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf);
space_entry_update_aabb(space_entry, aabb);
}
}
@ -1248,7 +1248,7 @@ void phys_step(struct phys_step_ctx *ctx, f32 timestep)
while (remaining_dt > 0) {
__profn("Step part");
++phys_iteration;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
/* TOI */
f32 step_dt = remaining_dt;

View File

@ -6,9 +6,9 @@ struct phys_contact_constraint;
struct phys_collision_data {
struct sim_ent_id e0;
struct sim_ent_id e1;
struct v2 point;
struct v2 normal; /* Normal of the collision from e0 to e1 */
struct v2 vrel; /* Relative velocity at point of collision */
V2 point;
V2 normal; /* Normal of the collision from e0 to e1 */
V2 vrel; /* Relative velocity at point of collision */
b32 is_start; /* Did this collision just begin */
f32 dt; /* How much time elapsed in the step when this event occurred (this will equal the physics timestep unless an early time of impact occurred) */
};
@ -35,8 +35,8 @@ struct phys_contact_point {
* shouldn't really be affected by rotation accross substeps
* (imagine re-building the manifold of a rotated shape, it would still be
* on the same side of the shape that it originally occured on) */
struct v2 vcp0;
struct v2 vcp1;
V2 vcp0;
V2 vcp1;
u32 id; /* ID generated during clipping */
f32 starting_separation; /* How far are original points along normal */
@ -48,7 +48,7 @@ struct phys_contact_point {
/* Debugging */
#if DEVELOPER
struct v2 dbg_pt;
V2 dbg_pt;
#endif
};
@ -63,7 +63,7 @@ struct phys_contact_constraint {
f32 inv_i0;
f32 inv_i1;
struct v2 normal; /* Normal vector of collision from e0 -> e1 */
V2 normal; /* Normal vector of collision from e0 -> e1 */
u64 last_iteration;
struct phys_contact_point points[2];
u32 num_points;
@ -76,16 +76,16 @@ struct phys_contact_constraint {
struct phys_collision_debug {
struct sim_ent_id e0;
struct sim_ent_id e1;
struct collider_collision_points_result res;
CLD_CollisionResult res;
struct phys_contact_point points[2];
u32 num_points;
struct v2 closest0;
struct v2 closest1;
V2 closest0;
V2 closest1;
struct xform xf0;
struct xform xf1;
Xform xf0;
Xform xf1;
};
void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt, u64 phys_iteration);
@ -117,13 +117,13 @@ struct phys_motor_joint {
f32 inv_i0;
f32 inv_i1;
struct v2 linear_impulse;
V2 linear_impulse;
f32 angular_impulse;
struct v2 point_local_e0;
struct v2 point_local_e1;
V2 point_local_e0;
V2 point_local_e1;
struct xform linear_mass_xf;
Xform linear_mass_xf;
f32 angular_mass;
};
@ -139,8 +139,8 @@ void phys_solve_motor_joints(struct phys_step_ctx *ctx, f32 dt);
struct phys_mouse_joint_def {
struct sim_ent_id target;
struct v2 point_local_start;
struct v2 point_end;
V2 point_local_start;
V2 point_end;
f32 linear_spring_hz;
f32 linear_spring_damp;
f32 angular_spring_hz;
@ -150,8 +150,8 @@ struct phys_mouse_joint_def {
struct phys_mouse_joint {
struct sim_ent_id target;
struct v2 point_local_start;
struct v2 point_end;
V2 point_local_start;
V2 point_end;
f32 linear_spring_hz;
f32 linear_spring_damp;
f32 angular_spring_hz;
@ -161,10 +161,10 @@ struct phys_mouse_joint {
f32 inv_m;
f32 inv_i;
struct v2 linear_impulse;
V2 linear_impulse;
f32 angular_impulse;
struct xform linear_mass_xf;
Xform linear_mass_xf;
};
struct phys_mouse_joint_def phys_mouse_joint_def_init(void);
@ -182,8 +182,8 @@ struct phys_weld_joint_def {
struct sim_ent_id e1;
/* The xform that transforms a point in e0's space into the desired e1 space
* (IE `xf` * V2(0, 0) should evaluate to the local point that e1's origin will lie) */
struct xform xf;
* (IE `xf` * V2FromXY(0, 0) should evaluate to the local point that e1's origin will lie) */
Xform xf;
f32 linear_spring_hz;
f32 linear_spring_damp;
@ -194,7 +194,7 @@ struct phys_weld_joint_def {
struct phys_weld_joint {
struct sim_ent_id e0;
struct sim_ent_id e1;
struct xform xf0_to_xf1;
Xform xf0_to_xf1;
f32 linear_spring_hz;
f32 linear_spring_damp;
@ -206,8 +206,8 @@ struct phys_weld_joint {
f32 inv_i0;
f32 inv_i1;
struct v2 linear_impulse0;
struct v2 linear_impulse1;
V2 linear_impulse0;
V2 linear_impulse1;
f32 angular_impulse0;
f32 angular_impulse1;
};

View File

@ -19,7 +19,7 @@ struct space *space_alloc(f32 cell_size, u32 num_bins_sqrt)
{
struct space *space;
{
struct arena *arena = arena_alloc(GIBI(64));
Arena *arena = arena_alloc(GIBI(64));
space = arena_push(arena, struct space);
space->entry_arena = arena;
}
@ -69,16 +69,16 @@ struct space *space_from_entry(struct space_entry *entry)
* Cell
* ========================== */
INTERNAL struct v2i32 world_to_cell_coords(f32 cell_size, struct v2 world_pos)
INTERNAL V2i32 world_to_cell_coords(f32 cell_size, V2 world_pos)
{
f32 x = world_pos.x;
f32 y = world_pos.y;
x = (x + ((x >= 0) - (x < 0)) * cell_size) / cell_size;
y = (y + ((y >= 0) - (y < 0)) * cell_size) / cell_size;
return V2I32((i32)x, (i32)y);
return V2i32FromXY((i32)x, (i32)y);
}
INTERNAL i32 cell_coords_to_bin_index(struct space *space, struct v2i32 cell_pos)
INTERNAL i32 cell_coords_to_bin_index(struct space *space, V2i32 cell_pos)
{
i32 num_bins_sqrt = space->num_bins_sqrt;
@ -100,7 +100,7 @@ INTERNAL i32 cell_coords_to_bin_index(struct space *space, struct v2i32 cell_pos
return bin_index;
}
struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos)
struct space_cell *space_get_cell(struct space *space, V2i32 cell_pos)
{
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
struct space_cell_bin *bin = &space->bins[bin_index];
@ -114,7 +114,7 @@ struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos)
return res;
}
INTERNAL void space_cell_node_alloc(struct v2i32 cell_pos, struct space_entry *entry)
INTERNAL void space_cell_node_alloc(V2i32 cell_pos, struct space_entry *entry)
{
struct space *space = space_from_entry(entry);
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
@ -306,27 +306,27 @@ void space_entry_release(struct space_entry *entry)
space->first_free_entry = entry;
}
void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb)
void space_entry_update_aabb(struct space_entry *entry, Aabb new_aabb)
{
struct space *space = space_from_entry(entry);
f32 cell_size = space->cell_size;
struct v2i32 old_cell_p0 = V2I32(0, 0);
struct v2i32 old_cell_p1 = V2I32(0, 0);
V2i32 old_cell_p0 = V2i32FromXY(0, 0);
V2i32 old_cell_p1 = V2i32FromXY(0, 0);
if (entry->first_node) {
struct aabb old_aabb = entry->aabb;
Aabb old_aabb = entry->aabb;
old_cell_p0 = world_to_cell_coords(cell_size, old_aabb.p0);
old_cell_p1 = world_to_cell_coords(cell_size, old_aabb.p1);
}
struct v2i32 new_cell_p0 = world_to_cell_coords(cell_size, new_aabb.p0);
struct v2i32 new_cell_p1 = world_to_cell_coords(cell_size, new_aabb.p1);
V2i32 new_cell_p0 = world_to_cell_coords(cell_size, new_aabb.p0);
V2i32 new_cell_p1 = world_to_cell_coords(cell_size, new_aabb.p1);
/* Release outdated nodes */
struct space_cell_node *n = entry->first_node;
while (n) {
struct space_cell *cell = n->cell;
struct v2i32 cell_pos = cell->pos;
V2i32 cell_pos = cell->pos;
if (cell_pos.x < new_cell_p0.x || cell_pos.x > new_cell_p1.x || cell_pos.y < new_cell_p0.y || cell_pos.y > new_cell_p1.y) {
/* Cell is outside of new AABB */
struct space_cell_node *next = n->next_in_entry;
@ -342,7 +342,7 @@ void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb)
for (i32 x = new_cell_p0.x; x <= new_cell_p1.x; ++x) {
if (x != 0 && y != 0 && (x < old_cell_p0.x || x > old_cell_p1.x || y < old_cell_p0.y || y > old_cell_p1.y)) {
/* Cell is outside of old AABB */
space_cell_node_alloc(V2I32(x, y), entry);
space_cell_node_alloc(V2i32FromXY(x, y), entry);
}
}
}
@ -354,7 +354,7 @@ void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb)
* Iter
* ========================== */
struct space_iter space_iter_begin_aabb(struct space *space, struct aabb aabb)
struct space_iter space_iter_begin_aabb(struct space *space, Aabb aabb)
{
struct space_iter iter = ZI;
f32 cell_size = space->cell_size;
@ -364,7 +364,7 @@ struct space_iter space_iter_begin_aabb(struct space *space, struct aabb aabb)
iter.cell_end = world_to_cell_coords(cell_size, aabb.p1);
if (iter.cell_start.x > iter.cell_end.x || iter.cell_start.y > iter.cell_end.y) {
/* Swap cell_start & cell_end */
struct v2i32 tmp = iter.cell_start;
V2i32 tmp = iter.cell_start;
iter.cell_start = iter.cell_end;
iter.cell_end = tmp;
}
@ -380,10 +380,10 @@ struct space_iter space_iter_begin_aabb(struct space *space, struct aabb aabb)
struct space_entry *space_iter_next(struct space_iter *iter)
{
struct space *space = iter->space;
struct aabb iter_aabb = iter->aabb;
struct v2i32 cell_start = iter->cell_start;
struct v2i32 cell_end = iter->cell_end;
struct v2i32 cell_cur = iter->cell_cur;
Aabb iter_aabb = iter->aabb;
V2i32 cell_start = iter->cell_start;
V2i32 cell_end = iter->cell_end;
V2i32 cell_cur = iter->cell_cur;
i32 span = cell_end.x - cell_start.x;
struct space_cell_node *next_node = 0;
@ -399,7 +399,7 @@ struct space_entry *space_iter_next(struct space_iter *iter)
for (;;) {
if (next_node) {
struct space_entry *entry = next_node->entry;
struct aabb entry_aabb = entry->aabb;
Aabb entry_aabb = entry->aabb;
if (collider_test_aabb(entry_aabb, iter_aabb)) {
break;
} else {

View File

@ -12,7 +12,7 @@ struct space_entry {
struct space_cell_node *first_node;
struct space_cell_node *last_node;
struct aabb aabb;
Aabb aabb;
struct sim_ent_id ent;
struct space_entry *next_free;
@ -37,7 +37,7 @@ struct space_cell_node {
struct space_cell {
b32 valid;
struct v2i32 pos;
V2i32 pos;
struct space_cell_node *first_node;
struct space_cell_node *last_node;
@ -58,25 +58,25 @@ struct space {
b32 valid;
f32 cell_size;
struct arena *cell_arena;
Arena *cell_arena;
struct space_cell_bin *bins;
i32 num_bins;
i32 num_bins_sqrt;
struct space_cell *first_free_cell;
struct space_cell_node *first_free_cell_node;
struct arena *entry_arena;
Arena *entry_arena;
u64 num_entries_reserved;
struct space_entry *entries;
struct space_entry *first_free_entry;
};
struct space_iter {
struct aabb aabb;
Aabb aabb;
struct space *space;
struct v2i32 cell_start;
struct v2i32 cell_end;
struct v2i32 cell_cur;
V2i32 cell_start;
V2i32 cell_end;
V2i32 cell_cur;
struct space_cell_node *prev;
};
@ -116,7 +116,7 @@ struct space *space_from_entry(struct space_entry *entry);
* Cell
* ========================== */
struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos);
struct space_cell *space_get_cell(struct space *space, V2i32 cell_pos);
/* ========================== *
* Entry
@ -125,12 +125,12 @@ struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos);
struct space_entry *space_entry_from_handle(struct space *space, struct space_entry_handle handle);
struct space_entry *space_entry_alloc(struct space *space, struct sim_ent_id entity);
void space_entry_release(struct space_entry *entry);
void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb);
void space_entry_update_aabb(struct space_entry *entry, Aabb new_aabb);
/* ========================== *
* Iter
* ========================== */
struct space_iter space_iter_begin_aabb(struct space *space, struct aabb aabb);
struct space_iter space_iter_begin_aabb(struct space *space, Aabb aabb);
struct space_entry *space_iter_next(struct space_iter *iter);
#define space_iter_end(i)

View File

@ -88,9 +88,9 @@ INTERNAL struct sim_ent *test_spawn_chucker(struct sim_ent *parent)
zone->attach_slice = LIT("out");
sim_ent_enable_prop(zone, SEPROP_SENSOR);
struct collider_shape collider = ZI;
CLD_Shape collider = ZI;
collider.count = 2;
collider.points[1] = V2(0, -0.5);
collider.points[1] = V2FromXY(0, -0.5);
collider.radius = 0.1f;
zone->local_collider = collider;
@ -108,11 +108,11 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent)
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
struct v2 pos = V2(1, -1);
V2 pos = V2FromXY(1, -1);
//struct v2 size = V2(0.5, 0.5);
//struct v2 size = V2(0.5, 0.25);
struct v2 size = V2(1.0, 1.0);
//V2 size = V2FromXY(0.5, 0.5);
//V2 size = V2FromXY(0.5, 0.25);
V2 size = V2FromXY(1.0, 1.0);
//f32 r = PI / 4;
f32 r = 0;
@ -130,11 +130,11 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent)
e->sprite_span_name = LIT("idle.two_handed");
e->layer = SIM_LAYER_SHOULDERS;
e->local_collider.points[0] = V2(0, 0);
e->local_collider.points[0] = V2FromXY(0, 0);
e->local_collider.count = 1;
e->local_collider.radius = 0.25f;
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
//xf.bx.y = -1.f;
sim_ent_set_xform(e, xf);
@ -148,7 +148,7 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent)
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
e->sprite_emittance = V3(1, 1, 1);
e->sprite_emittance = V3FromXYZ(1, 1, 1);
@ -178,7 +178,7 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent)
employee->equipped = e->id;
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
e->sprite_emittance = V3(1, 1, 1);
e->sprite_emittance = V3FromXYZ(1, 1, 1);
}
return employee;
@ -197,13 +197,13 @@ INTERNAL struct sim_ent *test_spawn_camera(struct sim_ent *parent, struct sim_en
f32 width = (f32)DEFAULT_CAMERA_WIDTH;
f32 height = (f32)DEFAULT_CAMERA_HEIGHT;
camera_ent->camera_quad_xform = XFORM_TRS(.s = V2(width, height));
camera_ent->camera_quad_xform = XFORM_TRS(.s = V2FromXY(width, height));
}
return camera_ent;
}
INTERNAL struct sim_ent *test_spawn_explosion(struct sim_ent *parent, struct v2 pos, f32 strength, f32 radius)
INTERNAL struct sim_ent *test_spawn_explosion(struct sim_ent *parent, V2 pos, f32 strength, f32 radius)
{
struct sim_ent *ent = sim_ent_alloc_sync_src(parent);
sim_ent_set_xform(ent, XFORM_POS(pos));
@ -219,28 +219,28 @@ INTERNAL struct sim_ent *test_spawn_explosion(struct sim_ent *parent, struct v2
return ent;
}
INTERNAL void test_teleport(struct sim_ent *ent, struct v2 pos)
INTERNAL void test_teleport(struct sim_ent *ent, V2 pos)
{
//++ent->continuity_gen;
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
xf.og = pos;
sim_ent_set_xform(ent, xf);
}
INTERNAL void test_spawn_entities1(struct sim_ent *parent, struct v2 pos)
INTERNAL void test_spawn_entities1(struct sim_ent *parent, V2 pos)
{
(UNUSED)pos;
/* Enemy */
{
struct sim_ent *e = test_spawn_employee(parent);
struct xform xf = sim_ent_get_xform(e);
Xform xf = sim_ent_get_xform(e);
xf.og = pos;
sim_ent_set_xform(e, xf);
}
}
INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
INTERNAL void test_spawn_entities2(struct sim_ent *parent, V2 pos)
{
(UNUSED)pos;
@ -251,8 +251,8 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
f32 rot = 0;
struct v2 size = V2(0.125, 0.125);
struct xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size);
V2 size = V2FromXY(0.125, 0.125);
Xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size);
sim_ent_set_xform(e, xf);
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase"));
@ -262,18 +262,18 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
//e->sprite_tint = ALPHA32_F(COLOR_WHITE, 1);
sim_ent_enable_prop(e, SEPROP_SOLID);
struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1));
Quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1));
e->local_collider = collider_from_quad(collider_quad);
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
/* FIXME: Remove this */
{
static struct rand_state rand = ZI;
static RandState rand = ZI;
f32 r = rand_f64_from_state(&rand, 1, 5);
f32 g = rand_f64_from_state(&rand, 1, 5);
f32 b = rand_f64_from_state(&rand, 1, 5);
e->sprite_emittance = V3(r, g, b);
e->sprite_emittance = V3FromXYZ(r, g, b);
e->sprite_tint = RGBA32_F(r / 5, g / 5, b / 5, 1);
}
@ -293,8 +293,8 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
f32 r = PI / 4;
struct v2 size = V2(0.5, 0.25);
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
V2 size = V2FromXY(0.5, 0.25);
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf);
e->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase"));
@ -311,7 +311,7 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
#endif
}
INTERNAL void test_spawn_entities3(struct sim_ent *parent, struct v2 pos)
INTERNAL void test_spawn_entities3(struct sim_ent *parent, V2 pos)
{
(UNUSED)pos;
@ -321,8 +321,8 @@ INTERNAL void test_spawn_entities3(struct sim_ent *parent, struct v2 pos)
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
f32 r = 0;
struct v2 size = V2(1, 1);
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
V2 size = V2FromXY(1, 1);
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf);
e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
@ -331,12 +331,12 @@ INTERNAL void test_spawn_entities3(struct sim_ent *parent, struct v2 pos)
e->sprite_tint = COLOR_RED;
sim_ent_enable_prop(e, SEPROP_SOLID);
struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1));
Quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1));
e->local_collider = collider_from_quad(collider_quad);
}
}
INTERNAL void test_spawn_entities4(struct sim_ent *parent, struct v2 pos)
INTERNAL void test_spawn_entities4(struct sim_ent *parent, V2 pos)
{
(UNUSED)pos;
@ -344,8 +344,8 @@ INTERNAL void test_spawn_entities4(struct sim_ent *parent, struct v2 pos)
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
f32 r = 0;
struct v2 size = V2(2, 1);
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
V2 size = V2FromXY(2, 1);
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf);
//e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
@ -353,28 +353,28 @@ INTERNAL void test_spawn_entities4(struct sim_ent *parent, struct v2 pos)
e->layer = SIM_LAYER_SHOULDERS;
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
e->sprite_emittance = V3(2, 2, 2);
e->sprite_emittance = V3FromXYZ(2, 2, 2);
e->sprite_tint = RGB32_F(1, 1, 1);
}
INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos)
INTERNAL void test_spawn_tile(struct sim_snapshot *world, V2 world_pos)
{
#if 0
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
i32 sign_x = (world_pos.x >= 0) - (world_pos.x < 0);
i32 sign_y = (world_pos.y >= 0) - (world_pos.y < 0);
struct v2i32 tile_index = V2I32(world_pos.x * SIM_TILES_PER_UNIT_SQRT, world_pos.y * SIM_TILES_PER_UNIT_SQRT);
V2i32 tile_index = V2i32FromXY(world_pos.x * SIM_TILES_PER_UNIT_SQRT, world_pos.y * SIM_TILES_PER_UNIT_SQRT);
world_pos.x -= sign_x < 0;
world_pos.y -= sign_y < 0;
struct v2 tile_size = V2(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT);
V2 tile_size = V2FromXY(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT);
struct v2 pos = V2((f32)tile_index.x / SIM_TILES_PER_UNIT_SQRT, (f32)tile_index.y / SIM_TILES_PER_UNIT_SQRT);
pos = v2_add(pos, v2_mul(V2(tile_size.x * sign_x, tile_size.y * sign_y), 0.5));
V2 pos = V2FromXY((f32)tile_index.x / SIM_TILES_PER_UNIT_SQRT, (f32)tile_index.y / SIM_TILES_PER_UNIT_SQRT);
pos = v2_add(pos, v2_mul(V2FromXY(tile_size.x * sign_x, tile_size.y * sign_y), 0.5));
struct xform xf = XFORM_TRS(.t = pos);
Xform xf = XFORM_TRS(.t = pos);
sim_ent_set_xform(e, xf);
e->layer = SIM_LAYER_WALLS;
@ -389,10 +389,10 @@ INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos)
}
sim_ent_enable_prop(e, SEPROP_SOLID);
struct quad collider_quad = quad_from_rect(RECT(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
Quad collider_quad = quad_from_rect(RECT(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
e->local_collider = collider_from_quad(collider_quad);
#else
struct v2i32 tile_index = sim_world_tile_index_from_pos(world_pos);
V2i32 tile_index = sim_world_tile_index_from_pos(world_pos);
sim_snapshot_set_tile(world, tile_index, SIM_TILE_KIND_WALL);
#endif
}
@ -434,7 +434,7 @@ INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_y, arg_a, arg_b, udata)
INTERNAL void test_generate_walls(struct sim_snapshot *world)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
/* Release existing walls and gather tile chunks.
@ -467,25 +467,25 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
}
struct wall_node {
struct v2i32 start;
struct v2i32 end;
V2i32 start;
V2i32 end;
i32 wall_dir; /* = 0 up, 1 = right, 2 = down, 3 = left */
struct wall_node *next;
};
/* Dicts containing walls that end on edge of tile chunk, keyed by tile end index.
* Used to merge walls accross tile chunks. */
struct dict *horizontal_ends_dict = dict_init(scratch.arena, 1024);
struct dict *vertical_ends_dict = dict_init(scratch.arena, 1024);
Dict *horizontal_ends_dict = dict_init(scratch.arena, 1024);
Dict *vertical_ends_dict = dict_init(scratch.arena, 1024);
struct wall_node *first_wall = 0;
/* Generate horizontal wall nodes */
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
struct sim_ent *chunk = x_sorted_tile_chunks[sorted_index];
struct v2i32 chunk_index = chunk->tile_chunk_index;
struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y - 1));
struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y + 1));
V2i32 chunk_index = chunk->tile_chunk_index;
struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x, chunk_index.y - 1));
struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x, chunk_index.y + 1));
/* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid;
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
@ -497,17 +497,17 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
i32 desired_wall_dir = -1;
enum sim_tile_kind tile = SIM_TILE_KIND_NONE;
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y));
tile = sim_get_chunk_tile(chunk, V2i32FromXY(tile_x, tile_y));
}
if (tile_x < SIM_TILES_PER_CHUNK_SQRT) {
enum sim_tile_kind top_tile = SIM_TILE_KIND_NONE;
if (tile_y == 0) {
if (top_chunk->valid) {
struct v2i32 top_tile_local_index = V2I32(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1);
V2i32 top_tile_local_index = V2i32FromXY(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1);
top_tile = sim_get_chunk_tile(top_chunk, top_tile_local_index);
}
} else {
top_tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y - 1));
top_tile = sim_get_chunk_tile(chunk, V2i32FromXY(tile_x, tile_y - 1));
}
if (tile == SIM_TILE_KIND_WALL) {
/* Process wall tile */
@ -524,13 +524,13 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
/* Stop wall */
if (wall_dir >= 0 && desired_wall_dir != wall_dir) {
struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_start, tile_y));
struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_end, tile_y));
V2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2i32FromXY(wall_start, tile_y));
V2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2i32FromXY(wall_end, tile_y));
struct wall_node *node = 0;
if (wall_start == 0) {
u64 start_hash = rand_u64_from_seed(*(u64 *)&start);
start_hash = rand_u64_from_seeds(start_hash, wall_dir);
struct dict_entry *entry = dict_get_entry(horizontal_ends_dict, start_hash);
DictEntry *entry = dict_get_entry(horizontal_ends_dict, start_hash);
if (entry) {
/* Existing wall exists accross chunk boundary */
node = (struct wall_node *)entry->value;
@ -572,9 +572,9 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
/* Generate vertical wall nodes */
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
struct sim_ent *chunk = y_sorted_tile_chunks[sorted_index];
struct v2i32 chunk_index = chunk->tile_chunk_index;
struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x - 1, chunk_index.y));
struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x + 1, chunk_index.y));
V2i32 chunk_index = chunk->tile_chunk_index;
struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x - 1, chunk_index.y));
struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x + 1, chunk_index.y));
/* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid;
@ -586,18 +586,18 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
i32 desired_wall_dir = -1;
enum sim_tile_kind tile = SIM_TILE_KIND_NONE;
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y));
tile = sim_get_chunk_tile(chunk, V2i32FromXY(tile_x, tile_y));
}
if (tile_y < SIM_TILES_PER_CHUNK_SQRT) {
enum sim_tile_kind left_tile = SIM_TILE_KIND_NONE;
if (tile_x == 0) {
if (left_chunk->valid) {
struct v2i32 left_tile_local_index = V2I32(SIM_TILES_PER_CHUNK_SQRT - 1, tile_y);
V2i32 left_tile_local_index = V2i32FromXY(SIM_TILES_PER_CHUNK_SQRT - 1, tile_y);
left_tile = sim_get_chunk_tile(left_chunk, left_tile_local_index);
}
} else {
left_tile = sim_get_chunk_tile(chunk, V2I32(tile_x - 1, tile_y));
left_tile = sim_get_chunk_tile(chunk, V2i32FromXY(tile_x - 1, tile_y));
}
if (tile == SIM_TILE_KIND_WALL) {
/* Process wall tile */
@ -614,13 +614,13 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
/* Stop wall */
if (wall_dir >= 0 && desired_wall_dir != wall_dir) {
struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_start));
struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_end));
V2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2i32FromXY(tile_x, wall_start));
V2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2i32FromXY(tile_x, wall_end));
struct wall_node *node = 0;
if (wall_start == 0) {
u64 start_hash = rand_u64_from_seed(*(u64 *)&start);
start_hash = rand_u64_from_seeds(start_hash, wall_dir);
struct dict_entry *entry = dict_get_entry(vertical_ends_dict, start_hash);
DictEntry *entry = dict_get_entry(vertical_ends_dict, start_hash);
if (entry) {
/* Existing wall exists accross chunk boundary */
node = (struct wall_node *)entry->value;
@ -664,17 +664,17 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
struct sim_ent *wall_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(wall_ent, SEPROP_WALL);
struct v2 start = sim_pos_from_world_tile_index(node->start);
struct v2 end = sim_pos_from_world_tile_index(node->end);
V2 start = sim_pos_from_world_tile_index(node->start);
V2 end = sim_pos_from_world_tile_index(node->end);
struct xform xf = XFORM_POS(start);
Xform xf = XFORM_POS(start);
sim_ent_set_xform(wall_ent, xf);
sim_ent_enable_prop(wall_ent, SEPROP_SOLID);
wall_ent->local_collider.count = 2;
wall_ent->local_collider.points[1] = v2_sub(end, start);
struct v2 dirs[4] = { V2(0, -1), V2(1, 0), V2(0, 1), V2(-1, 0) };
V2 dirs[4] = { V2FromXY(0, -1), V2FromXY(1, 0), V2FromXY(0, 1), V2FromXY(-1, 0) };
ASSERT(node->wall_dir >= 0 && (u32)node->wall_dir < countof(dirs));
wall_ent->collision_dir = dirs[node->wall_dir];
@ -721,8 +721,8 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
/* Bullet impact */
if (sim_ent_has_prop(e0, SEPROP_BULLET)) {
struct v2 normal = data->normal; /* Impact normal */
struct v2 vrel = data->vrel; /* Impact velocity */
V2 normal = data->normal; /* Impact normal */
V2 vrel = data->vrel; /* Impact velocity */
struct sim_ent *bullet = e0;
struct sim_ent *target = e1;
@ -730,25 +730,25 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
/* Process collision if bullet already spent or * target share same top level parent */
if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top) && sim_ent_has_prop(target, SEPROP_SOLID)) {
struct v2 point = data->point;
V2 point = data->point;
/* Update tracer */
struct sim_ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
if (sim_ent_should_simulate(tracer)) {
struct xform xf = sim_ent_get_xform(tracer);
Xform xf = sim_ent_get_xform(tracer);
xf.og = point;
sim_ent_set_xform(tracer, xf);
sim_ent_set_linear_velocity(tracer, V2(0, 0));
sim_ent_set_linear_velocity(tracer, V2FromXY(0, 0));
}
/* Update target */
struct v2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
V2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
sim_ent_apply_linear_impulse(target, knockback, point);
/* Create test blood */
/* TODO: Remove this */
{
struct xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU));
Xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU));
struct sim_ent *decal = sim_ent_alloc_sync_src(root);
decal->sprite = sprite_tag_from_path(LIT("sprite/blood.ase"));
decal->sprite_tint = RGBA32_F(1, 1, 1, 0.25f);
@ -756,7 +756,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
sim_ent_set_xform(decal, xf);
f32 perp_range = 0.5;
struct v2 linear_velocity = v2_mul(normal, 0.5);
V2 linear_velocity = v2_mul(normal, 0.5);
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rand_f64_from_state(&step_ctx->rand, -perp_range, perp_range)));
f32 angular_velocity_range = 5;
@ -786,15 +786,15 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
struct sim_ent *exp = e0;
struct sim_ent *victim = e1;
struct xform xf = sim_ent_get_xform(exp);
Xform xf = sim_ent_get_xform(exp);
struct collider_shape origin_collider = ZI;
CLD_Shape origin_collider = ZI;
origin_collider.count = 1;
struct xform victim_xf = sim_ent_get_xform(victim);
struct collider_closest_points_result closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
struct v2 dir = v2_sub(closest_points.p1, closest_points.p0);
struct v2 point = closest_points.p1;
Xform victim_xf = sim_ent_get_xform(victim);
CLD_ClosestResult closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
V2 dir = v2_sub(closest_points.p1, closest_points.p0);
V2 point = closest_points.p1;
f32 distance = v2_len(dir);
#if 0
if (closest_points.colliding) {
@ -815,7 +815,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
if (distance < radius) {
const f32 falloff_curve = 3; /* Cubic falloff */
f32 strength_factor = math_pow(1 - distance/radius, falloff_curve);
struct v2 impulse = v2_with_len(dir, strength_center * strength_factor);
V2 impulse = v2_with_len(dir, strength_center * strength_factor);
sim_ent_apply_linear_impulse(victim, impulse, point);
}
}
@ -839,7 +839,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
void sim_step(struct sim_step_ctx *ctx)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
b32 is_master = ctx->is_master;
struct sim_snapshot *world = ctx->world;
@ -1032,7 +1032,7 @@ void sim_step(struct sim_step_ctx *ctx)
u32 count = 1;
f32 spread = 0;
for (u32 j = 0; j < count; ++j) {
struct v2 pos = player->player_cursor_pos;
V2 pos = player->player_cursor_pos;
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
test_spawn_entities1(root, pos);
}
@ -1042,7 +1042,7 @@ void sim_step(struct sim_step_ctx *ctx)
u32 count = 1;
f32 spread = 0;
for (u32 j = 0; j < count; ++j) {
struct v2 pos = player->player_cursor_pos;
V2 pos = player->player_cursor_pos;
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
test_spawn_entities2(root, pos);
}
@ -1052,7 +1052,7 @@ void sim_step(struct sim_step_ctx *ctx)
u32 count = 1;
f32 spread = 0;
for (u32 j = 0; j < count; ++j) {
struct v2 pos = player->player_cursor_pos;
V2 pos = player->player_cursor_pos;
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
test_spawn_entities3(root, pos);
}
@ -1062,7 +1062,7 @@ void sim_step(struct sim_step_ctx *ctx)
u32 count = 1;
f32 spread = 0;
for (u32 j = 0; j < count; ++j) {
struct v2 pos = player->player_cursor_pos;
V2 pos = player->player_cursor_pos;
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
test_spawn_entities4(root, pos);
}
@ -1088,7 +1088,7 @@ void sim_step(struct sim_step_ctx *ctx)
case SIM_CMD_KIND_CHAT:
{
struct sim_data_key msg_key = cmd_ent->cmd_chat_msg;
struct string msg = sim_data_from_key(sim_data_store, msg_key);
String msg = sim_data_from_key(sim_data_store, msg_key);
if (msg.len > 0) {
struct sim_ent *chat_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(chat_ent, SEPROP_CHAT);
@ -1206,12 +1206,12 @@ void sim_step(struct sim_step_ctx *ctx)
/* Update sprite local xform */
{
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("pivot"), ent->animation_frame);
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
V2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
struct v2 dir = v2_mul_v2(sprite_size, slice.dir);
V2 dir = v2_mul_v2(sprite_size, slice.dir);
f32 rot = v2_angle(dir) + PI / 2;
struct xform xf = XFORM_IDENT;
Xform xf = XFORM_IDENT;
xf = xform_rotated(xf, -rot);
xf = xform_scaled(xf, sprite_size);
xf = xform_translated(xf, v2_neg(slice.center));
@ -1221,7 +1221,7 @@ void sim_step(struct sim_step_ctx *ctx)
/* Update collider from sprite */
if (ent->sprite_collider_slice.len > 0) {
struct xform cxf = ent->sprite_local_xform;
Xform cxf = ent->sprite_local_xform;
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, ent->sprite_collider_slice, ent->animation_frame);
ent->local_collider = collider_from_quad(xform_mul_quad(cxf, quad_from_rect(slice.rect)));
@ -1232,24 +1232,24 @@ void sim_step(struct sim_step_ctx *ctx)
if (sim_ent_has_prop(ent, SEPROP_TEST)) {
//if ((1)) {
#if 0
ent->local_collider.points[0] = V2(0, 0);
ent->local_collider.points[0] = V2FromXY(0, 0);
ent->local_collider.count = 1;
ent->local_collider.radius = 0.5;
#elif 0
ent->local_collider.points[0] = v2_with_len(V2(0.08f, 0.17f), 0.15f);
ent->local_collider.points[1] = v2_with_len(V2(-0.07f, -0.2f), 0.15f);
ent->local_collider.points[0] = v2_with_len(V2FromXY(0.08f, 0.17f), 0.15f);
ent->local_collider.points[1] = v2_with_len(V2FromXY(-0.07f, -0.2f), 0.15f);
ent->local_collider.count = 2;
ent->local_collider.radius = 0.075f;
#elif 1
#if 0
/* "Bad" winding order */
ent->local_collider.points[0] = V2(-0.15, 0.15);
ent->local_collider.points[1] = V2(0.15, 0.15);
ent->local_collider.points[2] = V2(0, -0.15);
ent->local_collider.points[0] = V2FromXY(-0.15, 0.15);
ent->local_collider.points[1] = V2FromXY(0.15, 0.15);
ent->local_collider.points[2] = V2FromXY(0, -0.15);
#else
ent->local_collider.points[0] = V2(0, -0.15);
ent->local_collider.points[1] = V2(0.15, 0.15);
ent->local_collider.points[2] = V2(-0.15, 0.15);
ent->local_collider.points[0] = V2FromXY(0, -0.15);
ent->local_collider.points[1] = V2FromXY(0.15, 0.15);
ent->local_collider.points[2] = V2FromXY(-0.15, 0.15);
#endif
ent->local_collider.count = 3;
ent->local_collider.radius = 0.25;
@ -1276,13 +1276,13 @@ void sim_step(struct sim_step_ctx *ctx)
struct sprite_tag parent_sprite = parent->sprite;
struct sprite_sheet *parent_sheet = sprite_sheet_from_tag_await(sprite_frame_scope, parent_sprite);
struct xform parent_sprite_xf = parent->sprite_local_xform;
Xform parent_sprite_xf = parent->sprite_local_xform;
struct sprite_sheet_slice attach_slice = sprite_sheet_get_slice(parent_sheet, ent->attach_slice, parent->animation_frame);
struct v2 attach_pos = xform_mul_v2(parent_sprite_xf, attach_slice.center);
struct v2 attach_dir = xform_basis_mul_v2(parent_sprite_xf, attach_slice.dir);
V2 attach_pos = xform_mul_v2(parent_sprite_xf, attach_slice.center);
V2 attach_dir = xform_basis_mul_v2(parent_sprite_xf, attach_slice.dir);
struct xform xf = sim_ent_get_local_xform(ent);
Xform xf = sim_ent_get_local_xform(ent);
xf.og = attach_pos;
xf = xform_basis_with_rotation_world(xf, v2_angle(attach_dir) + PI / 2);
sim_ent_set_local_xform(ent, xf);
@ -1353,10 +1353,10 @@ void sim_step(struct sim_step_ctx *ctx)
struct sprite_tag sprite = ent->sprite;
u32 animation_frame = ent->animation_frame;
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
struct xform sprite_local_xform = ent->sprite_local_xform;
Xform sprite_local_xform = ent->sprite_local_xform;
struct sprite_sheet_slice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame);
struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
V2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
V2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
/* Spawn bullet */
struct sim_ent *bullet;
@ -1374,7 +1374,7 @@ void sim_step(struct sim_step_ctx *ctx)
#if 1
/* Point collider */
bullet->local_collider.points[0] = V2(0, 0);
bullet->local_collider.points[0] = V2FromXY(0, 0);
bullet->local_collider.count = 1;
#else
bullet->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase"));
@ -1400,10 +1400,10 @@ void sim_step(struct sim_step_ctx *ctx)
struct sprite_tag sprite = ent->sprite;
u32 animation_frame = ent->animation_frame;
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
struct xform sprite_local_xform = ent->sprite_local_xform;
Xform sprite_local_xform = ent->sprite_local_xform;
struct sprite_sheet_slice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame);
struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
V2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
V2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
/* Spawn bullet */
struct sim_ent *bullet;
@ -1422,7 +1422,7 @@ void sim_step(struct sim_step_ctx *ctx)
bullet->layer = SIM_LAYER_BULLETS;
/* Point collider */
bullet->local_collider.points[0] = V2(0, 0);
bullet->local_collider.points[0] = V2FromXY(0, 0);
bullet->local_collider.count = 1;
bullet->local_collider.radius = 0.05f;
@ -1453,9 +1453,9 @@ void sim_step(struct sim_step_ctx *ctx)
struct sim_ent *joint_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
struct xform xf0 = sim_ent_get_xform(ent);
struct xform xf1 = sim_ent_get_xform(target);
struct xform xf0_to_xf1 = xform_mul(xform_invert(xf0), xf1);
Xform xf0 = sim_ent_get_xform(ent);
Xform xf1 = sim_ent_get_xform(target);
Xform xf0_to_xf1 = xform_mul(xform_invert(xf0), xf1);
sim_ent_enable_prop(joint_ent, SEPROP_WELD_JOINT);
struct phys_weld_joint_def def = phys_weld_joint_def_init();
@ -1524,8 +1524,8 @@ void sim_step(struct sim_step_ctx *ctx)
if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
struct xform xf = sim_ent_get_xform(ent);
struct xform sprite_xf = xform_mul(xf, ent->sprite_local_xform);
Xform xf = sim_ent_get_xform(ent);
Xform sprite_xf = xform_mul(xf, ent->sprite_local_xform);
/* Retrieve / create aim joint */
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
@ -1555,11 +1555,11 @@ void sim_step(struct sim_step_ctx *ctx)
/* Solve for final angle using law of sines */
f32 new_angle;
{
struct v2 ent_pos = xf.og;
struct v2 focus_pos = v2_add(ent_pos, ent->control.focus);
V2 ent_pos = xf.og;
V2 focus_pos = v2_add(ent_pos, ent->control.focus);
struct v2 sprite_hold_pos;
struct v2 sprite_hold_dir;
V2 sprite_hold_pos;
V2 sprite_hold_dir;
{
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
@ -1567,23 +1567,23 @@ void sim_step(struct sim_step_ctx *ctx)
sprite_hold_dir = slice.dir;
}
struct v2 hold_dir = xform_basis_mul_v2(sprite_xf, sprite_hold_dir);
struct v2 hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
V2 hold_dir = xform_basis_mul_v2(sprite_xf, sprite_hold_dir);
V2 hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
if (v2_eq(hold_pos, ent_pos)) {
/* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */
sprite_hold_pos = v2_add(sprite_hold_pos, V2(0, -1));
sprite_hold_pos = v2_add(sprite_hold_pos, V2FromXY(0, -1));
hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
}
f32 forward_hold_angle_offset;
{
struct xform xf_unrotated = xform_basis_with_rotation_world(xf, 0);
struct v2 hold_pos_unrotated = xform_mul_v2(xf_unrotated, xform_mul_v2(ent->sprite_local_xform, sprite_hold_pos));
forward_hold_angle_offset = v2_angle_from_dirs(V2(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og));
Xform xf_unrotated = xform_basis_with_rotation_world(xf, 0);
V2 hold_pos_unrotated = xform_mul_v2(xf_unrotated, xform_mul_v2(ent->sprite_local_xform, sprite_hold_pos));
forward_hold_angle_offset = v2_angle_from_dirs(V2FromXY(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og));
}
struct v2 hold_ent_dir = v2_sub(ent_pos, hold_pos);
struct v2 focus_ent_dir = v2_sub(ent_pos, focus_pos);
V2 hold_ent_dir = v2_sub(ent_pos, hold_pos);
V2 focus_ent_dir = v2_sub(ent_pos, focus_pos);
f32 hold_ent_len = v2_len(hold_ent_dir);
f32 focus_ent_len = v2_len(focus_ent_dir);
@ -1592,13 +1592,13 @@ void sim_step(struct sim_step_ctx *ctx)
f32 final_focus_angle_btw_ent_and_hold = math_asin((math_sin(final_hold_angle_btw_ent_and_focus) * hold_ent_len) / focus_ent_len);
f32 final_ent_angle_btw_focus_and_hold = PI - (final_focus_angle_btw_ent_and_hold + final_hold_angle_btw_ent_and_focus);
new_angle = math_unwind_angle(v2_angle_from_dirs(V2(0, -1), v2_sub(focus_pos, ent_pos)) + final_ent_angle_btw_focus_and_hold - forward_hold_angle_offset);
new_angle = math_unwind_angle(v2_angle_from_dirs(V2FromXY(0, -1), v2_sub(focus_pos, ent_pos)) + final_ent_angle_btw_focus_and_hold - forward_hold_angle_offset);
}
f32 new_vel = 0;
if (!F32_IS_NAN(new_angle)) {
const f32 angle_error_allowed = 0.001f;
struct xform joint_xf = sim_ent_get_xform(joint_ent);
Xform joint_xf = sim_ent_get_xform(joint_ent);
f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf));
if (math_fabs(diff) > angle_error_allowed) {
/* Instantly snap joint ent to new angle */
@ -1653,7 +1653,7 @@ void sim_step(struct sim_step_ctx *ctx)
if (!sim_ent_should_simulate(player)) continue;
if (!sim_ent_has_prop(player, SEPROP_PLAYER)) continue;
struct v2 cursor = player->player_cursor_pos;
V2 cursor = player->player_cursor_pos;
b32 start_dragging = player->player_dbg_drag_start;
b32 stop_dragging = player->player_dbg_drag_stop;
@ -1676,7 +1676,7 @@ void sim_step(struct sim_step_ctx *ctx)
sim_ent_enable_prop(joint_ent, SEPROP_MOUSE_JOINT);
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
}
struct xform xf = sim_ent_get_xform(target_ent);
Xform xf = sim_ent_get_xform(target_ent);
struct phys_mouse_joint_def def = phys_mouse_joint_def_init();
def.target = target_ent->id;
@ -1731,11 +1731,11 @@ void sim_step(struct sim_step_ctx *ctx)
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_TRACER)) continue;
struct v2 end = sim_ent_get_xform(ent).og;
V2 end = sim_ent_get_xform(ent).og;
struct v2 tick_velocity = v2_mul(ent->tracer_start_velocity, sim_dt);
struct v2 gradient_start = v2_add(ent->tracer_gradient_start, tick_velocity);
struct v2 gradient_end = v2_add(ent->tracer_gradient_end, tick_velocity);
V2 tick_velocity = v2_mul(ent->tracer_start_velocity, sim_dt);
V2 gradient_start = v2_add(ent->tracer_gradient_start, tick_velocity);
V2 gradient_end = v2_add(ent->tracer_gradient_end, tick_velocity);
if (v2_dot(tick_velocity, v2_sub(gradient_start, end)) > 0) {
/* Tracer has disappeared */
@ -1757,14 +1757,14 @@ void sim_step(struct sim_step_ctx *ctx)
if (ent->activation_tick == world->tick) {
struct sim_ent *src = sim_ent_from_id(world, ent->bullet_src);
struct xform src_xf = sim_ent_get_xform(src);
Xform src_xf = sim_ent_get_xform(src);
/* Activate collision */
sim_ent_enable_prop(ent, SEPROP_SENSOR);
sim_ent_enable_prop(ent, SEPROP_TOI);
struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
struct v2 vel = xform_basis_mul_v2(src_xf, ent->bullet_src_dir);
V2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
V2 vel = xform_basis_mul_v2(src_xf, ent->bullet_src_dir);
vel = v2_with_len(vel, ent->bullet_launch_velocity);
#if 0
@ -1776,7 +1776,7 @@ void sim_step(struct sim_step_ctx *ctx)
}
#endif
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(vel) + PI / 2);
Xform xf = XFORM_TRS(.t = pos, .r = v2_angle(vel) + PI / 2);
sim_ent_set_xform(ent, xf);
sim_ent_enable_prop(ent, SEPROP_KINEMATIC);
@ -1814,7 +1814,7 @@ void sim_step(struct sim_step_ctx *ctx)
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_CAMERA)) continue;
struct xform xf = sim_ent_get_xform(ent);
Xform xf = sim_ent_get_xform(ent);
/* Camera follow */
{
@ -1822,16 +1822,16 @@ void sim_step(struct sim_step_ctx *ctx)
f32 aspect_ratio = 1.0;
{
struct xform quad_xf = xform_mul(sim_ent_get_xform(ent), ent->camera_quad_xform);
struct v2 camera_size = xform_get_scale(quad_xf);
Xform quad_xf = xform_mul(sim_ent_get_xform(ent), ent->camera_quad_xform);
V2 camera_size = xform_get_scale(quad_xf);
if (!v2_is_zero(camera_size)) {
aspect_ratio = camera_size.x / camera_size.y;
}
}
f32 ratio_y = 0.33f;
f32 ratio_x = ratio_y / aspect_ratio;
struct v2 camera_focus_dir = v2_mul_v2(follow->control.focus, V2(ratio_x, ratio_y));
struct v2 camera_focus_pos = v2_add(sim_ent_get_xform(follow).og, camera_focus_dir);
V2 camera_focus_dir = v2_mul_v2(follow->control.focus, V2FromXY(ratio_x, ratio_y));
V2 camera_focus_pos = v2_add(sim_ent_get_xform(follow).og, camera_focus_dir);
ent->camera_xform_target = xf;
ent->camera_xform_target.og = camera_focus_pos;
@ -1881,7 +1881,7 @@ void sim_step(struct sim_step_ctx *ctx)
* ========================== */
{
struct arena_temp temp = arena_temp_begin(scratch.arena);
TempArena temp = arena_temp_begin(scratch.arena);
struct sim_ent **stack = arena_push_no_zero(temp.arena, struct sim_ent *);
u64 stack_count = 1;

View File

@ -24,7 +24,7 @@ void sim_accel_reset(struct sim_snapshot *ss, struct sim_accel *accel);
struct sim_step_ctx {
b32 is_master;
struct sim_accel *accel;
struct rand_state rand; /* TODO: Replace with per-sim rand for deterministic rng */
RandState rand; /* TODO: Replace with per-sim rand for deterministic rng */
struct sim_snapshot *world; /* The world to simulate */
i64 sim_dt_ns; /* How much sim time should progress */

View File

@ -4,14 +4,14 @@ struct sound_task_params {
struct sound_task_params *next_free;
u32 flags;
struct asset *asset;
AC_Asset *asset;
u64 path_len;
char path_cstr[1024];
};
struct sound_task_params_store {
struct sound_task_params *head_free;
struct arena *arena;
Arena *arena;
struct snc_mutex mutex;
};
@ -27,7 +27,7 @@ GLOBAL struct {
* Startup
* ========================== */
struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr)
struct sound_startup_receipt sound_startup(AC_StartupReceipt *asset_cache_sr)
{
__prof;
(UNUSED)asset_cache_sr;
@ -71,22 +71,22 @@ INTERNAL SYS_JOB_DEF(sound_load_asset_job, job)
{
__prof;
struct sound_task_params *params = job.sig;
struct arena_temp scratch = scratch_begin_no_conflict();
struct string path = STRING(params->path_len, (u8 *)params->path_cstr);
struct asset *asset = params->asset;
TempArena scratch = scratch_begin_no_conflict();
String path = STRING(params->path_len, (u8 *)params->path_cstr);
AC_Asset *asset = params->asset;
u32 flags = params->flags;
logf_info("Loading sound \"%F\"", FMT_STR(path));
i64 start_ns = sys_time_ns();
struct string error_msg = LIT("Unknown error");
String error_msg = LIT("Unknown error");
ASSERT(string_ends_with(path, LIT(".mp3")));
/* Decode */
struct mp3_decode_result decoded = ZI;
MP3_Result decoded = ZI;
{
struct resource sound_rs = resource_open(path);
R_Resource sound_rs = resource_open(path);
if (resource_exists(&sound_rs)) {
u64 decode_flags = 0;
if (flags & SOUND_FLAG_STEREO) {
@ -107,7 +107,7 @@ INTERNAL SYS_JOB_DEF(sound_load_asset_job, job)
struct sound *sound = 0;
i16 *samples = 0;
{
struct asset_cache_store store = asset_cache_store_open();
AC_Store store = asset_cache_store_open();
sound = arena_push_no_zero(store.arena, struct sound);
samples = arena_push_array_no_zero(store.arena, i16, decoded.pcm.count);
asset_cache_store_close(&store);
@ -128,7 +128,7 @@ INTERNAL SYS_JOB_DEF(sound_load_asset_job, job)
/* Store */
struct sound *sound = 0;
{
struct asset_cache_store store = asset_cache_store_open();
AC_Store store = asset_cache_store_open();
sound = arena_push_no_zero(store.arena, struct sound);
asset_cache_store_close(&store);
}
@ -141,19 +141,19 @@ INTERNAL SYS_JOB_DEF(sound_load_asset_job, job)
scratch_end(scratch);
}
struct asset *sound_load_asset(struct string path, u32 flags, b32 wait)
AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
/* Generate and append sound flags to path key */
struct string key = string_format(scratch.arena,
String key = string_format(scratch.arena,
LIT("%F%F_sound"),
FMT_STR(path),
FMT_UINT((u64)flags));
u64 hash = asset_cache_hash(key);
b32 is_first_touch;
struct asset *asset = asset_cache_touch(key, hash, &is_first_touch);
AC_Asset *asset = asset_cache_touch(key, hash, &is_first_touch);
if (is_first_touch) {
/* Assemble task params */
@ -180,19 +180,19 @@ struct asset *sound_load_asset(struct string path, u32 flags, b32 wait)
return asset;
}
struct sound *sound_load_async(struct string path, u32 flags)
struct sound *sound_load_async(String path, u32 flags)
{
__prof;
struct asset *asset = sound_load_asset(path, flags, 0);
AC_Asset *asset = sound_load_asset(path, flags, 0);
struct sound *sound = (struct sound *)asset_cache_get_store_data(asset);
return sound;
}
struct sound *sound_load(struct string path, u32 flags)
struct sound *sound_load(String path, u32 flags)
{
__prof;
struct asset *asset = sound_load_asset(path, flags, 1);
AC_Asset *asset = sound_load_asset(path, flags, 1);
asset_cache_wait(asset);
struct sound *sound = (struct sound *)asset_cache_get_store_data(asset);
return sound;

View File

@ -1,17 +1,14 @@
#define SOUND_FLAG_NONE 0x0
#define SOUND_FLAG_STEREO 0x1
struct asset;
struct asset_cache_startup_receipt;
struct sound {
u32 flags;
struct pcm pcm;
PcmData pcm;
};
struct sound_startup_receipt { i32 _; };
struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr);
struct sound_startup_receipt sound_startup(AC_StartupReceipt *asset_cache_sr);
struct asset *sound_load_asset(struct string path, u32 flags, b32 wait);
struct sound *sound_load_async(struct string path, u32 flags);
struct sound *sound_load(struct string path, u32 flags);
AC_Asset *sound_load_asset(String path, u32 flags, b32 wait);
struct sound *sound_load_async(String path, u32 flags);
struct sound *sound_load(String path, u32 flags);

View File

@ -52,14 +52,14 @@ struct cache_entry_hash {
struct cache_entry {
enum cache_entry_kind kind;
struct cache_entry_hash hash;
struct atomic32 state;
struct atomic64_padded refcount_struct; /* Cast fetched result to `cache_refcount` */
Atomic32 state;
Atomic64Padded refcount_struct; /* Cast fetched result to `cache_refcount` */
/* Allocated data */
/* NOTE: This data is finalized once entry state = loaded */
i64 load_time_ns;
u64 memory_usage;
struct arena *arena;
Arena *arena;
struct sprite_texture *texture;
struct sprite_sheet *sheet;
@ -71,7 +71,7 @@ struct cache_entry {
struct cache_entry *next_free;
#if RESOURCE_RELOADING
struct atomic32 out_of_date; /* Has the resource changed since this entry was loaded */
Atomic32 out_of_date; /* Has the resource changed since this entry was loaded */
#endif
};
@ -82,8 +82,8 @@ struct cache_bin {
};
struct cache {
struct atomic64_padded memory_usage;
struct arena *arena;
Atomic64Padded memory_usage;
Arena *arena;
struct cache_bin *bins;
struct snc_mutex entry_pool_mutex;
struct cache_entry *entry_pool_first_free;
@ -117,7 +117,7 @@ struct load_cmd {
* ========================== */
GLOBAL struct {
struct arena *perm_arena;
Arena *perm_arena;
struct sprite_texture *nil_texture;
struct sprite_texture *loading_texture;
struct sprite_sheet *nil_sheet;
@ -128,16 +128,16 @@ GLOBAL struct {
/* Load cmds */
struct snc_mutex load_cmds_mutex;
struct arena *load_cmds_arena;
Arena *load_cmds_arena;
struct load_cmd *first_free_load_cmd;
/* Scopes */
struct snc_mutex scopes_mutex;
struct arena *scopes_arena;
Arena *scopes_arena;
struct sprite_scope *first_free_scope;
/* Evictor */
struct atomic32_padded evictor_cycle;
Atomic32Padded evictor_cycle;
struct snc_counter shutdown_counter;
b32 evictor_scheduler_shutdown;
struct snc_mutex evictor_scheduler_mutex;
@ -148,7 +148,7 @@ GLOBAL struct {
* Purple-black image
* ========================== */
INTERNAL struct image_rgba generate_purple_black_image(struct arena *arena, u32 width, u32 height)
INTERNAL ImageDataRgba generate_purple_black_image(Arena *arena, u32 width, u32 height)
{
u32 *pixels = arena_push_array_no_zero(arena, u32, width * height);
@ -175,7 +175,7 @@ INTERNAL struct image_rgba generate_purple_black_image(struct arena *arena, u32
}
}
return (struct image_rgba) {
return (ImageDataRgba) {
.width = width,
.height = height,
.pixels = pixels
@ -206,21 +206,21 @@ struct sprite_startup_receipt sprite_startup(void)
G.nil_texture = arena_push(G.perm_arena, struct sprite_texture);
G.nil_texture->loaded = 1;
{
struct arena_temp scratch = scratch_begin_no_conflict();
struct image_rgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64);
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(purple_black_image.width, purple_black_image.height), purple_black_image.pixels);
TempArena scratch = scratch_begin_no_conflict();
ImageDataRgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64);
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2i32FromXY(purple_black_image.width, purple_black_image.height), purple_black_image.pixels);
scratch_end(scratch);
}
/* Init loading sheet */
G.loading_sheet = arena_push(G.perm_arena, struct sprite_sheet);
G.loading_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.loading_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.loading_sheet->image_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.loading_sheet->frame_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
/* Init nil sheet */
G.nil_sheet = arena_push(G.perm_arena, struct sprite_sheet);
G.nil_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.nil_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.nil_sheet->image_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.nil_sheet->frame_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
G.nil_sheet->loaded = 1;
}
arena_set_readonly(G.perm_arena);
@ -258,7 +258,7 @@ INTERNAL SYS_EXIT_FUNC(sprite_shutdown)
* Tag
* ========================== */
struct sprite_tag sprite_tag_from_path(struct string path)
struct sprite_tag sprite_tag_from_path(String path)
{
struct sprite_tag res = ZI;
res.hash = hash_fnv64(HASH_FNV64_BASIS, path);
@ -318,11 +318,11 @@ INTERNAL void push_load_job(struct cache_ref ref, struct sprite_tag tag)
INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag tag)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct cache_entry *e = ref.e;
atomic32_fetch_set(&e->state, CACHE_ENTRY_STATE_WORKING);
struct string path = tag.path;
String path = tag.path;
logf_info("Loading sprite texture [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path));
b32 success = 0;
@ -337,9 +337,9 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
u64 memory_size = 0;
{
/* Decode */
struct ase_decode_image_result decoded = ZI;
Ase_DecodedImage decoded = ZI;
{
struct resource texture_rs = resource_open(path);
R_Resource texture_rs = resource_open(path);
if (resource_exists(&texture_rs)) {
decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs));
} else {
@ -355,7 +355,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
e->texture->height = decoded.image.height;
e->texture->valid = 1;
e->texture->loaded = 1;
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels);
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2i32FromXY(decoded.image.width, decoded.image.height), decoded.image.pixels);
/* TODO: Query gpu for more accurate texture size in VRAM */
memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels);
success = 1;
@ -392,15 +392,15 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
scratch_end(scratch);
}
INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, struct ase_decode_sheet_result ase)
INTERNAL struct sprite_sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
{
__prof;
struct sprite_sheet sheet = ZI;
ASSERT(ase.num_frames >= 1);
struct v2 frame_size = ase.frame_size;
struct v2 frame_center = v2_mul(ase.frame_size, 0.5f);
V2 frame_size = ase.frame_size;
V2 frame_center = v2_mul(ase.frame_size, 0.5f);
/* Init frames */
{
@ -409,16 +409,16 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
sheet.frame_size = ase.frame_size;
sheet.frames = arena_push_array(arena, struct sprite_sheet_frame, ase.num_frames);
sheet.frames_count = ase.num_frames;
for (struct ase_frame *ase_frame = ase.frame_head; ase_frame; ase_frame = ase_frame->next) {
for (Ase_Frame *ase_frame = ase.frame_head; ase_frame; ase_frame = ase_frame->next) {
u32 index = ase_frame->index;
struct v2 clip_p1 = { (f32)ase_frame->x1 / (f32)ase.image_size.x, (f32)ase_frame->y1 / (f32)ase.image_size.y };
struct v2 clip_p2 = { (f32)ase_frame->x2 / (f32)ase.image_size.x, (f32)ase_frame->y2 / (f32)ase.image_size.y };
V2 clip_p1 = { (f32)ase_frame->x1 / (f32)ase.image_size.x, (f32)ase_frame->y1 / (f32)ase.image_size.y };
V2 clip_p2 = { (f32)ase_frame->x2 / (f32)ase.image_size.x, (f32)ase_frame->y2 / (f32)ase.image_size.y };
sheet.frames[index] = (struct sprite_sheet_frame) {
.index = index,
.duration = ase_frame->duration,
.clip = (struct clip_rect) { clip_p1, clip_p2 }
.clip = (ClipRect) { clip_p1, clip_p2 }
};
}
}
@ -430,8 +430,8 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
sheet.spans = arena_push_array(arena, struct sprite_sheet_span, sheet.spans_count);
sheet.spans_dict = dict_init(arena, (u64)(ase.num_spans * SHEET_SPAN_LOOKUP_TABLE_BIN_RATIO));
u64 index = 0;
for (struct ase_span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) {
struct string name = string_copy(arena, ase_span->name);
for (Ase_Span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) {
String name = string_copy(arena, ase_span->name);
struct sprite_sheet_span *span = &sheet.spans[index];
span->name = name;
span->start = ase_span->start;
@ -445,10 +445,10 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
/* Init slices */
if (ase.num_slice_keys > 0) {
__profn("Init slices");
struct arena_temp scratch = scratch_begin(arena);
TempArena scratch = scratch_begin(arena);
struct temp_ase_slice_key_node {
struct ase_slice_key *key;
Ase_SliceKey *key;
struct temp_ase_slice_key_node *next;
u32 index_in_frame;
@ -456,7 +456,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
};
struct temp_slice_group_node {
struct string name;
String name;
u64 per_frame_count;
struct temp_ase_slice_key_node *temp_ase_slice_key_head;
struct temp_slice_group_node *next;
@ -468,9 +468,9 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
u64 num_temp_slice_group_nodes = 0;
struct temp_slice_group_node *temp_slice_group_head = 0;
{
struct dict *temp_slice_dict = dict_init(scratch.arena, (u64)(ase.num_slice_keys * 2));
for (struct ase_slice_key *ase_slice_key = ase.slice_key_head; ase_slice_key; ase_slice_key = ase_slice_key->next) {
struct string name = ase_slice_key->name;
Dict *temp_slice_dict = dict_init(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) {
String name = ase_slice_key->name;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
struct temp_slice_group_node *temp_slice_group_node = (struct temp_slice_group_node *)dict_get(temp_slice_dict, hash);
if (!temp_slice_group_node) {
@ -509,9 +509,9 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
u64 index_in_frame = 0;
for (struct temp_ase_slice_key_node *node = temp_slice_group_node->temp_ase_slice_key_head; node; node = node->next) {
struct ase_slice_key *key = node->key;
Ase_SliceKey *key = node->key;
for (struct ase_slice *ase_slice = key->slice_head; ase_slice; ase_slice = ase_slice->next) {
for (Ase_Slice *ase_slice = key->slice_head; ase_slice; ase_slice = ase_slice->next) {
u32 start = ase_slice->start;
struct sprite_sheet_slice *slice = &slice_group->frame_slices[(start * slice_group->per_frame_count) + index_in_frame];
@ -532,14 +532,14 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
f32 height = y2 - y1;
/* Rect */
struct rect rect_px = RECT(x1_px, y1_px, width_px, height_px);
struct rect rect = RECT(x1, y1, width, height);
Rect rect_px = RECT(x1_px, y1_px, width_px, height_px);
Rect rect = RECT(x1, y1, width, height);
/* Center */
struct v2 center_px = V2(x1_px + (width_px * 0.5f), y1_px + (height_px * 0.5f));
struct v2 center = V2(x1 + (width * 0.5f), y1 + (height * 0.5f));
V2 center_px = V2FromXY(x1_px + (width_px * 0.5f), y1_px + (height_px * 0.5f));
V2 center = V2FromXY(x1 + (width * 0.5f), y1 + (height * 0.5f));
/* Dir */
struct v2 dir_px = V2(center_px.x, -1);
struct v2 dir = V2(0, -1);
V2 dir_px = V2FromXY(center_px.x, -1);
V2 dir = V2FromXY(0, -1);
slice->rect_px = rect_px;
slice->center_px = center_px;
@ -569,9 +569,9 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
struct sprite_sheet_slice_group *slice_group = temp_slice_group_node->final_slice_group;
for (struct temp_ase_slice_key_node *node = temp_slice_group_node->temp_ase_slice_key_head; node; node = node->next) {
struct ase_slice_key *key = node->key;
Ase_SliceKey *key = node->key;
u32 index_in_frame = node->index_in_frame;
for (struct ase_slice *ase_slice = key->slice_head; ase_slice; ase_slice = ase_slice->next) {
for (Ase_Slice *ase_slice = key->slice_head; ase_slice; ase_slice = ase_slice->next) {
u32 start = ase_slice->start;
struct sprite_sheet_slice *slice = &slice_group->frame_slices[(start * slice_group->per_frame_count) + index_in_frame];
@ -601,12 +601,12 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
/* 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) {
struct string ray_suffix = LIT(".ray");
String ray_suffix = LIT(".ray");
struct sprite_sheet_slice_group *ray_slice_group = temp_slice_group_node->final_slice_group;
struct 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)) {
struct string point_slice_name = ray_slice_name;
String point_slice_name = ray_slice_name;
point_slice_name.len -= ray_suffix.len;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, point_slice_name);
struct sprite_sheet_slice_group *point_slice_group = (struct sprite_sheet_slice_group *)dict_get(sheet.slice_groups_dict, hash);
@ -616,8 +616,8 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
for (u32 i = 0; i < ase.num_frames; ++i) {
/* Use ray slice in ray group */
struct sprite_sheet_slice *ray_slice = &ray_slice_group->frame_slices[i * point_slices_per_frame];
struct v2 ray_end = ray_slice->center_px;
struct v2 ray_end_norm = ray_slice->center;
V2 ray_end = ray_slice->center_px;
V2 ray_end_norm = ray_slice->center;
/* Apply to each point slice in point group */
for (u32 j = 0; j < point_slices_per_frame; ++j) {
@ -641,11 +641,11 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct cache_entry *e = ref.e;
atomic32_fetch_set(&e->state, CACHE_ENTRY_STATE_WORKING);
struct string path = tag.path;
String path = tag.path;
logf_info("Loading sprite sheet [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path));
b32 success = 0;
@ -657,9 +657,9 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag
e->arena = arena_alloc(SHEET_ARENA_RESERVE);
{
/* Decode */
struct ase_decode_sheet_result decoded = ZI;
Ase_DecodedSheet decoded = ZI;
{
struct resource sheet_rs = resource_open(path);
R_Resource sheet_rs = resource_open(path);
if (resource_exists(&sheet_rs)) {
decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs));
} else {
@ -669,7 +669,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag
}
if (decoded.success) {
struct resource sheet_rs = resource_open(path);
R_Resource sheet_rs = resource_open(path);
decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs));
resource_close(&sheet_rs);
@ -720,7 +720,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag
INTERNAL void refcount_add(struct cache_entry *e, i32 amount)
{
i32 evictor_cycle = atomic32_fetch(&G.evictor_cycle.v);
struct atomic64 *refcount_atomic = &e->refcount_struct.v;
Atomic64 *refcount_atomic = &e->refcount_struct.v;
u64 old_refcount_uncast = atomic64_fetch(refcount_atomic);
for (;;) {
struct cache_refcount new_refcount = *(struct cache_refcount *)&old_refcount_uncast;
@ -1053,7 +1053,7 @@ struct sprite_sheet_frame sprite_sheet_get_frame(struct sprite_sheet *sheet, u32
return res;
}
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struct string name)
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, String name)
{
struct sprite_sheet_span res = ZI;
if (sheet->spans_count > 0) {
@ -1066,7 +1066,7 @@ struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struc
return res;
}
struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, struct string name, u32 frame_index)
struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, String name, u32 frame_index)
{
if (sheet->slice_groups_count > 0) {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
@ -1080,10 +1080,10 @@ struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, str
struct sprite_sheet_slice res = ZI;
if (string_eq(name, LIT("pivot"))) {
/* 'pivot' slice does not exist, return center */
res.center = V2(0, 0);
res.center = V2FromXY(0, 0);
res.center_px = v2_mul(sheet->frame_size, 0.5f);
res.dir_px = V2(res.center_px.x, 0);
res.dir = V2(0, -0.5);
res.dir_px = V2FromXY(res.center_px.x, 0);
res.dir = V2FromXY(0, -0.5);
} else {
res = sprite_sheet_get_slice(sheet, LIT("pivot"), frame_index);
}
@ -1091,7 +1091,7 @@ struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, str
return res;
}
struct sprite_sheet_slice_array sprite_sheet_get_slices(struct sprite_sheet *sheet, struct string name, u32 frame_index)
struct sprite_sheet_slice_array sprite_sheet_get_slices(struct sprite_sheet *sheet, String name, u32 frame_index)
{
struct sprite_sheet_slice_array res = ZI;
if (sheet->slice_groups_count > 0) {
@ -1217,7 +1217,7 @@ INTERNAL SYS_JOB_DEF(sprite_evictor_job, _)
while (!shutdown) {
{
__profn("Sprite evictor cycle");
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u64 evict_array_count = 0;
struct evict_node *evict_array = arena_push_dry(scratch.arena, struct evict_node);
{

View File

@ -14,12 +14,12 @@ struct sprite_startup_receipt sprite_startup(void);
struct sprite_tag {
u64 hash;
struct string path;
String path;
};
INLINE struct sprite_tag sprite_tag_nil(void) { return (struct sprite_tag) { 0 }; }
struct sprite_tag sprite_tag_from_path(struct string path);
struct sprite_tag sprite_tag_from_path(String path);
b32 sprite_tag_is_nil(struct sprite_tag tag);
b32 sprite_tag_eq(struct sprite_tag t1, struct sprite_tag t2);
@ -44,7 +44,7 @@ void sprite_scope_end(struct sprite_scope *scope);
struct sprite_texture {
b32 loaded;
b32 valid;
struct gp_resource *gp_texture;
G_Resource *gp_texture;
u32 width;
u32 height;
};
@ -60,19 +60,19 @@ void sprite_texture_from_tag_prefetch(struct sprite_scope *scope, struct sprite_
struct sprite_sheet {
b32 loaded;
b32 valid;
struct v2 image_size;
struct v2 frame_size;
V2 image_size;
V2 frame_size;
u32 frames_count;
struct sprite_sheet_frame *frames;
u32 spans_count;
struct sprite_sheet_span *spans;
struct dict *spans_dict;
Dict *spans_dict;
u32 slice_groups_count;
struct sprite_sheet_slice_group *slice_groups;
struct dict *slice_groups_dict;
Dict *slice_groups_dict;
};
struct sprite_sheet *sprite_sheet_from_tag_await(struct sprite_scope *scope, struct sprite_tag tag);
@ -86,11 +86,11 @@ void sprite_sheet_from_tag_prefetch(struct sprite_scope *scope, struct sprite_ta
struct sprite_sheet_frame {
u32 index;
f64 duration;
struct clip_rect clip;
ClipRect clip;
};
struct sprite_sheet_span {
struct string name;
String name;
u32 start;
u32 end;
};
@ -103,14 +103,14 @@ struct sprite_sheet_slice {
b32 has_ray;
/* Values are in the range -0.5 (top / left edge) -> +0.5 (bottom / right edge) */
struct rect rect;
struct v2 center;
struct v2 dir;
Rect rect;
V2 center;
V2 dir;
/* '_px' values retain the original sprite pixel dimensions */
struct rect rect_px;
struct v2 center_px;
struct v2 dir_px;
Rect rect_px;
V2 center_px;
V2 dir_px;
};
struct sprite_sheet_slice_array {
@ -119,7 +119,7 @@ struct sprite_sheet_slice_array {
};
struct sprite_sheet_slice_group {
struct string name;
String name;
u64 per_frame_count;
/* 2d array of slices with length (num frames) * (num slices per frame).
@ -129,10 +129,10 @@ struct sprite_sheet_slice_group {
struct sprite_sheet_frame sprite_sheet_get_frame(struct sprite_sheet *sheet, u32 index);
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struct string name);
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, String name);
/* Returns first slice with name in frame */
struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, struct string name, u32 frame_index);
struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, String name, u32 frame_index);
/* Returns all slices with name in frame */
struct sprite_sheet_slice_array sprite_sheet_get_slices(struct sprite_sheet *sheet, struct string name, u32 frame_index);
struct sprite_sheet_slice_array sprite_sheet_get_slices(struct sprite_sheet *sheet, String name, u32 frame_index);

View File

@ -82,27 +82,27 @@ struct sys_file_time {
struct sys_datetime modified;
};
struct string sys_get_write_path(struct arena *arena);
String sys_get_write_path(Arena *arena);
b32 sys_is_file(struct string path);
b32 sys_is_file(String path);
b32 sys_is_dir(struct string path);
b32 sys_is_dir(String path);
void sys_mkdir(struct string path);
void sys_mkdir(String path);
struct sys_file sys_file_open_read(struct string path);
struct sys_file sys_file_open_read(String path);
struct sys_file sys_file_open_read_wait(struct string path); /* Waits until file is not being used by another program */
struct sys_file sys_file_open_read_wait(String path); /* Waits until file is not being used by another program */
struct sys_file sys_file_open_write(struct string path);
struct sys_file sys_file_open_write(String path);
struct sys_file sys_file_open_append(struct string path);
struct sys_file sys_file_open_append(String path);
void sys_file_close(struct sys_file file);
struct string sys_file_read_all(struct arena *arena, struct sys_file file);
String sys_file_read_all(Arena *arena, struct sys_file file);
void sys_file_write(struct sys_file file, struct string data);
void sys_file_write(struct sys_file file, String data);
u64 sys_file_get_size(struct sys_file file);
@ -113,7 +113,7 @@ struct sys_file_time sys_file_get_time(struct sys_file file);
* ========================== */
struct sys_file_map {
struct string mapped_memory;
String mapped_memory;
u64 handle;
b32 valid;
};
@ -122,14 +122,14 @@ struct sys_file_map sys_file_map_open_read(struct sys_file file);
void sys_file_map_close(struct sys_file_map map);
struct string sys_file_map_data(struct sys_file_map map);
String sys_file_map_data(struct sys_file_map map);
/* ========================== *
* Dir iter
* ========================== */
struct sys_file_filter_result {
struct string filename;
String filename;
b32 is_dir;
};
@ -139,9 +139,9 @@ struct sys_file_filter {
};
/* Iterate all files in a directory */
struct sys_file_filter sys_file_filter_begin(struct arena *arena, struct string pattern);
struct sys_file_filter sys_file_filter_begin(Arena *arena, String pattern);
b32 sys_file_filter_next(struct arena *arena, struct sys_file_filter *iter);
b32 sys_file_filter_next(Arena *arena, struct sys_file_filter *iter);
void sys_file_filter_end(struct sys_file_filter *iter);
@ -161,7 +161,7 @@ enum sys_watch_info_kind {
struct sys_watch_info {
enum sys_watch_info_kind kind;
struct string name;
String name;
struct sys_watch_info *next;
struct sys_watch_info *prev;
};
@ -172,11 +172,11 @@ struct sys_watch_info_list {
u64 count;
};
struct sys_watch *sys_watch_alloc(struct string path);
struct sys_watch *sys_watch_alloc(String path);
void sys_watch_release(struct sys_watch *dw);
struct sys_watch_info_list sys_watch_read_wait(struct arena *arena, struct sys_watch *dw);
struct sys_watch_info_list sys_watch_read_wait(Arena *arena, struct sys_watch *dw);
void sys_watch_wake(struct sys_watch *dw);
@ -313,10 +313,10 @@ struct sys_window_event {
u32 text_codepoint;
/* SYS_EVENT_KIND_CURSOR_MOVE */
struct v2 cursor_position;
V2 cursor_position;
/* SYS_EVENT_KIND_MOUSE_MOVE */
struct v2 mouse_delta;
V2 mouse_delta;
};
struct sys_window_event_array {
@ -364,7 +364,7 @@ struct sys_window *sys_window_alloc(void);
void sys_window_release(struct sys_window *sys_window);
struct sys_window_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window);
struct sys_window_event_array sys_window_pop_events(Arena *arena, struct sys_window *sys_window);
void sys_window_update_settings(struct sys_window *sys_window, struct sys_window_settings *settings);
@ -372,20 +372,20 @@ struct sys_window_settings sys_window_get_settings(struct sys_window *sys_window
void sys_window_show(struct sys_window *sys_window);
struct v2 sys_window_get_size(struct sys_window *sys_window);
V2 sys_window_get_size(struct sys_window *sys_window);
struct v2 sys_window_get_monitor_size(struct sys_window *sys_window);
V2 sys_window_get_monitor_size(struct sys_window *sys_window);
/* Returns a platform specific representation of the window. E.g. `hwnd` on win32. */
u64 sys_window_get_internal_handle(struct sys_window *sys_window);
void sys_window_cursor_set_pos(struct sys_window *sys_window, struct v2 pos);
void sys_window_cursor_set_pos(struct sys_window *sys_window, V2 pos);
void sys_window_cursor_show(struct sys_window *sys_window);
void sys_window_cursor_hide(struct sys_window *sys_window);
void sys_window_cursor_enable_clip(struct sys_window *sys_window, struct rect bounds);
void sys_window_cursor_enable_clip(struct sys_window *sys_window, Rect bounds);
void sys_window_cursor_disable_clip(struct sys_window *sys_window);
@ -408,11 +408,11 @@ struct sys_address {
u16 portnb;
};
struct sys_address sys_address_from_string(struct string str);
struct sys_address sys_address_from_string(String str);
struct sys_address sys_address_from_port(u16 port);
struct string sys_string_from_address(struct arena *arena, struct sys_address address);
String sys_string_from_address(Arena *arena, struct sys_address address);
b32 sys_address_eq(struct sys_address a, struct sys_address b);
@ -423,16 +423,16 @@ b32 sys_address_eq(struct sys_address a, struct sys_address b);
struct sys_sock_read_result {
b32 valid; /* Since data.len = 0 can be valid */
struct sys_address address;
struct string data;
String data;
};
struct sys_sock *sys_sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size);
void sys_sock_release(struct sys_sock *sock);
struct sys_sock_read_result sys_sock_read(struct arena *arena, struct sys_sock *sock);
struct sys_sock_read_result sys_sock_read(Arena *arena, struct sys_sock *sock);
void sys_sock_write(struct sys_sock *sock, struct sys_address address, struct string data);
void sys_sock_write(struct sys_sock *sock, struct sys_address address, String data);
/* ========================== *
* Util
@ -445,11 +445,11 @@ enum sys_message_box_kind {
SYS_MESSAGE_BOX_KIND_FATAL
};
void sys_message_box(enum sys_message_box_kind kind, struct string message);
void sys_message_box(enum sys_message_box_kind kind, String message);
void sys_set_clipboard_text(struct string str);
void sys_set_clipboard_text(String str);
struct string sys_get_clipboard_text(struct arena *arena);
String sys_get_clipboard_text(Arena *arena);
u32 sys_num_logical_processors(void);
@ -472,11 +472,11 @@ void sys_on_exit(sys_exit_func *func);
void sys_exit(void);
/* Forcefully exits the program and displays `msg` to the user */
void sys_panic(struct string msg);
void sys_panic(String msg);
/* ========================== *
* App entry point
* ========================== */
/* Must be defined by app */
void sys_app_startup(struct string args_str);
void sys_app_startup(String args_str);

View File

@ -51,8 +51,8 @@ typedef THREAD_DEF(thread_func, data);
#define WAKE_ALL_THRESHOLD 16
struct ticket_mutex {
struct atomic64_padded ticket;
struct atomic64_padded serving;
Atomic64Padded ticket;
Atomic64Padded serving;
};
struct thread {
@ -97,19 +97,19 @@ struct win32_window {
/* FIXME: Use a cmd buffer for updating cursor (and maybe also settings).
* Current setup means cursor_set calls can be applied out of order */
u32 cursor_set_flags;
struct v2 cursor_set_position;
struct rect cursor_clip_bounds;
V2 cursor_set_position;
Rect cursor_clip_bounds;
struct atomic32 topmost_toggles;
Atomic32 topmost_toggles;
b32 is_topmost;
struct snc_mutex event_arena_swp_mutex;
i32 current_event_arena_index;
struct arena *event_arenas[2];
Arena *event_arenas[2];
struct thread *window_thread;
struct atomic32 shutdown;
Atomic32 shutdown;
struct win32_window *next_free;
};
@ -173,7 +173,7 @@ struct alignas(64) fiber {
/* ---------------------------------------------------- */
char *name_cstr; /* 08 bytes */
/* ---------------------------------------------------- */
struct atomic32 wake_lock; /* 04 bytes (4 byte alignment) */
Atomic32 wake_lock; /* 04 bytes (4 byte alignment) */
i16 id; /* 02 bytes */
i16 parent_id; /* 02 bytes */
/* ---------------------------------------------------- */
@ -231,7 +231,7 @@ struct job_info {
struct alignas(64) job_queue {
struct ticket_mutex lock;
struct arena *arena;
Arena *arena;
struct job_info *first;
struct job_info *last;
@ -247,15 +247,15 @@ struct alignas(64) job_pool {
i16 first_free_fiber_id;
/* Workers */
struct atomic32_padded workers_shutdown;
struct atomic64_padded num_jobs_in_queue;
Atomic32Padded workers_shutdown;
Atomic64Padded num_jobs_in_queue;
struct ticket_mutex workers_wake_lock;
i32 num_worker_threads;
i32 thread_priority;
u64 thread_affinity_mask;
b32 thread_is_audio;
struct arena *worker_threads_arena;
Arena *worker_threads_arena;
struct thread **worker_threads;
struct worker_ctx *worker_contexts;
};
@ -269,12 +269,12 @@ GLOBAL struct {
i64 timer_start_qpc;
i64 ns_per_qpc;
u32 main_thread_id;
struct atomic32 shutdown;
Atomic32 shutdown;
wchar_t cmdline_args_wstr[8192];
/* Application control flow */
struct atomic32 panicking;
Atomic32 panicking;
wchar_t panic_wstr[4096];
HANDLE panic_event;
HANDLE startup_end_event;
@ -286,48 +286,48 @@ GLOBAL struct {
/* Threads pool */
struct snc_mutex threads_mutex;
struct arena *threads_arena;
Arena *threads_arena;
struct thread *first_thread;
struct thread *last_thread;
struct thread *first_free_thread;
/* Watches pool */
struct snc_mutex watches_mutex;
struct arena *watches_arena;
Arena *watches_arena;
struct win32_watch *watches_first_free;
/* Windows pool */
WNDCLASSEXW window_class;
struct snc_mutex windows_mutex;
struct arena *windows_arena;
Arena *windows_arena;
struct win32_window *first_free_window;
/* Sockets pool */
WSADATA wsa_data;
struct arena *socks_arena;
Arena *socks_arena;
struct snc_mutex socks_mutex;
struct win32_sock *first_free_sock;
/* Exit funcs */
struct atomic32 num_exit_funcs;
Atomic32 num_exit_funcs;
sys_exit_func *exit_funcs[MAX_EXIT_FUNCS];
/* Scheduler */
struct atomic64_padded current_scheduler_cycle;
struct atomic64_padded current_scheduler_cycle_period_ns;
Atomic64Padded current_scheduler_cycle;
Atomic64Padded current_scheduler_cycle_period_ns;
/* Fibers */
struct ticket_mutex fibers_lock;
i16 num_fibers;
struct arena *fiber_names_arena;
Arena *fiber_names_arena;
struct fiber fibers[MAX_FIBERS];
/* Wait lists */
struct atomic64_padded waiter_wake_gen;
Atomic64Padded waiter_wake_gen;
struct ticket_mutex wait_lists_arena_lock;
struct arena *wait_lists_arena;
Arena *wait_lists_arena;
/* Wait tables */
struct wait_bin wait_addr_bins[NUM_WAIT_ADDR_BINS];
@ -394,10 +394,10 @@ INTERNAL DWORD WINAPI win32_thread_proc(LPVOID vt)
return 0;
}
INTERNAL struct thread *thread_alloc(thread_func *entry_point, void *thread_data, struct string thread_name, i32 profiler_group)
INTERNAL struct thread *thread_alloc(thread_func *entry_point, void *thread_data, String thread_name, i32 profiler_group)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
ASSERT(entry_point != 0);
logf_info("Creating thread \"%F\"", FMT_STR(thread_name));
@ -435,7 +435,7 @@ INTERNAL struct thread *thread_alloc(thread_func *entry_point, void *thread_data
t->thread_name_cstr[cstr_len] = 0;
}
{
struct string16 thread_name16 = string16_from_string(scratch.arena, thread_name);
String16 thread_name16 = string16_from_string(scratch.arena, thread_name);
u64 wstr_len = min_u64((countof(t->thread_name_wstr) - 1), thread_name16.len);
MEMCPY(t->thread_name_wstr, thread_name16.text, wstr_len * sizeof(*t->thread_name_wstr));
t->thread_name_wstr[wstr_len] = 0;
@ -715,7 +715,7 @@ INTERNAL void wake_fibers_locked(i32 num_fibers, struct fiber **fibers)
INTERNAL void wake_address(void *addr, i32 count)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u64 wait_addr_bin_index = (u64)addr % NUM_WAIT_ADDR_BINS;
struct wait_bin *wait_addr_bin = &G.wait_addr_bins[wait_addr_bin_index];
@ -766,7 +766,7 @@ INTERNAL void wake_address(void *addr, i32 count)
INTERNAL void wake_time(u64 time)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u64 wait_time_bin_index = (u64)time % NUM_WAIT_TIME_BINS;
struct wait_bin *wait_time_bin = &G.wait_time_bins[wait_time_bin_index];
@ -1195,7 +1195,7 @@ INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg)
default:
{
/* Invalid yield kind */
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
sys_panic(string_format(scratch.arena, LIT("Invalid fiber yield kind \"%F\""), FMT_SINT(yield.kind)));
scratch_end(scratch);
} break;
@ -1475,17 +1475,17 @@ i64 sys_time_ns(void)
* File system
* ========================== */
INTERNAL struct string string_from_win32_path(struct arena *arena, wchar_t *src)
INTERNAL String string_from_win32_path(Arena *arena, wchar_t *src)
{
struct string res = {
String res = {
.len = 0,
.text = arena_push_dry(arena, u8)
};
while (*src) {
struct string16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src };
struct uni_decode_utf16_result decoded = uni_decode_utf16(decode_str);
struct uni_encode_utf8_result encoded = uni_encode_utf8(decoded.codepoint);
String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src };
Utf16DecodeResult decoded = uni_decode_utf16(decode_str);
Utf8EncodeResult encoded = uni_encode_utf8(decoded.codepoint);
u8 *dest = arena_push_array_no_zero(arena, u8, encoded.count8);
for (u32 i = 0; i < encoded.count8; ++i) {
u8 byte = encoded.chars8[i];
@ -1501,7 +1501,7 @@ INTERNAL struct string string_from_win32_path(struct arena *arena, wchar_t *src)
return res;
}
struct string sys_get_write_path(struct arena *arena)
String sys_get_write_path(Arena *arena)
{
u16 *p = 0;
/* TODO: cache this? */
@ -1511,7 +1511,7 @@ struct string sys_get_write_path(struct arena *arena)
0,
&p
);
struct string path = ZI;
String path = ZI;
if (res == S_OK) {
path = string_from_win32_path(arena, p);
}
@ -1519,32 +1519,32 @@ struct string sys_get_write_path(struct arena *arena)
return path;
}
b32 sys_is_file(struct string path)
b32 sys_is_file(String path)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
DWORD attributes = GetFileAttributesW(path_wstr);
scratch_end(scratch);
return attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY);
}
b32 sys_is_dir(struct string path)
b32 sys_is_dir(String path)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
DWORD attributes = GetFileAttributesW(path_wstr);
scratch_end(scratch);
return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY);
}
void sys_mkdir(struct string path)
void sys_mkdir(String path)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
int err_code = SHCreateDirectory(0, path_wstr);
struct string err = ZI;
String err = ZI;
switch (err_code) {
case ERROR_BAD_PATHNAME:
{
@ -1569,7 +1569,7 @@ void sys_mkdir(struct string path)
default: break;
}
if (err.len > 0) {
struct string msg = string_format(scratch.arena,
String msg = string_format(scratch.arena,
LIT("Failed to create directory \"%F\": %F"),
FMT_STR(path),
FMT_STR(err));
@ -1578,10 +1578,10 @@ void sys_mkdir(struct string path)
scratch_end(scratch);
}
struct sys_file sys_file_open_read(struct string path)
struct sys_file sys_file_open_read(String path)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sys_file file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
@ -1601,10 +1601,10 @@ struct sys_file sys_file_open_read(struct string path)
return file;
}
struct sys_file sys_file_open_read_wait(struct string path)
struct sys_file sys_file_open_read_wait(String path)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sys_file file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
@ -1628,10 +1628,10 @@ struct sys_file sys_file_open_read_wait(struct string path)
return file;
}
struct sys_file sys_file_open_write(struct string path)
struct sys_file sys_file_open_write(String path)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sys_file file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
@ -1651,10 +1651,10 @@ struct sys_file sys_file_open_write(struct string path)
return file;
}
struct sys_file sys_file_open_append(struct string path)
struct sys_file sys_file_open_append(String path)
{
__prof;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sys_file file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
@ -1682,13 +1682,13 @@ void sys_file_close(struct sys_file file)
}
}
struct string sys_file_read_all(struct arena *arena, struct sys_file file)
String sys_file_read_all(Arena *arena, struct sys_file file)
{
__prof;
i64 size = 0;
GetFileSizeEx((HANDLE)file.handle, (PLARGE_INTEGER)&size);
struct string s = {
String s = {
.len = size,
.text = 0
};
@ -1710,13 +1710,13 @@ struct string sys_file_read_all(struct arena *arena, struct sys_file file)
return s;
}
void sys_file_write(struct sys_file file, struct string data)
void sys_file_write(struct sys_file file, String data)
{
__prof;
/* TODO: Check what the real data limit is and chunk sequentially based on
* that (rather than failing) */
if (data.len >= 0x7FFF) {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
sys_panic(string_format(scratch.arena,
LIT("Tried to write too many bytes to disk (%F)"),
FMT_UINT(data.len)));
@ -1832,7 +1832,7 @@ void sys_file_map_close(struct sys_file_map map)
}
}
struct string sys_file_map_data(struct sys_file_map map)
String sys_file_map_data(struct sys_file_map map)
{
return map.mapped_memory;
}
@ -1846,7 +1846,7 @@ struct win32_file_filter {
wchar_t *filter_wstr;
};
struct sys_file_filter sys_file_filter_begin(struct arena *arena, struct string pattern)
struct sys_file_filter sys_file_filter_begin(Arena *arena, String pattern)
{
struct sys_file_filter filter = ZI;
struct win32_file_filter *filter_internal = arena_push(arena, struct win32_file_filter);
@ -1855,7 +1855,7 @@ struct sys_file_filter sys_file_filter_begin(struct arena *arena, struct string
return filter;
}
b32 sys_file_filter_next(struct arena *arena, struct sys_file_filter *filter)
b32 sys_file_filter_next(Arena *arena, struct sys_file_filter *filter)
{
struct win32_file_filter *filter_internal = (struct win32_file_filter *)filter->handle;
@ -1870,7 +1870,7 @@ b32 sys_file_filter_next(struct arena *arena, struct sys_file_filter *filter)
}
if (found) {
struct string file_name = string_from_wstr_no_limit(arena, find_file_data.cFileName);
String file_name = string_from_wstr_no_limit(arena, find_file_data.cFileName);
if (string_eq(file_name, LIT(".")) || string_eq(file_name, LIT(".."))) {
/* Skip initial '.' and '..' matches */
found = sys_file_filter_next(arena, filter);
@ -1902,9 +1902,9 @@ struct win32_watch {
u8 results_buff[KIBI(64)];
};
struct sys_watch *sys_watch_alloc(struct string dir_path)
struct sys_watch *sys_watch_alloc(String dir_path)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct win32_watch *w32_watch = 0;
{
@ -1952,7 +1952,7 @@ void sys_watch_release(struct sys_watch *dw)
snc_unlock(&lock);
}
struct sys_watch_info_list sys_watch_read_wait(struct arena *arena, struct sys_watch *dw)
struct sys_watch_info_list sys_watch_read_wait(Arena *arena, struct sys_watch *dw)
{
__prof;
struct win32_watch *w32_watch = (struct win32_watch *)dw;
@ -2001,7 +2001,7 @@ struct sys_watch_info_list sys_watch_read_wait(struct arena *arena, struct sys_w
list.last = info;
++list.count;
struct string16 name16 = ZI;
String16 name16 = ZI;
name16.text = res->FileName;
name16.len = res->FileNameLength / sizeof(wchar_t);
@ -2193,7 +2193,7 @@ INTERNAL void win32_window_release(struct win32_window *window)
snc_unlock(&lock);
}
struct sys_window_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window)
struct sys_window_event_array sys_window_pop_events(Arena *arena, struct sys_window *sys_window)
{
__prof;
struct win32_window *window = (struct win32_window *)sys_window;
@ -2205,7 +2205,7 @@ struct sys_window_event_array sys_window_pop_events(struct arena *arena, struct
window->current_event_arena_index = 1 - window->current_event_arena_index;
snc_unlock(&lock);
}
struct arena *events_arena = window->event_arenas[event_arena_index];
Arena *events_arena = window->event_arenas[event_arena_index];
struct sys_window_event_array events = ZI;
events.count = events_arena->pos / sizeof(struct sys_window_event);
events.events = arena_push_array_no_zero(arena, struct sys_window_event, events.count);
@ -2330,7 +2330,7 @@ INTERNAL void win32_update_window_from_settings(struct win32_window *window, str
SetWindowPlacement(hwnd, &wp);
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr_no_limit(settings->title));
SetWindowTextW(hwnd, title_wstr);
scratch_end(scratch);
@ -2368,7 +2368,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
/* Update position */
if (cursor_flags & WIN32_WINDOW_CURSOR_SET_FLAG_POSITION) {
struct v2 window_space_pos = window->cursor_set_position;
V2 window_space_pos = window->cursor_set_position;
POINT p = { window_space_pos.x, window_space_pos.y };
ClientToScreen(window->hwnd, &p);
SetCursorPos(p.x, p.y);
@ -2483,7 +2483,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
u16 low = utf16_char;
if (high) {
u16 utf16_pair_bytes[2] = { high, low };
struct uni_decode_utf16_result decoded = uni_decode_utf16((struct string16) { .len = countof(utf16_pair_bytes), .text = utf16_pair_bytes });
Utf16DecodeResult decoded = uni_decode_utf16((String16) { .len = countof(utf16_pair_bytes), .text = utf16_pair_bytes });
if (decoded.advance16 == 2 && decoded.codepoint < U32_MAX) {
codepoint = decoded.codepoint;
}
@ -2576,14 +2576,14 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
window,
(struct sys_window_event) {
.kind = SYS_EVENT_KIND_CURSOR_MOVE,
.cursor_position = V2(x, y)
.cursor_position = V2FromXY(x, y)
}
);
} break;
/* Raw mouse move */
case WM_INPUT: {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
/* Read raw input buffer */
UINT buff_size;
@ -2599,7 +2599,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
if (raw.header.dwType == RIM_TYPEMOUSE) {
i32 x = raw.data.mouse.lLastX;
i32 y = raw.data.mouse.lLastY;
struct v2 delta = V2(x, y);
V2 delta = V2FromXY(x, y);
win32_window_process_event(
window,
(struct sys_window_event) {
@ -2680,16 +2680,16 @@ void sys_window_show(struct sys_window *sys_window)
snc_unlock(&lock);
}
struct v2 sys_window_get_size(struct sys_window *sys_window)
V2 sys_window_get_size(struct sys_window *sys_window)
{
struct win32_window *window = (struct win32_window *)sys_window;
return V2((f32)window->width, (f32)window->height);
return V2FromXY((f32)window->width, (f32)window->height);
}
struct v2 sys_window_get_monitor_size(struct sys_window *sys_window)
V2 sys_window_get_monitor_size(struct sys_window *sys_window)
{
struct win32_window *window = (struct win32_window *)sys_window;
return V2((f32)window->monitor_width, (f32)window->monitor_height);
return V2FromXY((f32)window->monitor_width, (f32)window->monitor_height);
}
u64 sys_window_get_internal_handle(struct sys_window *sys_window)
@ -2698,7 +2698,7 @@ u64 sys_window_get_internal_handle(struct sys_window *sys_window)
return (u64)window->hwnd;
}
void sys_window_cursor_set_pos(struct sys_window *sys_window, struct v2 pos)
void sys_window_cursor_set_pos(struct sys_window *sys_window, V2 pos)
{
struct win32_window *window = (struct win32_window *)sys_window;
window->cursor_set_position = pos;
@ -2720,7 +2720,7 @@ void sys_window_cursor_hide(struct sys_window *sys_window)
win32_window_wake(window);
}
void sys_window_cursor_enable_clip(struct sys_window *sys_window, struct rect bounds)
void sys_window_cursor_enable_clip(struct sys_window *sys_window, Rect bounds)
{
struct win32_window *window = (struct win32_window *)sys_window;
window->cursor_clip_bounds = bounds;
@ -2787,7 +2787,7 @@ INTERNAL struct sys_address sys_address_from_ip_port_cstr(char *ip_cstr, char *p
return res;
}
struct sys_address sys_address_from_string(struct string str)
struct sys_address sys_address_from_string(String str)
{
/* Parse string into ip & port */
u8 ip_buff[1024];
@ -2887,9 +2887,9 @@ struct sys_address sys_address_from_port(u16 port)
return res;
}
struct string sys_string_from_address(struct arena *arena, struct sys_address address)
String sys_string_from_address(Arena *arena, struct sys_address address)
{
struct string res = ZI;
String res = ZI;
if (address.family == SYS_ADDRESS_FAMILY_IPV6) {
/* TODO */
@ -3028,12 +3028,12 @@ void sys_sock_release(struct sys_sock *sock)
snc_unlock(&lock);
}
struct sys_sock_read_result sys_sock_read(struct arena *arena, struct sys_sock *sock)
struct sys_sock_read_result sys_sock_read(Arena *arena, struct sys_sock *sock)
{
struct win32_sock *ws = (struct win32_sock *)sock;
u64 read_buff_size = KIBI(64);
struct string read_buff = ZI;
String read_buff = ZI;
read_buff.len = read_buff_size;
read_buff.text = arena_push_array_no_zero(arena, u8, read_buff_size);
@ -3066,7 +3066,7 @@ struct sys_sock_read_result sys_sock_read(struct arena *arena, struct sys_sock *
return res;
}
void sys_sock_write(struct sys_sock *sock, struct sys_address address, struct string data)
void sys_sock_write(struct sys_sock *sock, struct sys_address address, String data)
{
struct win32_sock *ws = (struct win32_sock *)sock;
struct win32_address ws_addr = win32_address_from_sys_address(address);
@ -3087,9 +3087,9 @@ void sys_sock_write(struct sys_sock *sock, struct sys_address address, struct st
* Util
* ========================== */
void sys_message_box(enum sys_message_box_kind kind, struct string message)
void sys_message_box(enum sys_message_box_kind kind, String message)
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
wchar_t *message_wstr = wstr_from_string(scratch.arena, message);
const wchar_t *title = L"";
@ -3126,11 +3126,11 @@ void sys_message_box(enum sys_message_box_kind kind, struct string message)
scratch_end(scratch);
}
void sys_set_clipboard_text(struct string str)
void sys_set_clipboard_text(String str)
{
if (OpenClipboard(0)) {
struct arena_temp scratch = scratch_begin_no_conflict();
struct string16 str16 = string16_from_string(scratch.arena, str);
TempArena scratch = scratch_begin_no_conflict();
String16 str16 = string16_from_string(scratch.arena, str);
u64 str16_size_bytes = str16.len * 2;
EmptyClipboard();
HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, str16_size_bytes + 1);
@ -3146,9 +3146,9 @@ void sys_set_clipboard_text(struct string str)
}
}
struct string sys_get_clipboard_text(struct arena *arena)
String sys_get_clipboard_text(Arena *arena)
{
struct string res = ZI;
String res = ZI;
if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(0)) {
HANDLE handle = GetClipboardData(CF_UNICODETEXT);
if (handle) {
@ -3194,7 +3194,7 @@ void sys_exit(void)
SetEvent(G.exit_begin_event);
}
void sys_panic(struct string msg)
void sys_panic(String msg)
{
if (atomic32_fetch_test_set(&G.panicking, 0, 1) == 0) {
log_panic(msg);
@ -3208,12 +3208,12 @@ void sys_panic(struct string msg)
/* Perform manual string encode to avoid any implicit memory
* allocation (in case allocation is unreliable) */
struct string str8 = msg;
String str8 = msg;
u64 pos8 = 0;
while (pos8 < str8.len) {
struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining);
struct uni_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint);
String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
Utf8DecodeResult decoded = uni_decode_utf8(str8_remaining);
Utf16EncodeResult encoded = uni_encode_utf16(decoded.codepoint);
u64 wstr_new_len = wstr_len + encoded.count16;
if (wstr_new_len < (countof(G.panic_wstr) - 1)) {
u16 *dest = wstr + wstr_len;
@ -3292,9 +3292,9 @@ INTERNAL void win32_init_vk_btn_table(void)
INTERNAL SYS_JOB_DEF(sys_app_startup_job, _)
{
(UNUSED)_;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
{
struct string cmdline_args = string_from_wstr(scratch.arena, G.cmdline_args_wstr, countof(G.cmdline_args_wstr));
String cmdline_args = string_from_wstr(scratch.arena, G.cmdline_args_wstr, countof(G.cmdline_args_wstr));
sys_app_startup(cmdline_args);
SetEvent(G.startup_end_event);
}
@ -3497,7 +3497,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
__profn("Start job workers");
for (enum sys_pool pool_kind = 0; pool_kind < (i32)countof(G.job_pools); ++pool_kind) {
struct job_pool *pool = &G.job_pools[pool_kind];
struct string name_fmt = ZI;
String name_fmt = ZI;
i32 prof_group = PROF_THREAD_GROUP_FIBERS - MEBI(pool_kind);
switch (pool_kind) {
default: ASSERT(0); break;
@ -3548,7 +3548,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
struct worker_ctx *ctx = &pool->worker_contexts[i];
ctx->pool_kind = pool_kind;
ctx->id = i;
struct string name = string_format(pool->worker_threads_arena, name_fmt, FMT_SINT(i));
String name = string_format(pool->worker_threads_arena, name_fmt, FMT_SINT(i));
pool->worker_threads[i] = thread_alloc(job_worker_entry, ctx, name, prof_group + i);
}
}
@ -3632,12 +3632,12 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
if (!atomic32_fetch(&G.panicking)) {
struct snc_lock lock = snc_lock_s(&G.threads_mutex);
if (G.first_thread) {
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
u64 num_dangling_threads = 0;
struct string threads_msg = ZI;
String threads_msg = ZI;
threads_msg.text = arena_push_dry(scratch.arena, u8);
for (struct thread *t = G.first_thread; t; t = t->next) {
struct string name = string_from_cstr(t->thread_name_cstr, countof(t->thread_name_cstr));
String name = string_from_cstr(t->thread_name_cstr, countof(t->thread_name_cstr));
threads_msg.len += string_format(scratch.arena, LIT(" \"%F\"\n"), FMT_STR(name)).len;
++num_dangling_threads;
}

View File

@ -9,10 +9,10 @@ struct log_event_callback {
* ========================== */
struct shared_log_ctx {
struct atomic32 initialized;
Atomic32 initialized;
struct snc_mutex callbacks_mutex;
struct arena *callbacks_arena;
Arena *callbacks_arena;
struct log_event_callback *first_callback;
struct log_event_callback *last_callback;
@ -57,7 +57,7 @@ GLOBAL READONLY struct log_level_settings g_log_settings[LOG_LEVEL_COUNT] = {
* Startup
* ========================== */
void log_startup(struct string logfile_path)
void log_startup(String logfile_path)
{
__prof;
struct shared_log_ctx *ctx = &g_shared_log_ctx;
@ -101,15 +101,15 @@ void log_register_callback(log_event_callback_func *func, i32 level)
* Log
* ========================== */
INTERNAL void append_to_logfile(struct string msg)
INTERNAL void append_to_logfile(String msg)
{
__prof;
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
if (ctx->file_valid) {
struct arena_temp scratch = scratch_begin_no_conflict();
struct string msg_line = string_cat(scratch.arena, msg, LIT("\n"));
TempArena scratch = scratch_begin_no_conflict();
String msg_line = string_cat(scratch.arena, msg, LIT("\n"));
sys_file_write(ctx->file, msg_line);
scratch_end(scratch);
}
@ -117,7 +117,7 @@ INTERNAL void append_to_logfile(struct string msg)
/* Panic log function is separate to enforce zero side effects other than
* writing to log file. */
void _log_panic(struct string msg)
void _log_panic(String msg)
{
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
@ -130,9 +130,9 @@ void _log_panic(struct string msg)
}
#if LOG_INCLUDE_SOURCE_LOCATION
void _log(i32 level, struct string file, u32 line, struct string msg)
void _log(i32 level, String file, u32 line, String msg)
#else
void _log(i32 level, struct string msg)
void _log(i32 level, String msg)
#endif
{
__prof;
@ -143,7 +143,7 @@ void _log(i32 level, struct string msg)
sys_panic(LIT("Invalid log level"));
}
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct sys_datetime datetime = sys_local_time();
i64 time_ns = sys_time_ns();
@ -151,10 +151,10 @@ void _log(i32 level, struct string msg)
u32 tid = sys_current_thread_id();
struct log_level_settings settings = g_log_settings[level];
struct string shorthand = settings.shorthand;
String shorthand = settings.shorthand;
#if LOG_INCLUDE_SOURCE_LOCATION
struct string msg_formatted = string_format(
String msg_formatted = string_format(
scratch.arena,
LIT("[%F:%F:%F.%F] |%F| [%F] <%F:%F> %F"),
@ -178,7 +178,7 @@ void _log(i32 level, struct string msg)
FMT_STR(msg)
);
#else
struct string msg_formatted = string_format(
String msg_formatted = string_format(
scratch.arena,
LIT("[%F:%F:%F.%F] |%F| [%F] %F"),
@ -228,15 +228,15 @@ void _log(i32 level, struct string msg)
}
#if LOG_INCLUDE_SOURCE_LOCATION
void _logfv(i32 level, struct string file, u32 line, struct string fmt, va_list args)
void _logfv(i32 level, String file, u32 line, String fmt, va_list args)
#else
void _logfv(i32 level, struct string fmt, va_list args)
void _logfv(i32 level, String fmt, va_list args)
#endif
{
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
struct arena_temp scratch = scratch_begin_no_conflict();
struct string msg = string_formatv(scratch.arena, fmt, args);
TempArena scratch = scratch_begin_no_conflict();
String msg = string_formatv(scratch.arena, fmt, args);
#if LOG_INCLUDE_SOURCE_LOCATION
_log(level, file, line, msg);
#else
@ -246,9 +246,9 @@ void _logfv(i32 level, struct string fmt, va_list args)
}
#if LOG_INCLUDE_SOURCE_LOCATION
void _logf(i32 level, struct string file, u32 line, struct string fmt, ...)
void _logf(i32 level, String file, u32 line, String fmt, ...)
#else
void _logf(i32 level, struct string fmt, ...)
void _logf(i32 level, String fmt, ...)
#endif
{
struct shared_log_ctx *ctx = &g_shared_log_ctx;

View File

@ -28,20 +28,20 @@
* ========================== */
struct log_level_settings {
struct string shorthand;
String shorthand;
u32 color;
};
struct log_event {
/* Msg lifetime is only as long as callback duration */
struct string msg;
String msg;
i32 level;
struct sys_datetime datetime;
i64 time_ns;
/* These will be zeroed if LOG_INCLUDE_SOURCE_LOCATION is disabled */
struct string file;
String file;
i32 line;
};
@ -138,24 +138,24 @@ void log_register_callback(log_event_callback_func *func, i32 level);
* Function declarations
* ========================== */
void log_startup(struct string logfile_path);
void log_startup(String logfile_path);
void _log_panic(struct string msg);
void _log_panic(String msg);
#if LOG_INCLUDE_SOURCE_LOCATION
void _log(i32 level, struct string file, u32 line, struct string msg);
void _log(i32 level, String file, u32 line, String msg);
#else
void _log(i32 level, struct string msg);
void _log(i32 level, String msg);
#endif
#if LOG_INCLUDE_SOURCE_LOCATION
void _logfv(i32 level, struct string file, u32 line, struct string fmt, va_list args);
void _logfv(i32 level, String file, u32 line, String fmt, va_list args);
#else
void _logfv(i32 level, struct string fmt, va_list args);
void _logfv(i32 level, String fmt, va_list args);
#endif
#if LOG_INCLUDE_SOURCE_LOCATION
void _logf(i32 level, struct string file, u32 line, struct string fmt, ...);
void _logf(i32 level, String file, u32 line, String fmt, ...);
#else
void _logf(i32 level, struct string fmt, ...);
void _logf(i32 level, String fmt, ...);
#endif

View File

@ -12,10 +12,10 @@ struct alignas(64) snc_mutex {
* Bit 30 = Exclusive lock is pending
* Bit 0-30 = Shared locks count
*/
struct atomic32 v;
Atomic32 v;
#if RTC
struct atomic32 exclusive_fiber_id;
Atomic32 exclusive_fiber_id;
u8 _pad[56];
#else
u8 _pad[60];
@ -43,7 +43,7 @@ void snc_unlock(struct snc_lock *lock);
* ========================== */
struct alignas(64) snc_cv {
struct atomic64 wake_gen;
Atomic64 wake_gen;
u8 _pad[56];
};
STATIC_ASSERT(sizeof(struct snc_cv) == 64); /* Padding validation */
@ -58,7 +58,7 @@ void snc_cv_signal(struct snc_cv *cv, i32 count);
* ========================== */
struct alignas(64) snc_counter {
struct atomic64 v;
Atomic64 v;
u8 _pad[56];
};
STATIC_ASSERT(sizeof(struct snc_counter) == 64); /* Padding validation */

View File

@ -44,7 +44,7 @@ PACK(struct tar_header {
u8 padding[12];
});
INTERNAL u64 str_oct_to_u64(struct string str)
INTERNAL u64 str_oct_to_u64(String str)
{
u64 n = 0;
for (u64 i = 0; i < str.len; ++i) {
@ -59,13 +59,13 @@ INTERNAL u64 str_oct_to_u64(struct string str)
* NOTE: The resulting archive merely points into the supplied tar data, no
* copying is done. Accessing the archive assumes that the data string is still valid.
*/
struct tar_archive tar_parse(struct arena *arena, struct string data, struct string prefix)
struct tar_archive tar_parse(Arena *arena, String data, String prefix)
{
__prof;
struct tar_archive archive = ZI;
struct bitbuff bb = bitbuff_from_string(data);
struct bitbuff_reader br = br_from_bitbuff_no_debug(&bb);
Bitbuff bb = bitbuff_from_string(data);
BitbuffReader br = br_from_bitbuff_no_debug(&bb);
u64 num_files = 0;
while (br_num_bytes_left(&br) > 1024) {
@ -85,14 +85,14 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str
continue;
}
struct string file_size_oct_str = { .len = 11, .text = header.file_size };
String file_size_oct_str = { .len = 11, .text = header.file_size };
u64 file_size = str_oct_to_u64(file_size_oct_str);
u8 *file_data_ptr = br_read_bytes_raw(&br, file_size);
if (!file_data_ptr) {
file_size = 0;
}
struct string file_data = STRING(file_size, file_data_ptr);
String file_data = STRING(file_size, file_data_ptr);
/* Skip sector padding */
u64 remaining = (512 - (file_size % 512)) % 512;
@ -106,13 +106,13 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str
continue;
}
struct string file_name_cstr = string_from_cstr_no_limit((char *)header.file_name);
String file_name_cstr = string_from_cstr_no_limit((char *)header.file_name);
if (file_name_cstr.len >= 2) {
/* Chop off './' prefix */
file_name_cstr.len -= 2;
file_name_cstr.text += 2;
}
struct string file_name = string_cat(arena, prefix, file_name_cstr);
String file_name = string_cat(arena, prefix, file_name_cstr);
struct tar_entry *entry = arena_push(arena, struct tar_entry);
entry->valid = 1;
@ -140,7 +140,7 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str
if (!entry->is_dir) {
/* Find parent entry */
struct tar_entry *parent_entry = 0;
for (struct 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] == '/') {
u64 hash = hash_fnv64(HASH_FNV64_BASIS, parent_dir_name);
parent_entry = (struct tar_entry *)dict_get(archive.lookup, hash);
@ -159,7 +159,7 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str
}
READONLY GLOBAL struct tar_entry g_nil_tar_entry = ZI;
struct tar_entry *tar_get(struct tar_archive *archive, struct string name)
struct tar_entry *tar_get(struct tar_archive *archive, String name)
{
u64 hash = hash_fnv64(HASH_FNV64_BASIS, name);
struct tar_entry *lookup = (struct tar_entry *)dict_get(archive->lookup, hash);

View File

@ -1,7 +1,7 @@
struct tar_entry {
b32 valid;
struct string file_name;
struct string data;
String file_name;
String data;
b32 is_dir;
struct tar_entry *next;
@ -9,9 +9,9 @@ struct tar_entry {
};
struct tar_archive {
struct dict *lookup;
Dict *lookup;
struct tar_entry *head;
};
struct tar_archive tar_parse(struct arena *arena, struct string data, struct string prefix);
struct tar_entry *tar_get(struct tar_archive *archive, struct string name);
struct tar_archive tar_parse(Arena *arena, String data, String prefix);
struct tar_entry *tar_get(struct tar_archive *archive, String name);

View File

@ -1,12 +1,23 @@
struct font_glyph;
struct ttf_decode_result {
struct font_glyph *glyphs;
u16 glyphs_count;
u16 *cache_indices; /* Array of indices into the `glyphs` array in order of `cache_chars` */
struct image_rgba image_data;
typedef struct TTF_Glyph TTF_Glyph;
struct TTF_Glyph {
f32 off_x;
f32 off_y;
i32 advance;
f32 width;
f32 height;
Rect atlas_rect;
};
struct ttf_startup_receipt { i32 _; };
struct ttf_startup_receipt ttf_startup(void);
struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded, f32 point_size, u32 *cache_codes, u32 cache_codes_count);
typedef struct TTF_Result TTF_Result;
struct TTF_Result {
TTF_Glyph *glyphs;
u16 glyphs_count;
u16 *cache_indices; /* Array of indices into the `glyphs` array in order of `cache_chars` */
ImageDataRgba image_data;
};
typedef struct TTF_StartupReceipt TTF_StartupReceipt;
struct TTF_StartupReceipt { i32 _; };
TTF_StartupReceipt ttf_startup(void);
TTF_Result ttf_decode(Arena *arena, String encoded, f32 point_size, u32 *cache_codes, u32 cache_codes_count);

View File

@ -1,11 +1,6 @@
/* Based on Allen Webster's dwrite rasterizer example -
* https://github.com/4th-dimention/examps */
extern "C"
{
#include "../font/font.h"
}
#pragma warning(push, 0)
# include <dwrite.h>
# include <dwrite_3.h>
@ -26,7 +21,7 @@ extern "C"
GLOBAL struct {
/* FIXME: Do we need to wrap this in a mutex? */
IDWriteFactory5 *factory;
} G = ZI, DEBUG_ALIAS(G, L_ttf_dwrite);
} G = ZI, DEBUG_ALIAS(G, G_ttf_dwrite);
/* ========================== *
* Decode font
@ -42,7 +37,7 @@ INTERNAL i32 round_up(f32 x)
}
/* Call this during font system startup */
struct ttf_startup_receipt ttf_startup(void)
TTF_StartupReceipt ttf_startup(void)
{
__prof;
ASSERT(!G.factory);
@ -71,7 +66,7 @@ struct ttf_startup_receipt ttf_startup(void)
return { 0 };
}
struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded, f32 point_size, u32 *cache_codes, u32 cache_codes_count)
TTF_Result ttf_decode(Arena *arena, String encoded, f32 point_size, u32 *cache_codes, u32 cache_codes_count)
{
__prof;
COLORREF bg_color = RGB32(0,0,0);
@ -157,7 +152,7 @@ struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded,
}
/* Allocate font memory */
struct font_glyph *glyphs = (struct font_glyph *)arena_push_array(arena, struct font_glyph, glyph_count);
TTF_Glyph *glyphs = (TTF_Glyph *)arena_push_array(arena, TTF_Glyph, glyph_count);
/* Allocate (starting) atlas memory
* NOTE: This is unecessary since atlas memory will grow anyway. Could
@ -210,7 +205,7 @@ struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded,
i32 tex_w = bounding_box.right - bounding_box.left;
i32 tex_h = bounding_box.bottom - bounding_box.top;
struct font_glyph *glyph = &glyphs[i];
TTF_Glyph *glyph = &glyphs[i];
glyph->off_x = off_x;
glyph->off_y = off_y;
glyph->advance = round_up(advance);
@ -297,7 +292,7 @@ struct ttf_decode_result ttf_decode(struct arena *arena, struct string encoded,
factory->Release();
/* Return */
struct ttf_decode_result result = ZI;
TTF_Result result = ZI;
result.glyphs = glyphs;
result.glyphs_count = glyph_count;
result.cache_indices = cache_indices;

View File

@ -8,7 +8,7 @@
#include "../font/font.h"
#include "../collider/collider.h"
#include "../draw/draw.h"
#include "../host/host.h"
#include "../net/net.h"
#include "user_core.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,5 @@
struct font_startup_receipt;
struct sprite_startup_receipt;
struct draw_startup_receipt;
struct asset_cache_startup_receipt;
struct sound_startup_receipt;
struct mixer_startup_receipt;
struct host_startup_receipt;
struct sim_startup_receipt;
enum user_bind_kind {
@ -57,12 +52,12 @@ enum user_bind_kind {
};
struct user_startup_receipt { i32 _; };
struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr,
struct user_startup_receipt user_startup(F_StartupReceipt *font_sr,
struct sprite_startup_receipt *sprite_sr,
struct draw_startup_receipt *draw_sr,
struct asset_cache_startup_receipt *asset_cache_sr,
D_StartupReceipt *draw_sr,
AC_StartupReceipt *asset_cache_sr,
struct sound_startup_receipt *sound_sr,
struct mixer_startup_receipt *mixer_sr,
struct host_startup_receipt *host_sr,
M_StartupReceipt *mixer_sr,
N_StartupReceipt *host_sr,
struct sim_startup_receipt *sim_sr,
struct string connect_address_str);
String connect_address_str);

View File

@ -1,17 +1,17 @@
#if RESOURCE_RELOADING
struct watch_event {
struct string name;
String name;
struct watch_event *next;
};
GLOBAL struct {
struct sys_watch *watch;
struct atomic32 watch_shutdown;
Atomic32 watch_shutdown;
struct snc_counter watch_jobs_counter;
struct snc_mutex watch_dispatcher_mutex;
struct arena *watch_events_arena;
Arena *watch_events_arena;
struct watch_event *first_watch_event;
struct watch_event *last_watch_event;
struct snc_cv watch_dispatcher_cv;
@ -74,21 +74,21 @@ void watch_register_callback(watch_callback *callback)
INTERNAL SYS_JOB_DEF(watch_monitor_job, _)
{
(UNUSED)_;
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct string ignored[] = {
String ignored[] = {
LIT(".vs"),
LIT(".git")
};
while (!atomic32_fetch(&G.watch_shutdown)) {
struct arena_temp temp = arena_temp_begin(scratch.arena);
TempArena temp = arena_temp_begin(scratch.arena);
struct sys_watch_info_list info_list = sys_watch_read_wait(temp.arena, G.watch);
if (info_list.first && !atomic32_fetch(&G.watch_shutdown)) {
struct snc_lock lock = snc_lock_e(&G.watch_dispatcher_mutex);
{
for (struct sys_watch_info *info = info_list.first; info; info = info->next) {
struct string name_src = info->name;
String name_src = info->name;
b32 ignore = 0;
for (u32 i = 0; i < countof(ignored); ++i) {
if (string_starts_with(name_src, ignored[i])) {
@ -125,7 +125,7 @@ INTERNAL SYS_JOB_DEF(watch_monitor_job, _)
#define WATCH_DISPATCHER_DEDUP_DICT_BINS 128
struct watch_callback_job_sig {
struct string name;
String name;
watch_callback **callbacks;
};
@ -133,7 +133,7 @@ INTERNAL SYS_JOB_DEF(watch_callback_job, job)
{
__prof;
struct watch_callback_job_sig *sig = job.sig;
struct string name = sig->name;
String name = sig->name;
watch_callback *callback = sig->callbacks[job.id];
callback(name);
}
@ -145,7 +145,7 @@ INTERNAL SYS_JOB_DEF(watch_dispatcher_job, _)
b32 shutdown = 0;
while (!shutdown) {
{
struct arena_temp scratch = scratch_begin_no_conflict();
TempArena scratch = scratch_begin_no_conflict();
struct watch_event *first_watch_event = 0;
struct watch_event *last_watch_event = 0;
@ -189,7 +189,7 @@ INTERNAL SYS_JOB_DEF(watch_dispatcher_job, _)
/* Run callbacks */
{
struct dict *dedup_dict = dict_init(scratch.arena, WATCH_DISPATCHER_DEDUP_DICT_BINS);
Dict *dedup_dict = dict_init(scratch.arena, WATCH_DISPATCHER_DEDUP_DICT_BINS);
for (struct watch_event *e = first_watch_event; e; e = e->next) {
__profn("Dispatch");
/* Do not run callbacks for the same file more than once */

View File

@ -1,4 +1,4 @@
#define WATCH_CALLBACK_FUNC_DEF(func_name, arg_name) void func_name(struct string arg_name)
#define WATCH_CALLBACK_FUNC_DEF(func_name, arg_name) void func_name(String arg_name)
typedef WATCH_CALLBACK_FUNC_DEF(watch_callback, name);
void watch_startup(void);