Conditionally compile oogabooga global state instance with OOGABOOGA_LINK_EXTERNAL_INSTANCE

This commit is contained in:
Charlie Malmqvist 2024-07-22 19:19:57 +02:00
parent 9f5d20d3de
commit e61a294960
13 changed files with 345 additions and 153 deletions

View file

@ -3,9 +3,6 @@
/// ///
// Build config stuff // Build config stuff
#define OOGABOOGA_ENABLE_COMPLICATED_BUILD_MODE 1
#define OOGABOOGA_NO_IMPLEMENTATION 1
#define INITIAL_PROGRAM_MEMORY_SIZE MB(5) #define INITIAL_PROGRAM_MEMORY_SIZE MB(5)
// You might want to increase this if you get a log warning saying the temporary storage was overflown. // You might want to increase this if you get a log warning saying the temporary storage was overflown.
@ -30,9 +27,6 @@ typedef struct Context_Extra {
// Ooga booga needs to be included AFTER configuration and BEFORE the program code // Ooga booga needs to be included AFTER configuration and BEFORE the program code
#include "oogabooga/oogabooga.c" #include "oogabooga/oogabooga.c"
// #Volatile tutorial below
// #Volatile tutorial below
// #Volatile tutorial below
// //
// Comment & Uncomment these to swap projects (only include one at a time) // Comment & Uncomment these to swap projects (only include one at a time)

View file

@ -52,9 +52,15 @@ typedef struct Audio_Format {
int sample_rate; int sample_rate;
} Audio_Format; } Audio_Format;
// #Global
// Implemented per OS // Implemented per OS
forward_global Audio_Format audio_output_format; ogb_instance Audio_Format audio_output_format;
forward_global Mutex audio_init_mutex; ogb_instance Mutex audio_init_mutex;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Audio_Format audio_output_format;
Mutex audio_init_mutex;
#endif
// I don't see a big reason for you to use anything else than WAV and OGG. // I don't see a big reason for you to use anything else than WAV and OGG.
// If you use mp3 that's just not very smart. // If you use mp3 that's just not very smart.
@ -1172,7 +1178,12 @@ typedef struct Audio_Player_Block {
struct Audio_Player_Block *next; struct Audio_Player_Block *next;
} Audio_Player_Block; } Audio_Player_Block;
// #Global
ogb_instance Audio_Player_Block audio_player_block;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Audio_Player_Block audio_player_block = {0}; Audio_Player_Block audio_player_block = {0};
#endif
Audio_Player * Audio_Player *
audio_player_get_one() { audio_player_get_one() {
@ -1329,8 +1340,14 @@ audio_player_set_looping(Audio_Player *p, bool looping) {
spinlock_release(&p->sample_lock); spinlock_release(&p->sample_lock);
} }
// #Global
ogb_instance Hash_Table just_audio_clips;
ogb_instance bool just_audio_clips_initted;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Hash_Table just_audio_clips; Hash_Table just_audio_clips;
bool just_audio_clips_initted = false; bool just_audio_clips_initted = false;
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
void void
play_one_audio_clip_source_at_position(Audio_Source source, Vector3 pos) { play_one_audio_clip_source_at_position(Audio_Source source, Vector3 pos) {

View file

@ -9,8 +9,12 @@
#define null 0 #define null 0
void printf(const char* fmt, ...); ogb_instance void
void dump_stack_trace(); printf(const char* fmt, ...);
ogb_instance void
dump_stack_trace();
#define ASSERT_STR_HELPER(x) #x #define ASSERT_STR_HELPER(x) #x
#define ASSERT_STR(x) ASSERT_STR_HELPER(x) #define ASSERT_STR(x) ASSERT_STR_HELPER(x)
#define assert_line(line, cond, ...) {if(!(cond)) { printf("Assertion failed in file " __FILE__ " on line " ASSERT_STR(line) "\nFailed Condition: " #cond ". Message: " __VA_ARGS__); dump_stack_trace(); crash(); }} #define assert_line(line, cond, ...) {if(!(cond)) { printf("Assertion failed in file " __FILE__ " on line " ASSERT_STR(line) "\nFailed Condition: " #cond ". Message: " __VA_ARGS__); dump_stack_trace(); crash(); }}
@ -77,8 +81,11 @@ typedef struct Allocator {
void *data; void *data;
} Allocator; } Allocator;
Allocator get_heap_allocator(); ogb_instance Allocator
Allocator get_temporary_allocator(); get_heap_allocator();
ogb_instance Allocator
get_temporary_allocator();
typedef struct Context { typedef struct Context {
void *logger; // void(*Logger_Proc)(Log_Level level, string fmt, ...) void *logger; // void(*Logger_Proc)(Log_Level level, string fmt, ...)
@ -88,16 +95,42 @@ typedef struct Context {
CONTEXT_EXTRA extra; CONTEXT_EXTRA extra;
} Context; } Context;
forward_global thread_local Allocator temp;
#define CONTEXT_STACK_MAX 512 #define CONTEXT_STACK_MAX 512
//
//
thread_local ogb_instance Context context;
thread_local ogb_instance Context context_stack[CONTEXT_STACK_MAX];
thread_local ogb_instance u64 num_contexts;
ogb_instance void*
alloc(Allocator allocator, u64 size);
ogb_instance void*
alloc_uninitialized(Allocator allocator, u64 size);
ogb_instance void
dealloc(Allocator allocator, void *p);
ogb_instance void
push_context(Context c);
ogb_instance void
pop_context();
//
//
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
thread_local Context context; thread_local Context context;
thread_local Context context_stack[CONTEXT_STACK_MAX]; thread_local Context context_stack[CONTEXT_STACK_MAX];
thread_local u64 num_contexts = 0; thread_local u64 num_contexts = 0;
forward_global thread_local Allocator temp; void*
alloc(Allocator allocator, u64 size) {
void* memset(void* dest, int value, size_t amount);
void* alloc(Allocator allocator, u64 size) {
assert(size > 0, "You requested an allocation of zero bytes. I'm not sure what you want with that."); assert(size > 0, "You requested an allocation of zero bytes. I'm not sure what you want with that.");
void *p = allocator.proc(size, 0, ALLOCATOR_ALLOCATE, allocator.data); void *p = allocator.proc(size, 0, ALLOCATOR_ALLOCATE, allocator.data);
#if DO_ZERO_INITIALIZATION #if DO_ZERO_INITIALIZATION
@ -105,23 +138,29 @@ void* alloc(Allocator allocator, u64 size) {
#endif #endif
return p; return p;
} }
void* alloc_uninitialized(Allocator allocator, u64 size) {
void*
alloc_uninitialized(Allocator allocator, u64 size) {
assert(size > 0, "You requested an allocation of zero bytes. I'm not sure what you want with that."); assert(size > 0, "You requested an allocation of zero bytes. I'm not sure what you want with that.");
return allocator.proc(size, 0, ALLOCATOR_ALLOCATE, allocator.data); return allocator.proc(size, 0, ALLOCATOR_ALLOCATE, allocator.data);
} }
void dealloc(Allocator allocator, void *p) {
void
dealloc(Allocator allocator, void *p) {
assert(p != 0, "You tried to deallocate a pointer at adress 0. That doesn't make sense!"); assert(p != 0, "You tried to deallocate a pointer at adress 0. That doesn't make sense!");
allocator.proc(0, p, ALLOCATOR_DEALLOCATE, allocator.data); allocator.proc(0, p, ALLOCATOR_DEALLOCATE, allocator.data);
} }
void push_context(Context c) { void
push_context(Context c) {
assert(num_contexts < CONTEXT_STACK_MAX, "Context stack overflow"); assert(num_contexts < CONTEXT_STACK_MAX, "Context stack overflow");
context_stack[num_contexts] = context; context_stack[num_contexts] = context;
context = c; context = c;
num_contexts += 1; num_contexts += 1;
} }
void pop_context() { void
pop_context() {
assert(num_contexts > 0, "No contexts to pop!"); assert(num_contexts > 0, "No contexts to pop!");
num_contexts -= 1; num_contexts -= 1;
context = context_stack[num_contexts]; context = context_stack[num_contexts];
@ -129,7 +168,10 @@ void pop_context() {
u64 get_next_power_of_two(u64 x) { #endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
u64
get_next_power_of_two(u64 x) {
if (x == 0) { if (x == 0) {
return 1; return 1;
} }

View file

@ -1,4 +1,6 @@
// #Cleanup
// usage example: hex_to_rgba(0x2a2d3aff); // usage example: hex_to_rgba(0x2a2d3aff);
Vector4 hex_to_rgba(s64 hex) { Vector4 hex_to_rgba(s64 hex) {
u8 r = (hex>>24) & 0x000000FF; u8 r = (hex>>24) & 0x000000FF;

View file

@ -47,8 +47,7 @@ typedef struct Draw_Quad {
} Draw_Quad; } Draw_Quad;
Draw_Quad *quad_buffer;
u64 allocated_quads;
typedef struct Draw_Frame { typedef struct Draw_Frame {
u64 num_quads; u64 num_quads;
@ -65,9 +64,20 @@ typedef struct Draw_Frame {
void *cbuffer; void *cbuffer;
} Draw_Frame; } Draw_Frame;
// #Cleanup this should be in Draw_Frame
// #Global
ogb_instance Draw_Quad *quad_buffer;
ogb_instance u64 allocated_quads;
// This frame is passed to the platform layer and rendered in os_update. // This frame is passed to the platform layer and rendered in os_update.
// Resets every frame. // Resets every frame.
ogb_instance Draw_Frame draw_frame;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Draw_Quad *quad_buffer;
u64 allocated_quads;
Draw_Frame draw_frame = ZERO(Draw_Frame); Draw_Frame draw_frame = ZERO(Draw_Frame);
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
void reset_draw_frame(Draw_Frame *frame) { void reset_draw_frame(Draw_Frame *frame) {
*frame = (Draw_Frame){0}; *frame = (Draw_Frame){0};

View file

@ -20,7 +20,7 @@
#define VERTEX_2D_USER_DATA_COUNT 1 #define VERTEX_2D_USER_DATA_COUNT 1
#endif #endif
forward_global const Gfx_Handle GFX_INVALID_HANDLE; ogb_instance const Gfx_Handle GFX_INVALID_HANDLE;
// #Volatile reflected in 2D batch shader // #Volatile reflected in 2D batch shader
#define QUAD_TYPE_REGULAR 0 #define QUAD_TYPE_REGULAR 0
#define QUAD_TYPE_TEXT 1 #define QUAD_TYPE_TEXT 1
@ -37,26 +37,31 @@ typedef struct Gfx_Image {
Allocator allocator; Allocator allocator;
} Gfx_Image; } Gfx_Image;
Gfx_Image * ogb_instance Gfx_Image *
make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator allocator); make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator allocator);
Gfx_Image * ogb_instance Gfx_Image *
load_image_from_disk(string path, Allocator allocator); load_image_from_disk(string path, Allocator allocator);
void ogb_instance void
delete_image(Gfx_Image *image); delete_image(Gfx_Image *image);
// Implemented per renderer // Implemented per renderer
void ogb_instance void
gfx_init_image(Gfx_Image *image, void *data); gfx_init_image(Gfx_Image *image, void *data);
void ogb_instance void
gfx_set_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *data); gfx_set_image_data(Gfx_Image *image, u32 x, u32 y, u32 w, u32 h, void *data);
void ogb_instance void
gfx_deinit_image(Gfx_Image *image); gfx_deinit_image(Gfx_Image *image);
bool ogb_instance void
gfx_init();
ogb_instance void
gfx_update();
ogb_instance bool
shader_recompile_with_extension(string ext_source, u64 cbuffer_size); shader_recompile_with_extension(string ext_source, u64 cbuffer_size);
// initial_data can be null to leave image data uninitialized // initial_data can be null to leave image data uninitialized
Gfx_Image * ogb_instance Gfx_Image *
make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator allocator) { make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator allocator) {
Gfx_Image *image = alloc(allocator, sizeof(Gfx_Image) + width*height*channels); Gfx_Image *image = alloc(allocator, sizeof(Gfx_Image) + width*height*channels);
@ -73,7 +78,7 @@ make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator al
return image; return image;
} }
Gfx_Image * ogb_instance Gfx_Image *
load_image_from_disk(string path, Allocator allocator) { load_image_from_disk(string path, Allocator allocator) {
string png; string png;
bool ok = os_read_entire_file(path, &png, allocator); bool ok = os_read_entire_file(path, &png, allocator);
@ -110,7 +115,7 @@ load_image_from_disk(string path, Allocator allocator) {
return image; return image;
} }
void ogb_instance void
delete_image(Gfx_Image *image) { delete_image(Gfx_Image *image) {
// Free the image data allocated by stb_image // Free the image data allocated by stb_image
image->width = 0; image->width = 0;

View file

@ -130,7 +130,13 @@ typedef struct Input_Frame {
Input_State_Flags key_states[INPUT_KEY_CODE_COUNT]; Input_State_Flags key_states[INPUT_KEY_CODE_COUNT];
} Input_Frame; } Input_Frame;
// #Global
ogb_instance Input_Frame input_frame;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Input_Frame input_frame = ZERO(Input_Frame); Input_Frame input_frame = ZERO(Input_Frame);
#endif
bool has_key_state(Input_Key_Code code, Input_State_Flags flags) { bool has_key_state(Input_Key_Code code, Input_State_Flags flags) {
assert(code > 0 && code < INPUT_KEY_CODE_COUNT, "Invalid key code %d!", code); assert(code > 0 && code < INPUT_KEY_CODE_COUNT, "Invalid key code %d!", code);

View file

@ -5,8 +5,16 @@
#define GB(x) ((MB(x))*1024ull) #define GB(x) ((MB(x))*1024ull)
// #Global
ogb_instance void *program_memory;
ogb_instance u64 program_memory_size;
ogb_instance Mutex_Handle program_memory_mutex;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
void *program_memory = 0; void *program_memory = 0;
u64 program_memory_size = 0; u64 program_memory_size = 0;
Mutex_Handle program_memory_mutex = 0;
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
#ifndef INIT_MEMORY_SIZE #ifndef INIT_MEMORY_SIZE
#define INIT_MEMORY_SIZE KB(50) #define INIT_MEMORY_SIZE KB(50)
@ -87,9 +95,16 @@ typedef alignat(16) struct Heap_Allocation_Metadata {
#endif #endif
} Heap_Allocation_Metadata; } Heap_Allocation_Metadata;
// #Global
ogb_instance Heap_Block *heap_head;
ogb_instance bool heap_initted;
ogb_instance Spinlock heap_lock;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Heap_Block *heap_head; Heap_Block *heap_head;
bool heap_initted = false; bool heap_initted = false;
Spinlock heap_lock; // This is terrible but I don't care for now Spinlock heap_lock;
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
u64 get_heap_block_size_excluding_metadata(Heap_Block *block) { u64 get_heap_block_size_excluding_metadata(Heap_Block *block) {
@ -524,11 +539,20 @@ Allocator get_heap_allocator() {
void* talloc(u64); void* talloc(u64);
void* temp_allocator_proc(u64 size, void *p, Allocator_Message message, void*); void* temp_allocator_proc(u64 size, void *p, Allocator_Message message, void*);
// #Global
thread_local ogb_instance void * temporary_storage;
thread_local ogb_instance bool temporary_storage_initted;
thread_local ogb_instance void * temporary_storage_pointer;
thread_local ogb_instance bool has_warned_temporary_storage_overflow;
thread_local ogb_instance Allocator temp;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
thread_local void * temporary_storage = 0; thread_local void * temporary_storage = 0;
thread_local bool temporary_storage_initted = false; thread_local bool temporary_storage_initted = false;
thread_local void * temporary_storage_pointer = 0; thread_local void * temporary_storage_pointer = 0;
thread_local bool has_warned_temporary_storage_overflow = false; thread_local bool has_warned_temporary_storage_overflow = false;
thread_local Allocator temp; thread_local Allocator temp;
#endif
Allocator get_temporary_allocator() { Allocator get_temporary_allocator() {
return temp; return temp;

View file

@ -244,20 +244,12 @@ typedef u8 bool;
#error "Current OS not supported!"; #error "Current OS not supported!";
#endif #endif
#if OOGABOOGA_LINK_EXTERNAL_INSTANCE
#if OOGABOOGA_ENABLE_COMPLICATED_BUILD_MODE #define ogb_instance SHARED_IMPORT extern
#if OOGABOOGA_NO_IMPLEMENTATION
#define ogb_proc SHARED_IMPORT
#else #else
#define ogb_proc SHARED_EXPORT #define ogb_instance SHARED_EXPORT
#endif #endif
#else
#define ogb_proc
#endif
// This needs to be included before dependencies // This needs to be included before dependencies
#include "base.c" #include "base.c"
@ -323,6 +315,8 @@ typedef u8 bool;
#include "audio.c" #include "audio.c"
#endif #endif
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
#if TARGET_OS == WINDOWS #if TARGET_OS == WINDOWS
#include "os_impl_windows.c" #include "os_impl_windows.c"
#elif TARGET_OS == LINUX #elif TARGET_OS == LINUX
@ -346,6 +340,8 @@ typedef u8 bool;
#endif #endif
#endif #endif
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
#include "tests.c" #include "tests.c"
#define malloc please_use_alloc_for_memory_allocations_instead_of_malloc #define malloc please_use_alloc_for_memory_allocations_instead_of_malloc

View file

@ -48,7 +48,38 @@ typedef struct Os_Info {
void *static_memory_start, *static_memory_end; void *static_memory_start, *static_memory_end;
} Os_Info; } Os_Info;
typedef struct Os_Window {
// Keep in mind that setting these in runtime is potentially slow!
string title;
union { s32 width; s32 pixel_width; };
union { s32 height; s32 pixel_height; };
s32 scaled_width; // DPI scaled!
s32 scaled_height; // DPI scaled!
s32 x;
s32 y;
Vector4 clear_color;
bool enable_vsync;
bool should_close;
// readonly
bool _initialized;
Window_Handle _os_handle;
} Os_Window;
// #Global
ogb_instance Os_Window window;
ogb_instance Os_Info os;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Os_Info os; Os_Info os;
Os_Window window;
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
inline bool bytes_match(void *a, void *b, u64 count) { return memcmp(a, b, count) == 0; } inline bool bytes_match(void *a, void *b, u64 count) { return memcmp(a, b, count) == 0; }
@ -56,7 +87,7 @@ inline int vsnprintf(char* buffer, size_t n, const char* fmt, va_list args) {
return os.crt_vsnprintf(buffer, n, fmt, args); return os.crt_vsnprintf(buffer, n, fmt, args);
} }
Mutex_Handle program_memory_mutex = 0;
bool os_grow_program_memory(size_t new_size); bool os_grow_program_memory(size_t new_size);
@ -79,31 +110,52 @@ typedef struct Thread {
} Thread; } Thread;
/// ///
// Thread primitive // Thread primitive #Cleanup
DEPRECATED(Thread* os_make_thread(Thread_Proc proc, Allocator allocator), "Use os_thread_init instead"); DEPRECATED(Thread* os_make_thread(Thread_Proc proc, Allocator allocator), "Use os_thread_init instead");
DEPRECATED(void os_destroy_thread(Thread *t), "Use os_thread_destroy instead"); DEPRECATED(void os_destroy_thread(Thread *t), "Use os_thread_destroy instead");
DEPRECATED(void os_start_thread(Thread* t), "Use os_thread_start instead"); DEPRECATED(void os_start_thread(Thread* t), "Use os_thread_start instead");
DEPRECATED(void os_join_thread(Thread* t), "Use os_thread_join instead"); DEPRECATED(void os_join_thread(Thread* t), "Use os_thread_join instead");
void os_thread_init(Thread *t, Thread_Proc proc); void ogb_instance
void os_thread_destroy(Thread *t); os_thread_init(Thread *t, Thread_Proc proc);
void os_thread_start(Thread *t);
void os_thread_join(Thread *t); void ogb_instance
os_thread_destroy(Thread *t);
void ogb_instance
os_thread_start(Thread *t);
void ogb_instance
os_thread_join(Thread *t);
/// ///
// Low-level Mutex primitive. Mutex in concurrency.c is probably a better alternative. // Low-level Mutex primitive. Mutex in concurrency.c is probably a better alternative.
Mutex_Handle os_make_mutex(); Mutex_Handle ogb_instance
void os_destroy_mutex(Mutex_Handle m); os_make_mutex();
void os_lock_mutex(Mutex_Handle m);
void os_unlock_mutex(Mutex_Handle m); void ogb_instance
os_destroy_mutex(Mutex_Handle m);
void ogb_instance
os_lock_mutex(Mutex_Handle m);
void ogb_instance
os_unlock_mutex(Mutex_Handle m);
/// ///
// Threading utilities // Threading utilities
void os_sleep(u32 ms); void ogb_instance
void os_yield_thread(); os_sleep(u32 ms);
void os_high_precision_sleep(f64 ms);
void ogb_instance
os_yield_thread();
void ogb_instance
os_high_precision_sleep(f64 ms);
/// ///
/// ///
@ -111,28 +163,33 @@ void os_high_precision_sleep(f64 ms);
/// ///
DEPRECATED(u64 os_get_current_cycle_count(), "use rdtsc() instead"); DEPRECATED(u64 os_get_current_cycle_count(), "use rdtsc() instead");
float64 os_get_current_time_in_seconds();
float64 ogb_instance
os_get_current_time_in_seconds();
/// ///
/// ///
// Dynamic Libraries // Dynamic Libraries
/// ///
Dynamic_Library_Handle os_load_dynamic_library(string path); Dynamic_Library_Handle ogb_instance
void *os_dynamic_library_load_symbol(Dynamic_Library_Handle l, string identifier); os_load_dynamic_library(string path);
void os_unload_dynamic_library(Dynamic_Library_Handle l);
ogb_instance void*
os_dynamic_library_load_symbol(Dynamic_Library_Handle l, string identifier);
void ogb_instance
os_unload_dynamic_library(Dynamic_Library_Handle l);
/// ///
/// ///
// IO // IO
/// ///
forward_global const File OS_INVALID_FILE; ogb_instance const File OS_INVALID_FILE;
void os_write_string_to_stdout(string s); void ogb_instance
os_write_string_to_stdout(string s);
typedef enum Os_Io_Open_Flags { typedef enum Os_Io_Open_Flags {
O_READ = 0, O_READ = 0,
@ -142,38 +199,82 @@ typedef enum Os_Io_Open_Flags {
// To append, pass WRITE flag without CREATE flag // To append, pass WRITE flag without CREATE flag
} Os_Io_Open_Flags; } Os_Io_Open_Flags;
File os_file_open_s(string path, Os_Io_Open_Flags flags); File ogb_instance
void os_file_close(File f); os_file_open_s(string path, Os_Io_Open_Flags flags);
bool os_file_delete_s(string path);
bool os_make_directory_s(string path, bool recursive); void ogb_instance
bool os_delete_directory_s(string path, bool recursive); os_file_close(File f);
bool os_file_write_string(File f, string s); bool ogb_instance
bool os_file_write_bytes(File f, void *buffer, u64 size_in_bytes); os_file_delete_s(string path);
bool os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes);
bool os_file_set_pos(File f, s64 pos_in_bytes); bool ogb_instance
s64 os_file_get_pos(File f); os_make_directory_s(string path, bool recursive);
s64 os_file_get_size(File f); bool ogb_instance
s64 os_file_get_size_from_path(string path); os_delete_directory_s(string path, bool recursive);
bool os_write_entire_file_handle(File f, string data);
bool os_write_entire_file_s(string path, string data);
bool os_read_entire_file_handle(File f, string *result, Allocator allocator);
bool os_read_entire_file_s(string path, string *result, Allocator allocator);
bool os_is_file_s(string path); bool ogb_instance
bool os_is_directory_s(string path); os_file_write_string(File f, string s);
bool os_is_path_absolute(string path); bool ogb_instance
os_file_write_bytes(File f, void *buffer, u64 size_in_bytes);
bool os_get_absolute_path(string path, string *result, Allocator allocator);
bool os_get_relative_path(string from, string to, string *result, Allocator allocator);
bool os_do_paths_match(string a, string b); bool ogb_instance
os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes);
bool ogb_instance
os_file_set_pos(File f, s64 pos_in_bytes);
s64 ogb_instance
os_file_get_pos(File f);
s64 ogb_instance
os_file_get_size(File f);
s64 ogb_instance
os_file_get_size_from_path(string path);
bool ogb_instance
os_write_entire_file_handle(File f, string data);
bool ogb_instance
os_write_entire_file_s(string path, string data);
bool ogb_instance
os_read_entire_file_handle(File f, string *result, Allocator allocator);
bool ogb_instance
os_read_entire_file_s(string path, string *result, Allocator allocator);
bool ogb_instance
os_is_file_s(string path);
bool ogb_instance
os_is_directory_s(string path);
bool ogb_instance
os_is_path_absolute(string path);
bool ogb_instance
os_get_absolute_path(string path, string *result, Allocator allocator);
bool ogb_instance
os_get_relative_path(string from, string to, string *result, Allocator allocator);
bool ogb_instance
os_do_paths_match(string a, string b);
// It's a little unfortunate that we need to do this but I can't think of a better solution // It's a little unfortunate that we need to do this but I can't think of a better solution
@ -226,13 +327,18 @@ inline bool os_is_directory_f(const char *path) {return os_is_directory_s(STR(pa
void fprints(File f, string fmt, ...); void ogb_instance
void fprintf(File f, const char* fmt, ...); fprints(File f, string fmt, ...);
void ogb_instance
fprintf(File f, const char* fmt, ...);
#define fprint(...) _Generic((FIRST_ARG(__VA_ARGS__)), \ #define fprint(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
string: fprints, \ string: fprints, \
default: fprintf \ default: fprintf \
)(__VA_ARGS__) )(__VA_ARGS__)
void fprint_va_list_buffered(File f, const string fmt, va_list args) { void fprint_va_list_buffered(File f, const string fmt, va_list args) {
string current = fmt; string current = fmt;
@ -262,9 +368,9 @@ void fprint_va_list_buffered(File f, const string fmt, va_list args) {
/// ///
// Memory // Memory
/// ///
void* ogb_instance void*
os_get_stack_base(); os_get_stack_base();
void* ogb_instance void*
os_get_stack_limit(); os_get_stack_limit();
@ -272,7 +378,7 @@ os_get_stack_limit();
/// ///
// Debug // Debug
/// ///
string * ogb_instance string*
os_get_stack_trace(u64 *trace_count, Allocator allocator); os_get_stack_trace(u64 *trace_count, Allocator allocator);
void dump_stack_trace() { void dump_stack_trace() {
@ -285,34 +391,9 @@ void dump_stack_trace() {
} }
} }
#ifndef OOGABOOGA_HEADLESS void ogb_instance
os_init(u64 program_memory_size);
/// void ogb_instance
/// os_update();
// Window management
///
typedef struct Os_Window {
// Keep in mind that setting these in runtime is potentially slow!
string title;
union { s32 width; s32 pixel_width; };
union { s32 height; s32 pixel_height; };
s32 scaled_width; // DPI scaled!
s32 scaled_height; // DPI scaled!
s32 x;
s32 y;
Vector4 clear_color;
bool enable_vsync;
bool should_close;
// readonly
bool _initialized;
Window_Handle _os_handle;
} Os_Window;
Os_Window window;
#endif
void os_update();

View file

@ -1,6 +1,16 @@
// #Global
ogb_instance String_Builder _profile_output;
ogb_instance bool profiler_initted;
ogb_instance Spinlock _profiler_lock;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
String_Builder _profile_output = {0}; String_Builder _profile_output = {0};
bool profiler_initted = false; bool profiler_initted = false;
Spinlock _profiler_lock; Spinlock _profiler_lock;
#endif
void dump_profile_result() { void dump_profile_result() {
File file = os_file_open("google_trace.json", O_CREATE | O_WRITE); File file = os_file_open("google_trace.json", O_CREATE | O_WRITE);

View file

@ -5,8 +5,13 @@
#define MULTIPLIER 6364136223846793005ull #define MULTIPLIER 6364136223846793005ull
#define INCREMENT 1442695040888963407ull #define INCREMENT 1442695040888963407ull
// #Global
// set this to something like os_get_current_cycle_count() for very randomized seed // set this to something like os_get_current_cycle_count() for very randomized seed
ogb_instance u64 seed_for_random;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
u64 seed_for_random = 1; u64 seed_for_random = 1;
#endif
u64 get_random() { u64 get_random() {
seed_for_random = seed_for_random * MULTIPLIER + INCREMENT; seed_for_random = seed_for_random * MULTIPLIER + INCREMENT;

View file

@ -454,7 +454,7 @@ void test_strings() {
void test_file_io() { void test_file_io() {
#if TARGET_OS == WINDOWS #if TARGET_OS == WINDOWS && !OOGABOOGA_LINK_EXTERNAL_INSTANCE
// Test win32_fixed_utf8_to_null_terminated_wide // Test win32_fixed_utf8_to_null_terminated_wide
string utf8_str = STR("Test"); string utf8_str = STR("Test");
u16 *wide_str = win32_fixed_utf8_to_null_terminated_wide(utf8_str, get_heap_allocator()); u16 *wide_str = win32_fixed_utf8_to_null_terminated_wide(utf8_str, get_heap_allocator());