Refactor more to be able to build as dll and link a single global oogabooga instance, and made an example for a hot loaded game
This commit is contained in:
parent
fe3fea0c29
commit
4aa832a822
29 changed files with 549 additions and 112 deletions
6
build.c
6
build.c
|
@ -3,6 +3,8 @@
|
|||
///
|
||||
// Build config stuff
|
||||
|
||||
#define RUN_TESTS 1
|
||||
|
||||
#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.
|
||||
|
@ -37,10 +39,10 @@ typedef struct Context_Extra {
|
|||
|
||||
// #include "oogabooga/examples/text_rendering.c"
|
||||
// #include "oogabooga/examples/custom_logger.c"
|
||||
// #include "oogabooga/examples/renderer_stress_test.c"
|
||||
#include "oogabooga/examples/renderer_stress_test.c"
|
||||
// #include "oogabooga/examples/tile_game.c"
|
||||
// #include "oogabooga/examples/audio_test.c"
|
||||
#include "oogabooga/examples/custom_shader.c"
|
||||
// #include "oogabooga/examples/custom_shader.c"
|
||||
|
||||
// This is where you swap in your own project!
|
||||
// #include "entry_yourepicgamename.c"
|
||||
|
|
79
build_engine.c
Normal file
79
build_engine.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
|
||||
///
|
||||
// Build config stuff
|
||||
|
||||
#define OOGABOOGA_BUILD_SHARED_LIBRARY 1
|
||||
|
||||
#include "oogabooga/oogabooga.c"
|
||||
|
||||
///
|
||||
///
|
||||
// This is the "engine" part of your game, which will call into your game.dll
|
||||
|
||||
|
||||
typedef void (*Game_Update_Proc)(f64);
|
||||
Game_Update_Proc game_update;
|
||||
|
||||
Dynamic_Library_Handle dll = 0;
|
||||
|
||||
void load_game_dll(char **argv) {
|
||||
|
||||
// Here we load all the game symbols
|
||||
|
||||
if (dll) {
|
||||
os_unload_dynamic_library(dll);
|
||||
}
|
||||
|
||||
string exe_path = STR(argv[0]);
|
||||
string exe_dir = get_directory_of(exe_path);
|
||||
|
||||
// We need to copy the original and open the copy, so we can recompile the original and then close & replace
|
||||
// the copy.
|
||||
string dll_path = string_concat(exe_dir, STR("/game.dll"), get_temporary_allocator());
|
||||
string used_dll_path = string_concat(exe_dir, STR("/game-in-use.dll"), get_temporary_allocator());
|
||||
|
||||
bool ok = os_file_copy(dll_path, used_dll_path, true);
|
||||
assert(ok, "Could not copy %s to %s", dll_path, used_dll_path);
|
||||
|
||||
dll = os_load_dynamic_library(used_dll_path);
|
||||
assert(dll, "Failed loading game dll");
|
||||
|
||||
game_update = os_dynamic_library_load_symbol(dll, STR("game_update"));
|
||||
assert(game_update, "game is missing game_update()");
|
||||
|
||||
log("Loaded game procedures");
|
||||
}
|
||||
|
||||
int entry(int argc, char **argv) {
|
||||
|
||||
load_game_dll(argv);
|
||||
|
||||
window.title = STR("Minimal Game Example");
|
||||
window.scaled_width = 1280; // We need to set the scaled size if we want to handle system scaling (DPI)
|
||||
window.scaled_height = 720;
|
||||
window.x = 200;
|
||||
window.y = 90;
|
||||
window.clear_color = hex_to_rgba(0x6495EDff);
|
||||
|
||||
float64 last_time = os_get_current_time_in_seconds();
|
||||
while (!window.should_close) {
|
||||
float64 now = os_get_current_time_in_seconds();
|
||||
float64 delta = now-last_time;
|
||||
if ((int)now != (int)last_time) log("%.2f FPS\n%.2fms", 1.0/(delta), (delta)*1000);
|
||||
last_time = now;
|
||||
|
||||
reset_temporary_storage();
|
||||
|
||||
game_update(delta);
|
||||
|
||||
if (is_key_just_pressed('R')) {
|
||||
load_game_dll(argv);
|
||||
play_one_audio_clip(STR("oogabooga/examples/bruh.wav"));
|
||||
}
|
||||
|
||||
os_update();
|
||||
gfx_update();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
30
build_game.c
Normal file
30
build_game.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
|
||||
// !!!!!!!! BUILD CONFIG SHOULD BE DONE IN build_engine.c
|
||||
|
||||
#define OOGABOOGA_LINK_EXTERNAL_INSTANCE 1
|
||||
#include "oogabooga/oogabooga.c"
|
||||
|
||||
///
|
||||
///
|
||||
// This is the game module which is what can be recompiled in the engine runtime
|
||||
|
||||
// For the engine to be able to detect a symbol, it needs to be marked with SHARED_EXPORT
|
||||
void SHARED_EXPORT
|
||||
game_update(f64 delta_time) {
|
||||
|
||||
float64 now = os_get_current_time_in_seconds();
|
||||
|
||||
Matrix4 rect_xform = m4_scalar(1.0);
|
||||
rect_xform = m4_rotate_z(rect_xform, (f32)now);
|
||||
rect_xform = m4_translate(rect_xform, v3(-.25f, -.25f, 0));
|
||||
draw_rect_xform(rect_xform, v2(.5f, .5f), COLOR_GREEN);
|
||||
|
||||
draw_rect(v2(sin(now), -.8), v2(.5, .25), COLOR_RED);
|
||||
|
||||
float aspect = (f32)window.width/(f32)window.height;
|
||||
float mx = (input_frame.mouse_x/(f32)window.width * 2.0 - 1.0)*aspect;
|
||||
float my = input_frame.mouse_y/(f32)window.height * 2.0 - 1.0;
|
||||
|
||||
draw_line(v2(-.75, -.75), v2(mx, my), 0.005, COLOR_WHITE);
|
||||
}
|
36
build_launcher.c
Normal file
36
build_launcher.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
|
||||
// !!!!!!!! BUILD CONFIG SHOULD BE DONE IN build_engine.c
|
||||
|
||||
#define OOGABOOGA_LINK_EXTERNAL_INSTANCE 1
|
||||
#include "oogabooga/oogabooga.c"
|
||||
|
||||
|
||||
// All we do with the launcher is to launch the engine
|
||||
// We need to be careful to use oogabooga things because it has not yet been initialized.
|
||||
// We can use get_temporary_allocator() because that actually gives us the initialization allocator.
|
||||
// We cannot use log() but we can use print()
|
||||
int main(int argc, char **argv) {
|
||||
string exe_path = STR(argv[0]);
|
||||
string exe_dir = get_directory_of(exe_path);
|
||||
|
||||
Allocator a = get_initialization_allocator();
|
||||
string dll_path = string_concat(exe_dir, STR("/engine.dll"), a);
|
||||
|
||||
Dynamic_Library_Handle dll = os_load_dynamic_library(dll_path);
|
||||
if (!dll) {
|
||||
os_write_string_to_stdout(STR("Failed loading engine dll from "));
|
||||
os_write_string_to_stdout(dll_path);
|
||||
os_write_string_to_stdout(STR("\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int (*engine_main)(int, char**) = os_dynamic_library_load_symbol(dll, STR("main"));
|
||||
if (!engine_main) {
|
||||
os_write_string_to_stdout(STR("Failed loading engine main\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
print("Launcher found engine main(), running...\n");
|
||||
return engine_main(argc, argv);
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
## v0.01.002 -
|
||||
|
||||
## v0.01.001 - Spacial audio, custom shading, scissor boxing
|
||||
- Audio
|
||||
- Implemented spacial audio playback
|
||||
|
|
16
hotload_build_all.bat
Normal file
16
hotload_build_all.bat
Normal file
|
@ -0,0 +1,16 @@
|
|||
@echo on
|
||||
if exist build (
|
||||
rmdir /s /q build
|
||||
)
|
||||
mkdir build
|
||||
|
||||
pushd build
|
||||
|
||||
clang ../build_engine.c -g -shared -o engine.dll -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -fuse-ld=lld -lkernel32 -lgdi32 -luser32 -lruntimeobject -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -lole32 -lavrt -lksuser -ldbghelp -femit-all-decls -Xlinker /IMPLIB:engine.lib -Xlinker /MACHINE:X64 -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
clang ../build_launcher.c -g -o launcher.exe -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -femit-all-decls -luser32 -fuse-ld=lld -L. -lengine -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
clang ../build_game.c -g -shared -o game.dll -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -femit-all-decls -luser32 -fuse-ld=lld -L. -lengine -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
|
||||
popd
|
8
hotload_build_game.bat
Normal file
8
hotload_build_game.bat
Normal file
|
@ -0,0 +1,8 @@
|
|||
@echo on
|
||||
|
||||
pushd build
|
||||
|
||||
clang ../build_game.c -g -shared -o game.dll -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -femit-all-decls -luser32 -fuse-ld=lld -L. -lengine -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
|
||||
popd
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#define thread_local _Thread_local
|
||||
|
||||
|
||||
#define local_persist static
|
||||
|
||||
|
@ -9,10 +9,10 @@
|
|||
|
||||
#define null 0
|
||||
|
||||
ogb_instance void
|
||||
void
|
||||
printf(const char* fmt, ...);
|
||||
|
||||
ogb_instance void
|
||||
void
|
||||
dump_stack_trace();
|
||||
|
||||
#define ASSERT_STR_HELPER(x) #x
|
||||
|
@ -81,7 +81,7 @@ typedef struct Allocator {
|
|||
void *data;
|
||||
} Allocator;
|
||||
|
||||
ogb_instance Allocator
|
||||
Allocator
|
||||
get_heap_allocator();
|
||||
|
||||
ogb_instance Allocator
|
||||
|
@ -95,15 +95,15 @@ typedef struct Context {
|
|||
CONTEXT_EXTRA extra;
|
||||
} Context;
|
||||
|
||||
forward_global thread_local Allocator temp;
|
||||
|
||||
#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;
|
||||
// #Global
|
||||
//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
|
||||
Context get_context();
|
||||
|
||||
ogb_instance void*
|
||||
alloc(Allocator allocator, u64 size);
|
||||
|
@ -166,7 +166,10 @@ pop_context() {
|
|||
context = context_stack[num_contexts];
|
||||
}
|
||||
|
||||
|
||||
ogb_instance
|
||||
Context get_context() {
|
||||
return context;
|
||||
}
|
||||
|
||||
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
|
||||
|
||||
typedef struct Bucket_Array {
|
||||
|
||||
|
||||
|
||||
u64 _block_size;
|
||||
u64 _bucket_count;
|
||||
} Bucket_Array;
|
||||
|
||||
typedef struct Bucket_Array_Free_Node {
|
||||
struct Bucket_Array_Free_Node *next;
|
||||
} Bucket_Array_Free_Node;
|
||||
typedef struct Bucket_Array_Bucket {
|
||||
Bucket_Array_Free_Node *first_free;
|
||||
void *data;
|
||||
Bucket *next;
|
||||
} Bucket_Array_Bucket;
|
||||
|
||||
|
||||
Bucket_Array make_bucket_array(u64 block_size, u64 bucket_count) {
|
||||
Bucket_Array ba;
|
||||
|
||||
ba._block_size = block_size;
|
||||
ba._bucket_count = bucket_count;
|
||||
}
|
|
@ -14,31 +14,71 @@ inline bool compare_and_swap_bool(bool *a, bool b, bool old);
|
|||
// Spinlock "primitive"
|
||||
// Like a mutex but it eats up the entire core while waiting.
|
||||
// Beneficial if contention is low or sync speed is important
|
||||
void spinlock_init(Spinlock *l);
|
||||
void spinlock_acquire_or_wait(Spinlock* l);
|
||||
typedef struct Spinlock {
|
||||
bool locked;
|
||||
} Spinlock;
|
||||
|
||||
void ogb_instance
|
||||
spinlock_init(Spinlock *l);
|
||||
|
||||
void ogb_instance
|
||||
spinlock_acquire_or_wait(Spinlock* l);
|
||||
|
||||
// This returns true if successfully acquired or false if timeout reached.
|
||||
bool spinlock_acquire_or_wait_timeout(Spinlock* l, f64 timeout_seconds);
|
||||
void spinlock_release(Spinlock* l);
|
||||
bool ogb_instance
|
||||
spinlock_acquire_or_wait_timeout(Spinlock* l, f64 timeout_seconds);
|
||||
|
||||
void ogb_instance
|
||||
spinlock_release(Spinlock* l);
|
||||
|
||||
|
||||
///
|
||||
// High-level mutex primitive (short spinlock then OS mutex lock)
|
||||
// Just spins for a few (configurable) microseconds with a spinlock,
|
||||
// and if acquiring fails it falls back to a OS mutex.
|
||||
void mutex_init(Mutex *m);
|
||||
void mutex_destroy(Mutex *m);
|
||||
void mutex_acquire_or_wait(Mutex *m);
|
||||
void mutex_release(Mutex *m);
|
||||
#define MUTEX_DEFAULT_SPIN_TIME_MICROSECONDS 100
|
||||
typedef struct Mutex {
|
||||
Spinlock spinlock;
|
||||
f64 spin_time_microseconds;
|
||||
Mutex_Handle os_handle;
|
||||
volatile bool spinlock_acquired;
|
||||
volatile u64 acquiring_thread;
|
||||
} Mutex;
|
||||
|
||||
void ogb_instance
|
||||
mutex_init(Mutex *m);
|
||||
|
||||
void ogb_instance
|
||||
mutex_destroy(Mutex *m);
|
||||
|
||||
void ogb_instance
|
||||
mutex_acquire_or_wait(Mutex *m);
|
||||
|
||||
void ogb_instance
|
||||
mutex_release(Mutex *m);
|
||||
|
||||
|
||||
///
|
||||
// Binary semaphore
|
||||
void binary_semaphore_init(Binary_Semaphore *sem, bool initial_state);
|
||||
void binary_semaphore_destroy(Binary_Semaphore *sem);
|
||||
void binary_semaphore_wait(Binary_Semaphore *sem);
|
||||
void binary_semaphore_signal(Binary_Semaphore *sem);
|
||||
typedef struct Binary_Semaphore {
|
||||
bool signaled;
|
||||
Mutex mutex;
|
||||
} Binary_Semaphore;
|
||||
|
||||
typedef struct Spinlock {
|
||||
bool locked;
|
||||
} Spinlock;
|
||||
void ogb_instance
|
||||
binary_semaphore_init(Binary_Semaphore *sem, bool initial_state);
|
||||
|
||||
void ogb_instance
|
||||
binary_semaphore_destroy(Binary_Semaphore *sem);
|
||||
|
||||
void ogb_instance
|
||||
binary_semaphore_wait(Binary_Semaphore *sem);
|
||||
|
||||
void ogb_instance
|
||||
binary_semaphore_signal(Binary_Semaphore *sem);
|
||||
|
||||
|
||||
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
|
||||
void spinlock_init(Spinlock *l) {
|
||||
memset(l, 0, sizeof(*l));
|
||||
|
@ -87,14 +127,7 @@ void spinlock_release(Spinlock* l) {
|
|||
|
||||
///
|
||||
// High-level mutex primitive (short spinlock then OS mutex lock)
|
||||
#define MUTEX_DEFAULT_SPIN_TIME_MICROSECONDS 100
|
||||
typedef struct Mutex {
|
||||
Spinlock spinlock;
|
||||
f64 spin_time_microseconds;
|
||||
Mutex_Handle os_handle;
|
||||
volatile bool spinlock_acquired;
|
||||
volatile u64 acquiring_thread;
|
||||
} Mutex;
|
||||
|
||||
void mutex_init(Mutex *m) {
|
||||
spinlock_init(&m->spinlock);
|
||||
m->spin_time_microseconds = MUTEX_DEFAULT_SPIN_TIME_MICROSECONDS;
|
||||
|
@ -134,10 +167,7 @@ void mutex_release(Mutex *m) {
|
|||
MEMORY_BARRIER;
|
||||
}
|
||||
|
||||
typedef struct Binary_Semaphore {
|
||||
bool signaled;
|
||||
Mutex mutex;
|
||||
} Binary_Semaphore;
|
||||
|
||||
|
||||
void binary_semaphore_init(Binary_Semaphore *sem, bool initial_state) {
|
||||
sem->signaled = initial_state;
|
||||
|
@ -163,4 +193,6 @@ void binary_semaphore_signal(Binary_Semaphore *sem) {
|
|||
mutex_acquire_or_wait(&sem->mutex);
|
||||
sem->signaled = true;
|
||||
mutex_release(&sem->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -106,6 +106,8 @@ typedef struct Cpu_Capabilities {
|
|||
|
||||
#define MEMORY_BARRIER _ReadWriteBarrier()
|
||||
|
||||
#define thread_local __declspec(thread)
|
||||
|
||||
#define SHARED_EXPORT __declspec(dllexport)
|
||||
#define SHARED_IMPORT __declspec(dllimport)
|
||||
|
||||
|
@ -223,8 +225,15 @@ typedef struct Cpu_Capabilities {
|
|||
|
||||
#define MEMORY_BARRIER __asm__ __volatile__("" ::: "memory")
|
||||
|
||||
#define thread_local __thread
|
||||
|
||||
#if TARGET_OS == WINDOWS
|
||||
#define SHARED_EXPORT __attribute__((visibility("default"))) __declspec(dllexport)
|
||||
#define SHARED_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
#define SHARED_EXPORT __attribute__((visibility("default")))
|
||||
#define SHARED_IMPORT
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define inline inline
|
||||
|
|
12
oogabooga/examples/hotload/README.md
Normal file
12
oogabooga/examples/hotload/README.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
# !!! THIS VERY EXPERIMENTAL !!!
|
||||
|
||||
|
||||
This is an example how how we can set up a oogabooga project where some code can be recompiled while the engine is still running.
|
||||
|
||||
To try this:
|
||||
1. Copy the files in this directory into the root project directory
|
||||
2. Compile with `hotload_build_all.bat`
|
||||
3. Run `build/launcher.exe`
|
||||
4. Modify `build_game.c`
|
||||
5. Recompile the game code only with `hotload_build_game.bat`
|
||||
6. Go back to the application and press 'R'
|
79
oogabooga/examples/hotload/build_engine.c
Normal file
79
oogabooga/examples/hotload/build_engine.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
|
||||
///
|
||||
// Build config stuff
|
||||
|
||||
#define OOGABOOGA_BUILD_SHARED_LIBRARY 1
|
||||
|
||||
#include "oogabooga/oogabooga.c"
|
||||
|
||||
///
|
||||
///
|
||||
// This is the "engine" part of your game, which will call into your game.dll
|
||||
|
||||
|
||||
typedef void (*Game_Update_Proc)(f64);
|
||||
Game_Update_Proc game_update;
|
||||
|
||||
Dynamic_Library_Handle dll = 0;
|
||||
|
||||
void load_game_dll(char **argv) {
|
||||
|
||||
// Here we load all the game symbols
|
||||
|
||||
if (dll) {
|
||||
os_unload_dynamic_library(dll);
|
||||
}
|
||||
|
||||
string exe_path = STR(argv[0]);
|
||||
string exe_dir = get_directory_of(exe_path);
|
||||
|
||||
// We need to copy the original and open the copy, so we can recompile the original and then close & replace
|
||||
// the copy.
|
||||
string dll_path = string_concat(exe_dir, STR("/game.dll"), get_temporary_allocator());
|
||||
string used_dll_path = string_concat(exe_dir, STR("/game-in-use.dll"), get_temporary_allocator());
|
||||
|
||||
bool ok = os_file_copy(dll_path, used_dll_path, true);
|
||||
assert(ok, "Could not copy %s to %s", dll_path, used_dll_path);
|
||||
|
||||
dll = os_load_dynamic_library(used_dll_path);
|
||||
assert(dll, "Failed loading game dll");
|
||||
|
||||
game_update = os_dynamic_library_load_symbol(dll, STR("game_update"));
|
||||
assert(game_update, "game is missing game_update()");
|
||||
|
||||
log("Loaded game procedures");
|
||||
}
|
||||
|
||||
int entry(int argc, char **argv) {
|
||||
|
||||
load_game_dll(argv);
|
||||
|
||||
window.title = STR("Minimal Game Example");
|
||||
window.scaled_width = 1280; // We need to set the scaled size if we want to handle system scaling (DPI)
|
||||
window.scaled_height = 720;
|
||||
window.x = 200;
|
||||
window.y = 90;
|
||||
window.clear_color = hex_to_rgba(0x6495EDff);
|
||||
|
||||
float64 last_time = os_get_current_time_in_seconds();
|
||||
while (!window.should_close) {
|
||||
float64 now = os_get_current_time_in_seconds();
|
||||
float64 delta = now-last_time;
|
||||
if ((int)now != (int)last_time) log("%.2f FPS\n%.2fms", 1.0/(delta), (delta)*1000);
|
||||
last_time = now;
|
||||
|
||||
reset_temporary_storage();
|
||||
|
||||
game_update(delta);
|
||||
|
||||
if (is_key_just_pressed('R')) {
|
||||
load_game_dll(argv);
|
||||
play_one_audio_clip(STR("oogabooga/examples/bruh.wav"));
|
||||
}
|
||||
|
||||
os_update();
|
||||
gfx_update();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
30
oogabooga/examples/hotload/build_game.c
Normal file
30
oogabooga/examples/hotload/build_game.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
|
||||
// !!!!!!!! BUILD CONFIG SHOULD BE DONE IN build_engine.c
|
||||
|
||||
#define OOGABOOGA_LINK_EXTERNAL_INSTANCE 1
|
||||
#include "oogabooga/oogabooga.c"
|
||||
|
||||
///
|
||||
///
|
||||
// This is the game module which is what can be recompiled in the engine runtime
|
||||
|
||||
// For the engine to be able to detect a symbol, it needs to be marked with SHARED_EXPORT
|
||||
void SHARED_EXPORT
|
||||
game_update(f64 delta_time) {
|
||||
|
||||
float64 now = os_get_current_time_in_seconds();
|
||||
|
||||
Matrix4 rect_xform = m4_scalar(1.0);
|
||||
rect_xform = m4_rotate_z(rect_xform, (f32)now);
|
||||
rect_xform = m4_translate(rect_xform, v3(-.25f, -.25f, 0));
|
||||
draw_rect_xform(rect_xform, v2(.5f, .5f), COLOR_GREEN);
|
||||
|
||||
draw_rect(v2(sin(now), -.8), v2(.5, .25), COLOR_RED);
|
||||
|
||||
float aspect = (f32)window.width/(f32)window.height;
|
||||
float mx = (input_frame.mouse_x/(f32)window.width * 2.0 - 1.0)*aspect;
|
||||
float my = input_frame.mouse_y/(f32)window.height * 2.0 - 1.0;
|
||||
|
||||
draw_line(v2(-.75, -.75), v2(mx, my), 0.005, COLOR_WHITE);
|
||||
}
|
36
oogabooga/examples/hotload/build_launcher.c
Normal file
36
oogabooga/examples/hotload/build_launcher.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
|
||||
// !!!!!!!! BUILD CONFIG SHOULD BE DONE IN build_engine.c
|
||||
|
||||
#define OOGABOOGA_LINK_EXTERNAL_INSTANCE 1
|
||||
#include "oogabooga/oogabooga.c"
|
||||
|
||||
|
||||
// All we do with the launcher is to launch the engine
|
||||
// We need to be careful to use oogabooga things because it has not yet been initialized.
|
||||
// We can use get_temporary_allocator() because that actually gives us the initialization allocator.
|
||||
// We cannot use log() but we can use print()
|
||||
int main(int argc, char **argv) {
|
||||
string exe_path = STR(argv[0]);
|
||||
string exe_dir = get_directory_of(exe_path);
|
||||
|
||||
Allocator a = get_initialization_allocator();
|
||||
string dll_path = string_concat(exe_dir, STR("/engine.dll"), a);
|
||||
|
||||
Dynamic_Library_Handle dll = os_load_dynamic_library(dll_path);
|
||||
if (!dll) {
|
||||
os_write_string_to_stdout(STR("Failed loading engine dll from "));
|
||||
os_write_string_to_stdout(dll_path);
|
||||
os_write_string_to_stdout(STR("\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int (*engine_main)(int, char**) = os_dynamic_library_load_symbol(dll, STR("main"));
|
||||
if (!engine_main) {
|
||||
os_write_string_to_stdout(STR("Failed loading engine main\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
print("Launcher found engine main(), running...\n");
|
||||
return engine_main(argc, argv);
|
||||
}
|
16
oogabooga/examples/hotload/hotload_build_all.bat
Normal file
16
oogabooga/examples/hotload/hotload_build_all.bat
Normal file
|
@ -0,0 +1,16 @@
|
|||
@echo on
|
||||
if exist build (
|
||||
rmdir /s /q build
|
||||
)
|
||||
mkdir build
|
||||
|
||||
pushd build
|
||||
|
||||
clang ../build_engine.c -g -shared -o engine.dll -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -fuse-ld=lld -lkernel32 -lgdi32 -luser32 -lruntimeobject -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -lole32 -lavrt -lksuser -ldbghelp -femit-all-decls -Xlinker /IMPLIB:engine.lib -Xlinker /MACHINE:X64 -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
clang ../build_launcher.c -g -o launcher.exe -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -femit-all-decls -luser32 -fuse-ld=lld -L. -lengine -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
clang ../build_game.c -g -shared -o game.dll -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -femit-all-decls -luser32 -fuse-ld=lld -L. -lengine -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
|
||||
popd
|
8
oogabooga/examples/hotload/hotload_build_game.bat
Normal file
8
oogabooga/examples/hotload/hotload_build_game.bat
Normal file
|
@ -0,0 +1,8 @@
|
|||
@echo on
|
||||
|
||||
pushd build
|
||||
|
||||
clang ../build_game.c -g -shared -o game.dll -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -femit-all-decls -luser32 -fuse-ld=lld -L. -lengine -Xlinker /SUBSYSTEM:CONSOLE
|
||||
|
||||
|
||||
popd
|
|
@ -231,8 +231,8 @@ void d3d11_update_swapchain() {
|
|||
bool
|
||||
d3d11_compile_shader(string source) {
|
||||
|
||||
source = string_replace_all(source, STR("$INJECT_PIXEL_POST_PROCESS"), STR("float4 pixel_shader_extension(PS_INPUT input, float4 color) { return color; }"), temp);
|
||||
source = string_replace_all(source, STR("$VERTEX_2D_USER_DATA_COUNT"), tprint("%d", VERTEX_2D_USER_DATA_COUNT), temp);
|
||||
source = string_replace_all(source, STR("$INJECT_PIXEL_POST_PROCESS"), STR("float4 pixel_shader_extension(PS_INPUT input, float4 color) { return color; }"), get_temporary_allocator());
|
||||
source = string_replace_all(source, STR("$VERTEX_2D_USER_DATA_COUNT"), tprint("%d", VERTEX_2D_USER_DATA_COUNT), get_temporary_allocator());
|
||||
|
||||
// #Leak on recompile
|
||||
|
||||
|
@ -921,7 +921,7 @@ bool
|
|||
shader_recompile_with_extension(string ext_source, u64 cbuffer_size) {
|
||||
|
||||
|
||||
string source = string_replace_all(STR(d3d11_image_shader_source), STR("$INJECT_PIXEL_POST_PROCESS"), ext_source, temp);
|
||||
string source = string_replace_all(STR(d3d11_image_shader_source), STR("$INJECT_PIXEL_POST_PROCESS"), ext_source, get_temporary_allocator());
|
||||
|
||||
|
||||
if (!d3d11_compile_shader(source)) return false;
|
||||
|
|
|
@ -37,11 +37,11 @@ typedef struct Gfx_Image {
|
|||
Allocator allocator;
|
||||
} Gfx_Image;
|
||||
|
||||
ogb_instance Gfx_Image *
|
||||
Gfx_Image *
|
||||
make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator allocator);
|
||||
ogb_instance Gfx_Image *
|
||||
Gfx_Image *
|
||||
load_image_from_disk(string path, Allocator allocator);
|
||||
ogb_instance void
|
||||
void
|
||||
delete_image(Gfx_Image *image);
|
||||
|
||||
// Implemented per renderer
|
||||
|
@ -61,7 +61,7 @@ ogb_instance bool
|
|||
shader_recompile_with_extension(string ext_source, u64 cbuffer_size);
|
||||
|
||||
// initial_data can be null to leave image data uninitialized
|
||||
ogb_instance Gfx_Image *
|
||||
Gfx_Image *
|
||||
make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator allocator) {
|
||||
Gfx_Image *image = alloc(allocator, sizeof(Gfx_Image) + width*height*channels);
|
||||
|
||||
|
@ -78,7 +78,7 @@ make_image(u32 width, u32 height, u32 channels, void *initial_data, Allocator al
|
|||
return image;
|
||||
}
|
||||
|
||||
ogb_instance Gfx_Image *
|
||||
Gfx_Image *
|
||||
load_image_from_disk(string path, Allocator allocator) {
|
||||
string png;
|
||||
bool ok = os_read_entire_file(path, &png, allocator);
|
||||
|
@ -115,7 +115,7 @@ load_image_from_disk(string path, Allocator allocator) {
|
|||
return image;
|
||||
}
|
||||
|
||||
ogb_instance void
|
||||
void
|
||||
delete_image(Gfx_Image *image) {
|
||||
// Free the image data allocated by stb_image
|
||||
image->width = 0;
|
||||
|
|
|
@ -536,28 +536,41 @@ Allocator get_heap_allocator() {
|
|||
#define TEMPORARY_STORAGE_SIZE (1024ULL*1024ULL*2ULL) // 2mb
|
||||
#endif
|
||||
|
||||
void* talloc(u64);
|
||||
void* temp_allocator_proc(u64 size, void *p, Allocator_Message message, void*);
|
||||
ogb_instance void* talloc(u64);
|
||||
ogb_instance 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;
|
||||
ogb_instance Allocator
|
||||
get_temporary_allocator();
|
||||
|
||||
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
thread_local void * temporary_storage = 0;
|
||||
thread_local bool temporary_storage_initted = false;
|
||||
thread_local void * temporary_storage_pointer = 0;
|
||||
thread_local bool has_warned_temporary_storage_overflow = false;
|
||||
thread_local Allocator temp;
|
||||
thread_local Allocator temp_allocator;
|
||||
|
||||
ogb_instance Allocator
|
||||
get_temporary_allocator() {
|
||||
if (!temporary_storage_initted) return get_initialization_allocator();
|
||||
return temp_allocator;
|
||||
}
|
||||
#endif
|
||||
|
||||
Allocator get_temporary_allocator() {
|
||||
return temp;
|
||||
}
|
||||
ogb_instance void*
|
||||
temp_allocator_proc(u64 size, void *p, Allocator_Message message, void* data);
|
||||
|
||||
ogb_instance void
|
||||
temporary_storage_init();
|
||||
|
||||
ogb_instance void*
|
||||
talloc(u64 size);
|
||||
|
||||
ogb_instance void
|
||||
reset_temporary_storage();
|
||||
|
||||
|
||||
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
void* temp_allocator_proc(u64 size, void *p, Allocator_Message message, void* data) {
|
||||
switch (message) {
|
||||
case ALLOCATOR_ALLOCATE: {
|
||||
|
@ -581,12 +594,12 @@ void temporary_storage_init() {
|
|||
assert(temporary_storage, "Failed allocating temporary storage");
|
||||
temporary_storage_pointer = temporary_storage;
|
||||
|
||||
temp.proc = temp_allocator_proc;
|
||||
temp.data = 0;
|
||||
temp_allocator.proc = temp_allocator_proc;
|
||||
temp_allocator.data = 0;
|
||||
|
||||
temporary_storage_initted = true;
|
||||
|
||||
temp.proc = temp_allocator_proc;
|
||||
temp_allocator.proc = temp_allocator_proc;
|
||||
}
|
||||
|
||||
void* talloc(u64 size) {
|
||||
|
@ -617,3 +630,4 @@ void reset_temporary_storage() {
|
|||
has_warned_temporary_storage_overflow = true;
|
||||
}
|
||||
|
||||
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
|
@ -197,6 +197,10 @@ typedef u8 bool;
|
|||
#define ENABLE_SIMD 1
|
||||
#endif
|
||||
|
||||
#ifndef INITIAL_PROGRAM_MEMORY_SIZE
|
||||
#define INITIAL_PROGRAM_MEMORY_SIZE MB(5)
|
||||
#endif
|
||||
|
||||
#if ENABLE_SIMD && !defined(SIMD_ENABLE_SSE2)
|
||||
#if COMPILER_CAN_DO_SSE2
|
||||
#define SIMD_ENABLE_SSE2 1
|
||||
|
@ -246,10 +250,13 @@ typedef u8 bool;
|
|||
|
||||
#if OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
#define ogb_instance SHARED_IMPORT extern
|
||||
#else
|
||||
#elif OOGABOOGA_BUILD_SHARED_LIBRARY
|
||||
#define ogb_instance SHARED_EXPORT
|
||||
#else
|
||||
#define ogb_instance
|
||||
#endif
|
||||
|
||||
|
||||
// This needs to be included before dependencies
|
||||
#include "base.c"
|
||||
|
||||
|
@ -367,9 +374,12 @@ void default_logger(Log_Level level, string s) {
|
|||
mutex_release(&_default_logger_mutex);
|
||||
}
|
||||
|
||||
ogb_instance void oogabooga_init(u64 program_memory_size);
|
||||
|
||||
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
void oogabooga_init(u64 program_memory_size) {
|
||||
context.logger = default_logger;
|
||||
temp = get_initialization_allocator();
|
||||
temp_allocator = get_initialization_allocator();
|
||||
Cpu_Capabilities features = query_cpu_capabilities();
|
||||
os_init(program_memory_size);
|
||||
heap_init();
|
||||
|
@ -390,10 +400,17 @@ void oogabooga_init(u64 program_memory_size) {
|
|||
log_verbose("CPU has avx2: %cs", features.avx2 ? "true" : "false");
|
||||
log_verbose("CPU has avx512: %cs", features.avx512 ? "true" : "false");
|
||||
}
|
||||
#endif
|
||||
|
||||
int ENTRY_PROC(int argc, char **argv);
|
||||
|
||||
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
|
||||
|
||||
#if OOGABOOGA_BUILD_SHARED_LIBRARY
|
||||
int SHARED_EXPORT main(int argc, char **argv) {
|
||||
#else
|
||||
int main(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
|
||||
print("Ooga booga program started\n");
|
||||
|
@ -421,6 +438,8 @@ int main(int argc, char **argv) {
|
|||
|
||||
return code;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -588,8 +588,10 @@ float64 os_get_current_time_in_seconds() {
|
|||
// Dynamic Libraries
|
||||
///
|
||||
|
||||
u16 *temp_win32_fixed_utf8_to_null_terminated_wide(string utf8);
|
||||
|
||||
Dynamic_Library_Handle os_load_dynamic_library(string path) {
|
||||
return LoadLibraryA(temp_convert_to_null_terminated_string(path));
|
||||
return LoadLibraryW(temp_win32_fixed_utf8_to_null_terminated_wide(path));
|
||||
}
|
||||
void *os_dynamic_library_load_symbol(Dynamic_Library_Handle l, string identifier) {
|
||||
return GetProcAddress(l, temp_convert_to_null_terminated_string(identifier));
|
||||
|
@ -635,7 +637,7 @@ u16 *win32_fixed_utf8_to_null_terminated_wide(string utf8, Allocator allocator)
|
|||
return utf16_str;
|
||||
}
|
||||
u16 *temp_win32_fixed_utf8_to_null_terminated_wide(string utf8) {
|
||||
return win32_fixed_utf8_to_null_terminated_wide(utf8, temp);
|
||||
return win32_fixed_utf8_to_null_terminated_wide(utf8, get_temporary_allocator());
|
||||
}
|
||||
string win32_null_terminated_wide_to_fixed_utf8(const u16 *utf16, Allocator allocator) {
|
||||
u64 utf8_length = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)utf16, -1, 0, 0, 0, 0);
|
||||
|
@ -663,7 +665,7 @@ string win32_null_terminated_wide_to_fixed_utf8(const u16 *utf16, Allocator allo
|
|||
}
|
||||
|
||||
string temp_win32_null_terminated_wide_to_fixed_utf8(const u16 *utf16) {
|
||||
return win32_null_terminated_wide_to_fixed_utf8(utf16, temp);
|
||||
return win32_null_terminated_wide_to_fixed_utf8(utf16, get_temporary_allocator());
|
||||
}
|
||||
|
||||
|
||||
|
@ -694,6 +696,12 @@ bool os_file_delete_s(string path) {
|
|||
return (bool)DeleteFileW(path_wide);
|
||||
}
|
||||
|
||||
bool os_file_copy_s(string from, string to, bool replace_if_exists) {
|
||||
u16 *from_wide = temp_win32_fixed_utf8_to_null_terminated_wide(from);
|
||||
u16 *to_wide = temp_win32_fixed_utf8_to_null_terminated_wide(to);
|
||||
return (bool)CopyFileW(from_wide, to_wide, !replace_if_exists);
|
||||
}
|
||||
|
||||
bool os_make_directory_s(string path, bool recursive) {
|
||||
wchar_t *wide_path = temp_win32_fixed_utf8_to_null_terminated_wide(path);
|
||||
|
||||
|
@ -946,11 +954,11 @@ bool os_get_absolute_path(string path, string *result, Allocator allocator) {
|
|||
bool os_get_relative_path(string from, string to, string *result, Allocator allocator) {
|
||||
|
||||
if (!os_is_path_absolute(from)) {
|
||||
bool abs_ok = os_get_absolute_path(from, &from, temp);
|
||||
bool abs_ok = os_get_absolute_path(from, &from, get_temporary_allocator());
|
||||
if (!abs_ok) return false;
|
||||
}
|
||||
if (!os_is_path_absolute(to)) {
|
||||
bool abs_ok = os_get_absolute_path(to, &to, temp);
|
||||
bool abs_ok = os_get_absolute_path(to, &to, get_temporary_allocator());
|
||||
if (!abs_ok) return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,8 @@ inline int vsnprintf(char* buffer, size_t n, const char* fmt, va_list args) {
|
|||
|
||||
|
||||
|
||||
bool os_grow_program_memory(size_t new_size);
|
||||
bool ogb_instance
|
||||
os_grow_program_memory(size_t new_size);
|
||||
|
||||
///
|
||||
///
|
||||
|
@ -172,6 +173,8 @@ os_get_current_time_in_seconds();
|
|||
// Dynamic Libraries
|
||||
///
|
||||
|
||||
// #Cleanup this naming is bleh
|
||||
|
||||
Dynamic_Library_Handle ogb_instance
|
||||
os_load_dynamic_library(string path);
|
||||
|
||||
|
@ -208,6 +211,9 @@ os_file_close(File f);
|
|||
bool ogb_instance
|
||||
os_file_delete_s(string path);
|
||||
|
||||
bool ogb_instance
|
||||
os_file_copy_s(string from, string to, bool replace_if_exists);
|
||||
|
||||
|
||||
bool ogb_instance
|
||||
os_make_directory_s(string path, bool recursive);
|
||||
|
@ -290,6 +296,12 @@ inline bool os_file_delete_f(const char *path) {return os_file_delete_s(STR(path
|
|||
default: os_file_delete_f \
|
||||
)(__VA_ARGS__)
|
||||
|
||||
inline bool os_file_copy_f(const char *from, const char *to, bool replace_if_exists) {return os_file_copy_s(STR(from), STR(to), replace_if_exists);}
|
||||
#define os_file_copy(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
||||
string: os_file_copy_s, \
|
||||
default: os_file_copy_f \
|
||||
)(__VA_ARGS__)
|
||||
|
||||
inline bool os_make_directory_f(const char *path, bool recursive) { return os_make_directory_s(STR(path), recursive); }
|
||||
#define os_make_directory(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
||||
string: os_make_directory_s, \
|
||||
|
|
|
@ -51,4 +51,16 @@ string get_file_name_excluding_extension(string file_path) {
|
|||
}
|
||||
}
|
||||
return file_name;
|
||||
}
|
||||
|
||||
string get_directory_of(string path) {
|
||||
if (path.count <= 0) return ZERO(string);
|
||||
|
||||
for (u64 i = path.count; i >= 0; i--) {
|
||||
if (path.data[i] == '/' || path.data[i] == '\\' || path.data[i] == ':') {
|
||||
return string_view(path, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
return ZERO(string);
|
||||
}
|
|
@ -34,7 +34,7 @@ void _profiler_report_time_cycles(string name, u64 count, u64 start) {
|
|||
spinlock_acquire_or_wait(&_profiler_lock);
|
||||
|
||||
string fmt = STR("{\"cat\":\"function\",\"dur\":%.3f,\"name\":\"%s\",\"ph\":\"X\",\"pid\":0,\"tid\":%zu,\"ts\":%lld},");
|
||||
string_builder_print(&_profile_output, fmt, (float64)count*1000, name, context.thread_id, start*1000);
|
||||
string_builder_print(&_profile_output, fmt, (float64)count*1000, name, get_context().thread_id, start*1000);
|
||||
|
||||
spinlock_release(&_profiler_lock);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
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() {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
*/
|
||||
|
||||
void* talloc(u64);
|
||||
ogb_instance void* talloc(u64);
|
||||
|
||||
typedef struct string {
|
||||
u64 count;
|
||||
|
@ -41,7 +41,7 @@ dealloc_string(Allocator allocator, string s) {
|
|||
}
|
||||
string
|
||||
talloc_string(u64 count) {
|
||||
string s = alloc_string(temp, count);
|
||||
string s = alloc_string(get_temporary_allocator(), count);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ convert_to_null_terminated_string(const string s, Allocator allocator) {
|
|||
|
||||
char *
|
||||
temp_convert_to_null_terminated_string(const string s) {
|
||||
char *c = convert_to_null_terminated_string(s, temp);
|
||||
char *c = convert_to_null_terminated_string(s, get_temporary_allocator());
|
||||
return c;
|
||||
}
|
||||
bool
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
void os_write_string_to_stdout(string s);
|
||||
ogb_instance void os_write_string_to_stdout(string s);
|
||||
inline int crt_sprintf(char *str, const char *format, ...);
|
||||
int vsnprintf(char* buffer, size_t n, const char* fmt, va_list args);
|
||||
bool is_pointer_valid(void *p);
|
||||
|
@ -135,7 +135,7 @@ string sprints(Allocator allocator, const string fmt, ...) {
|
|||
string tprints(const string fmt, ...) {
|
||||
va_list args = 0;
|
||||
va_start(args, fmt);
|
||||
string s = sprint_va_list(temp, fmt, args);
|
||||
string s = sprint_va_list(get_temporary_allocator(), fmt, args);
|
||||
va_end(args);
|
||||
return s;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ string tprintf(const char *fmt, ...) {
|
|||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
string s = sprint_va_list(temp, sfmt, args);
|
||||
string s = sprint_va_list(get_temporary_allocator(), sfmt, args);
|
||||
va_end(args);
|
||||
|
||||
return s;
|
||||
|
@ -220,7 +220,7 @@ void printf(const char* fmt, ...) {
|
|||
|
||||
|
||||
typedef void(*Logger_Proc)(Log_Level level, string s);
|
||||
#define LOG_BASE(level, ...) if (context.logger) ((Logger_Proc)context.logger)(level, tprint(__VA_ARGS__))
|
||||
#define LOG_BASE(level, ...) if (get_context().logger) ((Logger_Proc)get_context().logger)(level, tprint(__VA_ARGS__))
|
||||
|
||||
|
||||
#define log_verbose(...) LOG_BASE(LOG_VERBOSE, __VA_ARGS__)
|
||||
|
|
|
@ -122,11 +122,11 @@ void test_allocator(bool do_log_heap) {
|
|||
reset_temporary_storage();
|
||||
|
||||
|
||||
int* foo = (int*)alloc(temp, 72);
|
||||
int* foo = (int*)alloc(get_temporary_allocator(), 72);
|
||||
*foo = 1337;
|
||||
void* bar = alloc(temp, 69);
|
||||
void* bar = alloc(get_temporary_allocator(), 69);
|
||||
(void)bar;
|
||||
void* baz = alloc(temp, 420);
|
||||
void* baz = alloc(get_temporary_allocator(), 420);
|
||||
(void)baz;
|
||||
|
||||
assert(*foo == 1337, "Temp memory corruptada");
|
||||
|
@ -135,7 +135,7 @@ void test_allocator(bool do_log_heap) {
|
|||
|
||||
reset_temporary_storage();
|
||||
|
||||
foo = (int*)alloc(temp, 72);
|
||||
foo = (int*)alloc(get_temporary_allocator(), 72);
|
||||
|
||||
assert(old_foo == foo, "Temp allocator goof");
|
||||
|
||||
|
|
Reference in a new issue