codebase layers progress

This commit is contained in:
jacob 2025-07-28 15:58:03 -05:00
parent 1738c3e1f0
commit 70e5e115c9
114 changed files with 629 additions and 797 deletions

37
build.c
View File

@ -1,5 +1,5 @@
#include "buildit.h"
#include "buildit.h"
typedef struct StepList StepList;
/* ========================== *
@ -475,7 +475,7 @@ void OnBuild(StringList cli_args)
String warnings = Lit("/WX /Wall "
"/options:strict "
"/wd4820 /wd4201 /wd5220 /wd4514 /wd4244 /wd5045 /wd4242 /wd4061 /wd4189 /wd4723 /wd5246 /wd4324");
"/wd4820 /wd4201 /wd5220 /wd4514 /wd4244 /wd5045 /wd4242 /wd4061 /wd4189 /wd4723 /wd5246 /wd4324 /wd4464 /wd4577");
StringListAppend(&perm, &compile_warnings, warnings);
StringListAppend(&perm, &link_warnings, Lit("/WX"));
@ -496,6 +496,7 @@ void OnBuild(StringList cli_args)
"-fno-strict-aliasing "
"-fno-finite-loops "
"-fwrapv "
"-I src/ "
"-msse4.1 "
"-msse4.2 "));
@ -521,6 +522,13 @@ void OnBuild(StringList cli_args)
StringListAppend(&perm, &link_warnings, warnings);
}
/* DXC */
{
StringListAppend(&perm, &dxc_compile_args, Lit("-I src/ -H -WX -Ges"));
String dxc_args_define = StringFromStringList(&perm, Lit(" "), dxc_compile_args);
StringListAppend(&perm, &compile_args, StringF(&perm, Lit("-DDXC_ARGS=\"%F\""), FmtStr(dxc_args_define)));
}
/* RTC */
if (arg_rtc) {
if (!arg_crtlib) {
@ -627,13 +635,6 @@ void OnBuild(StringList cli_args)
String incbin_dir = StringReplace(&perm, out_inc_dir_path, Lit("\\"), Lit("/"));
StringListAppend(&perm, &compile_args, StringF(&perm, Lit("-DINCBIN_DIR_RAW=\"%F\""), FmtStr(incbin_dir)));
}
/* DXC */
{
StringListAppend(&perm, &dxc_compile_args, Lit("-H -WX -Ges"));
String dxc_args_define = StringFromStringList(&perm, Lit(" "), dxc_compile_args);
StringListAppend(&perm, &compile_args, StringF(&perm, Lit("-DDXC_ARGS=\"%F\""), FmtStr(dxc_args_define)));
}
}
/* ========================== *
@ -683,7 +684,8 @@ void OnBuild(StringList cli_args)
D_TagList src_input_files = { 0 };
{
D_Tag src_dir = D_TagFromPath(&perm, Lit("src/sh"), D_TagKind_Dir);
D_TagList src_files = D_GetDirContents(&perm, src_dir, 0);
D_TagList src_files = { 0 };
D_GetDirContents(&perm, &src_files, src_dir, 0);
for (D_TagListNode *n = src_files.first; n; n = n->next) {
D_Tag file = n->tag;
@ -956,7 +958,20 @@ void OnBuild(StringList cli_args)
D_TagList src_input_files = { 0 };
{
D_Tag src_dir = D_TagFromPath(&perm, Lit("src"), D_TagKind_Dir);
D_TagList src_files = D_GetDirContents(&perm, src_dir, 0);
D_TagList src_files = { 0 };
D_GetDirContents(&perm, &src_files, src_dir, 0);
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/base/base.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/sys/sys.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/gp/gp.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/tar/tar.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/ase/ase.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/mp3/mp3.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/json/json.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/ttf/ttf.cpp"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/dxc/dxc.cpp"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/sim/sim.c"), D_TagKind_File));
D_TagListAppend(&perm, &src_files, D_TagFromPath(&perm, Lit("src/user/user.c"), D_TagKind_File));
for (D_TagListNode *n = src_files.first; n; n = n->next) {
Bool ignore = 1;

View File

@ -1,26 +1,20 @@
#include "app.h"
#include "arena.h"
#include "string.h"
#include "sys.h"
#include "user.h"
#include "sim.h"
#include "base/base.h"
#include "sys/sys.h"
#include "ttf/ttf.h"
#include "gp/gp.h"
#include "sim/sim.h"
#include "user/user.h"
#include "playback.h"
#include "log.h"
#include "resource.h"
#include "asset_cache.h"
#include "font.h"
#include "sprite.h"
#include "ttf.h"
#include "mixer.h"
#include "sound.h"
#include "util.h"
#include "settings.h"
#include "draw.h"
#include "math.h"
#include "gp.h"
#include "phys.h"
#include "host.h"
#include "bitbuff.h"
#include "watch.h"
GLOBAL struct {

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

@ -0,0 +1,3 @@
#include "ase.h"
#include "ase_core.c"

8
src/ase/ase.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef ASE_H
#define ASE_H
#include "../base/base.h"
#include "ase_core.h"
#endif

View File

@ -4,16 +4,6 @@
* DEFLATE decoder based on Handmade Hero's png parser
* ========================== */
#include "ase.h"
#include "arena.h"
#include "bitbuff.h"
#include "string.h"
#include "log.h"
/* ========================== *
* Bitbuf
* ========================== */
struct huff_bb {
u8 *data;
u64 cur_bit;
@ -452,7 +442,6 @@ PACK(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->msg = string_copy(arena, msg_src);
if (!list->first) {

View File

@ -1,6 +1,3 @@
#ifndef ASE_H
#define ASE_H
struct ase_error {
struct string msg;
struct ase_error *next;
@ -66,5 +63,3 @@ struct ase_decode_sheet_result {
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);
#endif

View File

@ -1,11 +1,6 @@
#include "asset_cache.h"
#include "sys.h"
#include "string.h"
#include "memory.h"
#include "arena.h"
#include "util.h"
#include "log.h"
#include "snc.h"
#include "base/base.h"
#include "sys/sys.h"
/* ========================== *
* Global state

View File

@ -1,8 +1,8 @@
#ifndef ASSET_CACHE_H
#define ASSET_CACHE_H
#include "sys.h"
#include "util.h"
#include "base/base.h"
#include "sys/sys.h"
enum asset_status {
ASSET_STATUS_NONE,

12
src/base/base.c Normal file
View File

@ -0,0 +1,12 @@
#include "base.h"
#include "base_fiber.c"
#include "base_arena.c"
#include "base_buddy.c"
#include "base_memory.c"
#include "base_rand.c"
#include "base_string.c"
#include "base_bitbuff.c"
#include "base_uid.c"
#include "base_uni.c"
#include "base_incbin.c"

21
src/base/base.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef BASE_H
#define BASE_H
#include "../gstat.h"
#include "base_intrinsics.h"
#include "base_atomic.h"
#include "base_fiber.h"
#include "base_memory.h"
#include "base_arena.h"
#include "base_buddy.h"
#include "base_math.h"
#include "base_rand.h"
#include "base_string.h"
#include "base_bitbuff.h"
#include "base_uid.h"
#include "base_uni.h"
#include "base_util.h"
#include "base_incbin.h"
#endif

View File

@ -1,9 +1,4 @@
#include "arena.h"
#include "sys.h"
#include "memory.h"
#include "string.h"
#include "atomic.h"
#include "gstat.h"
struct scratch_shared g_scratch_shared = ZI;
/* NOTE: Application will exit if arena fails to reserve or commit initial memory. */
struct arena *arena_alloc(u64 reserve)
@ -17,19 +12,23 @@ struct arena *arena_alloc(u64 reserve)
reserve += ARENA_BLOCK_SIZE - block_remainder;
}
u8 *base = sys_memory_reserve(reserve);
u8 *base = memory_reserve(reserve);
if (!base) {
/* Hard fail on memory reserve failure for now */
sys_panic(LIT("Failed to reserve memory"));
/* FIXME: Enable this */
//sys_panic(LIT("Failed to reserve memory"));
(*(volatile int *)0) = 0;
}
u64 reserved = reserve;
gstat_add(GSTAT_MEMORY_RESERVED, reserve);
/* Commit initial block */
base = sys_memory_commit(base, ARENA_BLOCK_SIZE);
base = memory_commit(base, ARENA_BLOCK_SIZE);
if (!base) {
/* Hard fail on commit failure */
sys_panic(LIT("Failed to commit initial memory block: System may be out of memory"));
/* FIXME: Enable this */
//sys_panic(LIT("Failed to commit initial memory block: System may be out of memory"));
(*(volatile int *)0) = 0;
}
ASSERT(((u64)base & 0xFFF) == 0); /* Base should be 4k aligned */
@ -57,7 +56,7 @@ void arena_release(struct arena *arena)
gstat_add(GSTAT_MEMORY_COMMITTED, -(i64)(arena->committed - ARENA_HEADER_SIZE));
gstat_add(GSTAT_MEMORY_RESERVED, -(i64)(arena->reserved));
gstat_add(GSTAT_NUM_ARENAS, -1);
sys_memory_release(arena);
memory_release(arena);
}
/* NOTE: Application will exit if arena fails to commit memory */
@ -83,12 +82,16 @@ void *arena_push_bytes_no_zero(struct arena *arena, u64 size, u64 align)
u64 new_capacity = arena->committed + commit_bytes;
if (new_capacity > arena->reserved) {
/* Hard fail if we overflow reserved memory for now */
sys_panic(LIT("Failed to commit new memory block: Overflow of reserved memory"));
/* FIXME: Enable this */
//sys_panic(LIT("Failed to commit new memory block: Overflow of reserved memory"));
(*(volatile int *)0) = 0;
}
void *commit_address = base + arena->committed;
if (!sys_memory_commit(commit_address, commit_bytes)) {
if (!memory_commit(commit_address, commit_bytes)) {
/* Hard fail on memory allocation failure for now */
sys_panic(LIT("Failed to commit new memory block: System may be out of memory"));
/* FIXME: Enable this */
//sys_panic(LIT("Failed to commit new memory block: System may be out of memory"));
(*(volatile int *)0) = 0;
}
arena->committed += commit_bytes;
gstat_add(GSTAT_MEMORY_COMMITTED, commit_bytes);
@ -130,12 +133,12 @@ void arena_set_readonly(struct arena *arena)
#if RTC
arena->readonly = 1;
#endif
sys_memory_set_committed_readonly(arena, arena->committed + ARENA_HEADER_SIZE);
memory_set_committed_readonly(arena, arena->committed + ARENA_HEADER_SIZE);
}
void arena_set_readwrite(struct arena *arena)
{
sys_memory_set_committed_readwrite(arena, arena->committed + ARENA_HEADER_SIZE);
memory_set_committed_readwrite(arena, arena->committed + ARENA_HEADER_SIZE);
#if RTC
arena->readonly = 0;
#endif

View File

@ -1,9 +1,3 @@
#ifndef ARENA_H
#define ARENA_H
#include "sys.h"
#include "memory.h"
#define ARENA_HEADER_SIZE 256
#define ARENA_BLOCK_SIZE 16384
@ -128,7 +122,31 @@ INLINE void *_arena_push_dry(struct arena *arena, u64 align)
* Scratch
* ========================== */
/* Any parameterized arenas in the caller's scope should be passed into this
#define SCRATCH_ARENAS_PER_CTX 2
struct scratch_ctx {
struct arena *arenas[SCRATCH_ARENAS_PER_CTX];
};
struct scratch_shared {
struct scratch_ctx scratch_contexts[MAX_FIBERS];
};
extern struct scratch_shared g_scratch_shared;
INLINE struct scratch_ctx *scratch_ctx_from_fiber_id(i16 fiber_id)
{
struct scratch_shared *shared = &g_scratch_shared;
struct scratch_ctx *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));
}
}
return ctx;
}
/* Any parameterized arenas in the caller's scope should be passed into this
* function as a potential "conflict". This is to prevent friction in case the
* passed arena is itself a scratch arena from another scope (since
* parameterized arenas are often used to allocate persistent results for the
@ -141,12 +159,12 @@ INLINE void *_arena_push_dry(struct arena *arena, u64 align)
INLINE struct arena_temp _scratch_begin(struct arena *potential_conflict)
{
/* This function is currently hard-coded to support 2 scratch arenas */
STATIC_ASSERT(SYS_SCRATCH_ARENAS_PER_CTX == 2);
STATIC_ASSERT(SCRATCH_ARENAS_PER_CTX == 2);
/* Use `scratch_begin_no_conflict` if no conflicts are present */
ASSERT(potential_conflict != 0);
struct sys_scratch_ctx *ctx = sys_scratch_ctx_from_fiber_id(sys_current_fiber_id());
struct scratch_ctx *ctx = scratch_ctx_from_fiber_id(FiberId());
struct arena *scratch_arena = ctx->arenas[0];
if (potential_conflict && scratch_arena == potential_conflict) {
scratch_arena = ctx->arenas[1];
@ -169,7 +187,7 @@ INLINE struct arena_temp _scratch_begin(struct arena *potential_conflict)
INLINE struct arena_temp _scratch_begin_no_conflict(void)
{
struct sys_scratch_ctx *ctx = sys_scratch_ctx_from_fiber_id(sys_current_fiber_id());
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);
return temp;
@ -179,5 +197,3 @@ INLINE void scratch_end(struct arena_temp scratch_temp)
{
arena_temp_end(scratch_temp);
}
#endif

View File

@ -1,6 +1,3 @@
#ifndef ATOMIC_H
#define ATOMIC_H
#if PLATFORM_WINDOWS
FORCE_INLINE i8 atomic8_fetch(struct atomic8 *x) { return (i8)_InterlockedCompareExchange8((char *)&x->_v, 0, 0); }
@ -28,7 +25,5 @@ FORCE_INLINE i64 atomic64_fetch_xor(struct atomic64 *x, i64 c) { return (i64)_In
FORCE_INLINE i64 atomic64_fetch_add(struct atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_v, a); }
#else
# error "Atomics not implemented"
#endif
# error Atomics not implemented
#endif

View File

@ -1,7 +1,3 @@
#include "bitbuff.h"
#include "memory.h"
#include "arena.h"
/* TODO: Safety check that functions taking byte length can't overflow bit conversion (log2(num_bytes) > 61) */
#define WRITE_OVERFLOW_ARENA_PUSH_SIZE 4096
@ -682,8 +678,6 @@ void br_read_dbg_marker(struct bitbuff_reader *br, struct string name)
#if BITBUFF_TEST
#include "string.h"
void bitbuff_test(void)
{
struct arena_temp scratch = scratch_begin_no_conflict();

View File

@ -1,6 +1,3 @@
#ifndef BITBUFF_H
#define BITBUFF_H
/* ========================== *
* Bitbuff
* ========================== */
@ -123,5 +120,3 @@ void br_read_dbg_marker(struct bitbuff_reader *br, struct string name);
#if BITBUFF_TEST
void bitbuff_test(void);
#endif
#endif

View File

@ -1,6 +1,3 @@
#include "buddy.h"
#include "arena.h"
/* TODO: Elminiate meta arena. Just store levels in first 4096 bytes of buddy arena, and then zone header data at the beginning of each allocation. */
/* ========================== *

View File

@ -1,6 +1,3 @@
#ifndef BUDDY_H
#define BUDDY_H
struct buddy_block {
b32 is_used;
struct buddy_level *level;
@ -34,5 +31,3 @@ void buddy_ctx_release(struct buddy_ctx *ctx);
struct buddy_block *buddy_alloc(struct buddy_ctx *ctx, u64 size);
void buddy_release(struct buddy_block *block);
#endif

14
src/base/base_fiber.c Normal file
View File

@ -0,0 +1,14 @@
#if PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
i16 FiberId(void)
{
return (i16)(i64)GetFiberData();
}
#else
# error FiberId not implemented for this platform
#endif

4
src/base/base_fiber.h Normal file
View File

@ -0,0 +1,4 @@
#define MAX_FIBERS 4096
STATIC_ASSERT(MAX_FIBERS < I16_MAX); /* Fiber id should fit max fibers */
i16 FiberId(void);

View File

@ -4,12 +4,6 @@
* Msvc RC file lookup
* ========================== */
#include "incbin.h"
#include "arena.h"
#include "string.h"
#include "atomic.h"
#include "intrinsics.h"
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
@ -59,9 +53,11 @@ struct string _incbin_get(struct _incbin_rc_resource *inc)
struct rc_search_params params = { .name_lower = name_lower };
EnumResourceNamesW(0, RT_RCDATA, &enum_func, (LONG_PTR)&params);
if (!params.found) {
sys_panic(string_format(scratch.arena,
LIT("INCBIN include not found in RC file: \"%F\""),
FMT_STR(inc->rc_name)));
/* FIXME: enable this */
//sys_panic(string_format(scratch.arena,
// LIT("INCBIN include not found in RC file: \"%F\""),
// FMT_STR(inc->rc_name)));
(*(volatile int *)0) = 0;
}
inc->data = params.data;
state = INCBIN_STATE_SEARCHED;

View File

@ -1,6 +1,3 @@
#ifndef INCBIN_H
#define INCBIN_H
#if COMPILER_MSVC
/* ========================== *
@ -66,5 +63,3 @@ struct string _incbin_get(struct _incbin_rc_resource *inc);
#define INCBIN_GET(var) STRING_FROM_POINTERS(_incbin_ ## var ## _start, _incbin_ ## var ## _end)
#endif
#endif

View File

@ -1,6 +1,3 @@
#ifndef INTRINSICS_H
#define INTRINSICS_H
/* ========================== *
* Math
* ========================== */
@ -119,5 +116,3 @@ INLINE u64 ix_clock(void)
{
return __rdtsc();
}
#endif

View File

@ -1,10 +1,5 @@
#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);
/* ========================== *
@ -1299,5 +1294,3 @@ INLINE struct math_spring math_spring_init(f32 hertz, f32 damping_ratio, f32 dt)
}
return res;
}
#endif

86
src/base/base_memory.c Normal file
View File

@ -0,0 +1,86 @@
/* ========================== *
* Memory operations
* ========================== */
#if !CRTLIB
__attribute((section(".text.memcpy")))
void *memcpy(void *__restrict dst, const void *__restrict src, u64 n)
{
for (u64 i = 0; i < n; ++i) {
((u8 *)dst)[i] = ((u8 *)src)[i];
}
return dst;
}
__attribute((section(".text.memset")))
void *memset(void *dst, i32 c, u64 n)
{
for (u64 i = 0; i < n; ++i) {
((u8 *)dst)[i] = c;
}
return dst;
}
__attribute((section(".text.memcmp")))
i32 memcmp(const void *p1, const void *p2, u64 n)
{
i32 res = 0;
for (u64 i = 0; i < n; ++i) {
res = ((u8 *)p1)[i] - ((u8 *)p2)[i];
if (res != 0) {
break;
}
}
return res;
}
#endif /* !CRTLIB */
/* ========================== *
* Memory allocation
* ========================== */
#if PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
void *memory_reserve(u64 size)
{
void *ptr = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS);
return ptr;
}
void memory_release(void *address)
{
VirtualFree(address, 0, MEM_RELEASE);
}
void *memory_commit(void *address, u64 size)
{
void *ptr = VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE);
return ptr;
}
void memory_decommit(void *address, u64 size)
{
VirtualFree(address, size, MEM_DECOMMIT);
}
void memory_set_committed_readonly(void *address, u64 size)
{
DWORD old;
VirtualProtect(address, size, PAGE_READONLY, &old);
}
void memory_set_committed_readwrite(void *address, u64 size)
{
DWORD old;
VirtualProtect(address, size, PAGE_READWRITE, &old);
}
#else
# error Memory allocation not implemented for this platform
#endif

View File

@ -1,5 +1,6 @@
#ifndef MEMORY_H
#define MEMORY_H
/* ========================== *
* Memory operations
* ========================== */
#define MEMZERO_STRUCT(ptr) MEMZERO((ptr), sizeof(*(ptr)))
#define MEMZERO_ARRAY(a) MEMZERO((a), sizeof((a)))
@ -23,4 +24,13 @@ void *memset(void *dst, i32 c, u64 n);
i32 memcmp(const void *p1, const void *p2, u64 n);
#endif
#endif
/* ========================== *
* Memory allocation
* ========================== */
void *memory_reserve(u64 size);
void memory_release(void *address);
void *memory_commit(void *address, u64 size);
void memory_decommit(void *address, u64 size);
void memory_set_committed_readonly(void *address, u64 size);
void memory_set_committed_readwrite(void *address, u64 size);

View File

@ -1,10 +1,17 @@
#include "rand.h"
#include "sys.h"
#include "memory.h"
/* TODO: Use a value that gives good precision when dividing into range 0 -> 1 */
#define F64_RAND_MAX U64_MAX
#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)
{
BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (u8 *)buffer.text, buffer.len, 0);
}
#else
# error rand_true not implemented for this platform
#endif
/* ========================== *
* Stateful prng
* ========================== */
@ -13,7 +20,7 @@ u64 rand_u64_from_state(struct rand_state *state)
{
u64 seed = state->seed;
if (seed == 0) {
sys_true_rand(STRING_FROM_STRUCT(&seed));
rand_true(STRING_FROM_STRUCT(&seed));
state->seed = seed;
}
return seed ^ rand_u64_from_seed(++state->counter);

View File

@ -1,17 +1,14 @@
#ifndef RAND_H
#define RAND_H
struct rand_state {
/* 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);
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_seed(u64 seed);
u64 rand_u64_from_seeds(u64 seed_a, u64 seed_b);
f64 rand_f64_from_seed(u64 seed, f64 range_start, f64 range_end);
#endif

View File

@ -1,9 +1,3 @@
#include "string.h"
#include "arena.h"
#include "memory.h"
#include "math.h"
#include "uni.h"
/*
* NOTE: Strings should be considered ~IMMUTABLE~ slices
*

View File

@ -1,6 +1,3 @@
#ifndef STRING_H
#define STRING_H
struct string_array {
u64 count;
struct string *strings;
@ -135,5 +132,3 @@ 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);
#endif

View File

@ -1,12 +1,8 @@
#include "uid.h"
#include "rand.h"
#include "sys.h"
/* Returns a uid generated from the system's random number generator */
struct uid uid_true_rand(void)
{
struct uid res = ZI;
sys_true_rand(STRING_FROM_STRUCT(&res));
rand_true(STRING_FROM_STRUCT(&res));
return res;
}

View File

@ -1,7 +1,3 @@
#ifndef UID_H
#define UID_H
struct uid uid_true_rand(void);
struct uid uid_combine(struct uid a, struct uid b);
#endif
struct uid uid_combine(struct uid a, struct uid b);

View File

@ -1,5 +1,3 @@
#include "uni.h"
/* ========================== *
* utf8
* ========================== */

View File

@ -1,6 +1,3 @@
#ifndef UNI_H
#define UNI_H
/* ========================== *
* utf8
* ========================== */
@ -52,5 +49,3 @@ struct uni_encode_utf32_result {
struct uni_decode_utf32_result uni_decode_utf32(struct string32 str);
struct uni_encode_utf32_result uni_encode_utf32(u32 codepoint);
#endif

View File

@ -1,14 +1,3 @@
#ifndef UTIL_H
#define UTIL_H
#include "sys.h"
#include "string.h"
#include "memory.h"
#include "arena.h"
#include "atomic.h"
#include "math.h"
#include "snc.h"
/* Utility functions and stuff that don't have a home :( */
/* ========================== *
@ -256,49 +245,3 @@ INLINE void dict_remove_entry(struct dict *dict, struct dict_entry *entry)
dict->first_free = entry;
}
}
/* ========================== *
* Sleep frame
* ========================== */
INLINE void sleep_precise(i64 sleep_time_ns)
{
__prof;
i64 big_sleep = sys_current_scheduler_period_ns();
i64 tolerance = (f64)big_sleep * 0.5;
//i64 tolerance = 1000000000;
i64 now_ns = sys_time_ns();
i64 target_ns = now_ns + sleep_time_ns;
/* Sleep */
while (now_ns < target_ns - big_sleep - tolerance) {
__profn("Sleep part");
sys_wait(0, 0, 0, big_sleep);
now_ns = sys_time_ns();
}
/* Spin */
{
__profn("Sleep spin");
while (now_ns < target_ns) {
ix_pause();
now_ns = sys_time_ns();
}
}
}
INLINE void sleep_frame(i64 last_frame_time_ns, i64 target_dt_ns)
{
if (last_frame_time_ns != 0 && target_dt_ns > 0) {
i64 now_ns = sys_time_ns();
i64 last_frame_dt_ns = now_ns - last_frame_time_ns;
i64 sleep_time_ns = target_dt_ns - last_frame_dt_ns;
if (sleep_time_ns > 0) {
sleep_precise(sleep_time_ns);
}
}
}
#endif

View File

@ -1,6 +1,5 @@
#include "collider.h"
#include "math.h"
#include "arena.h"
#include "base/base.h"
#include "gstat.h"
/* How close can non-overlapping shapes be before collision is considered */

View File

@ -13,23 +13,23 @@ extern "C" {
* ========================== */
/* Intrinsic header info:
* <mmintrin.h> MMX
* <xmmintrin.h> SSE
* <emmintrin.h> SSE2
* <pmmintrin.h> SSE3
* <tmmintrin.h> SSSE3
* <smmintrin.h> SSE4.1
* <nmmintrin.h> SSE4.2
* <ammintrin.h> SSE4A
* <wmmintrin.h> AES
* <immintrin.h> AVX, AVX2, FMA
* <mmintrin.h" MMX
* <xmmintrin.h" SSE
* <emmintrin.h" SSE2
* <pmmintrin.h" SSE3
* <tmmintrin.h" SSSE3
* <smmintrin.h" SSE4.1
* <nmmintrin.h" SSE4.2
* <ammintrin.h" SSE4A
* <wmmintrin.h" AES
* <immintrin.h" AVX, AVX2, FMA
*/
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include <intrin.h>
#include <nmmintrin.h> /* SSE4.2 */
#include "stddef.h"
#include "stdint.h"
#include "stdarg.h"
#include "intrin.h"
#include "nmmintrin.h" /* SSE4.2 */
/* ========================== *
* Flag defaults
@ -86,7 +86,7 @@ extern "C" {
# define COMPILER_CLANG 0
# define COMPILER_MSVC 1
#else
# error "Unknown compiler"
# error Unknown compiler
#endif
/* Operating system */
@ -103,7 +103,7 @@ extern "C" {
# define PLATFORM_MAC 0
# define PLATFORM_LINUX 1
#else
# error "Unknown OS"
# error Unknown platform
#endif
#if defined(__cplusplus)
@ -260,12 +260,12 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#endif
/* alignof */
#if COMPILER_MSVC || (LANGUAGE_C && (__STDC_VERSION__ < 202311L))
#if (COMPILER_MSVC && LANGUAGE_C) || (LANGUAGE_C && (__STDC_VERSION__ < 202311L))
# define alignof(type) __alignof(type)
#endif
/* alignas */
#if COMPILER_MSVC || (LANGUAGE_C && __STDC_VERSION__ < 202311L)
#if (COMPILER_MSVC && LANGUAGE_C) || (LANGUAGE_C && __STDC_VERSION__ < 202311L)
# if COMPILER_MSVC
# define alignas(n) __declspec(align(n))
# else
@ -326,7 +326,7 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
# define WRITE_BARRIER() __asm__ volatile("" ::: "memory")
# define READ_BARRIER() __asm__ volatile("" ::: "memory")
#else
# error "Memory barriers not implemented"
# error Memory barriers not implemented
#endif
/* Cat */

View File

@ -1,6 +1,5 @@
#include "draw.h"
#include "arena.h"
#include "math.h"
#include "base/base.h"
#include "font.h"
#include "sprite.h"
#include "collider.h"

View File

@ -1,7 +1,7 @@
#ifndef DRAW_H
#define DRAW_H
#include "gp.h"
#include "gp/gp.h"
struct font;
struct font_startup_receipt;

10
src/dxc/dxc.cpp Normal file
View File

@ -0,0 +1,10 @@
extern "C"
{
#include "dxc.h"
}
#if PLATFORM_WINDOWS
# include "dxc_core_win32.cpp"
#else
# error Dxc core not implemented for this platform
#endif

8
src/dxc/dxc.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef DXC_H
#define DXC_H
#include "../base/base.h"
#include "dxc_core.h"
#endif

View File

@ -1,6 +1,3 @@
#ifndef DXC_H
#define DXC_H
struct dxc_compile_result {
struct string dxc;
struct string errors;
@ -8,5 +5,3 @@ struct dxc_compile_result {
};
struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_source, i32 num_args, struct string *args);
#endif

View File

@ -1,4 +1,3 @@
#if !RESOURCE_RELOADING
extern "C"
@ -18,18 +17,22 @@ struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_
#else
extern "C"
{
#include "dxc.h"
#include "arena.h"
#include "string.h"
}
#if COMPILER_CLANG
# pragma clang diagnostic ignored "-Wlanguage-extension-token"
#endif
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
#include <Windows.h>
#include <atlbase.h>
#include <dxcapi.h>
#include <d3d12shader.h>
#define _ALLOW_RTCc_IN_STL
#pragma warning(push, 0)
# define WIN32_LEAN_AND_MEAN
# define UNICODE
# define NTDDI_WIN11_DT 0x0C0A0000
# define NTDDI_VERSION 0x0A000000
# include <Windows.h>
# include <atlbase.h>
# include <dxcapi.h>
# include <d3d12shader.h>
#pragma warning(pop)
#pragma comment(lib, "d3dcompiler")
#pragma comment(lib, "dxcompiler")
@ -61,13 +64,16 @@ struct dxc_compile_result dxc_compile(struct arena *arena, struct string shader_
/* Compile */
CComPtr<IDxcResult> compile_results = 0;
dxc_compiler->Compile(&dxc_src_buffer, (LPCWSTR *)wstr_args, num_args, dxc_include_handler, IID_PPV_ARGS(&compile_results));
dxc_compiler->Compile(&dxc_src_buffer, (LPCWSTR *)wstr_args, (u32)num_args, dxc_include_handler, IID_PPV_ARGS(&compile_results));
/* Copy errors */
CComPtr<IDxcBlobUtf8> dxc_errors = 0;
compile_results->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&dxc_errors), 0);
if (dxc_errors != 0) {
res.errors = string_copy(arena, STRING(dxc_errors->GetStringLength(), (u8 *)dxc_errors->GetBufferPointer()));
struct string blob_str = ZI;
blob_str.len = dxc_errors->GetBufferSize();
blob_str.text = (u8 *)dxc_errors->GetBufferPointer();
res.errors = string_copy(arena, blob_str);
}
/* Get status */
@ -80,7 +86,10 @@ 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) {
res.dxc = string_copy(arena, STRING(dxc_shader->GetBufferSize(), (u8 *)dxc_shader->GetBufferPointer()));
struct 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

@ -1,11 +1,9 @@
#include "font.h"
#include "arena.h"
#include "ttf.h"
#include "base/base.h"
#include "ttf/ttf.h"
#include "gp/gp.h"
#include "asset_cache.h"
#include "resource.h"
#include "log.h"
#include "string.h"
#include "gp.h"
#define LOOKUP_TABLE_SIZE (256)
GLOBAL u32 g_font_codes[] = {

View File

@ -1,7 +1,7 @@
#ifndef FONT_H
#define FONT_H
#include "util.h"
#include "base/base.h"
struct asset;
struct asset_cache_startup_receipt;

7
src/gp/gp.c Normal file
View File

@ -0,0 +1,7 @@
#include "gp.h"
#if PLATFORM_WINDOWS
# include "gp_core_dx12.c"
#else
# error Gp core not implemented for this platform
#endif

12
src/gp/gp.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef GP_H
#define GP_H
#include "../base/base.h"
#include "../sys/sys.h"
#include "../tar/tar.h"
#include "../ase/ase.h"
#include "../dxc/dxc.h"
#include "gp_core.h"
#endif

View File

@ -1,6 +1,3 @@
#ifndef GP_H
#define GP_H
struct sys_window;
struct snc_counter;
@ -151,5 +148,3 @@ void gp_swapchain_wait(struct gp_swapchain *gp_swapchain);
* 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);
#endif

View File

@ -1,26 +1,12 @@
#include "gp.h"
#include "sys.h"
#include "arena.h"
#include "memory.h"
#include "string.h"
#include "app.h"
#include "log.h"
#include "atomic.h"
#include "util.h"
#include "rand.h"
#include "sprite.h"
#include "gstat.h"
#include "snc.h"
#include "ase.h"
#include "resource.h"
#include "tar.h"
#include "inc.h"
#include "dxc.h"
#include "watch.h"
#include "../sprite.h"
#include "../gstat.h"
#include "../resource.h"
#include "../inc.h"
#include "../watch.h"
/* Include common shader types */
#define SH_CPU 1
#include "sh/sh_common.h"
#include "../sh/sh_common.h"
#pragma warning(push, 0)
# define UNICODE

View File

@ -5,7 +5,7 @@
#if GSTAT_ENABLED
#include "atomic.h"
#include "base/base.h"
struct _gstats {
struct atomic64_padded GSTAT_SOCK_BYTES_SENT;

View File

@ -1,11 +1,6 @@
#include "host.h"
#include "arena.h"
#include "bitbuff.h"
#include "sys.h"
#include "util.h"
#include "log.h"
#include "buddy.h"
#include "atomic.h"
#include "base/base.h"
#include "sys/sys.h"
/* TODO:
*

View File

@ -1,8 +1,8 @@
#ifndef HOST_H
#define HOST_H
#include "sys.h"
#include "snc.h"
#include "base/base.h"
#include "sys/sys.h"
#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 }

View File

@ -1,5 +1,5 @@
#include "inc.h"
#include "incbin.h"
#include "base/base.h"
/* This is the file that actually includes binary data meant to be embedded in
* the executable. Embedded files should be added as dependencies to this source

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

@ -0,0 +1,3 @@
#include "json.h"
#include "json_core.c"

8
src/json/json.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef JSON_H
#define JSON_H
#include "../base/base.h"
#include "json_core.h"
#endif

View File

@ -1,9 +1,3 @@
#include "json.h"
#include "arena.h"
#include "string.h"
#include "arena.h"
#include "math.h"
/* TODO (if we want to be JSON standard compliant):
* - Support unicode escape sequences in strings (\u)
* - Don't allow leading 0s in numbers

View File

@ -1,6 +1,3 @@
#ifndef JSON_H
#define JSON_H
enum json_type {
JSON_TYPE_NULL,
JSON_TYPE_BOOL,
@ -45,5 +42,3 @@ struct json_parse_result {
};
struct json_parse_result json_from_string(struct arena *arena, struct string src);
#endif

View File

@ -1,36 +0,0 @@
#include "memory.h"
#if !CRTLIB
__attribute((section(".text.memcpy")))
void *memcpy(void *__restrict dst, const void *__restrict src, u64 n)
{
for (u64 i = 0; i < n; ++i) {
((u8 *)dst)[i] = ((u8 *)src)[i];
}
return dst;
}
__attribute((section(".text.memset")))
void *memset(void *dst, i32 c, u64 n)
{
for (u64 i = 0; i < n; ++i) {
((u8 *)dst)[i] = c;
}
return dst;
}
__attribute((section(".text.memcmp")))
i32 memcmp(const void *p1, const void *p2, u64 n)
{
i32 res = 0;
for (u64 i = 0; i < n; ++i) {
res = ((u8 *)p1)[i] - ((u8 *)p2)[i];
if (res != 0) {
break;
}
}
return res;
}
#endif /* !CRTLIB */

View File

@ -1,9 +1,7 @@
#include "mixer.h"
#include "arena.h"
#include "base/base.h"
#include "sys/sys.h"
#include "sound.h"
#include "sys.h"
#include "math.h"
#include "snc.h"
/* TODO: Cap max sounds playing. */

7
src/mp3/mp3.c Normal file
View File

@ -0,0 +1,7 @@
#include "mp3.h"
#if PLATFORM_WINDOWS
# include "mp3_core_mmf.c"
#else
# error Mp3 core not implemented for this platform
#endif

8
src/mp3/mp3.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef MP3_H
#define MP3_H
#include "../base/base.h"
#include "mp3_core.h"
#endif

View File

@ -1,6 +1,3 @@
#ifndef MP3
#define MP3
#define MP3_DECODE_FLAG_NONE 0x00
#define MP3_DECODE_FLAG_STEREO 0x01
@ -9,6 +6,4 @@ struct mp3_decode_result {
b32 success;
};
struct mp3_decode_result mp3_decode(struct arena *arena, struct string encoded, u32 flags);
#endif
struct mp3_decode_result mp3_decode(struct arena *arena, struct string encoded, u32 sample_rate, u32 flags);

View File

@ -2,12 +2,6 @@
* Microsoft Media Foundation (MMF) mp3 decoder
* ========================== */
#include "mp3.h"
#include "arena.h"
#include "playback.h"
#pragma warning(push, 0)
# define COBJMACROS
# define WIN32_LEAN_AND_MEAN
@ -24,11 +18,9 @@
#pragma comment(lib, "mfreadwrite")
#pragma comment(lib, "shlwapi")
struct mp3_decode_result mp3_decode(struct arena *arena, struct string encoded, u32 flags)
struct mp3_decode_result mp3_decode(struct arena *arena, struct string encoded, u32 sample_rate, u32 flags)
{
struct mp3_decode_result res = ZI;
u64 sample_rate = PLAYBACK_SAMPLE_RATE;
u64 bytes_per_sample = 2;
u64 channel_count;

View File

@ -1,8 +1,6 @@
#ifndef PLAYBACK_H
#define PLAYBACK_H
#define PLAYBACK_SAMPLE_RATE 48000
struct mixer_startup_receipt;
struct playback_startup_receipt { i32 _; };

View File

@ -6,12 +6,10 @@
* ========================== */
#include "playback.h"
#include "arena.h"
#include "sys.h"
#include "base/base.h"
#include "sys/sys.h"
#include "mixer.h"
#include "atomic.h"
#include "app.h"
#include "snc.h"
#define COBJMACROS
#define WIN32_LEAN_AND_MEAN
@ -33,6 +31,8 @@ DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1, 0x78, 0x
DEFINE_GUID(IID_IAudioClient3, 0x7ed4ee07, 0x8e67, 0x4cd4, 0x8c, 0x1a, 0x2b, 0x7a, 0x59, 0x87, 0xad, 0x42);
DEFINE_GUID(IID_IAudioRenderClient, 0xf294acfc, 0x3146, 0x4483, 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2);
#define PLAYBACK_SAMPLE_RATE 48000
struct wasapi_buffer {
u32 frames_count;
u8 *frames;

View File

@ -4,7 +4,7 @@
#if PROFILING
#if COMPILER_MSVC
# error "MSVC not supported for profiling (cleanup attributes are required for profiling markup)"
# error MSVC not supported for profiling (cleanup attributes are required for profiling markup)
#endif
#define PROFILING_SYSTEM_TRACE 0

View File

@ -1,9 +1,8 @@
#include "resource.h"
#include "app.h"
#include "arena.h"
#include "tar.h"
#include "incbin.h"
#include "util.h"
#include "base/base.h"
#include "sys/sys.h"
#include "tar/tar.h"
/* ========================== *
* Global data

View File

@ -1,7 +1,7 @@
#ifndef RESOURCE_H
#define RESOURCE_H
#include "sys.h"
#include "sys/sys.h"
#define RESOURCE_NAME_LEN_MAX 256

View File

@ -1,8 +1,7 @@
#include "settings.h"
#include "arena.h"
#include "json.h"
#include "string.h"
#include "math.h"
#include "base/base.h"
#include "sys/sys.h"
#include "json/json.h"
struct string settings_serialize(struct arena *arena, const struct sys_window_settings *settings)
{

View File

@ -1,4 +1,4 @@
#include "common.hlsl"
#include "sh/common.hlsl"
ConstantBuffer<struct sh_blit_sig> sig : register(b0);

View File

@ -1,4 +1,4 @@
#include "sh_common.h"
#include "sh/sh_common.h"
#define TAU 6.28318530718
#define PI 3.14159265359

View File

@ -1,4 +1,4 @@
#include "common.hlsl"
#include "sh/common.hlsl"
ConstantBuffer<struct sh_flood_sig> sig : register(b0);

View File

@ -1,4 +1,4 @@
#include "common.hlsl"
#include "sh/common.hlsl"
ConstantBuffer<struct sh_material_sig> sig : register(b0);

View File

@ -1,4 +1,4 @@
#include "common.hlsl"
#include "sh/common.hlsl"
ConstantBuffer<struct sh_shade_sig> sig : register(b0);

View File

@ -1,4 +1,4 @@
#include "common.hlsl"
#include "sh/common.hlsl"
ConstantBuffer<struct sh_shape_sig> sig : register(b0);

View File

@ -1,4 +1,4 @@
#include "common.hlsl"
#include "sh/common.hlsl"
ConstantBuffer<struct sh_ui_sig> sig : register(b0);

6
src/sim/sim.c Normal file
View File

@ -0,0 +1,6 @@
#include "sim.h"
#include "sim_core.c"
#include "sim_ent.c"
#include "sim_phys.c"
#include "sim_step.c"

16
src/sim/sim.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef SIM_H
#define SIM_H
#include "../base/base.h"
#include "../collider.h"
#include "../sprite.h"
#include "../space.h"
#include "../host.h"
#include "../mixer.h"
#include "sim_core.h"
#include "sim_phys.h"
#include "sim_ent.h"
#include "sim_step.h"
#endif

View File

@ -1,11 +1,3 @@
#include "sim.h"
#include "sim_ent.h"
#include "host.h"
#include "arena.h"
#include "util.h"
#include "arena.h"
#include "bitbuff.h"
/* Sim hierarchy is as follows:
*
* Client store -> clients -> snapshots -> ents

View File

@ -1,6 +1,3 @@
#ifndef SIM_H
#define SIM_H
#define SIM_CLIENT_NIL_HANDLE ((struct sim_client_handle) { .gen = 0, .idx = 0 })
/* Absolute layers */
@ -249,12 +246,3 @@ void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *
/* 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);
#endif

View File

@ -1,10 +1,3 @@
#include "sim_ent.h"
#include "sim.h"
#include "math.h"
#include "bitbuff.h"
#include "uid.h"
#include "rand.h"
/* 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))

View File

@ -1,11 +1,3 @@
#ifndef SIM_ENT_H
#define SIM_ENT_H
#include "sim.h"
#include "sprite.h"
#include "mixer.h"
#include "phys.h"
#define SIM_ENT_NIL_ID ((struct sim_ent_id) { UID(0, 0) })
#define SIM_ENT_ROOT_ID ((struct sim_ent_id) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
@ -559,5 +551,3 @@ 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);
#endif

View File

@ -1,11 +1,3 @@
#include "phys.h"
#include "arena.h"
#include "sim_ent.h"
#include "sim_step.h"
#include "math.h"
#include "space.h"
#include "uid.h"
#define CONTACT_SPRING_HZ 25
#define CONTACT_SPRING_DAMP 10

View File

@ -1,9 +1,3 @@
#ifndef PHYS_H
#define PHYS_H
#include "collider.h"
#include "math.h"
struct space;
struct sim_ent_lookup;
struct sim_step_ctx;
@ -248,5 +242,3 @@ void phys_update_aabbs(struct phys_step_ctx *ctx);
* ========================== */
void phys_step(struct phys_step_ctx *ctx, f32 timestep);
#endif

View File

@ -1,21 +1,3 @@
#include "sim_step.h"
#include "sim_ent.h"
#include "sim.h"
#include "sys.h"
#include "arena.h"
#include "util.h"
#include "sprite.h"
#include "math.h"
#include "atomic.h"
#include "app.h"
#include "log.h"
#include "phys.h"
#include "collider.h"
#include "rand.h"
#include "space.h"
#include "bitbuff.h"
#include "host.h"
/* ========================== *
* Sim accel
* ========================== */

View File

@ -1,8 +1,3 @@
#ifndef SIM_STEP_H
#define SIM_STEP_H
#include "rand.h"
struct space;
struct sim_snapshot;
struct sim_snapshot_list;
@ -40,5 +35,3 @@ struct sim_step_ctx {
};
void sim_step(struct sim_step_ctx *ctx);
#endif

View File

@ -1,10 +1,11 @@
#include "sound.h"
#include "arena.h"
#include "log.h"
#include "sys.h"
#include "base/base.h"
#include "sys/sys.h"
#include "resource.h"
#include "asset_cache.h"
#include "mp3.h"
#include "mp3/mp3.h"
#define SOUND_SAMPLE_RATE 48000
struct sound_task_params {
struct sound_task_params *next_free;
@ -98,7 +99,7 @@ INTERNAL SYS_JOB_DEF(sound_load_asset_job, job)
if (flags & SOUND_FLAG_STEREO) {
decode_flags |= MP3_DECODE_FLAG_STEREO;
}
decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), decode_flags);
decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), SOUND_SAMPLE_RATE, decode_flags);
if (!decoded.success) {
error_msg = LIT("Failed to decode sound file");
}

View File

@ -1,6 +1,5 @@
#include "space.h"
#include "math.h"
#include "arena.h"
#include "base/base.h"
#include "collider.h"
/* FIXME: Default space entry & cell pointers to nil */

View File

@ -1,16 +1,10 @@
#include "sprite.h"
#include "arena.h"
#include "log.h"
#include "sys.h"
#include "base/base.h"
#include "sys/sys.h"
#include "ase/ase.h"
#include "resource.h"
#include "ase.h"
#include "util.h"
#include "atomic.h"
#include "app.h"
#include "gp.h"
#include "math.h"
#include "rand.h"
#include "snc.h"
#include "gp/gp.h"
#include "watch.h"
/* The evictor will begin evicting once cache usage is > threshold.

View File

@ -1,7 +1,7 @@
#ifndef SPRITE_H
#define SPRITE_H
#include "util.h"
#include "base/base.h"
struct sprite_sheet_span;
struct sprite_sheet_slice_group;

6
src/sys/sys.c Normal file
View File

@ -0,0 +1,6 @@
#include "sys.h"
#include "sys_snc.c"
#include "sys_sleep.c"
#include "sys_core.c"
#include "sys_log.c"

13
src/sys/sys.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef SYS_H
#define SYS_H
#include "../base/base.h"
#include "../app.h"
#include "../gstat.h"
#include "sys_snc.h"
#include "sys_sleep.h"
#include "sys_core.h"
#include "sys_log.h"
#endif

5
src/sys/sys_core.c Normal file
View File

@ -0,0 +1,5 @@
#if PLATFORM_WINDOWS
# include "sys_core_win32.c"
#else
# error System core layer not implemented
#endif

View File

@ -1,8 +1,3 @@
#ifndef SYS_H
#define SYS_H
struct snc_counter;
/* ========================== *
* Wait
* ========================== */
@ -11,19 +6,11 @@ struct snc_counter;
void sys_wait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns);
void sys_wake(void *addr, i32 count);
/* ========================== *
* Fiber
* ========================== */
#define SYS_MAX_FIBERS 4096
i16 sys_current_fiber_id(void);
/* ========================== *
* Job
* ========================== */
/* Work pools contain their own worker threads with their own thread priority/affinity based on the intended context of the pool. */
/* Work pools contain their own worker threads with their own thread priority/affinity based on the intended context of the pool. */
enum sys_pool {
SYS_POOL_INHERIT = -1,
@ -59,44 +46,6 @@ typedef SYS_JOB_DEF(sys_job_func, job_data);
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter);
/* ========================== *
* Scratch context
* ========================== */
#define SYS_SCRATCH_ARENAS_PER_CTX 2
struct sys_scratch_ctx {
struct arena *arenas[SYS_SCRATCH_ARENAS_PER_CTX];
};
struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 fiber_id);
/* ========================== *
* Memory
* ========================== */
/* Reserve a continuous block of virtual address space. Shouldn't be
* read / written to until memory is committed.
* NOTE: Guaranteed to be 16 byte aligned. */
void *sys_memory_reserve(u64 size);
/* Release a continuous block of virtual address space. Before releasing,
* decommit any committed memory within the reserved space to be safe. */
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 reserved
* address space) */
void sys_memory_decommit(void *address, u64 size);
/* Mark committed pages as readonly */
void sys_memory_set_committed_readonly(void *address, u64 size);
/* Mark committed pages as readable & writeable (default for committed memory) */
void sys_memory_set_committed_readwrite(void *address, u64 size);
/* ========================== *
* Time
* ========================== */
@ -502,8 +451,6 @@ void sys_set_clipboard_text(struct string str);
struct string sys_get_clipboard_text(struct arena *arena);
void sys_true_rand(struct string b);
u32 sys_num_logical_processors(void);
u32 sys_current_thread_id(void);
@ -533,5 +480,3 @@ void sys_panic(struct string msg);
/* Must be defined by app */
void sys_app_startup(struct string args_str);
#endif

View File

@ -1,16 +1,3 @@
#include "sys.h"
#include "memory.h"
#include "arena.h"
#include "app.h"
#include "string.h"
#include "atomic.h"
#include "log.h"
#include "math.h"
#include "util.h"
#include "uni.h"
#include "resource.h"
#include "gstat.h"
#pragma warning(push, 0)
# define UNICODE
# define WIN32_LEAN_AND_MEAN
@ -205,8 +192,6 @@ struct alignas(64) fiber {
/* ---------------------------------------------------- */
/* -------------------- Cache line -------------------- */
/* ---------------------------------------------------- */
struct sys_scratch_ctx scratch_ctx; /* 16 bytes */
/* ---------------------------------------------------- */
sys_job_func *job_func; /* 08 bytes */
/* ---------------------------------------------------- */
void *job_sig; /* 08 bytes */
@ -219,13 +204,12 @@ struct alignas(64) fiber {
/* ---------------------------------------------------- */
struct yield_param *yield_param; /* 08 bytes */
/* ---------------------------------------------------- */
u8 _pad3[8]; /* 08 bytes (padding) */
u8 _pad3[24]; /* 24 bytes (padding) */
};
STATIC_ASSERT(sizeof(struct fiber) == 128); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct fiber) == 64); /* Avoid false sharing */
STATIC_ASSERT(offsetof(struct fiber, wake_lock) % 4 == 0); /* Atomic must be aligned */
STATIC_ASSERT(SYS_MAX_FIBERS < I16_MAX); /* Max fibers should fit in fiber id */
struct alignas(64) worker_ctx {
enum sys_pool pool_kind;
@ -338,7 +322,7 @@ GLOBAL struct {
struct ticket_mutex fibers_lock;
i16 num_fibers;
struct arena *fiber_names_arena;
struct fiber fibers[SYS_MAX_FIBERS];
struct fiber fibers[MAX_FIBERS];
/* Wait lists */
struct atomic64_padded waiter_wake_gen;
@ -528,7 +512,7 @@ INTERNAL void thread_wait_release(struct thread *thread)
void sys_wait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns)
{
struct fiber *fiber = fiber_from_id(sys_current_fiber_id());
struct fiber *fiber = fiber_from_id(FiberId());
i16 parent_id = fiber->parent_id;
if (parent_id != 0) {
*fiber->yield_param = (struct yield_param) {
@ -853,7 +837,7 @@ INTERNAL struct fiber *fiber_alloc(struct job_pool *pool)
{
{
fiber_id = G.num_fibers++;
if (fiber_id >= SYS_MAX_FIBERS) {
if (fiber_id >= MAX_FIBERS) {
sys_panic(LIT("Max fibers reached"));
}
fiber = &G.fibers[fiber_id];
@ -909,14 +893,6 @@ INTERNAL struct fiber *fiber_alloc(struct job_pool *pool)
__profn("ConvertThreadToFiber");
fiber->addr = ConvertThreadToFiber((void *)(i64)fiber_id);
}
/* Init scratch context */
{
__profn("Initialize scratch context");
for (u32 i = 0; i < countof(fiber->scratch_ctx.arenas); ++i) {
fiber->scratch_ctx.arenas[i] = arena_alloc(GIBI(64));
}
}
}
fiber->wait_addr = 0;
fiber->wait_time = 0;
@ -962,11 +938,6 @@ INTERNAL FORCE_NO_INLINE void fiber_resume(struct fiber *fiber)
MemoryBarrier();
}
i16 sys_current_fiber_id(void)
{
return (i16)(i64)GetFiberData();
}
/* ========================== *
* Job
* ========================== */
@ -974,7 +945,7 @@ i16 sys_current_fiber_id(void)
INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber)
{
(UNUSED)fiber;
ASSERT(fiber->id == sys_current_fiber_id());
ASSERT(fiber->id == FiberId());
ASSERT(parent_fiber->id == fiber->parent_id);
ASSERT(parent_fiber->id > 0);
{
@ -1025,7 +996,7 @@ void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind,
if (counter) {
snc_counter_add(counter, count);
}
struct fiber *fiber = fiber_from_id(sys_current_fiber_id());
struct fiber *fiber = fiber_from_id(FiberId());
priority = clamp_i32(priority, fiber->job_priority, NUM_SYS_PRIORITIES - 1); /* A job cannot create a job with a higher priority than itself */
if (pool_kind == SYS_POOL_INHERIT) {
pool_kind = fiber->job_pool;
@ -1127,7 +1098,7 @@ INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg)
}
}
i32 worker_fiber_id = sys_current_fiber_id();
i32 worker_fiber_id = FiberId();
struct fiber *job_fiber = 0;
b32 shutdown = 0;
@ -1466,54 +1437,6 @@ INTERNAL THREAD_DEF(job_scheduler_entry, _)
}
}
/* ========================== *
* Scratch context
* ========================== */
struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 id)
{
struct fiber *fiber = fiber_from_id(id);
return &fiber->scratch_ctx;
}
/* ========================== *
* Memory
* ========================== */
void *sys_memory_reserve(u64 size)
{
void *ptr = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS);
return ptr;
}
void sys_memory_release(void *address)
{
VirtualFree(address, 0, MEM_RELEASE);
}
void *sys_memory_commit(void *address, u64 size)
{
void *ptr = VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE);
return ptr;
}
void sys_memory_decommit(void *address, u64 size)
{
VirtualFree(address, size, MEM_DECOMMIT);
}
void sys_memory_set_committed_readonly(void *address, u64 size)
{
DWORD old;
VirtualProtect(address, size, PAGE_READONLY, &old);
}
void sys_memory_set_committed_readwrite(void *address, u64 size)
{
DWORD old;
VirtualProtect(address, size, PAGE_READWRITE, &old);
}
/* ========================== *
* Time
* ========================== */
@ -3238,11 +3161,6 @@ struct string sys_get_clipboard_text(struct arena *arena)
return res;
}
void sys_true_rand(struct string b)
{
BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (PUCHAR)b.text, b.len, 0);
}
u32 sys_num_logical_processors(void)
{
return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);

View File

@ -1,9 +1,3 @@
#include "arena.h"
#include "log.h"
#include "string.h"
#include "atomic.h"
#include "snc.h"
struct log_event_callback {
log_event_callback_func *func;
struct log_event_callback *next;
@ -14,7 +8,7 @@ struct log_event_callback {
* Global state
* ========================== */
GLOBAL struct {
struct shared_log_ctx {
struct atomic32 initialized;
struct snc_mutex callbacks_mutex;
@ -24,9 +18,10 @@ GLOBAL struct {
struct sys_file file;
b32 file_valid;
} G = ZI, DEBUG_ALIAS(G, G_log);
};
GLOBAL READONLY struct log_level_settings g_log_level_settings[LOG_LEVEL_COUNT] = {
GLOBAL struct shared_log_ctx g_shared_log_ctx = ZI;
GLOBAL READONLY struct log_level_settings g_log_settings[LOG_LEVEL_COUNT] = {
[LOG_LEVEL_CRITICAL] = {
LIT_NOCAST("CRITICAL"),
COLOR_PURPLE
@ -65,17 +60,18 @@ GLOBAL READONLY struct log_level_settings g_log_level_settings[LOG_LEVEL_COUNT]
void log_startup(struct string logfile_path)
{
__prof;
G.callbacks_arena = arena_alloc(MEBI(8));
struct shared_log_ctx *ctx = &g_shared_log_ctx;
ctx->callbacks_arena = arena_alloc(MEBI(8));
if (logfile_path.len > 0) {
/* Create / wipe log file */
sys_file_close(sys_file_open_write(logfile_path));
/* Keep log file open for appending */
if (sys_is_file(logfile_path)) {
G.file = sys_file_open_append(logfile_path);
G.file_valid = 1;
ctx->file = sys_file_open_append(logfile_path);
ctx->file_valid = 1;
}
}
atomic32_fetch_set(&G.initialized, 1);
atomic32_fetch_set(&ctx->initialized, 1);
}
/* ========================== *
@ -84,18 +80,19 @@ void log_startup(struct string logfile_path)
void log_register_callback(log_event_callback_func *func, i32 level)
{
if (!atomic32_fetch(&G.initialized)) { return; }
struct snc_lock lock = snc_lock_e(&G.callbacks_mutex);
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
struct snc_lock lock = snc_lock_e(&ctx->callbacks_mutex);
{
struct log_event_callback *callback = arena_push(G.callbacks_arena, struct log_event_callback);
struct log_event_callback *callback = arena_push(ctx->callbacks_arena, struct log_event_callback);
callback->func = func;
callback->level = level;
if (G.last_callback) {
G.last_callback->next = callback;
if (ctx->last_callback) {
ctx->last_callback->next = callback;
} else {
G.first_callback = callback;
ctx->first_callback = callback;
}
G.last_callback = callback;
ctx->last_callback = callback;
}
snc_unlock(&lock);
}
@ -107,12 +104,13 @@ void log_register_callback(log_event_callback_func *func, i32 level)
INTERNAL void append_to_logfile(struct string msg)
{
__prof;
if (!atomic32_fetch(&G.initialized)) { return; }
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
if (G.file_valid) {
if (ctx->file_valid) {
struct arena_temp scratch = scratch_begin_no_conflict();
struct string msg_line = string_cat(scratch.arena, msg, LIT("\n"));
sys_file_write(G.file, msg_line);
sys_file_write(ctx->file, msg_line);
scratch_end(scratch);
}
}
@ -121,12 +119,13 @@ INTERNAL void append_to_logfile(struct string msg)
* writing to log file. */
void _log_panic(struct string msg)
{
if (!atomic32_fetch(&G.initialized)) { return; }
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
if (G.file_valid) {
sys_file_write(G.file, LIT("******** PANICKING ********\n"));
sys_file_write(G.file, msg);
sys_file_write(G.file, LIT("\n***************************\n"));
if (ctx->file_valid) {
sys_file_write(ctx->file, LIT("******** PANICKING ********\n"));
sys_file_write(ctx->file, msg);
sys_file_write(ctx->file, LIT("\n***************************\n"));
}
}
@ -137,7 +136,8 @@ void _log(i32 level, struct string msg)
#endif
{
__prof;
if (!atomic32_fetch(&G.initialized)) { return; }
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
if (level < 0 || level >= LOG_LEVEL_COUNT) {
sys_panic(LIT("Invalid log level"));
@ -150,7 +150,7 @@ void _log(i32 level, struct string msg)
u32 tid = sys_current_thread_id();
struct log_level_settings settings = g_log_level_settings[level];
struct log_level_settings settings = g_log_settings[level];
struct string shorthand = settings.shorthand;
#if LOG_INCLUDE_SOURCE_LOCATION
@ -214,8 +214,8 @@ void _log(i32 level, struct string msg)
event.line = line;
#endif
{
struct snc_lock lock = snc_lock_s(&G.callbacks_mutex);
for (struct log_event_callback *callback = G.first_callback; callback; callback = callback->next) {
struct snc_lock lock = snc_lock_s(&ctx->callbacks_mutex);
for (struct log_event_callback *callback = ctx->first_callback; callback; callback = callback->next) {
if (level <= callback->level) {
__profn("Run log callback");
callback->func(event);
@ -233,7 +233,8 @@ void _logfv(i32 level, struct string file, u32 line, struct string fmt, va_list
void _logfv(i32 level, struct string fmt, va_list args)
#endif
{
if (!atomic32_fetch(&G.initialized)) { return; }
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);
#if LOG_INCLUDE_SOURCE_LOCATION
@ -250,7 +251,8 @@ void _logf(i32 level, struct string file, u32 line, struct string fmt, ...)
void _logf(i32 level, struct string fmt, ...)
#endif
{
if (!atomic32_fetch(&G.initialized)) { return; }
struct shared_log_ctx *ctx = &g_shared_log_ctx;
if (!atomic32_fetch(&ctx->initialized)) { return; }
va_list args;
va_start(args, fmt);
#if LOG_INCLUDE_SOURCE_LOCATION

View File

@ -1,9 +1,3 @@
#ifndef LOG_H
#define LOG_H
#include "string.h"
#include "sys.h"
#define LOG_LEVEL(l) (l <= LOG_LEVEL_COMPTIME)
/* Log level configuration */
@ -165,5 +159,3 @@ void _logf(i32 level, struct string file, u32 line, struct string fmt, ...);
#else
void _logf(i32 level, struct string fmt, ...);
#endif
#endif

39
src/sys/sys_sleep.c Normal file
View File

@ -0,0 +1,39 @@
void sys_sleep_precise(i64 sleep_time_ns)
{
__prof;
i64 big_sleep = sys_current_scheduler_period_ns();
i64 tolerance = (f64)big_sleep * 0.5;
//i64 tolerance = 1000000000;
i64 now_ns = sys_time_ns();
i64 target_ns = now_ns + sleep_time_ns;
/* Sleep */
while (now_ns < target_ns - big_sleep - tolerance) {
__profn("Sleep part");
sys_wait(0, 0, 0, big_sleep);
now_ns = sys_time_ns();
}
/* Spin */
{
__profn("Sleep spin");
while (now_ns < target_ns) {
ix_pause();
now_ns = sys_time_ns();
}
}
}
void sys_sleep_frame(i64 last_frame_time_ns, i64 target_dt_ns)
{
if (last_frame_time_ns != 0 && target_dt_ns > 0) {
i64 now_ns = sys_time_ns();
i64 last_frame_dt_ns = now_ns - last_frame_time_ns;
i64 sleep_time_ns = target_dt_ns - last_frame_dt_ns;
if (sleep_time_ns > 0) {
sys_sleep_precise(sleep_time_ns);
}
}
}

3
src/sys/sys_sleep.h Normal file
View File

@ -0,0 +1,3 @@
void sys_sleep_precise(i64 sleep_time_ns);
void sys_sleep_frame(i64 last_frame_time_ns, i64 target_dt_ns);

View File

@ -1,9 +1,3 @@
#include "snc.h"
#include "atomic.h"
#include "sys.h"
#include "memory.h"
#include "intrinsics.h"
#define DEFAULT_MUTEX_SPIN 4000
/* ========================== *
@ -52,7 +46,7 @@ struct snc_lock snc_lock_spin_e(struct snc_mutex *m, i32 spin)
}
#if RTC
atomic32_fetch_set(&m->exclusive_fiber_id, sys_current_fiber_id());
atomic32_fetch_set(&m->exclusive_fiber_id, FiberId());
#endif
struct snc_lock lock = ZI;

View File

@ -1,6 +1,3 @@
#ifndef SNC_H
#define SNC_H
/* ========================== *
* Mutex
* ========================== */
@ -69,5 +66,3 @@ STATIC_ASSERT(alignof(struct snc_counter) == 64); /* Prevent false sharing */
void snc_counter_add(struct snc_counter *counter, i64 x);
void snc_counter_wait(struct snc_counter *counter);
#endif

Some files were not shown because too many files have changed in this diff Show More