red-black tree implemented

This commit is contained in:
Matthew 2025-04-12 19:33:16 +10:00
parent d9ec3f4be2
commit 2f0722132d
12 changed files with 504 additions and 44 deletions

View File

@ -16,6 +16,7 @@ if [ -v webgl ] && [ ! -v render_flag ]; then render_flag="-DSTG_WEBGL_RENDERER"
if [ -v dx11 ] && [ ! -v render_flag ]; then render_flag="-DSTG_DX11_RENDERER"; echo "[dx11 renderer]"; fi if [ -v dx11 ] && [ ! -v render_flag ]; then render_flag="-DSTG_DX11_RENDERER"; echo "[dx11 renderer]"; fi
if [ -v dx11 ]; then render_link="-l:libdxvk_d3d11.so.0"; fi if [ -v dx11 ]; then render_link="-l:libdxvk_d3d11.so.0"; fi
if [ ! -v render_flag ]; then render_flag="-DSTG_VULKAN_RENDERER"; vulkan="vulkan"; echo "[default renderer - vulkan]"; fi if [ ! -v render_flag ]; then render_flag="-DSTG_VULKAN_RENDERER"; vulkan="vulkan"; echo "[default renderer - vulkan]"; fi
if [ -v test ]; then test_build=1; echo "[test build]"; fi
# source files # source files
source_files="../src/entry_linux.c" source_files="../src/entry_linux.c"
@ -46,16 +47,17 @@ glsl_stage_geom="-fshader-stage=geom"
glsl_stage_comp="-fshader-stage=comp" glsl_stage_comp="-fshader-stage=comp"
glsl_out="-o./shaders/glsl/" glsl_out="-o./shaders/glsl/"
clang_common="${include_flags} ${render_flag} -g -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -DVMA_STATIC_VULKAN_FUNCTIONS=0" clang_common="${include_flags} ${render_flag} -g -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -DVMA_STATIC_VULKAN_FUNCTIONS=0"
clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common}" clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common}"
clang_release="$compiler -g -O2 ${clang_common}" clang_release="$compiler -g -O2 ${clang_common}"
clang_test="$compiler -O2 -DBUILD_TEST=1 ${clang_common}"
clang_link="-lpthread -lm -lrt -ldl -l:libvma.a" clang_link="-lpthread -lm -lrt -ldl -l:libvma.a"
clang_out="-o" clang_out="-o"
gcc_common="${include_flags} ${render_flag} -std=c99 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0" gcc_common="${include_flags} ${render_flag} -std=c99 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0"
gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}" gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}"
gcc_release="$compiler -g -O2 ${gcc_common} ${render_flag}" gcc_release="$compiler -O2 ${gcc_common} ${render_flag}"
gcc_test="$compiler -O2 -DBUILD_TEST=1 ${gcc_common} ${render_flag}"
gcc_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++" gcc_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++"
gcc_out="-o" gcc_out="-o"
@ -64,16 +66,19 @@ link_os_gfx="-lxcb -lX11 -lX11-xcb -lvulkan"
if [ -v gcc ]; then compile_debug="$gcc_debug"; fi if [ -v gcc ]; then compile_debug="$gcc_debug"; fi
if [ -v gcc ]; then compile_release="$gcc_release"; fi if [ -v gcc ]; then compile_release="$gcc_release"; fi
if [ -v gcc ]; then compile_test="$gcc_test"; fi
if [ -v gcc ]; then compile_link="$gcc_link"; fi if [ -v gcc ]; then compile_link="$gcc_link"; fi
if [ -v gcc ]; then out="$gcc_out"; fi if [ -v gcc ]; then out="$gcc_out"; fi
if [ -v clang ]; then compile_debug="$clang_debug"; fi if [ -v clang ]; then compile_debug="$clang_debug"; fi
if [ -v clang ]; then compile_release="$clang_release"; fi if [ -v clang ]; then compile_release="$clang_release"; fi
if [ -v clang ]; then compile_test="$clang_debug"; fi
if [ -v clang ]; then compile_link="$clang_link"; fi if [ -v clang ]; then compile_link="$clang_link"; fi
if [ -v clang ]; then out="$clang_out"; fi if [ -v clang ]; then out="$clang_out"; fi
if [ -v debug ]; then compile="$compile_debug"; fi if [ -v debug ]; then compile="$compile_debug"; fi
if [ -v release ]; then compile="$compile_release"; fi if [ -v release ]; then compile="$compile_release"; fi
if [ -v test ]; then compile="$compile_test"; fi
mkdir -p build mkdir -p build

View File

@ -66,14 +66,14 @@ static Arena * CreateArenaDebug(rawptr buffer, isize length, u32 init_line_no)
// ::Allocator::FreeList::Start:: // ::Allocator::FreeList::Start::
static FreeListAlloc *CreateFreeListAlloc(isize init_size, isize grow_size) static Alloc *CreateFreeListAlloc(isize init_size, isize grow_size)
{ {
isize size = init_size + sizeof(FreeListAlloc) + sizeof(FreeListBuffer) + sizeof(rawptr) + sizeof(FLNode); isize size = init_size + sizeof(Alloc) + sizeof(FreeListBuffer) + sizeof(rawptr) + sizeof(RBNode);
u8 *mem = (u8 *)MemAllocZeroed(size); u8 *mem = (u8 *)MemAllocZeroed(size);
FreeListAlloc *fl_alloc = (FreeListAlloc *)mem; Alloc *fl_alloc = (Alloc *)mem;
u8 *pre_mem = mem; u8 *pre_mem = mem;
mem = (u8 *)PtrAdd(mem, sizeof(FreeListAlloc)); mem = (u8 *)PtrAdd(mem, sizeof(Alloc));
isize rem_size = (size) - (pre_mem - mem); isize rem_size = (size) - (pre_mem - mem);
fl_alloc->buf_len = 1; fl_alloc->buf_len = 1;
@ -84,10 +84,10 @@ static FreeListAlloc *CreateFreeListAlloc(isize init_size, isize grow_size)
mem = (u8 *)PtrAdd(mem, sizeof(FreeListBuffer)); mem = (u8 *)PtrAdd(mem, sizeof(FreeListBuffer));
rem_size -= pre_mem - mem; rem_size -= pre_mem - mem;
fl_alloc->nil = (FLNode *)mem; fl_alloc->nil = (RBNode *)mem;
pre_mem = mem; pre_mem = mem;
mem = (u8 *)PtrAdd(mem, sizeof(FLNode)); mem = (u8 *)PtrAdd(mem, sizeof(RBNode));
rem_size -= pre_mem - mem; rem_size -= pre_mem - mem;
fl_alloc->buffers[0].buf = mem; fl_alloc->buffers[0].buf = mem;
@ -97,7 +97,7 @@ static FreeListAlloc *CreateFreeListAlloc(isize init_size, isize grow_size)
return fl_alloc; return fl_alloc;
} }
static void DeallocFreeListAlloc(FreeListAlloc *alloc) static void DeallocFreeListAlloc(Alloc *alloc)
{ {
for (u8 i = alloc->buf_len-1; i >= 0; i--) for (u8 i = alloc->buf_len-1; i >= 0; i--)
{ {
@ -108,4 +108,21 @@ static void DeallocFreeListAlloc(FreeListAlloc *alloc)
} }
} }
static rawptr FLAlloc(Alloc *alloc, isize size)
{
return NULL;
}
static void FLFree(Alloc *alloc, rawptr ptr)
{
}
static void FreeListGrow(Alloc *alloc)
{
u8 *mem = (u8 *)MemAllocZeroed(alloc->grow_size);
}
// ::Allocator::FreeList::End:: // ::Allocator::FreeList::End::

View File

@ -28,24 +28,6 @@ static Arena *CreateArenaDebug(rawptr buffer, isize length, u32 init_line_no);
// ::Allocator::FreeList::Header:: // ::Allocator::FreeList::Header::
typedef enum FLNodeColor_e
{
RB_RED,
RB_BLACK,
} FLNodeColor;
typedef struct FLNode_t FLNode;
typedef struct FLNode_t
{
FLNode *parent;
FLNode *left;
FLNode *right;
i32 value;
rawptr data;
FLNodeColor color;
} FLNode;
typedef struct FreeListBuffer_t typedef struct FreeListBuffer_t
{ {
rawptr buf; rawptr buf;
@ -53,18 +35,21 @@ typedef struct FreeListBuffer_t
u32 free_size; u32 free_size;
} FreeListBuffer; } FreeListBuffer;
typedef struct FreeListAlloc_t typedef struct Alloc_t
{ {
FLNode *head; RBNode *head;
FLNode *nil; RBNode *nil;
FreeListBuffer *buffers; FreeListBuffer *buffers;
isize grow_size; isize grow_size;
u8 buf_len; u8 buf_len;
} FreeListAlloc; } Alloc;
static FreeListAlloc *CreateFreeListAlloc(isize init_size, isize grow_size); static Alloc *CreateFreeListAlloc(isize init_size, isize grow_size);
static void DeallocFreeListAlloc(FreeListAlloc *alloc); static void DeallocFreeListAlloc(Alloc *alloc);
static inline b32 FLNodeInsert(FreeListAlloc *alloc, FLNode *node); static void FreeListGrow(Alloc *alloc);
static inline void FLNodeDelete(FLNode *node); static rawptr FLAlloc(Alloc *alloc, isize size);
static inline void FLNodeLeftRotate(FLNode *node); static void FLFree(Alloc *alloc, rawptr ptr);
static inline void FLNodeRightRotate(FLNode *node); static inline b32 FLNodeInsert(Alloc *alloc, RBNode *node);
static inline void FLNodeDelete(RBNode *node);
static inline void FLNodeLeftRotate(RBNode *node);
static inline void FLNodeRightRotate(RBNode *node);

View File

@ -52,3 +52,5 @@ typedef enum ModelAssetTag_e
{ {
MODEL_ASSET_TAG_MAX, MODEL_ASSET_TAG_MAX,
} ModelAssetTag; } ModelAssetTag;

320
src/ds.c
View File

@ -1,2 +1,322 @@
RBNode RB_NIL = { .color = RB_BLACK };
static void CreateRBTree(RBTree *tree)
{
Assert(tree != NULL, "RBTree is null");
RB_NIL.right = RB_NIL.left = RB_NIL.parent = &RB_NIL;
tree->root = &RB_NIL;
tree->nil = &RB_NIL;
}
static void RBTreeInsert(RBTree *tree, RBNode *node)
{
node->left = node->right = tree->nil;
node->color = RB_RED;
if (tree->root == tree->nil)
{
node->color = RB_BLACK;
node->parent = tree->nil;
tree->root = node;
}
else
{
RBNode *curr_node = tree->root;
while (true)
{
Assert(curr_node != tree->nil, "Current Node is NIL");
if (curr_node->value < node->value)
{
if (curr_node->right == tree->nil)
{
node->parent = curr_node;
curr_node->right = node;
break;
}
else
{
curr_node = curr_node->right;
}
}
else
{
if (curr_node->left == tree->nil)
{
node->parent = curr_node;
curr_node->left = node;
break;
}
else
{
curr_node = curr_node->left;
}
}
}
}
if (node->parent->color != RB_BLACK)
RBTreeCorrect(tree, node);
}
static void RBTreeCorrect(RBTree *tree, RBNode *node)
{
RBNode *gp = node->parent->parent;
RBNode *p = node->parent;
do
{
if (node == tree->root)
{
node->color = RB_BLACK;
break;
}
if (gp == tree->nil)
{
p->color = RB_BLACK;
break;
}
RBNodeDir dir = NodeDir(p);
RBNode *unc = gp->child[1 - dir];
if (unc == tree->nil || unc->color == RB_BLACK)
{
if (node == p->child[1 - dir])
{
RBTreeRotate(tree, p, dir);
node = p;
p = gp->child[dir];
}
RBTreeRotate(tree, gp, 1 - dir);
p->color = RB_BLACK;
gp->color = RB_RED;
break;
}
p->color = RB_BLACK;
unc->color = RB_BLACK;
gp->color = RB_RED;
node = gp;
gp = node->parent->parent;
} while ((p = node->parent));
}
static void RBTreeDelete(RBTree *tree, i32 value)
{
RBNode *node = NULL;
Assert(RBTreeSearch(tree, value, &node), "Unable to find node in RBTreeDelete");
if (node == tree->root && node->left == tree->nil && node->right == tree->nil)
{
tree->root = tree->nil;
}
else if (node->left != tree->nil && node->right != tree->nil)
{
RBNode *ln = node->right;
while (ln->left != tree->nil)
ln = ln->left;
node->value = ln->value;
node->data = ln->data;
if (node->right == ln)
node->right = tree->nil;
else
ln->parent->left = tree->nil;
ln->parent = tree->nil;
}
else if (node->color == RB_BLACK && node->left != tree->nil)
{
node->value = node->left->value;
node->data = node->left->data;
node->left = tree->nil;
}
else if (node->color == RB_BLACK && node->right != tree->nil)
{
node->value = node->right->value;
node->data = node->right->data;
node->right = tree->nil;
}
else if (node->color == RB_RED && node->right == tree->nil && node->left == tree->nil)
{
RBNodeDir dir = NodeDir(node);
node->parent->child[dir] = tree->nil;
}
else
{
RBNode *p = node->parent;
RBNodeColor col = node->color;
RBNode *s, *cn, *dn;
RBNodeDir dir = NodeDir(node);
p->child[dir] = tree->nil;
goto start_deletion;
do
{
dir = NodeDir(node);
start_deletion:
s = p->child[1 - dir];
dn = s->child[1 - dir];
cn = s->child[dir];
if (s->color == RB_RED)
{
RBTreeRotate(tree, p, dir);
p->color = RB_RED;
s->color = RB_BLACK;
s = cn;
dn = s->child[1 - dir];
if (dn->color == RB_RED)
goto rotate_sibling;
cn = s->child[dir];
if (cn->color == RB_RED)
goto rotate_parent;
s->color = RB_RED;
p->color = RB_BLACK;
return;
}
if (dn->color == RB_RED)
goto rotate_parent;
if (cn->color == RB_RED)
goto rotate_sibling;
if (p->color == RB_RED)
{
s->color = RB_RED;
p->color = RB_BLACK;
return;
}
if (p == tree->nil)
return;
s->color = RB_RED;
node = p;
} while ((p = node->parent));
rotate_sibling:
RBTreeRotate(tree, s, 1 - dir);
s->color = RB_RED;
cn->color = RB_BLACK;
dn = s;
s = cn;
rotate_parent:
RBTreeRotate(tree, p, dir);
s->color = p->color;
p->color = RB_BLACK;
dn->color = RB_BLACK;
}
}
static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **out_node)
{
if (tree->root == tree->nil) return false;
b32 found = false;
RBNode *node = tree->root;
while (true)
{
if (node->value == value)
{
found = true;
break;
}
if (node == tree->nil)
break;
if (node->value < value)
node = node->right;
else
node = node->left;
}
if (found)
*out_node = node;
return found;
}
static inline void RBTreeTransplant(RBTree *tree, RBNode *node, RBNode *placed_node)
{
if (node->parent == tree->nil)
tree->root = placed_node;
else if (node == node->parent->left)
node->parent->left = placed_node;
else
node->parent->right = placed_node;
placed_node->parent = node->parent;
}
static void RBTreeRotate(RBTree *tree, RBNode *node, RBNodeDir dir)
{
RBNode *p = node->parent;
RBNode *root = node->child[1 - dir];
RBNode *child = root->child[dir];
node->child[1 - dir] = child;
if (child != tree->nil)
child->parent = node;
root->child[dir] = node;
root->parent = p;
node->parent = root;
if (p != tree->nil)
p->child[node == p->right] = root;
else
tree->root = root;
}
static void RBTreeLeftRotate(RBTree *tree, RBNode *node)
{
RBNode *right = node->right;
if (right->left != tree->nil)
node->right = right->left;
if (node->parent == tree->nil)
tree->root = right;
else if (node->parent->left == node)
node->parent->left = right;
else
node->parent->right = right;
right->parent = node->parent;
right->left = node;
node->parent = right;
}
static void RBTreeRightRotate(RBTree *tree, RBNode *node)
{
RBNode *left = node->left;
if (left->right != tree->nil)
node->left = left->right;
if (node->parent == tree->nil)
tree->root = left;
else if (node->parent->left == node)
node->parent->left = left;
else
node->parent->right = left;
left->parent = node->parent;
left->right = node;
node->parent = left;
}

View File

@ -1,3 +1,50 @@
#pragma once #pragma once
typedef enum RBNodeColor_e
{
RB_RED,
RB_BLACK,
} RBNodeColor;
typedef enum RBNodeDir_e
{
RB_LEFT,
RB_RIGHT,
} RBNodeDir;
typedef struct RBNode_t RBNode;
typedef struct RBNode_t
{
RBNode *parent;
union
{
struct
{
RBNode *left;
RBNode *right;
};
RBNode *child[2];
};
i32 value;
rawptr data;
RBNodeColor color;
} RBNode;
typedef struct RBTree_t
{
RBNode *root;
RBNode *nil;
} RBTree;
#define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT)
static void CreateRBTree(RBTree *tree);
static void RBTreeInsert(RBTree *tree, RBNode *node);
static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **out_node);
static void RBTreeDelete(RBTree *tree, i32 value);
static void RBTreeLeftRotate(RBTree *tree, RBNode *node);
static void RBTreeRightRotate(RBTree *tree, RBNode *node);
static void RBTreeRotate(RBTree *tree, RBNode *node, RBNodeDir dir);
static void RBTreeCorrect(RBTree *tree, RBNode *node);
static inline void RBTreeTransplant(RBTree *tree, RBNode *node, RBNode *placed_node);

View File

@ -12,9 +12,85 @@
#include "allocators.c" #include "allocators.c"
#include "renderer.c" #include "renderer.c"
#include "game.c" #include "game.c"
#ifdef BUILD_TEST
# include "tests.c"
#endif
void TraverseNode(RBTree *tree, RBNode *node, RBNodeDir *dir)
{
char *dir_str = dir == NULL ? "Root" : *dir == RB_RIGHT ? "Right" : "Left";
Printfln("Color: %s Value: %d Dir: %s", node->color == RB_RED ? "Red" : "Black", node->value, dir_str);
if (node->left != tree->nil)
{
RBNodeDir left_dir = RB_LEFT;
TraverseNode(tree, node->left, &left_dir);
}
if (node->right != tree->nil)
{
RBNodeDir right_dir = RB_RIGHT;
TraverseNode(tree, node->right, &right_dir);
}
}
void Traverse(RBTree *tree)
{
TraverseNode(tree, tree->root, NULL);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
#ifdef BUILD_TEST
RunTests();
return 0;
#endif
RBTree tree;
CreateRBTree(&tree);
RBNode node1 = { .value = 4 };
RBNode node2 = { .value = 7 };
RBNode node3 = { .value = 33 };
RBNode node4 = { .value = 53 };
RBNode node5 = { .value = 25 };
RBNode node6 = { .value = 22 };
RBNode node7 = { .value = 6 };
RBNode node8 = { .value = 1 };
RBTreeInsert(&tree, &node1);
RBTreeInsert(&tree, &node2);
RBTreeInsert(&tree, &node3);
RBTreeInsert(&tree, &node4);
RBTreeInsert(&tree, &node5);
RBTreeInsert(&tree, &node6);
RBTreeInsert(&tree, &node7);
RBTreeInsert(&tree, &node8);
RBNode *search_node = NULL;
Assert(RBTreeSearch(&tree, 25, &search_node), "Unable to find node");
Assert(search_node->value == 25, "Node has an invalid value");
RBTreeDelete(&tree, 25);
RBNode node9 = { .value = 57 };
RBTreeInsert(&tree, &node9);
RBTreeDelete(&tree, 22);
RBNode node10 = { .value = 59 };
RBNode node11 = { .value = 60 };
RBNode node12 = { .value = 58 };
RBTreeInsert(&tree, &node10);
RBTreeInsert(&tree, &node11);
RBTreeInsert(&tree, &node12);
RBTreeDelete(&tree, 59);
RBTreeDelete(&tree, 33);
Traverse(&tree);
return 0;
u8 *mem = (u8 *)MemAllocZeroed(MB(64)); u8 *mem = (u8 *)MemAllocZeroed(MB(64));
Arena *arena = CreateArenaDebug(mem, MB(64), __LINE__); Arena *arena = CreateArenaDebug(mem, MB(64), __LINE__);

View File

@ -21,6 +21,10 @@
#include "renderer.h" #include "renderer.h"
#include "game.h" #include "game.h"
#ifdef BUILD_TEST
# include "tests.h"
#endif
int main(int argc, char **argv); int main(int argc, char **argv);
#endif // __linux__ #endif // __linux__

View File

@ -90,7 +90,9 @@ u64 FileLength(FILE *file)
u64 WriteData(void *buf, u64 pos, u64 size, FILE *file) u64 WriteData(void *buf, u64 pos, u64 size, FILE *file)
{ {
Assert(fseek(file, pos, SEEK_SET) == 0, "WriteData fseek failure"); Assert(fseek(file, pos, SEEK_SET) == 0, "WriteData fseek failure");
return FWrite(buf, size, 1, file); u64 written = (u64)FWrite(buf, size, 1, file);
fflush(file);
return written;
} }
u64 ReadData(void *buf, u64 pos, u64 size, FILE *file) u64 ReadData(void *buf, u64 pos, u64 size, FILE *file)
@ -293,15 +295,11 @@ void PackFiles(Arena *arena, FileHeader *header)
WriteData(shader_assets, header->asset_offsets[SHADER_ASSET], sizeof(AssetFile)*SHADER_ASSET_MAX, file); WriteData(shader_assets, header->asset_offsets[SHADER_ASSET], sizeof(AssetFile)*SHADER_ASSET_MAX, file);
WriteData(texture_assets, header->asset_offsets[TEXTURE_ASSET], sizeof(AssetFile)*TEXTURE_ASSET_MAX, file); WriteData(texture_assets, header->asset_offsets[TEXTURE_ASSET], sizeof(AssetFile)*TEXTURE_ASSET_MAX, file);
FileLength(file);
ChangeDir(return_dir); ChangeDir(return_dir);
} }
void PrintBytes(u8 *bytes, u64 len) void PrintBytes(u8 *bytes, u64 len)
{ {
return;
u32 count = 0; u32 count = 0;
while (count + 8 < len) while (count + 8 < len)
{ {

View File

@ -47,8 +47,6 @@ b32 InitRenderer(Arena *arena)
ArenaFree(renderer.arena); ArenaFree(renderer.arena);
return true; return true;
return true;
} }
void DestroyRenderer() void DestroyRenderer()

5
src/tests.c Normal file
View File

@ -0,0 +1,5 @@
void RunTests()
{
}

3
src/tests.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void RunTests();