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);
i32 width = 1280;
i32 height = math_round(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
i32 x = math_round(monitor_size.x / 2.f - width / 2);
i32 y = math_round(monitor_size.y / 2.f - height / 2);
i32 height = math_round_to_int(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
i32 x = math_round_to_int(monitor_size.x / 2.f - width / 2);
i32 y = math_round_to_int(monitor_size.y / 2.f - height / 2);
return (struct sys_window_settings) {
.title = WINDOW_TITLE,

View File

@ -10,6 +10,7 @@
* memory. */
struct arena arena_alloc(u64 reserve)
{
__prof;
struct arena arena = { 0 };
/* Round up to nearest block size */
@ -43,6 +44,7 @@ struct arena arena_alloc(u64 reserve)
void arena_release(struct arena *arena)
{
__prof;
sys_memory_decommit(arena->base, arena->committed);
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,
* 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)
{
arena_reset(dest);

View File

@ -9,6 +9,7 @@
#include "scratch.h"
#include "byteio.h"
#include "string.h"
#include "log.h"
/* ========================== *
* Bitbuf
@ -383,9 +384,6 @@ INTERNAL void inflate(struct arena *arena, u8 *dest, u8 *encoded)
* Decoder structs
* ========================== */
#define LAYER_FLAG_NONE 0x0
#define LAYER_FLAG_VISIBLE 0x1
enum chunk_type {
CHUNK_TYPE_OLD_PALETTE1 = 0x0004,
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)
{
logf_error("Error while decoding .ase: \"%F\"", FMT_STR(msg_src));
struct ase_error *e = arena_push(arena, struct ase_error);
*e = (struct ase_error) {
.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_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 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_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_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 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_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_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 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_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_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 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_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
# error "Atomics not implemented"

View File

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

View File

@ -1,6 +1,7 @@
#ifndef ENTITY_H
#define ENTITY_H
#include "mixer.h"
#include "sheet.h"
#include "mixer.h"
@ -66,6 +67,7 @@ struct entity {
/* Sprite */
struct string sprite_name;
struct sheet_tag sprite_sheet_tag;
struct string sprite_span_name;
struct xform sprite_quad_xform;
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)));
asset_cache_mark_ready(asset, font);
scratch_end_and_decommit(scratch);
scratch_end(scratch);
}
/* 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();
/* ========================== *
* Begin frame cache scopes
* ========================== */
struct sheet_scope *sheet_frame_scope = sheet_scope_begin();
/* TODO: remove this (testing) */
/* Initialize entities */
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_span_name = STR("UNARMED");
struct sheet *sheet = sheet_load(sprite_name);
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
struct sheet_tag sprite_sheet_tag = sheet_tag_from_path(sprite_name);
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);
f32 sprite_rot = 0;
@ -198,6 +213,7 @@ INTERNAL void game_update(void)
e->sprite_quad_xform = sprite_xf;
e->sprite_name = sprite_name;
e->sprite_sheet_tag = sprite_sheet_tag;
e->sprite_span_name = sprite_span_name;
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_span_name = STR("UNARMED");
struct sheet *sheet = sheet_load(sprite_name);
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
struct sheet_tag sprite_sheet_tag = sheet_tag_from_path(sprite_name);
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);
f32 sprite_rot = 0;
@ -249,6 +274,7 @@ INTERNAL void game_update(void)
e->sprite_quad_xform = sprite_xf;
e->sprite_name = sprite_name;
e->sprite_sheet_tag = sprite_sheet_tag;
e->sprite_span_name = sprite_span_name;
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));
struct string sprite_name = STR("res/graphics/sound.ase");
struct sheet *sheet = sheet_load(sprite_name);
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
struct sheet_tag sprite_sheet_tag = sheet_tag_from_path(sprite_name);
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);
e->sprite_quad_xform = xform_with_scale(XFORM_IDENT, sprite_size);
e->sprite_name = sprite_name;
e->sprite_sheet_tag = sprite_sheet_tag;
e->sprite_tint = RGBA_F(1, 1, 0, 1);
entity_enable_prop(e, ENTITY_PROP_TEST_SOUND_EMITTER);
@ -380,13 +416,11 @@ INTERNAL void game_update(void)
* Update animation
* ========================== */
#if 0
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
u64 span_frame_offset = ent->animation_frame;
struct sheet *sheet = sheet_load(ent->sprite_name);
if (sheet) {
struct sheet *sheet = sheet_from_tag_await(sheet_frame_scope, ent->sprite_sheet_tag);
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
u64 frame_index = span.start + span_frame_offset;
@ -401,12 +435,10 @@ INTERNAL void game_update(void)
frame = sheet_get_frame(sheet, frame_index);
}
span_frame_offset = frame_index - span.start;
}
ent->animation_time_in_frame = time_in_frame;
ent->animation_frame = span_frame_offset;
}
#endif
/* ========================== *
* Test
@ -579,6 +611,12 @@ INTERNAL void game_update(void)
publish_game_tick();
__profframe("Game");
/* ========================== *
* End frame cache scopes
* ========================== */
sheet_scope_end(sheet_frame_scope);
scratch_end(scratch);
}

View File

@ -5,6 +5,8 @@
* Math
* ========================== */
/* Sqrt */
INLINE f32 ix_sqrt_f32(f32 f)
{
__m128 n = _mm_set_ss(f);
@ -19,25 +21,82 @@ INLINE f32 ix_rsqrt_f32(f32 f)
return _mm_cvtss_f32(n);
}
/* Round */
INLINE i32 ix_round_f32_to_i32(f32 f)
{
__m128 n = _mm_set_ss(f);
n = _mm_round_ss(_mm_setzero_ps(), n, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
return _mm_cvtss_si32(n);
return _mm_cvtss_si32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
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)
{
__m128 n = _mm_set_ss(f);
n = _mm_floor_ss(_mm_setzero_ps(), n);
return _mm_cvtss_si32(n);
return _mm_cvtss_si32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
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)
{
__m128 n = _mm_set_ss(f);
n = _mm_ceil_ss(_mm_setzero_ps(), n);
return _mm_cvtss_si32(n);
return _mm_cvtss_si32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
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
#define MATH_H
/* Math functions are default 32 bit (f32, i32, etc) unless specified */
#include "intrinsics.h"
INLINE f32 math_sqrt(f32 x);
/* ========================== *
* Rounding
* Float rounding
* ========================== */
/* 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);
}
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);
}
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);
}
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)
{
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)
@ -37,12 +112,24 @@ INLINE f32 math_fabs(f32 f)
return *(f32 *)&truncated;
}
INLINE f64 math_fabs64(f64 f)
{
u64 truncated = *(u64 *)&f & 0x7FFFFFFFFFFFFFFFULL;
return *(f64 *)&truncated;
}
INLINE i32 math_fsign(f32 f)
{
u32 sign_bit = (*(u32 *)&f >> 31) & 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
* ========================== */
@ -288,7 +375,7 @@ INLINE f32 math_pow(f32 a, f32 b)
return math_exp(math_ln(a) * b);
} else {
/* 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;
}
}
@ -334,7 +421,7 @@ INLINE f32 math_rsqrt_fast(f32 x)
INLINE f32 math_sin(f32 x)
{
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] */
f32 y = (4.0f/PI) * x + (-4.0f/(PI*PI)) * x * math_fabs(x);
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);
}
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);
}
@ -482,24 +569,24 @@ INLINE struct v2 v2_norm_fast(struct v2 a)
INLINE struct v2 v2_round(struct v2 a)
{
return V2(
(f32)math_round(a.x),
(f32)math_round(a.y)
math_round(a.x),
math_round(a.y)
);
}
INLINE struct v2 v2_floor(struct v2 a)
{
return V2(
(f32)math_floor(a.x),
(f32)math_floor(a.y)
math_floor(a.x),
math_floor(a.y)
);
}
INLINE struct v2 v2_ceil(struct v2 a)
{
return V2(
(f32)math_ceil(a.x),
(f32)math_ceil(a.y)
math_ceil(a.x),
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) {
source_samples_count = frame_count * 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;
} else {
source_samples_count = frame_count;
/* 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;
@ -361,8 +361,8 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
/* 16 bit Stereo -> 32 bit Stereo */
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);
u32 in_frame_pos_prev = math_floor(in_frame_pos_exact);
u32 in_frame_pos_next = math_ceil(in_frame_pos_exact);
u32 in_frame_pos_prev = math_floor_to_int(in_frame_pos_exact);
u32 in_frame_pos_next = math_ceil_to_int(in_frame_pos_exact);
/* Sample source */
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 */
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);
u32 in_frame_pos_prev = math_floor(in_frame_pos_exact);
u32 in_frame_pos_next = math_ceil(in_frame_pos_exact);
u32 in_frame_pos_prev = math_floor_to_int(in_frame_pos_exact);
u32 in_frame_pos_next = math_ceil_to_int(in_frame_pos_exact);
/* Sample source */
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;
#if 1
#if 0
b32 client_initialized = FALSE;
IAudioClient3 *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 */
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];
if (potential_conflict && scratch_arena->base == potential_conflict->base) {
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)
{
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 temp_arena temp = arena_temp_begin(scratch_arena);
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)
{
#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) {
u64 scratch_id = scratch_temp.scratch_id;
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);
}
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

View File

@ -104,28 +104,28 @@ struct sys_window_settings *settings_deserialize(struct arena *arena, struct buf
error = STR("Expected number for \"x\"");
goto abort;
}
settings->floating_x = math_round(child->value.number);
settings->floating_x = math_round_to_int(child->value.number);
found_x = true;
} else if (string_eq(key, STR("y"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = STR("Expected number for \"y\"");
goto abort;
}
settings->floating_y = math_round(child->value.number);
settings->floating_y = math_round_to_int(child->value.number);
found_y = true;
} else if (string_eq(key, STR("width"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = STR("Expected number for \"width\"");
goto abort;
}
settings->floating_width = math_round(child->value.number);
settings->floating_width = math_round_to_int(child->value.number);
found_width = true;
} else if (string_eq(key, STR("height"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = STR("Expected number for \"height\"");
goto abort;
}
settings->floating_height = math_round(child->value.number);
settings->floating_height = math_round_to_int(child->value.number);
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 resource_startup_receipt;
struct sheet_tag {
u64 hash;
struct string path;
};
struct sheet {
struct v2 image_size;
struct v2 frame_size;
@ -18,10 +23,44 @@ struct sheet {
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 string name;
u32 start;
@ -34,15 +73,6 @@ struct sheet_frame {
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_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);
/* Decommit decoded sound data */
scratch_end_and_decommit(scratch);
scratch_end(scratch);
}
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)
{
u8 *final_text = arena_dry_push(arena, u8);
u64 final_len = 0;
/* Currently this function doesn't support large floats. We should
* 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) {
if (f != f) {
final_len += string_copy(arena, STR("NaN")).len;
} else if (too_large) {
string_from_char(arena, '?');
++final_len;
} else if (f == F64_INFINITY) {
final_len += string_copy(arena, STR("inf")).len;
} else if (f == -F64_INFINITY) {
final_len += string_copy(arena, STR("-inf")).len;
} else {
if (f < 0) {
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 */
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 */
u64 whole = (u64)f;
struct string whole_str = string_from_uint(arena, whole, 10);
final_len += whole_str.len;
{
struct temp_arena scratch = scratch_begin(arena);
/* 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 */
if (precision > 0) {
string_from_char(arena, '.');
f -= (f64)whole;
for (u64 i = 0; i < precision; ++i) {
f *= 10.0;
u64 digit = (u64)f;
f -= (f64)digit;
part_decimal *= 10.0;
u64 digit = (u64)math_floor_to_int64(part_decimal);
part_decimal -= digit;
string_from_char(arena, INT_CHARS[digit % 10]);
}
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 eq = true;
if (str1.len == str2.len) {
for (u64 i = 0; i < str1.len; ++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)

View File

@ -163,7 +163,8 @@ void sys_memory_release(void *address);
/* Commit a region of reserved address space to make it readable / writable */
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);
/* ========================== *

View File

@ -649,10 +649,10 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(window_thread_entry_point, arg)
/* Clip cursor in window window */
if (cursor_flags & WIN32_WINDOW_CURSOR_SET_FLAG_ENABLE_CLIP) {
i32 left = window->x + math_round(window->cursor_clip_bounds.x);
i32 right = left + math_round(window->cursor_clip_bounds.width);
i32 top = window->y + math_round(window->cursor_clip_bounds.y);
i32 bottom = top + math_round(window->cursor_clip_bounds.height);
i32 left = window->x + math_round_to_int(window->cursor_clip_bounds.x);
i32 right = left + math_round_to_int(window->cursor_clip_bounds.width);
i32 top = window->y + math_round_to_int(window->cursor_clip_bounds.y);
i32 bottom = top + math_round_to_int(window->cursor_clip_bounds.height);
RECT clip = {
.left = clamp_i32(left, 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
atomic_i64_inc_eval(&cv->num_sleepers);
#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);
#if RTC
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)
{
__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);
}
@ -1974,7 +1974,7 @@ void sys_sleep_precise(f64 seconds)
void sys_sleep(f64 seconds)
{
__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);
}
@ -2056,8 +2056,8 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
wc->hInstance = instance;
/* Use first icon resource as window icon (same as explorer) */
wchar_t path[MAX_PATH] = { 0 };
GetModuleFileNameW(instance, path, MAX_PATH);
wchar_t path[4096] = { 0 };
GetModuleFileNameW(instance, path, ARRAY_COUNT(path));
ExtractIconExW(path, 0, &wc->hIcon, &wc->hIconSm, 1);
if (!RegisterClassExW(wc)) {

View File

@ -226,8 +226,7 @@ INTERNAL WORK_TASK_FUNC_DEF(texture_load_asset_task, vparams)
texture_task_params_release(params);
/* Decommit decoded texture data */
scratch_end_and_decommit(scratch);
scratch_end(scratch);
}
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);
}
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 */
u64 id;
{
u64 id_plus_one = atomic_u64_eval(&meta->id_plus_one);
if (id_plus_one == 0) {
__profscope(_thread_local_eval__REGISTER);
__profscope(_thread_local_var_eval__REGISTER);
metas_lock();
{
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();
void *data = t->lookup[id];
if (!data) {
__profscope(_thread_local_eval__ALLOC);
__profscope(_thread_local_var_eval__ALLOC);
/* Allocate */
arena_align(&t->arena, meta->align);
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));
void *_thread_local_eval(struct thread_local_var_meta *meta);
#define thread_local_var_eval(var_ptr) (typeof((var_ptr)->_t))(_thread_local_var_eval(&(var_ptr)->meta));
void *_thread_local_var_eval(struct thread_local_var_meta *meta);
#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;
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) {
.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
* 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) {
b32 work_done = false;
while (!work_done && G.idle_worker_count == 0 && work->workers == 0) {