working sheet cache prototype

This commit is contained in:
jacob 2024-04-24 18:19:19 -05:00
parent f72c05297b
commit e3830fccae
25 changed files with 806 additions and 1793 deletions

View File

@ -83,9 +83,9 @@ INTERNAL struct sys_window_settings default_window_settings(struct sys_window *w
struct v2 monitor_size = sys_window_get_monitor_size(window); struct v2 monitor_size = sys_window_get_monitor_size(window);
i32 width = 1280; i32 width = 1280;
i32 height = math_round(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT)); i32 height = math_round_to_int(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
i32 x = math_round(monitor_size.x / 2.f - width / 2); i32 x = math_round_to_int(monitor_size.x / 2.f - width / 2);
i32 y = math_round(monitor_size.y / 2.f - height / 2); i32 y = math_round_to_int(monitor_size.y / 2.f - height / 2);
return (struct sys_window_settings) { return (struct sys_window_settings) {
.title = WINDOW_TITLE, .title = WINDOW_TITLE,

View File

@ -10,6 +10,7 @@
* memory. */ * memory. */
struct arena arena_alloc(u64 reserve) struct arena arena_alloc(u64 reserve)
{ {
__prof;
struct arena arena = { 0 }; struct arena arena = { 0 };
/* Round up to nearest block size */ /* Round up to nearest block size */
@ -43,6 +44,7 @@ struct arena arena_alloc(u64 reserve)
void arena_release(struct arena *arena) void arena_release(struct arena *arena)
{ {
__prof;
sys_memory_decommit(arena->base, arena->committed); sys_memory_decommit(arena->base, arena->committed);
sys_memory_release(arena->base); sys_memory_release(arena->base);
} }
@ -91,7 +93,7 @@ void *_arena_push_bytes(struct arena *arena, u64 size, u64 align)
} }
/* Copies the memory from the source arena into the destination arena, /* Copies the memory from the source arena into the destination arena,
* replacing old contents. Destination arena will be expanded if necessary contents. */ * replacing old contents. Destination arena will be expanded if necessary. */
void arena_copy_replace(struct arena *dest, struct arena *src) void arena_copy_replace(struct arena *dest, struct arena *src)
{ {
arena_reset(dest); arena_reset(dest);

View File

@ -9,6 +9,7 @@
#include "scratch.h" #include "scratch.h"
#include "byteio.h" #include "byteio.h"
#include "string.h" #include "string.h"
#include "log.h"
/* ========================== * /* ========================== *
* Bitbuf * Bitbuf
@ -383,9 +384,6 @@ INTERNAL void inflate(struct arena *arena, u8 *dest, u8 *encoded)
* Decoder structs * Decoder structs
* ========================== */ * ========================== */
#define LAYER_FLAG_NONE 0x0
#define LAYER_FLAG_VISIBLE 0x1
enum chunk_type { enum chunk_type {
CHUNK_TYPE_OLD_PALETTE1 = 0x0004, CHUNK_TYPE_OLD_PALETTE1 = 0x0004,
CHUNK_TYPE_OLD_PALETTE2 = 0x0011, CHUNK_TYPE_OLD_PALETTE2 = 0x0011,
@ -444,6 +442,7 @@ struct frame_header {
INTERNAL void push_error_copy_msg(struct arena *arena, struct ase_error_list *list, struct string msg_src) INTERNAL void push_error_copy_msg(struct arena *arena, struct ase_error_list *list, struct string msg_src)
{ {
logf_error("Error while decoding .ase: \"%F\"", FMT_STR(msg_src));
struct ase_error *e = arena_push(arena, struct ase_error); struct ase_error *e = arena_push(arena, struct ase_error);
*e = (struct ase_error) { *e = (struct ase_error) {
.msg = string_copy(arena, msg_src) .msg = string_copy(arena, msg_src)

View File

@ -9,6 +9,7 @@ FORCE_INLINE i32 atomic_i32_dec_eval(struct atomic_i32 *x) { return _Interlocked
FORCE_INLINE i32 atomic_i32_eval_add(struct atomic_i32 *x, i32 a) { return _InterlockedExchangeAdd((volatile long *)&x->_v, a); } FORCE_INLINE i32 atomic_i32_eval_add(struct atomic_i32 *x, i32 a) { return _InterlockedExchangeAdd((volatile long *)&x->_v, a); }
FORCE_INLINE i32 atomic_i32_eval_exchange(struct atomic_i32 *x, i32 e) { return _InterlockedExchange((volatile long *)&x->_v, e); } FORCE_INLINE i32 atomic_i32_eval_exchange(struct atomic_i32 *x, i32 e) { return _InterlockedExchange((volatile long *)&x->_v, e); }
FORCE_INLINE i32 atomic_i32_eval_compare_exchange(struct atomic_i32 *x, i32 c, i32 e) { return _InterlockedCompareExchange((volatile long *)&x->_v, e, c); } FORCE_INLINE i32 atomic_i32_eval_compare_exchange(struct atomic_i32 *x, i32 c, i32 e) { return _InterlockedCompareExchange((volatile long *)&x->_v, e, c); }
FORCE_INLINE volatile i32 *atomic_i32_raw(struct atomic_i32 *x) { return &x->_v; }
FORCE_INLINE i64 atomic_i64_eval(struct atomic_i64 *x) { return _InterlockedOr64(&x->_v, 0); } FORCE_INLINE i64 atomic_i64_eval(struct atomic_i64 *x) { return _InterlockedOr64(&x->_v, 0); }
FORCE_INLINE i64 atomic_i64_inc_eval(struct atomic_i64 *x) { return _InterlockedIncrement64(&x->_v); } FORCE_INLINE i64 atomic_i64_inc_eval(struct atomic_i64 *x) { return _InterlockedIncrement64(&x->_v); }
@ -16,6 +17,7 @@ FORCE_INLINE i64 atomic_i64_dec_eval(struct atomic_i64 *x) { return _Interlocked
FORCE_INLINE i64 atomic_i64_eval_add(struct atomic_i64 *x, i64 a) { return _InterlockedExchangeAdd64(&x->_v, a); } FORCE_INLINE i64 atomic_i64_eval_add(struct atomic_i64 *x, i64 a) { return _InterlockedExchangeAdd64(&x->_v, a); }
FORCE_INLINE i64 atomic_i64_eval_exchange(struct atomic_i64 *x, i64 e) { return _InterlockedExchange64(&x->_v, e); } FORCE_INLINE i64 atomic_i64_eval_exchange(struct atomic_i64 *x, i64 e) { return _InterlockedExchange64(&x->_v, e); }
FORCE_INLINE i64 atomic_i64_eval_compare_exchange(struct atomic_i64 *x, i64 c, i64 e) { return _InterlockedCompareExchange64(&x->_v, e, c); } FORCE_INLINE i64 atomic_i64_eval_compare_exchange(struct atomic_i64 *x, i64 c, i64 e) { return _InterlockedCompareExchange64(&x->_v, e, c); }
FORCE_INLINE volatile i64 *atomic_i64_raw(struct atomic_i64 *x) { return &x->_v; }
FORCE_INLINE u32 atomic_u32_eval(struct atomic_u32 *x) { return _InterlockedExchangeAdd((volatile long *)&x->_v, 0); } FORCE_INLINE u32 atomic_u32_eval(struct atomic_u32 *x) { return _InterlockedExchangeAdd((volatile long *)&x->_v, 0); }
FORCE_INLINE u32 atomic_u32_inc_eval(struct atomic_u32 *x) { return _InterlockedIncrement((volatile long *)&x->_v); } FORCE_INLINE u32 atomic_u32_inc_eval(struct atomic_u32 *x) { return _InterlockedIncrement((volatile long *)&x->_v); }
@ -23,6 +25,7 @@ FORCE_INLINE u32 atomic_u32_dec_eval(struct atomic_u32 *x) { return _Interlocked
FORCE_INLINE u32 atomic_u32_eval_add(struct atomic_u32 *x, u32 a) { return _InterlockedExchangeAdd((volatile long *)&x->_v, a); } FORCE_INLINE u32 atomic_u32_eval_add(struct atomic_u32 *x, u32 a) { return _InterlockedExchangeAdd((volatile long *)&x->_v, a); }
FORCE_INLINE u32 atomic_u32_eval_exchange(struct atomic_u32 *x, u32 e) { return _InterlockedExchange((volatile long *)&x->_v, e); } FORCE_INLINE u32 atomic_u32_eval_exchange(struct atomic_u32 *x, u32 e) { return _InterlockedExchange((volatile long *)&x->_v, e); }
FORCE_INLINE u32 atomic_u32_eval_compare_exchange(struct atomic_u32 *x, u32 c, u32 e) { return _InterlockedCompareExchange((volatile long *)&x->_v, e, c); } FORCE_INLINE u32 atomic_u32_eval_compare_exchange(struct atomic_u32 *x, u32 c, u32 e) { return _InterlockedCompareExchange((volatile long *)&x->_v, e, c); }
FORCE_INLINE volatile u32 *atomic_u32_raw(struct atomic_u32 *x) { return &x->_v; }
FORCE_INLINE u64 atomic_u64_eval(struct atomic_u64 *x) { return _InterlockedOr64((volatile i64 *)&x->_v, 0); } FORCE_INLINE u64 atomic_u64_eval(struct atomic_u64 *x) { return _InterlockedOr64((volatile i64 *)&x->_v, 0); }
FORCE_INLINE u64 atomic_u64_inc_eval(struct atomic_u64 *x) { return _InterlockedIncrement64((volatile i64 *)&x->_v); } FORCE_INLINE u64 atomic_u64_inc_eval(struct atomic_u64 *x) { return _InterlockedIncrement64((volatile i64 *)&x->_v); }
@ -30,9 +33,11 @@ FORCE_INLINE u64 atomic_u64_dec_eval(struct atomic_u64 *x) { return _Interlocked
FORCE_INLINE u64 atomic_u64_eval_add(struct atomic_u64 *x, u64 a) { return _InterlockedExchangeAdd64((volatile i64 *)&x->_v, a); } FORCE_INLINE u64 atomic_u64_eval_add(struct atomic_u64 *x, u64 a) { return _InterlockedExchangeAdd64((volatile i64 *)&x->_v, a); }
FORCE_INLINE u64 atomic_u64_eval_exchange(struct atomic_u64 *x, u64 e) { return _InterlockedExchange64((volatile i64 *)&x->_v, e); } FORCE_INLINE u64 atomic_u64_eval_exchange(struct atomic_u64 *x, u64 e) { return _InterlockedExchange64((volatile i64 *)&x->_v, e); }
FORCE_INLINE u64 atomic_u64_eval_compare_exchange(struct atomic_u64 *x, u64 c, u64 e) { return _InterlockedCompareExchange64((volatile i64 *)&x->_v, e, c); } FORCE_INLINE u64 atomic_u64_eval_compare_exchange(struct atomic_u64 *x, u64 c, u64 e) { return _InterlockedCompareExchange64((volatile i64 *)&x->_v, e, c); }
FORCE_INLINE volatile u64 *atomic_u64_raw(struct atomic_u64 *x) { return &x->_v; }
FORCE_INLINE void *atomic_ptr_eval(struct atomic_ptr *x) { return (void *)_InterlockedOr64((volatile i64 *)&x->_v, 0); } FORCE_INLINE void *atomic_ptr_eval(struct atomic_ptr *x) { return (void *)_InterlockedOr64((volatile i64 *)&x->_v, 0); }
FORCE_INLINE void *atomic_ptr_eval_compare_exchange(struct atomic_ptr *x, void *c, void *e) { return (void *)_InterlockedCompareExchange64((volatile i64 *)&x->_v, (i64)e, (i64)c); } FORCE_INLINE void *atomic_ptr_eval_compare_exchange(struct atomic_ptr *x, void *c, void *e) { return (void *)_InterlockedCompareExchange64((volatile i64 *)&x->_v, (i64)e, (i64)c); }
FORCE_INLINE volatile void **atomic_ptr_raw(struct atomic_ptr *x) { return &x->_v; }
#else #else
# error "Atomics not implemented" # error "Atomics not implemented"

View File

@ -192,6 +192,8 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#endif #endif
#define ARRAY_COUNT(a) (sizeof(a) / sizeof((a)[0])) #define ARRAY_COUNT(a) (sizeof(a) / sizeof((a)[0]))
/* field macros */
#define FIELD_SIZEOF(type, field) sizeof(((type *)0)->field) #define FIELD_SIZEOF(type, field) sizeof(((type *)0)->field)
#if COMPILER_MSVC && !defined _CRT_USE_BUILTIN_OFFSETOF #if COMPILER_MSVC && !defined _CRT_USE_BUILTIN_OFFSETOF
# define FIELD_OFFSETOF(type, field) ((u64)&(((type *)0)->field)) # define FIELD_OFFSETOF(type, field) ((u64)&(((type *)0)->field))
@ -199,8 +201,6 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
# define FIELD_OFFSETOF(type, field) __builtin_offsetof(type, field) # define FIELD_OFFSETOF(type, field) __builtin_offsetof(type, field)
#endif #endif
#define FIELD_SIZEOF(type, field) sizeof(((type *)0)->field)
/* Bool */ /* Bool */
#ifndef __cplusplus #ifndef __cplusplus
# define true 1 # define true 1
@ -288,8 +288,7 @@ typedef u64 umm;
#define I64_MIN ((i64)-0x8000000000000000LL) #define I64_MIN ((i64)-0x8000000000000000LL)
#define F32_INFINITY (1.0 / 0.0f) #define F32_INFINITY (1.0 / 0.0f)
#define F32_MAX (3.402823466e+38F) #define F64_INFINITY (1.0 / 0.0)
#define F32_MIN (1.175494351e-38F)
#define PI ((f32)3.14159265358979323846) #define PI ((f32)3.14159265358979323846)
#define TAU ((f32)6.28318530717958647693) #define TAU ((f32)6.28318530717958647693)

View File

@ -1,6 +1,7 @@
#ifndef ENTITY_H #ifndef ENTITY_H
#define ENTITY_H #define ENTITY_H
#include "mixer.h"
#include "sheet.h" #include "sheet.h"
#include "mixer.h" #include "mixer.h"
@ -66,6 +67,7 @@ struct entity {
/* Sprite */ /* Sprite */
struct string sprite_name; struct string sprite_name;
struct sheet_tag sprite_sheet_tag;
struct string sprite_span_name; struct string sprite_span_name;
struct xform sprite_quad_xform; struct xform sprite_quad_xform;
u32 sprite_tint; u32 sprite_tint;

View File

@ -162,7 +162,7 @@ INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams)
logf_info("Finished loading font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts))); logf_info("Finished loading font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts)));
asset_cache_mark_ready(asset, font); asset_cache_mark_ready(asset, font);
scratch_end_and_decommit(scratch); scratch_end(scratch);
} }
/* Returns the asset from the asset cache */ /* Returns the asset from the asset cache */

View File

@ -157,6 +157,12 @@ INTERNAL void game_update(void)
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
/* ========================== *
* Begin frame cache scopes
* ========================== */
struct sheet_scope *sheet_frame_scope = sheet_scope_begin();
/* TODO: remove this (testing) */ /* TODO: remove this (testing) */
/* Initialize entities */ /* Initialize entities */
static b32 run = 0; static b32 run = 0;
@ -176,9 +182,18 @@ INTERNAL void game_update(void)
struct string sprite_name = STR("res/graphics/tim.ase"); struct string sprite_name = STR("res/graphics/tim.ase");
struct string sprite_span_name = STR("UNARMED"); struct string sprite_span_name = STR("UNARMED");
struct sheet *sheet = sheet_load(sprite_name); struct sheet_tag sprite_sheet_tag = sheet_tag_from_path(sprite_name);
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT; f32 meters_width, meters_height;
{
struct sheet_scope *scope = sheet_scope_begin();
{
struct sheet *sheet = sheet_from_tag_await(scope, sprite_sheet_tag);
meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
}
sheet_scope_end(scope);
}
struct v2 sprite_pos = V2(0, 0); struct v2 sprite_pos = V2(0, 0);
f32 sprite_rot = 0; f32 sprite_rot = 0;
@ -198,6 +213,7 @@ INTERNAL void game_update(void)
e->sprite_quad_xform = sprite_xf; e->sprite_quad_xform = sprite_xf;
e->sprite_name = sprite_name; e->sprite_name = sprite_name;
e->sprite_sheet_tag = sprite_sheet_tag;
e->sprite_span_name = sprite_span_name; e->sprite_span_name = sprite_span_name;
e->sprite_tint = COLOR_WHITE; e->sprite_tint = COLOR_WHITE;
@ -227,9 +243,18 @@ INTERNAL void game_update(void)
struct string sprite_name = STR("res/graphics/tim.ase"); struct string sprite_name = STR("res/graphics/tim.ase");
struct string sprite_span_name = STR("UNARMED"); struct string sprite_span_name = STR("UNARMED");
struct sheet *sheet = sheet_load(sprite_name); struct sheet_tag sprite_sheet_tag = sheet_tag_from_path(sprite_name);
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT; f32 meters_width, meters_height;
{
struct sheet_scope *scope = sheet_scope_begin();
{
struct sheet *sheet = sheet_from_tag_await(scope, sprite_sheet_tag);
meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
}
sheet_scope_end(scope);
}
struct v2 sprite_pos = V2(0, 0); struct v2 sprite_pos = V2(0, 0);
f32 sprite_rot = 0; f32 sprite_rot = 0;
@ -249,6 +274,7 @@ INTERNAL void game_update(void)
e->sprite_quad_xform = sprite_xf; e->sprite_quad_xform = sprite_xf;
e->sprite_name = sprite_name; e->sprite_name = sprite_name;
e->sprite_sheet_tag = sprite_sheet_tag;
e->sprite_span_name = sprite_span_name; e->sprite_span_name = sprite_span_name;
e->sprite_tint = RGBA_F(0.5, 0.5, 0, 1); e->sprite_tint = RGBA_F(0.5, 0.5, 0, 1);
@ -296,14 +322,24 @@ INTERNAL void game_update(void)
e->rel_xform = XFORM_POS(V2(-3, -3)); e->rel_xform = XFORM_POS(V2(-3, -3));
struct string sprite_name = STR("res/graphics/sound.ase"); struct string sprite_name = STR("res/graphics/sound.ase");
struct sheet *sheet = sheet_load(sprite_name); struct sheet_tag sprite_sheet_tag = sheet_tag_from_path(sprite_name);
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT; f32 meters_width, meters_height;
{
struct sheet_scope *scope = sheet_scope_begin();
{
struct sheet *sheet = sheet_from_tag_await(scope, sprite_sheet_tag);
meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
}
sheet_scope_end(scope);
}
struct v2 sprite_size = V2(meters_width, meters_height); struct v2 sprite_size = V2(meters_width, meters_height);
e->sprite_quad_xform = xform_with_scale(XFORM_IDENT, sprite_size); e->sprite_quad_xform = xform_with_scale(XFORM_IDENT, sprite_size);
e->sprite_name = sprite_name; e->sprite_name = sprite_name;
e->sprite_sheet_tag = sprite_sheet_tag;
e->sprite_tint = RGBA_F(1, 1, 0, 1); e->sprite_tint = RGBA_F(1, 1, 0, 1);
entity_enable_prop(e, ENTITY_PROP_TEST_SOUND_EMITTER); entity_enable_prop(e, ENTITY_PROP_TEST_SOUND_EMITTER);
@ -380,33 +416,29 @@ INTERNAL void game_update(void)
* Update animation * Update animation
* ========================== */ * ========================== */
#if 0
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) { if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt; f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
u64 span_frame_offset = ent->animation_frame; u64 span_frame_offset = ent->animation_frame;
struct sheet *sheet = sheet_load(ent->sprite_name); struct sheet *sheet = sheet_from_tag_await(sheet_frame_scope, ent->sprite_sheet_tag);
if (sheet) { struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name); u64 frame_index = span.start + span_frame_offset;
u64 frame_index = span.start + span_frame_offset;
struct sheet_frame frame = sheet_get_frame(sheet, frame_index); struct sheet_frame frame = sheet_get_frame(sheet, frame_index);
while (time_in_frame > frame.duration) { while (time_in_frame > frame.duration) {
time_in_frame -= frame.duration; time_in_frame -= frame.duration;
++frame_index; ++frame_index;
if (frame_index > span.end) { if (frame_index > span.end) {
/* Loop animation */ /* Loop animation */
frame_index = span.start; frame_index = span.start;
}
frame = sheet_get_frame(sheet, frame_index);
} }
span_frame_offset = frame_index - span.start; frame = sheet_get_frame(sheet, frame_index);
} }
span_frame_offset = frame_index - span.start;
ent->animation_time_in_frame = time_in_frame; ent->animation_time_in_frame = time_in_frame;
ent->animation_frame = span_frame_offset; ent->animation_frame = span_frame_offset;
} }
#endif
/* ========================== * /* ========================== *
* Test * Test
@ -579,6 +611,12 @@ INTERNAL void game_update(void)
publish_game_tick(); publish_game_tick();
__profframe("Game"); __profframe("Game");
/* ========================== *
* End frame cache scopes
* ========================== */
sheet_scope_end(sheet_frame_scope);
scratch_end(scratch); scratch_end(scratch);
} }

View File

@ -5,6 +5,8 @@
* Math * Math
* ========================== */ * ========================== */
/* Sqrt */
INLINE f32 ix_sqrt_f32(f32 f) INLINE f32 ix_sqrt_f32(f32 f)
{ {
__m128 n = _mm_set_ss(f); __m128 n = _mm_set_ss(f);
@ -19,25 +21,82 @@ INLINE f32 ix_rsqrt_f32(f32 f)
return _mm_cvtss_f32(n); return _mm_cvtss_f32(n);
} }
/* Round */
INLINE i32 ix_round_f32_to_i32(f32 f) INLINE i32 ix_round_f32_to_i32(f32 f)
{ {
__m128 n = _mm_set_ss(f); return _mm_cvtss_si32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
n = _mm_round_ss(_mm_setzero_ps(), n, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
return _mm_cvtss_si32(n);
} }
INLINE f32 ix_round_f32_to_f32(f32 f)
{
return _mm_cvtss_f32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
INLINE i64 ix_round_f64_to_i64(f64 f)
{
return _mm_cvtsd_si64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
INLINE f64 ix_round_f64_to_f64(f64 f)
{
return _mm_cvtsd_f64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
/* Floor */
INLINE i32 ix_floor_f32_to_i32(f32 f) INLINE i32 ix_floor_f32_to_i32(f32 f)
{ {
__m128 n = _mm_set_ss(f); return _mm_cvtss_si32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f)));
n = _mm_floor_ss(_mm_setzero_ps(), n);
return _mm_cvtss_si32(n);
} }
INLINE f32 ix_floor_f32_to_f32(f32 f)
{
return _mm_cvtss_f32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
INLINE i64 ix_floor_f64_to_i64(f64 f)
{
return _mm_cvtsd_si64(_mm_floor_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
INLINE f64 ix_floor_f64_to_f64(f64 f)
{
return _mm_cvtsd_f64(_mm_floor_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
/* Ceil */
INLINE i32 ix_ceil_f32_to_i32(f32 f) INLINE i32 ix_ceil_f32_to_i32(f32 f)
{ {
__m128 n = _mm_set_ss(f); return _mm_cvtss_si32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f)));
n = _mm_ceil_ss(_mm_setzero_ps(), n); }
return _mm_cvtss_si32(n);
INLINE f32 ix_ceil_f32_to_f32(f32 f)
{
return _mm_cvtss_f32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
INLINE i64 ix_ceil_f64_to_i64(f64 f)
{
return _mm_cvtsd_si64(_mm_ceil_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
INLINE f64 ix_ceil_f64_to_f64(f64 f)
{
return _mm_cvtsd_f64(_mm_ceil_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
/* Truncate */
INLINE f32 ix_trunc_f32_to_f32(f32 f)
{
return _mm_cvtss_f32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));
}
INLINE f64 ix_trunc_f64_to_f64(f64 f)
{
return _mm_cvtsd_f64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));
} }
/* ========================== * /* ========================== *

View File

@ -1,34 +1,109 @@
#ifndef MATH_H #ifndef MATH_H
#define MATH_H #define MATH_H
/* Math functions are default 32 bit (f32, i32, etc) unless specified */
#include "intrinsics.h" #include "intrinsics.h"
INLINE f32 math_sqrt(f32 x); INLINE f32 math_sqrt(f32 x);
/* ========================== * /* ========================== *
* Rounding * Float rounding
* ========================== */ * ========================== */
/* TODO: Don't use intrinsics for these. */ /* TODO: Don't use intrinsics for these. */
INLINE i32 math_round(f32 f) /* Round */
INLINE f32 math_round(f32 f)
{
return ix_round_f32_to_f32(f);
}
INLINE f64 math_round64(f64 f)
{
return ix_round_f64_to_f64(f);
}
INLINE i32 math_round_to_int(f32 f)
{ {
return ix_round_f32_to_i32(f); return ix_round_f32_to_i32(f);
} }
INLINE i32 math_floor(f32 f) INLINE i64 math_round_to_int64(f64 f)
{
return ix_round_f64_to_i64(f);
}
/* Floor */
INLINE f32 math_floor(f32 f)
{
return ix_floor_f32_to_f32(f);
}
INLINE f64 math_floor64(f64 f)
{
return ix_floor_f64_to_f64(f);
}
INLINE i32 math_floor_to_int(f32 f)
{ {
return ix_floor_f32_to_i32(f); return ix_floor_f32_to_i32(f);
} }
INLINE i32 math_ceil(f32 f)
INLINE i64 math_floor_to_int64(f64 f)
{
return ix_floor_f64_to_i64(f);
}
/* Ceil */
INLINE f32 math_ceil(f32 f)
{
return ix_ceil_f32_to_f32(f);
}
INLINE f64 math_ceil64(f64 f)
{
return ix_ceil_f64_to_f64(f);
}
INLINE i32 math_ceil_to_int(f32 f)
{ {
return ix_ceil_f32_to_i32(f); return ix_ceil_f32_to_i32(f);
} }
INLINE i64 math_ceil_to_int64(f64 f)
{
return ix_ceil_f64_to_i64(f);
}
/* Truncate */
INLINE f32 math_trunc(f32 f)
{
return ix_trunc_f32_to_f32(f);
}
INLINE f64 math_trunc64(f64 f)
{
return ix_trunc_f64_to_f64(f);
}
/* ========================== *
* Float properties
* ========================== */
INLINE f32 math_fmod(f32 x, f32 m) INLINE f32 math_fmod(f32 x, f32 m)
{ {
return x - m * (i32)(x / m); return x - m * math_trunc(x / m);
}
INLINE f64 math_fmod64(f64 x, f64 m)
{
return x - m * math_trunc64(x / m);
} }
INLINE f32 math_fabs(f32 f) INLINE f32 math_fabs(f32 f)
@ -37,12 +112,24 @@ INLINE f32 math_fabs(f32 f)
return *(f32 *)&truncated; return *(f32 *)&truncated;
} }
INLINE f64 math_fabs64(f64 f)
{
u64 truncated = *(u64 *)&f & 0x7FFFFFFFFFFFFFFFULL;
return *(f64 *)&truncated;
}
INLINE i32 math_fsign(f32 f) INLINE i32 math_fsign(f32 f)
{ {
u32 sign_bit = (*(u32 *)&f >> 31) & 1; u32 sign_bit = (*(u32 *)&f >> 31) & 1;
return 1 + -(sign_bit << 1); return 1 + -(sign_bit << 1);
} }
INLINE i64 math_fsign64(f64 f)
{
u64 sign_bit = (*(u64 *)&f >> 63) & 1;
return 1 + -(sign_bit << 1);
}
/* ========================== * /* ========================== *
* Exponential * Exponential
* ========================== */ * ========================== */
@ -288,7 +375,7 @@ INLINE f32 math_pow(f32 a, f32 b)
return math_exp(math_ln(a) * b); return math_exp(math_ln(a) * b);
} else { } else {
/* a is negative */ /* a is negative */
i32 res_sign = math_round(b) % 2 == 0 ? 1 : -1; i32 res_sign = math_round_to_int(b) % 2 == 0 ? 1 : -1;
return math_exp(math_ln(-a) * b) * res_sign; return math_exp(math_ln(-a) * b) * res_sign;
} }
} }
@ -334,7 +421,7 @@ INLINE f32 math_rsqrt_fast(f32 x)
INLINE f32 math_sin(f32 x) INLINE f32 math_sin(f32 x)
{ {
const f32 c = 0.225; const f32 c = 0.225;
x -= (TAU * (f32)math_floor(x / TAU)); /* [0, TAU] */ x -= (TAU * math_trunc(x / TAU)); /* [0, TAU] */
x += (TAU * (x < -PI)) - (TAU * (x > PI)); /* [-PI, PI] */ x += (TAU * (x < -PI)) - (TAU * (x > PI)); /* [-PI, PI] */
f32 y = (4.0f/PI) * x + (-4.0f/(PI*PI)) * x * math_fabs(x); f32 y = (4.0f/PI) * x + (-4.0f/(PI*PI)) * x * math_fabs(x);
y = c * (y * math_fabs(y) - y) + y; y = c * (y * math_fabs(y) - y) + y;
@ -393,7 +480,7 @@ INLINE f32 math_lerp(f32 val0, f32 val1, f32 t)
return val0 + ((val1 - val0) * t); return val0 + ((val1 - val0) * t);
} }
INLINE f64 math_lerp_f64(f64 val0, f64 val1, f64 t) INLINE f64 math_lerp64(f64 val0, f64 val1, f64 t)
{ {
return val0 + ((val1 - val0) * t); return val0 + ((val1 - val0) * t);
} }
@ -482,24 +569,24 @@ INLINE struct v2 v2_norm_fast(struct v2 a)
INLINE struct v2 v2_round(struct v2 a) INLINE struct v2 v2_round(struct v2 a)
{ {
return V2( return V2(
(f32)math_round(a.x), math_round(a.x),
(f32)math_round(a.y) math_round(a.y)
); );
} }
INLINE struct v2 v2_floor(struct v2 a) INLINE struct v2 v2_floor(struct v2 a)
{ {
return V2( return V2(
(f32)math_floor(a.x), math_floor(a.x),
(f32)math_floor(a.y) math_floor(a.y)
); );
} }
INLINE struct v2 v2_ceil(struct v2 a) INLINE struct v2 v2_ceil(struct v2 a)
{ {
return V2( return V2(
(f32)math_ceil(a.x), math_ceil(a.x),
(f32)math_ceil(a.y) math_ceil(a.y)
); );
} }

View File

@ -316,12 +316,12 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
if (source_is_stereo) { if (source_is_stereo) {
source_samples_count = frame_count * 2; source_samples_count = frame_count * 2;
/* Round <samples_count * speed> to nearest frame boundary (nearest multiple of 2) */ /* Round <samples_count * speed> to nearest frame boundary (nearest multiple of 2) */
source_samples_count = (u64)math_ceil((f32)source_samples_count * speed); source_samples_count = (u64)math_ceil_to_int((f32)source_samples_count * speed);
source_samples_count &= ~1; source_samples_count &= ~1;
} else { } else {
source_samples_count = frame_count; source_samples_count = frame_count;
/* Round <samples_count * speed> to nearest sample */ /* Round <samples_count * speed> to nearest sample */
source_samples_count = (u64)math_round((f32)source_samples_count * speed); source_samples_count = (u64)math_round_to_int((f32)source_samples_count * speed);
} }
u64 source_sample_pos_start = mix->source_pos; u64 source_sample_pos_start = mix->source_pos;
@ -361,8 +361,8 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
/* 16 bit Stereo -> 32 bit Stereo */ /* 16 bit Stereo -> 32 bit Stereo */
for (u64 out_frame_pos = 0; out_frame_pos < out_frames_count; ++out_frame_pos) { for (u64 out_frame_pos = 0; out_frame_pos < out_frames_count; ++out_frame_pos) {
f32 in_frame_pos_exact = source_frame_pos_start + (((f32)out_frame_pos / (f32)out_frames_count) * (f32)source_frames_count); f32 in_frame_pos_exact = source_frame_pos_start + (((f32)out_frame_pos / (f32)out_frames_count) * (f32)source_frames_count);
u32 in_frame_pos_prev = math_floor(in_frame_pos_exact); u32 in_frame_pos_prev = math_floor_to_int(in_frame_pos_exact);
u32 in_frame_pos_next = math_ceil(in_frame_pos_exact); u32 in_frame_pos_next = math_ceil_to_int(in_frame_pos_exact);
/* Sample source */ /* Sample source */
f32 sample1_prev = sample_sound(source, (in_frame_pos_prev * 2) + 0, desc.looping) * (1.f / 32768.f); f32 sample1_prev = sample_sound(source, (in_frame_pos_prev * 2) + 0, desc.looping) * (1.f / 32768.f);
@ -382,8 +382,8 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
/* 16 bit Mono -> 32 bit Stereo */ /* 16 bit Mono -> 32 bit Stereo */
for (u64 out_frame_pos = 0; out_frame_pos < out_frames_count; ++out_frame_pos) { for (u64 out_frame_pos = 0; out_frame_pos < out_frames_count; ++out_frame_pos) {
f32 in_frame_pos_exact = source_frame_pos_start + (((f32)out_frame_pos / (f32)out_frames_count) * (f32)source_frames_count); f32 in_frame_pos_exact = source_frame_pos_start + (((f32)out_frame_pos / (f32)out_frames_count) * (f32)source_frames_count);
u32 in_frame_pos_prev = math_floor(in_frame_pos_exact); u32 in_frame_pos_prev = math_floor_to_int(in_frame_pos_exact);
u32 in_frame_pos_next = math_ceil(in_frame_pos_exact); u32 in_frame_pos_next = math_ceil_to_int(in_frame_pos_exact);
/* Sample source */ /* Sample source */
f32 sample_prev = sample_sound(source, in_frame_pos_prev, desc.looping) * (1.f / 32768.f); f32 sample_prev = sample_sound(source, in_frame_pos_prev, desc.looping) * (1.f / 32768.f);

View File

@ -115,8 +115,7 @@ INTERNAL void wasapi_initialize(void)
}; };
WAVEFORMATEX *wfx = &format_ex.Format; WAVEFORMATEX *wfx = &format_ex.Format;
#if 0
#if 1
b32 client_initialized = FALSE; b32 client_initialized = FALSE;
IAudioClient3 *client3; IAudioClient3 *client3;
if (SUCCEEDED(IAudioClient_QueryInterface(G.client, &IID_IAudioClient3, (LPVOID *)&client3))) { if (SUCCEEDED(IAudioClient_QueryInterface(G.client, &IID_IAudioClient3, (LPVOID *)&client3))) {

View File

@ -59,7 +59,7 @@ INLINE struct temp_arena _scratch_begin(struct arena *potential_conflict)
/* Use `scratch_begin_no_conflict` if no conflicts are present */ /* Use `scratch_begin_no_conflict` if no conflicts are present */
ASSERT(potential_conflict != NULL); ASSERT(potential_conflict != NULL);
struct scratch_ctx *ctx = thread_local_eval(&tl_scratch_ctx); struct scratch_ctx *ctx = thread_local_var_eval(&tl_scratch_ctx);
struct arena *scratch_arena = &ctx->arenas[0]; struct arena *scratch_arena = &ctx->arenas[0];
if (potential_conflict && scratch_arena->base == potential_conflict->base) { if (potential_conflict && scratch_arena->base == potential_conflict->base) {
scratch_arena = &ctx->arenas[1]; scratch_arena = &ctx->arenas[1];
@ -83,7 +83,7 @@ INLINE struct temp_arena _scratch_begin(struct arena *potential_conflict)
INLINE struct temp_arena _scratch_begin_no_conflict(void) INLINE struct temp_arena _scratch_begin_no_conflict(void)
{ {
struct scratch_ctx *ctx = thread_local_eval(&tl_scratch_ctx); struct scratch_ctx *ctx = thread_local_var_eval(&tl_scratch_ctx);
struct arena *scratch_arena = &ctx->arenas[0]; struct arena *scratch_arena = &ctx->arenas[0];
struct temp_arena temp = arena_temp_begin(scratch_arena); struct temp_arena temp = arena_temp_begin(scratch_arena);
scratch_dbg_push(ctx, &temp); scratch_dbg_push(ctx, &temp);
@ -97,7 +97,7 @@ INLINE struct temp_arena _scratch_begin_no_conflict(void)
INLINE void scratch_end(struct temp_arena scratch_temp) INLINE void scratch_end(struct temp_arena scratch_temp)
{ {
#if RTC #if RTC
struct scratch_ctx *ctx = thread_local_eval(&tl_scratch_ctx); struct scratch_ctx *ctx = thread_local_var_eval(&tl_scratch_ctx);
if (ctx->scratch_id_stack_count > 0) { if (ctx->scratch_id_stack_count > 0) {
u64 scratch_id = scratch_temp.scratch_id; u64 scratch_id = scratch_temp.scratch_id;
u64 expected_id = ctx->scratch_id_stack[--ctx->scratch_id_stack_count]; u64 expected_id = ctx->scratch_id_stack[--ctx->scratch_id_stack_count];
@ -112,12 +112,4 @@ INLINE void scratch_end(struct temp_arena scratch_temp)
arena_temp_end(scratch_temp); arena_temp_end(scratch_temp);
} }
INLINE void scratch_end_and_decommit(struct temp_arena scratch_temp)
{
scratch_end(scratch_temp);
/* Disabled for now */
// arena_decommit_unused_blocks(scratch_temp.arena);
}
#endif #endif

View File

@ -104,28 +104,28 @@ struct sys_window_settings *settings_deserialize(struct arena *arena, struct buf
error = STR("Expected number for \"x\""); error = STR("Expected number for \"x\"");
goto abort; goto abort;
} }
settings->floating_x = math_round(child->value.number); settings->floating_x = math_round_to_int(child->value.number);
found_x = true; found_x = true;
} else if (string_eq(key, STR("y"))) { } else if (string_eq(key, STR("y"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = STR("Expected number for \"y\""); error = STR("Expected number for \"y\"");
goto abort; goto abort;
} }
settings->floating_y = math_round(child->value.number); settings->floating_y = math_round_to_int(child->value.number);
found_y = true; found_y = true;
} else if (string_eq(key, STR("width"))) { } else if (string_eq(key, STR("width"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = STR("Expected number for \"width\""); error = STR("Expected number for \"width\"");
goto abort; goto abort;
} }
settings->floating_width = math_round(child->value.number); settings->floating_width = math_round_to_int(child->value.number);
found_width = true; found_width = true;
} else if (string_eq(key, STR("height"))) { } else if (string_eq(key, STR("height"))) {
if (child->type != JSON_TYPE_NUMBER) { if (child->type != JSON_TYPE_NUMBER) {
error = STR("Expected number for \"height\""); error = STR("Expected number for \"height\"");
goto abort; goto abort;
} }
settings->floating_height = math_round(child->value.number); settings->floating_height = math_round_to_int(child->value.number);
found_height = true; found_height = true;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,11 @@ struct work_startup_receipt;
struct asset_cache_startup_receipt; struct asset_cache_startup_receipt;
struct resource_startup_receipt; struct resource_startup_receipt;
struct sheet_tag {
u64 hash;
struct string path;
};
struct sheet { struct sheet {
struct v2 image_size; struct v2 image_size;
struct v2 frame_size; struct v2 frame_size;
@ -18,10 +23,44 @@ struct sheet {
struct fixed_dict spans_dict; struct fixed_dict spans_dict;
}; };
struct sheet_tag { /* ========================== *
struct string path; * Startup
* ========================== */
struct sheet_startup_receipt { i32 _; };
struct sheet_startup_receipt sheet_startup(struct work_startup_receipt *work_sr,
struct asset_cache_startup_receipt *asset_cache_srm,
struct resource_startup_receipt *resource_sr);
/* ========================== *
* Tag
* ========================== */
struct sheet_tag sheet_tag_from_path(struct string path);
/* ========================== *
* Scope
* ========================== */
struct sheet_scope {
struct sheet_scope_reference **reference_buckets;
struct sheet_scope *next_free;
}; };
struct sheet_scope *sheet_scope_begin(void);
void sheet_scope_end(struct sheet_scope *scope);
/* ========================== *
* Load
* ========================== */
struct sheet *sheet_from_tag_await(struct sheet_scope *scope, struct sheet_tag tag);
struct sheet *sheet_from_tag_async(struct sheet_scope *scope, struct sheet_tag tag);
/* ========================== *
* Inspect
* ========================== */
struct sheet_span { struct sheet_span {
struct string name; struct string name;
u32 start; u32 start;
@ -34,15 +73,6 @@ struct sheet_frame {
struct clip_rect clip; struct clip_rect clip;
}; };
struct sheet_startup_receipt { i32 _; };
struct sheet_startup_receipt sheet_startup(struct work_startup_receipt *work_sr,
struct asset_cache_startup_receipt *asset_cache_srm,
struct resource_startup_receipt *resource_sr);
struct asset *sheet_load_asset(struct string path, b32 wait);
struct sheet *sheet_load_async(struct string path);
struct sheet *sheet_load(struct string path);
struct sheet_span sheet_get_span(struct sheet *sheet, struct string name); struct sheet_span sheet_get_span(struct sheet *sheet, struct string name);
struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index); struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index);

View File

@ -166,8 +166,7 @@ INTERNAL WORK_TASK_FUNC_DEF(sound_load_asset_task, vparams)
sound_task_params_release(params); sound_task_params_release(params);
/* Decommit decoded sound data */ scratch_end(scratch);
scratch_end_and_decommit(scratch);
} }
struct asset *sound_load_asset(struct string path, u32 flags, b32 help) struct asset *sound_load_asset(struct string path, u32 flags, b32 help)

View File

@ -94,23 +94,17 @@ struct string string_from_ptr(struct arena *arena, void *ptr)
}; };
} }
/* NOTE: This is an imprecise and inefficient way of doing this */
struct string string_from_float(struct arena *arena, f64 f, u32 precision) struct string string_from_float(struct arena *arena, f64 f, u32 precision)
{ {
u8 *final_text = arena_dry_push(arena, u8); u8 *final_text = arena_dry_push(arena, u8);
u64 final_len = 0; u64 final_len = 0;
/* Currently this function doesn't support large floats. We should if (f != f) {
* rewrite this function if this needs to change. */
f64 max_representable = (f64)((u64)1 << 62);
b32 too_large = (f >= max_representable) || (f <= -max_representable);
b32 nan = f != f;
if (nan) {
final_len += string_copy(arena, STR("NaN")).len; final_len += string_copy(arena, STR("NaN")).len;
} else if (too_large) { } else if (f == F64_INFINITY) {
string_from_char(arena, '?'); final_len += string_copy(arena, STR("inf")).len;
++final_len; } else if (f == -F64_INFINITY) {
final_len += string_copy(arena, STR("-inf")).len;
} else { } else {
if (f < 0) { if (f < 0) {
string_from_char(arena, '-'); string_from_char(arena, '-');
@ -121,19 +115,39 @@ struct string string_from_float(struct arena *arena, f64 f, u32 precision)
/* Add one half of next precision level to round up */ /* Add one half of next precision level to round up */
f += 0.5 / (f64)math_pow_u64(10, (u8)precision); f += 0.5 / (f64)math_pow_u64(10, (u8)precision);
f64 part_whole = math_floor64(f);
f64 part_decimal = f - part_whole;
/* Print whole part */ /* Print whole part */
u64 whole = (u64)f; {
struct string whole_str = string_from_uint(arena, whole, 10); struct temp_arena scratch = scratch_begin(arena);
final_len += whole_str.len;
/* Build backwards text starting from least significant digit */
u8 *backwards_text = arena_dry_push(scratch.arena, u8);
u64 backwards_text_len = 0;
do {
u64 digit = (u64)math_round_to_int64(math_fmod64(part_whole, 10.0));
string_from_char(scratch.arena, INT_CHARS[digit % 10]);
++backwards_text_len;
part_whole = math_floor64(part_whole / 10.0);
} while (part_whole > 0);
/* Reverse text into final string */
arena_push_array(arena, u8, backwards_text_len);
for (u64 i = backwards_text_len; i-- > 0;) {
final_text[final_len++] = backwards_text[i];
}
scratch_end(scratch);
}
/* Print decimal part */ /* Print decimal part */
if (precision > 0) { if (precision > 0) {
string_from_char(arena, '.'); string_from_char(arena, '.');
f -= (f64)whole;
for (u64 i = 0; i < precision; ++i) { for (u64 i = 0; i < precision; ++i) {
f *= 10.0; part_decimal *= 10.0;
u64 digit = (u64)f; u64 digit = (u64)math_floor_to_int64(part_decimal);
f -= (f64)digit; part_decimal -= digit;
string_from_char(arena, INT_CHARS[digit % 10]); string_from_char(arena, INT_CHARS[digit % 10]);
} }
final_len += (u64)precision + 1; final_len += (u64)precision + 1;
@ -268,15 +282,18 @@ struct string string_indent(struct arena *arena, struct string str, u32 indent)
b32 string_eq(struct string str1, struct string str2) b32 string_eq(struct string str1, struct string str2)
{ {
b32 eq = true;
if (str1.len == str2.len) { if (str1.len == str2.len) {
for (u64 i = 0; i < str1.len; ++i) { for (u64 i = 0; i < str1.len; ++i) {
if (str1.text[i] != str2.text[i]) { if (str1.text[i] != str2.text[i]) {
return false; eq = false;
break;
} }
} }
return true; } else {
eq = false;
} }
return false; return eq;
} }
b32 string_contains(struct string str, struct string substring) b32 string_contains(struct string str, struct string substring)

View File

@ -163,7 +163,8 @@ void sys_memory_release(void *address);
/* Commit a region of reserved address space to make it readable / writable */ /* Commit a region of reserved address space to make it readable / writable */
void *sys_memory_commit(void *address, u64 size); void *sys_memory_commit(void *address, u64 size);
/* Decommit a region of committed memory (does not release the address space) */ /* Decommit a region of committed memory (does not release the reserved
* address space) */
void sys_memory_decommit(void *address, u64 size); void sys_memory_decommit(void *address, u64 size);
/* ========================== * /* ========================== *

View File

@ -649,10 +649,10 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(window_thread_entry_point, arg)
/* Clip cursor in window window */ /* Clip cursor in window window */
if (cursor_flags & WIN32_WINDOW_CURSOR_SET_FLAG_ENABLE_CLIP) { if (cursor_flags & WIN32_WINDOW_CURSOR_SET_FLAG_ENABLE_CLIP) {
i32 left = window->x + math_round(window->cursor_clip_bounds.x); i32 left = window->x + math_round_to_int(window->cursor_clip_bounds.x);
i32 right = left + math_round(window->cursor_clip_bounds.width); i32 right = left + math_round_to_int(window->cursor_clip_bounds.width);
i32 top = window->y + math_round(window->cursor_clip_bounds.y); i32 top = window->y + math_round_to_int(window->cursor_clip_bounds.y);
i32 bottom = top + math_round(window->cursor_clip_bounds.height); i32 bottom = top + math_round_to_int(window->cursor_clip_bounds.height);
RECT clip = { RECT clip = {
.left = clamp_i32(left, window->x, window->x + window->width), .left = clamp_i32(left, window->x, window->x + window->width),
.right = clamp_i32(right, window->x, window->x + window->width), .right = clamp_i32(right, window->x, window->x + window->width),
@ -1415,7 +1415,7 @@ void sys_condition_variable_wait_time(struct sys_condition_variable *cv, struct
#if RTC #if RTC
atomic_i64_inc_eval(&cv->num_sleepers); atomic_i64_inc_eval(&cv->num_sleepers);
#endif #endif
u32 ms = (u32)math_round((f32)seconds * 1000.f); u32 ms = (u32)math_round_to_int((f32)seconds * 1000.f);
SleepConditionVariableSRW((PCONDITION_VARIABLE)cv->handle, (SRWLOCK *)&mutex->handle, ms, 0); SleepConditionVariableSRW((PCONDITION_VARIABLE)cv->handle, (SRWLOCK *)&mutex->handle, ms, 0);
#if RTC #if RTC
atomic_i64_dec_eval(&cv->num_sleepers); atomic_i64_dec_eval(&cv->num_sleepers);
@ -1457,7 +1457,7 @@ void sys_semaphore_wait(struct sys_semaphore *semaphore)
void sys_semaphore_wait_timed(struct sys_semaphore *semaphore, f64 seconds) void sys_semaphore_wait_timed(struct sys_semaphore *semaphore, f64 seconds)
{ {
__prof; __prof;
u32 ms = max_u32(1, math_round((f32)(seconds * 1000.0))); u32 ms = max_u32(1, math_round_to_int((f32)(seconds * 1000.0)));
WaitForSingleObjectEx((HANDLE)semaphore->handle, ms, FALSE); WaitForSingleObjectEx((HANDLE)semaphore->handle, ms, FALSE);
} }
@ -1974,7 +1974,7 @@ void sys_sleep_precise(f64 seconds)
void sys_sleep(f64 seconds) void sys_sleep(f64 seconds)
{ {
__prof; __prof;
u32 ms = max_u32(1, math_round((f32)(seconds * 1000.0))); u32 ms = max_u32(1, math_round_to_int((f32)(seconds * 1000.0)));
Sleep(ms); Sleep(ms);
} }
@ -2056,8 +2056,8 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
wc->hInstance = instance; wc->hInstance = instance;
/* Use first icon resource as window icon (same as explorer) */ /* Use first icon resource as window icon (same as explorer) */
wchar_t path[MAX_PATH] = { 0 }; wchar_t path[4096] = { 0 };
GetModuleFileNameW(instance, path, MAX_PATH); GetModuleFileNameW(instance, path, ARRAY_COUNT(path));
ExtractIconExW(path, 0, &wc->hIcon, &wc->hIconSm, 1); ExtractIconExW(path, 0, &wc->hIcon, &wc->hIconSm, 1);
if (!RegisterClassExW(wc)) { if (!RegisterClassExW(wc)) {

View File

@ -226,8 +226,7 @@ INTERNAL WORK_TASK_FUNC_DEF(texture_load_asset_task, vparams)
texture_task_params_release(params); texture_task_params_release(params);
/* Decommit decoded texture data */ scratch_end(scratch);
scratch_end_and_decommit(scratch);
} }
struct asset *texture_load_asset(struct string path, b32 help) struct asset *texture_load_asset(struct string path, b32 help)

View File

@ -58,14 +58,14 @@ void thread_local_store_release(struct thread_local_store *t)
arena_release(&t->arena); arena_release(&t->arena);
} }
void *_thread_local_eval(struct thread_local_var_meta *meta) void *_thread_local_var_eval(struct thread_local_var_meta *meta)
{ {
/* Register var if unregistered */ /* Register var if unregistered */
u64 id; u64 id;
{ {
u64 id_plus_one = atomic_u64_eval(&meta->id_plus_one); u64 id_plus_one = atomic_u64_eval(&meta->id_plus_one);
if (id_plus_one == 0) { if (id_plus_one == 0) {
__profscope(_thread_local_eval__REGISTER); __profscope(_thread_local_var_eval__REGISTER);
metas_lock(); metas_lock();
{ {
id_plus_one = atomic_u64_eval(&meta->id_plus_one); /* Re-check now that locked */ id_plus_one = atomic_u64_eval(&meta->id_plus_one); /* Re-check now that locked */
@ -90,7 +90,7 @@ void *_thread_local_eval(struct thread_local_var_meta *meta)
struct thread_local_store *t = sys_thread_get_thread_local_store(); struct thread_local_store *t = sys_thread_get_thread_local_store();
void *data = t->lookup[id]; void *data = t->lookup[id];
if (!data) { if (!data) {
__profscope(_thread_local_eval__ALLOC); __profscope(_thread_local_var_eval__ALLOC);
/* Allocate */ /* Allocate */
arena_align(&t->arena, meta->align); arena_align(&t->arena, meta->align);
data = arena_push_array(&t->arena, u8, meta->size); data = arena_push_array(&t->arena, u8, meta->size);

View File

@ -54,7 +54,7 @@ struct thread_local_var_meta {
} \ } \
} }
#define thread_local_eval(var_ptr) (typeof((var_ptr)->_t))(_thread_local_eval(&(var_ptr)->meta)); #define thread_local_var_eval(var_ptr) (typeof((var_ptr)->_t))(_thread_local_var_eval(&(var_ptr)->meta));
void *_thread_local_eval(struct thread_local_var_meta *meta); void *_thread_local_var_eval(struct thread_local_var_meta *meta);
#endif #endif

1123
src/user.c

File diff suppressed because it is too large Load Diff

View File

@ -382,7 +382,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(worker_thread_entry_point, thread_data)
{ {
(UNUSED)thread_data; (UNUSED)thread_data;
struct worker_ctx *ctx = thread_local_eval(&tl_worker_ctx); struct worker_ctx *ctx = thread_local_var_eval(&tl_worker_ctx);
*ctx = (struct worker_ctx) { *ctx = (struct worker_ctx) {
.is_worker = true .is_worker = true
}; };
@ -444,7 +444,7 @@ INTERNAL struct work_handle work_push_from_slate_assume_locked(struct work_slate
* does not occur. However it is not ideal since it creates situations in * does not occur. However it is not ideal since it creates situations in
* which work is not done asynchronously. * which work is not done asynchronously.
*/ */
struct worker_ctx *ctx = thread_local_eval(&tl_worker_ctx); struct worker_ctx *ctx = thread_local_var_eval(&tl_worker_ctx);
if (ctx->is_worker) { if (ctx->is_worker) {
b32 work_done = false; b32 work_done = false;
while (!work_done && G.idle_worker_count == 0 && work->workers == 0) { while (!work_done && G.idle_worker_count == 0 && work->workers == 0) {