diff --git a/build.bat b/build.bat index 63911b7..e1e4a7a 100644 --- a/build.bat +++ b/build.bat @@ -15,14 +15,24 @@ set LastError=%ERRORLEVEL% ctime -end timeBuild.ctm %LastError% popd +echo --- Codegen: IF NOT %LastError%==0 GOTO :end +ctime -begin timeBuild.ctm + pushd src pushd gen_test ..\..\build\codegen.exe ./ popd +pushd os +..\..\build\codegen.exe ./ popd +popd + +echo Codegen time: +set LastError=%ERRORLEVEL% +ctime -end timeBuild.ctm %LastError% echo --- Main diff --git a/src/base/base_arena.c b/src/base/base_arena.c new file mode 100644 index 0000000..d129b5b --- /dev/null +++ b/src/base/base_arena.c @@ -0,0 +1,151 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ Base arena implementation + + +internal Arena * +arena_alloc_() +{ + U64 reserve_size = g_arena_default_reserve_size; + U64 commit_size = g_arena_default_commit_size; + + + // TODO align to page sizes + + + // Reserve/commit initial block + void *base = 0; + if(base == 0) // TODO(anton): can have optional backing buffer + { + base = os_reserve(reserve_size); + os_commit(base, commit_size); + } + + // Extract arena header and fill it + Arena *arena = (Arena *)base; + arena->current = arena; + arena->commit_size = commit_size; + arena->reserve_size = reserve_size; + arena->base_pos = 0; + arena->pos = ARENA_HEADER_SIZE; + arena->commit = commit_size; + arena->reserve = reserve_size; + + + return arena; +} + +internal void +arena_release(Arena *arena) +{ + // Go back in chain and release + for(Arena *n = arena->current, *prev = 0; n != 0; n = prev) + { + prev = n->prev; + os_release(n, n->reserve); + } +} + +internal void * +arena_push(Arena *arena, U64 size, U64 align) +{ + Arena *current = arena->current; + U64 pos_pre = AlignPow2(current->pos, align); + U64 pos_post = pos_pre + size; + + // TODO(anton): Add chaining etc. Now we always just put up a new block. + + + // Commit new pages if needed, that is if the new position of the arena pointer + // is larger than the current commit adress. + if(current->commit < pos_post) + { + U64 commit_post_aligned = pos_post + current->commit_size - 1; + commit_post_aligned -= commit_post_aligned % current->commit_size; + // Now commit_post_aligned is aligned + U64 commit_post_clamped = ClampTop(commit_post_aligned, current->reserve); + U64 commit_size = commit_post_clamped - current->commit; + U8 *commit_ptr = (U8 *)current + current->commit; + os_commit(commit_ptr, commit_size); + + current->commit = commit_post_clamped; + } + + // Push to current block + void *result = 0; + if(current->commit >= pos_post) + { + result = (U8 *)current+pos_pre; + current->pos = pos_post; + } + + if(result == 0) + { + LOG("FATAL ERROR IN ARENA ALLOC"); + ExitProcess(0); + } + + + return result; +} + +internal U64 +arena_pos(Arena *arena) +{ + Arena *current = arena->current; + U64 pos = current->base_pos + current->pos; + return pos; +} + +internal void +arena_pop_to(Arena *arena, U64 pos) +{ + U64 big_pos = ClampBot(ARENA_HEADER_SIZE, pos); + Arena *current = arena->current; + + + for(Arena *prev = 0; current->base_pos >= big_pos; current = prev) + { + prev = current->prev; + os_release(current, current->reserve); + } + + arena->current = current; + U64 new_pos = big_pos - current->base_pos; + AssertAlways(new_pos <= current->pos); + current->pos = new_pos; +} + +internal void +arena_clear(Arena *arena) +{ + arena_pop_to(arena, 0); +} + +internal void +arena_pop(Arena *arena, U64 amt) +{ + U64 pos_old = arena_pos(arena); + U64 pos_new = pos_old; + if(amt < pos_old) + { + pos_new = pos_old - amt; + } + arena_pop_to(arena, pos_new); +} + +//- rjf: temporary arena scopes + +internal Temp +temp_begin(Arena *arena) +{ + U64 pos = arena_pos(arena); + Temp temp = {arena, pos}; + return temp; +} + +internal void +temp_end(Temp temp) +{ + arena_pop_to(temp.arena, temp.pos); +} + diff --git a/src/base/base_arena.h b/src/base/base_arena.h new file mode 100644 index 0000000..b49e24f --- /dev/null +++ b/src/base/base_arena.h @@ -0,0 +1,64 @@ +#ifndef BASE_ARENA_H +#define BASE_ARENA_H + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ + +#define ARENA_HEADER_SIZE 128 + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ + +typedef struct Arena Arena; +struct Arena +{ + // If we have chains of arenas we have linked list links here + Arena *prev; + Arena *current; + U64 commit_size; + U64 reserve_size; + U64 base_pos; + U64 pos; + U64 commit; + U64 reserve; +}; + +typedef struct Temp Temp; +struct Temp +{ + Arena *arena; + U64 pos; +}; + +global U64 g_arena_default_reserve_size = MB(64); +global U64 g_arena_default_commit_size = MB(64); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ +internal Arena *arena_alloc_(/* TODO arena params */); +// Macro for arena alloc with default params: +#define arena_alloc(...) arena_alloc_() +internal void arena_release(Arena *arena); + + +//- arena push/pop/pos core functions +internal void *arena_push(Arena *arena, U64 size, U64 align); +internal U64 arena_pos(Arena *arena); +internal void arena_pop_to(Arena *arena, U64 pos); + +//- arena push/pop helpers +internal void arena_clear(Arena *arena); +internal void arena_pop(Arena *arena, U64 amt); + +//- temporary arena scopes +internal Temp temp_begin(Arena *arena); +internal void temp_end(Temp temp); + +//- push helper macros +#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align)) +#define push_array_aligned(a, T, c, align) (T *)MemoryZero(push_array_no_zero_aligned(a, T, c, align), sizeof(T)*(c)) +#define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, Max(8, AlignOf(T))) +#define push_array(a, T, c) push_array_aligned(a, T, c, Max(8, AlignOf(T))) + + +#endif /* BASE_ARENA_H */ \ No newline at end of file diff --git a/src/base/base_core.h b/src/base/base_core.h index 6e0ccd2..54db56e 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -1,19 +1,120 @@ #ifndef BASE_CORE_H #define BASE_CORE_H + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ #include +#include -typedef int32_t S32; -typedef uint32_t U32; -typedef int64_t S64; -typedef uint64_t U64; -typedef float F32; -typedef double F64; +// TODO(anton): Move to context cracking +#if defined(_MSC_VER) +#define COMPILER_MSVC 1 +#endif + +//////////////////////////////// +//~ Asserts + +#if COMPILER_MSVC +# define Trap() __debugbreak() +#elif COMPILER_CLANG || COMPILER_GCC +# define Trap() __builtin_trap() +#else +# error Unknown trap intrinsic for this compiler. +#endif + +#if COMPILER_MSVC +# define AlignOf(T) __alignof(T) +#else +# error Need MSVC for now! +#endif + +#define AssertAlways(x) do{if(!(x)) {Trap();}}while(0) +#if BUILD_DEBUG +# define Assert(x) AssertAlways(x) +#else +# define Assert(x) (void)(x) +#endif +#define InvalidPath Assert(!"Invalid Path!") +#define NotImplemented Assert(!"Not Implemented!") +#define NoOp ((void)0) +#define StaticAssert(C, ID) global U8 Glue(ID, __LINE__)[(C)?1:-1] -#define global static -#define function static +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ +typedef uint8_t U8; +typedef uint16_t U16; +typedef uint32_t U32; +typedef uint64_t U64; +typedef int8_t S8; +typedef int16_t S16; +typedef int32_t S32; +typedef int64_t S64; +typedef S8 B8; +typedef S16 B16; +typedef S32 B32; +typedef S64 B64; +typedef float F32; +typedef double F64; +typedef void VoidProc(void); +typedef union U128 U128; +union U128 +{ + U8 u8[16]; + U16 u16[8]; + U32 u32[4]; + U64 u64[2]; +}; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ +#define global static +#define internal static +#define local_persist static + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ + +#define Min(A,B) (((A)<(B))?(A):(B)) +#define Max(A,B) (((A)>(B))?(A):(B)) +#define ClampTop(A,X) Min(A,X) +#define ClampBot(X,B) Max(X,B) +#define Clamp(A,X,B) (((X)<(A))?(A):((X)>(B))?(B):(X)) + +#define MemoryCopy(dst, src, size) memmove((dst), (src), (size)) +#define MemorySet(dst, byte, size) memset((dst), (byte), (size)) + +#define MemoryCopyStruct(d,s) MemoryCopy((d),(s),sizeof(*(d))) +#define MemoryCopyArray(d,s) MemoryCopy((d),(s),sizeof(d)) + +#define MemoryZero(s,z) memset((s),0,(z)) +#define MemoryZeroStruct(s) MemoryZero((s),sizeof(*(s))) +#define MemoryZeroArray(a) MemoryZero((a),sizeof(a)) + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ + +#define KB(n) (((U64)(n)) << 10) +#define MB(n) (((U64)(n)) << 20) +#define GB(n) (((U64)(n)) << 30) +#define TB(n) (((U64)(n)) << 40) +#define Thousand(n) ((n)*1000) +#define Million(n) ((n)*1000000) +#define Billion(n) ((n)*1000000000) + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ Helper macros +#define ArrayCount(a) (sizeof(a) / sizeof((a)[0])) + +#define AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1))) + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ +#define LOG OS_W32_log_debug + #endif /* BASE_CORE_H */ diff --git a/src/base/base_inc.c b/src/base/base_inc.c index c488e70..f30674e 100644 --- a/src/base/base_inc.c +++ b/src/base/base_inc.c @@ -1,2 +1,4 @@ ////////////////////////////////////////////////////////////////////////////////////////////// -//~ \ No newline at end of file +//~ + +#include "base_arena.c" \ No newline at end of file diff --git a/src/base/base_inc.h b/src/base/base_inc.h index 1c95ac7..f37f047 100644 --- a/src/base/base_inc.h +++ b/src/base/base_inc.h @@ -4,7 +4,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////// //~ #include "base_core.h" -// #include "base_arena.h" +#include "base_arena.h" // #include "base_math.h" // #include "base_entry_point.h" diff --git a/src/main.c b/src/main.c index 9afb54e..a4cf281 100644 --- a/src/main.c +++ b/src/main.c @@ -16,15 +16,83 @@ static void entry_point(); #include "os/os_inc.c" #include "render/render_inc.c" -#include "gen_test/generated/test.meta.h" -#include "gen_test/generated/test.meta.c" +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ +internal void +test_arena(Arena *arena) +{ + LOG("Testing arena with filled entries with A prefix.\n"); + U64 count = 0; + U64 N1 = 32; + U64 *arr = push_array(arena, U64, N1); + for(U64 i = 0; i < N1; i += 1) + { + arr[i] = i; + count += 1; + } + + for(U64 i = 0; i < count; i += 1) + { + U64 value = arr[i]; + LOG("arr[%i] = %i \n", i, value); + } + + arena_pop(arena, sizeof(U64)*N1); + + U64 N2 = 8; + count = 0; + for(U64 i = 0; i < N2; i += 1) + { + arr[i] = 100 + i; + count += 1; + } + + LOG("After pop: \n"); + for(U64 i = 0; i < count; i += 1) + { + U64 value = arr[i]; + LOG("arr[%i] = %i \n", i, value); + } + +} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //~ Main entry -function void +internal void entry_point() { - printf("HELLO MAIN"); + LOG("HELLO MAIN \n"); + + // Init systems + Arena *arena = arena_alloc(); + //test_arena(arena); + + + // Main program loop + U32 do_exit = 0; + for(;;) + { + MSG Message; + while(PeekMessage(&Message, 0, 0, 0, PM_REMOVE)) + { + switch(Message.message) + { + case WM_CLOSE: + { + SendMessageW(g_service_window_handle, OS_W32_MSG_DESTROY_WINDOW, Message.wParam, 0); + do_exit = 1; + } break; + } + } + + if(do_exit) + { + break; + } + } + + arena_release(arena); + } diff --git a/src/os/generated/os_core.meta.c b/src/os/generated/os_core.meta.c new file mode 100644 index 0000000..e69de29 diff --git a/src/os/generated/os_core.meta.h b/src/os/generated/os_core.meta.h new file mode 100644 index 0000000..cf51498 --- /dev/null +++ b/src/os/generated/os_core.meta.h @@ -0,0 +1,119 @@ +typedef enum OS_Key +{ + OS_Key_Null, + OS_Key_Esc, + OS_Key_F1, + OS_Key_F2, + OS_Key_F3, + OS_Key_F4, + OS_Key_F5, + OS_Key_F6, + OS_Key_F7, + OS_Key_F8, + OS_Key_F9, + OS_Key_F10, + OS_Key_F11, + OS_Key_F12, + OS_Key_F13, + OS_Key_F14, + OS_Key_F15, + OS_Key_F16, + OS_Key_F17, + OS_Key_F18, + OS_Key_F19, + OS_Key_F20, + OS_Key_F21, + OS_Key_F22, + OS_Key_F23, + OS_Key_F24, + OS_Key_Tick, + OS_Key_0, + OS_Key_1, + OS_Key_2, + OS_Key_3, + OS_Key_4, + OS_Key_5, + OS_Key_6, + OS_Key_7, + OS_Key_8, + OS_Key_9, + OS_Key_Minus, + OS_Key_Equal, + OS_Key_Backspace, + OS_Key_Tab, + OS_Key_Q, + OS_Key_W, + OS_Key_E, + OS_Key_R, + OS_Key_T, + OS_Key_Y, + OS_Key_U, + OS_Key_I, + OS_Key_O, + OS_Key_P, + OS_Key_LeftBracket, + OS_Key_RightBracket, + OS_Key_BackSlash, + OS_Key_CapsLock, + OS_Key_A, + OS_Key_S, + OS_Key_D, + OS_Key_F, + OS_Key_G, + OS_Key_H, + OS_Key_J, + OS_Key_K, + OS_Key_L, + OS_Key_Semicolon, + OS_Key_Quote, + OS_Key_Return, + OS_Key_Shift, + OS_Key_Z, + OS_Key_X, + OS_Key_C, + OS_Key_V, + OS_Key_B, + OS_Key_N, + OS_Key_M, + OS_Key_Comma, + OS_Key_Period, + OS_Key_Slash, + OS_Key_Ctrl, + OS_Key_Alt, + OS_Key_Space, + OS_Key_Menu, + OS_Key_ScrollLock, + OS_Key_Pause, + OS_Key_Insert, + OS_Key_Home, + OS_Key_PageUp, + OS_Key_Delete, + OS_Key_End, + OS_Key_PageDown, + OS_Key_Up, + OS_Key_Left, + OS_Key_Down, + OS_Key_Right, + OS_Key_NumLock, + OS_Key_NumSlash, + OS_Key_NumStar, + OS_Key_NumMinus, + OS_Key_NumPlus, + OS_Key_NumPeriod, + OS_Key_Num0, + OS_Key_Num1, + OS_Key_Num2, + OS_Key_Num3, + OS_Key_Num4, + OS_Key_Num5, + OS_Key_Num6, + OS_Key_Num7, + OS_Key_Num8, + OS_Key_Num9, + OS_Key_LeftMouseButton, + OS_Key_MiddleMouseButton, + OS_Key_RightMouseButton, + OS_Key_COUNT +} +OS_Key; + diff --git a/src/os/os_core.h b/src/os/os_core.h index 4263eed..44cc516 100644 --- a/src/os/os_core.h +++ b/src/os/os_core.h @@ -3,5 +3,51 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //~ +#include "os/generated/os_core.meta.h" + +typedef struct OS_Handle OS_Handle; +struct OS_Handle +{ + U64 handle[1]; +}; + +typedef enum OS_EventKind +{ + OS_EventKind_Null, + OS_EventKind_Press, + OS_EventKind_Release, + OS_EventKind_MouseMove, + OS_EventKind_COUNT +} +OS_EventKind; + +typedef struct OS_Event OS_Event; +struct OS_Event +{ + OS_Event *next; + OS_Event *prev; + OS_Handle window; + OS_EventKind kind; + OS_Key key; +}; + + +typedef struct OS_EventList OS_EventList; +struct OS_EventList +{ + U64 count; + OS_Event *first; + OS_Event *last; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ + +// OS memory +internal void *os_reserve(U64 size); +internal B32 os_commit(void *ptr, U64 size); +internal void os_decommit(void *ptr, U64 size); +internal void os_release(void *ptr, U64 size); #endif /* OS_CORE_H */ \ No newline at end of file diff --git a/src/os/os_core.mdesk b/src/os/os_core.mdesk new file mode 100644 index 0000000..8c97fb7 --- /dev/null +++ b/src/os/os_core.mdesk @@ -0,0 +1,133 @@ + + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ Table with key enums. +// TODO(anton): Extend this table to include description strings etc when necessary. + +@table(name) +OS_KeyTable: +{ + {Null } + {Esc } + {F1 } + {F2 } + {F3 } + {F4 } + {F5 } + {F6 } + {F7 } + {F8 } + {F9 } + {F10 } + {F11 } + {F12 } + {F13 } + {F14 } + {F15 } + {F16 } + {F17 } + {F18 } + {F19 } + {F20 } + {F21 } + {F22 } + {F23 } + {F24 } + {Tick } + {0 } + {1 } + {2 } + {3 } + {4 } + {5 } + {6 } + {7 } + {8 } + {9 } + {Minus } + {Equal } + {Backspace } + {Tab } + {Q } + {W } + {E } + {R } + {T } + {Y } + {U } + {I } + {O } + {P } + {LeftBracket } + {RightBracket } + {BackSlash } + {CapsLock } + {A } + {S } + {D } + {F } + {G } + {H } + {J } + {K } + {L } + {Semicolon } + {Quote } + {Return } + {Shift } + {Z } + {X } + {C } + {V } + {B } + {N } + {M } + {Comma } + {Period } + {Slash } + {Ctrl } + {Alt } + {Space } + {Menu } + {ScrollLock } + {Pause } + {Insert } + {Home } + {PageUp } + {Delete } + {End } + {PageDown } + {Up } + {Left } + {Down } + {Right } + {NumLock } + {NumSlash } + {NumStar } + {NumMinus } + {NumPlus } + {NumPeriod } + {Num0 } + {Num1 } + {Num2 } + {Num3 } + {Num4 } + {Num5 } + {Num6 } + {Num7 } + {Num8 } + {Num9 } + {LeftMouseButton } + {MiddleMouseButton } + {RightMouseButton } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//~ Generators + +@table_gen_enum OS_Key: +{ + @expand(OS_KeyTable a) + ` OS_Key_$(a.name),`; + ` OS_Key_COUNT` +} \ No newline at end of file diff --git a/timeBuild.ctm b/timeBuild.ctm new file mode 100644 index 0000000..1440ce8 Binary files /dev/null and b/timeBuild.ctm differ