Switch mem allocation to custom memory block

No longer repeatedly invoke malloc for retrieving memory. Some operations still
leak memory (notably audio streaming). We introduce notion of Transient and
Permanent storage. Transient memory is used for data in memory that is
temporarily allocated (i.e. graphics for that frame's output), and permanent as
more like game state storage.

We now give out pointers from a pre-allocated block of memory, so we have no
allocation cost and benefits of reduced memory leaks. The transient block gets
reset every frame. Any memory allocated within is cleared at no cost simply by
rearranging the base pointer of the memory block.
This commit is contained in:
Doyle Thai 2016-09-24 14:43:59 +10:00
parent 85b757aaa7
commit 332888f3b5
24 changed files with 352 additions and 248 deletions

View File

@ -126,6 +126,7 @@
<ClCompile Include="src\Debug.c" /> <ClCompile Include="src\Debug.c" />
<ClCompile Include="src\dengine.c" /> <ClCompile Include="src\dengine.c" />
<ClCompile Include="src\Entity.c" /> <ClCompile Include="src\Entity.c" />
<ClCompile Include="src\MemoryArena.c" />
<ClCompile Include="src\Platform.c" /> <ClCompile Include="src\Platform.c" />
<ClCompile Include="src\Renderer.c" /> <ClCompile Include="src\Renderer.c" />
<ClCompile Include="src\Shader.c" /> <ClCompile Include="src\Shader.c" />

View File

@ -54,6 +54,9 @@
<ClCompile Include="src\String.c"> <ClCompile Include="src\String.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\MemoryArena.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="data\shaders\default.vert.glsl" /> <None Include="data\shaders\default.vert.glsl" />

View File

@ -28,7 +28,7 @@
********************************* *********************************
*/ */
INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table, INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table,
MemoryArena *const arena, MemoryArena_ *const arena,
const char *const key) const char *const key)
{ {
u32 hashIndex = common_getHashIndex(key, table->size); u32 hashIndex = common_getHashIndex(key, table->size);
@ -45,7 +45,7 @@ INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table,
result = result->next; result = result->next;
} }
result->next = PLATFORM_MEM_ALLOC(arena, 1, HashTableEntry); result->next = MEMORY_PUSH_STRUCT(arena, HashTableEntry);
result = result->next; result = result->next;
} }
@ -56,7 +56,7 @@ INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table,
{ {
// +1 Null terminator // +1 Null terminator
i32 keyLen = common_strlen(key) + 1; i32 keyLen = common_strlen(key) + 1;
result->key = PLATFORM_MEM_ALLOC(arena, keyLen, char); result->key = memory_pushBytes(arena, keyLen * sizeof(char));
common_strncpy(result->key, key, keyLen); common_strncpy(result->key, key, keyLen);
} }
@ -83,14 +83,14 @@ INTERNAL HashTableEntry *const getEntryFromHash(HashTable *const table,
********************************* *********************************
*/ */
INTERNAL SubTexture *getFreeAtlasSubTexSlot(TexAtlas *const atlas, INTERNAL SubTexture *getFreeAtlasSubTexSlot(TexAtlas *const atlas,
MemoryArena *const arena, MemoryArena_ *const arena,
const char *const key) const char *const key)
{ {
HashTableEntry *entry = getFreeHashSlot(&atlas->subTex, arena, key); HashTableEntry *entry = getFreeHashSlot(&atlas->subTex, arena, key);
if (entry) if (entry)
{ {
entry->data = PLATFORM_MEM_ALLOC(arena, 1, SubTexture); entry->data = MEMORY_PUSH_STRUCT(arena, SubTexture);
SubTexture *result = CAST(SubTexture *)entry->data; SubTexture *result = CAST(SubTexture *)entry->data;
return result; return result;
} }
@ -127,7 +127,7 @@ Texture *asset_getTex(AssetManager *const assetManager, const char *const key)
} }
TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager, TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager,
MemoryArena *arena, const char *const key, MemoryArena_ *arena, const char *const key,
i32 numSubTex) i32 numSubTex)
{ {
@ -136,19 +136,22 @@ TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager,
if (entry) if (entry)
{ {
entry->data = PLATFORM_MEM_ALLOC(arena, 1, TexAtlas); entry->data = MEMORY_PUSH_STRUCT(arena, TexAtlas);
TexAtlas *result = CAST(TexAtlas *) entry->data; TexAtlas *result = CAST(TexAtlas *) entry->data;
if (result) if (result)
{ {
result->subTex.size = numSubTex; result->subTex.size = numSubTex;
result->subTex.entries = result->subTex.entries =
PLATFORM_MEM_ALLOC(arena, numSubTex, HashTableEntry); memory_pushBytes(arena, numSubTex * sizeof(HashTableEntry));
if (!result->subTex.entries) if (!result->subTex.entries)
{ {
// TODO(doyle): Mem free
/*
PLATFORM_MEM_FREE(arena, result, sizeof(TexAtlas)); PLATFORM_MEM_FREE(arena, result, sizeof(TexAtlas));
result = NULL; result = NULL;
*/
} }
} }
@ -174,7 +177,7 @@ TexAtlas *asset_getTexAtlas(AssetManager *const assetManager,
Texture *asset_getFreeTexSlot(AssetManager *const assetManager, Texture *asset_getFreeTexSlot(AssetManager *const assetManager,
MemoryArena *const arena, const char *const key) MemoryArena_ *const arena, const char *const key)
{ {
HashTableEntry *const entry = HashTableEntry *const entry =
@ -182,7 +185,7 @@ Texture *asset_getFreeTexSlot(AssetManager *const assetManager,
if (entry) if (entry)
{ {
entry->data = PLATFORM_MEM_ALLOC(arena, 1, Texture); entry->data = MEMORY_PUSH_STRUCT(arena, Texture);
Texture *result = CAST(Texture *) entry->data; Texture *result = CAST(Texture *) entry->data;
return result; return result;
} }
@ -192,7 +195,7 @@ Texture *asset_getFreeTexSlot(AssetManager *const assetManager,
} }
} }
Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena, Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena_ *arena,
const char *const path, const char *const key) const char *const path, const char *const key)
{ {
/* Open the texture image */ /* Open the texture image */
@ -232,14 +235,14 @@ Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena,
********************************* *********************************
*/ */
INTERNAL Animation *getFreeAnimationSlot(AssetManager *const assetManager, INTERNAL Animation *getFreeAnimationSlot(AssetManager *const assetManager,
MemoryArena *const arena, MemoryArena_ *const arena,
const char *const key) const char *const key)
{ {
HashTableEntry *entry = getFreeHashSlot(&assetManager->anims, arena, key); HashTableEntry *entry = getFreeHashSlot(&assetManager->anims, arena, key);
if (entry) if (entry)
{ {
entry->data = PLATFORM_MEM_ALLOC(arena, 1, Animation); entry->data = MEMORY_PUSH_STRUCT(arena, Animation);
Animation *result = CAST(Animation *) entry->data; Animation *result = CAST(Animation *) entry->data;
return result; return result;
} }
@ -250,7 +253,7 @@ INTERNAL Animation *getFreeAnimationSlot(AssetManager *const assetManager,
} }
void asset_addAnimation(AssetManager *const assetManager, void asset_addAnimation(AssetManager *const assetManager,
MemoryArena *const arena, const char *const animName, MemoryArena_ *const arena, const char *const animName,
TexAtlas *const atlas, TexAtlas *const atlas,
char **const subTextureNames, char **const subTextureNames,
const i32 numSubTextures, const f32 frameDuration) const i32 numSubTextures, const f32 frameDuration)
@ -265,7 +268,7 @@ void asset_addAnimation(AssetManager *const assetManager,
anim->frameDuration = frameDuration; anim->frameDuration = frameDuration;
anim->numFrames = numSubTextures; anim->numFrames = numSubTextures;
anim->frameList = PLATFORM_MEM_ALLOC(arena, numSubTextures, char*); anim->frameList = memory_pushBytes(arena, numSubTextures * sizeof(char *));
for (i32 i = 0; i < numSubTextures; i++) for (i32 i = 0; i < numSubTextures; i++)
{ {
anim->frameList[i] = subTextureNames[i]; anim->frameList[i] = subTextureNames[i];
@ -310,12 +313,12 @@ typedef struct XmlToken
i32 len; i32 len;
} XmlToken; } XmlToken;
INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena *const arena, INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena_ *const arena,
const char *const buffer, const char *const buffer,
const i32 bufferSize, const i32 bufferSize,
int *const numTokens) int *const numTokens)
{ {
XmlToken *xmlTokens = PLATFORM_MEM_ALLOC(arena, 8192, XmlToken); XmlToken *xmlTokens = memory_pushBytes(arena, 8192 * sizeof(XmlToken));
i32 tokenIndex = 0; i32 tokenIndex = 0;
for (i32 i = 0; i < bufferSize; i++) for (i32 i = 0; i < bufferSize; i++)
{ {
@ -417,11 +420,11 @@ INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena *const arena,
return xmlTokens; return xmlTokens;
} }
INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, INTERNAL XmlNode *const buildXmlTree(MemoryArena_ *const arena,
XmlToken *const xmlTokens, XmlToken *const xmlTokens,
const i32 numTokens) const i32 numTokens)
{ {
XmlNode *root = PLATFORM_MEM_ALLOC(arena, 1, XmlNode); XmlNode *root = MEMORY_PUSH_STRUCT(arena, XmlNode);
if (!root) return NULL; if (!root) return NULL;
XmlNode *node = root; XmlNode *node = root;
@ -457,7 +460,8 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
} }
XmlNode *parent = node->parent; XmlNode *parent = node->parent;
PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode)); // TODO(doyle): Mem free
//PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode));
node = node->parent; node = node->parent;
} }
else else
@ -496,7 +500,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
while (attribute->next) while (attribute->next)
attribute = attribute->next; attribute = attribute->next;
attribute->next = PLATFORM_MEM_ALLOC(arena, 1, XmlAttribute); attribute->next = MEMORY_PUSH_STRUCT(arena, XmlAttribute);
attribute = attribute->next; attribute = attribute->next;
} }
@ -531,7 +535,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
if (!node->child) if (!node->child)
{ {
// TODO(doyle): Mem alloc error checking // TODO(doyle): Mem alloc error checking
node->child = PLATFORM_MEM_ALLOC(arena, 1, XmlNode); node->child = MEMORY_PUSH_STRUCT(arena, XmlNode);
node->child->parent = node; node->child->parent = node;
node = node->child; node = node->child;
} }
@ -541,7 +545,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
while (nodeToCheck->next) while (nodeToCheck->next)
nodeToCheck = nodeToCheck->next; nodeToCheck = nodeToCheck->next;
nodeToCheck->next = PLATFORM_MEM_ALLOC(arena, 1, XmlNode); nodeToCheck->next = MEMORY_PUSH_STRUCT(arena, XmlNode);
nodeToCheck->next->parent = node; nodeToCheck->next->parent = node;
node = nodeToCheck->next; node = nodeToCheck->next;
} }
@ -560,7 +564,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
return root; return root;
} }
INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena, INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena_ *arena,
XmlNode *root) XmlNode *root)
{ {
XmlNode *node = root; XmlNode *node = root;
@ -606,7 +610,8 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena,
i32 imageNameLen = common_strlen(imageName); i32 imageNameLen = common_strlen(imageName);
i32 totalPathLen = (dataDirLen + imageNameLen) + 1; i32 totalPathLen = (dataDirLen + imageNameLen) + 1;
char *imagePath = PLATFORM_MEM_ALLOC(arena, totalPathLen, char); char *imagePath =
memory_pushBytes(arena, totalPathLen * sizeof(char));
common_strncat(imagePath, dataDir, dataDirLen); common_strncat(imagePath, dataDir, dataDirLen);
common_strncat(imagePath, imageName, imageNameLen); common_strncat(imagePath, imageName, imageNameLen);
@ -616,13 +621,15 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena,
if (!tex) if (!tex)
{ {
DEBUG_LOG("parseXmlTreeToGame() failed: Could not load image"); DEBUG_LOG("parseXmlTreeToGame() failed: Could not load image");
PLATFORM_MEM_FREE(arena, imagePath, // TODO(doyle): Mem free
totalPathLen * sizeof(char)); //PLATFORM_MEM_FREE(arena, imagePath,
// totalPathLen * sizeof(char));
return; return;
} }
PLATFORM_MEM_FREE(arena, imagePath, // TODO(doyle): Mem free
totalPathLen * sizeof(char)); //PLATFORM_MEM_FREE(arena, imagePath,
// totalPathLen * sizeof(char));
atlas->tex = tex; atlas->tex = tex;
/* /*
@ -757,7 +764,7 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena,
} }
} }
INTERNAL void recursiveFreeXmlTree(MemoryArena *const arena, INTERNAL void recursiveFreeXmlTree(MemoryArena_ *const arena,
XmlNode *node) XmlNode *node)
{ {
if (!node) if (!node)
@ -775,7 +782,8 @@ INTERNAL void recursiveFreeXmlTree(MemoryArena *const arena,
attrib->name = NULL; attrib->name = NULL;
attrib->value = NULL; attrib->value = NULL;
PLATFORM_MEM_FREE(arena, attrib, sizeof(XmlAttribute)); // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, attrib, sizeof(XmlAttribute));
attrib = next; attrib = next;
} }
@ -784,16 +792,18 @@ INTERNAL void recursiveFreeXmlTree(MemoryArena *const arena,
node->name = NULL; node->name = NULL;
node->isClosed = FALSE; node->isClosed = FALSE;
PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode)); // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode));
node = NULL; node = NULL;
} }
} }
INTERNAL void freeXmlData(MemoryArena *const arena, XmlToken *tokens, INTERNAL void freeXmlData(MemoryArena_ *const arena, XmlToken *tokens,
const i32 numTokens, XmlNode *tree) const i32 numTokens, XmlNode *tree)
{ {
if (tree) recursiveFreeXmlTree(arena, tree); if (tree) recursiveFreeXmlTree(arena, tree);
if (tokens) PLATFORM_MEM_FREE(arena, tokens, numTokens * sizeof(XmlToken)); // TODO(doyle): Mem free
// if (tokens) PLATFORM_MEM_FREE(arena, tokens, numTokens * sizeof(XmlToken));
} }
/* /*
@ -802,8 +812,8 @@ INTERNAL void freeXmlData(MemoryArena *const arena, XmlToken *tokens,
********************************* *********************************
*/ */
const i32 asset_loadXmlFile(AssetManager *const assetManager, const i32 asset_loadXmlFile(AssetManager *const assetManager,
MemoryArena *const arena, MemoryArena_ *const arena,
const PlatformFileRead *const fileRead) const PlatformFileRead *const fileRead)
{ {
i32 result = 0; i32 result = 0;
/* Tokenise buffer */ /* Tokenise buffer */
@ -842,7 +852,7 @@ AudioVorbis *const asset_getVorbis(AssetManager *const assetManager,
return result; return result;
} }
const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena_ *arena,
const char *const path, const char *const key) const char *const path, const char *const key)
{ {
HashTableEntry *entry = getFreeHashSlot(&assetManager->audio, arena, key); HashTableEntry *entry = getFreeHashSlot(&assetManager->audio, arena, key);
@ -852,7 +862,7 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
PlatformFileRead fileRead = {0}; PlatformFileRead fileRead = {0};
platform_readFileToBuffer(arena, path, &fileRead); platform_readFileToBuffer(arena, path, &fileRead);
entry->data = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis); entry->data = MEMORY_PUSH_STRUCT(arena, AudioVorbis);
i32 error; i32 error;
AudioVorbis *audio = CAST(AudioVorbis *) entry->data; AudioVorbis *audio = CAST(AudioVorbis *) entry->data;
@ -862,7 +872,8 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
if (!audio->file) if (!audio->file)
{ {
printf("stb_vorbis_open_memory() failed: Error code %d\n", error); printf("stb_vorbis_open_memory() failed: Error code %d\n", error);
platform_closeFileRead(arena, &fileRead); // TODO(doyle): Mem free
// platform_closeFileRead(arena, &fileRead);
stb_vorbis_close(audio->file); stb_vorbis_close(audio->file);
return 0; return 0;
} }
@ -877,11 +888,12 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
return 0; return 0;
} }
INTERNAL GLuint createShaderFromPath(MemoryArena *arena, const char *const path, INTERNAL GLuint createShaderFromPath(MemoryArena_ *arena, const char *const path,
GLuint shadertype) GLuint shadertype)
{ {
PlatformFileRead file = {0}; PlatformFileRead file = {0};
// TODO(doyle): Revise platform reads
i32 status = platform_readFileToBuffer(arena, path, &file); i32 status = platform_readFileToBuffer(arena, path, &file);
if (status) if (status)
return status; return status;
@ -942,7 +954,7 @@ Shader *const asset_getShader(AssetManager *assetManager,
return NULL; return NULL;
} }
const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena,
const char *const vertexPath, const char *const vertexPath,
const char *const fragmentPath, const char *const fragmentPath,
const enum ShaderList type) const enum ShaderList type)
@ -968,7 +980,7 @@ typedef struct GlyphBitmap
i32 codepoint; i32 codepoint;
} GlyphBitmap; } GlyphBitmap;
const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
const char *filePath) const char *filePath)
{ {
PlatformFileRead fontFileRead = {0}; PlatformFileRead fontFileRead = {0};
@ -990,7 +1002,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x); const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x);
GlyphBitmap *glyphBitmaps = GlyphBitmap *glyphBitmaps =
PLATFORM_MEM_ALLOC(arena, numGlyphs, GlyphBitmap); memory_pushBytes(arena, numGlyphs * sizeof(GlyphBitmap));
v2 largestGlyphDimension = V2(0, 0); v2 largestGlyphDimension = V2(0, 0);
const f32 targetFontHeight = 15.0f; const f32 targetFontHeight = 15.0f;
@ -1005,7 +1017,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
font->metrics = CAST(FontMetrics){ascent, descent, lineGap}; font->metrics = CAST(FontMetrics){ascent, descent, lineGap};
font->charMetrics = PLATFORM_MEM_ALLOC(arena, numGlyphs, CharMetrics); font->charMetrics =
memory_pushBytes(arena, numGlyphs * sizeof(CharMetrics));
/* /*
************************************************************ ************************************************************
@ -1024,7 +1037,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
&height, &xOffset, &yOffset); &height, &xOffset, &yOffset);
u8 *source = monoBitmap; u8 *source = monoBitmap;
u32 *colorBitmap = PLATFORM_MEM_ALLOC(arena, width * height, u32); u32 *colorBitmap =
memory_pushBytes(arena, width * height * sizeof(u32));
u32 *dest = colorBitmap; u32 *dest = colorBitmap;
// NOTE(doyle): STB generates 1 byte per pixel bitmaps, we use 4bpp, so // NOTE(doyle): STB generates 1 byte per pixel bitmaps, we use 4bpp, so
@ -1100,7 +1114,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
#endif #endif
i32 bitmapSize = SQUARED(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL; i32 bitmapSize = SQUARED(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL;
u32 *fontBitmap = PLATFORM_MEM_ALLOC(arena, bitmapSize, u32); u32 *fontBitmap = memory_pushBytes(arena, bitmapSize * sizeof(u32));
const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL; const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL;
// Check value to determine when a row of glyphs is completely printed // Check value to determine when a row of glyphs is completely printed
@ -1208,7 +1222,9 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
stbi_write_png("out.png", MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4, fontBitmap, stbi_write_png("out.png", MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4, fontBitmap,
MAX_TEXTURE_SIZE * 4); MAX_TEXTURE_SIZE * 4);
#endif #endif
PLATFORM_MEM_FREE(arena, fontBitmap, bitmapSize);
// TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, fontBitmap, bitmapSize);
fontAtlas->tex = tex; fontAtlas->tex = tex;
font->atlas = fontAtlas; font->atlas = fontAtlas;
@ -1222,10 +1238,12 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
i32 glyphBitmapSizeInBytes = CAST(i32) glyphBitmaps[i].dimensions.w * i32 glyphBitmapSizeInBytes = CAST(i32) glyphBitmaps[i].dimensions.w *
CAST(i32) glyphBitmaps[i].dimensions.h * CAST(i32) glyphBitmaps[i].dimensions.h *
sizeof(u32); sizeof(u32);
PLATFORM_MEM_FREE(arena, glyphBitmaps[i].pixels, glyphBitmapSizeInBytes); // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, glyphBitmaps[i].pixels, glyphBitmapSizeInBytes);
} }
PLATFORM_MEM_FREE(arena, glyphBitmaps, numGlyphs * sizeof(GlyphBitmap)); // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, glyphBitmaps, numGlyphs * sizeof(GlyphBitmap));
platform_closeFileRead(arena, &fontFileRead); platform_closeFileRead(arena, &fontFileRead);
return 0; return 0;
@ -1254,7 +1272,7 @@ const v2 asset_stringDimInPixels(const Font *const font,
return stringDim; return stringDim;
} }
void asset_unitTest(MemoryArena *arena) void asset_unitTest(MemoryArena_ *arena)
{ {
PlatformFileRead xmlFileRead = {0}; PlatformFileRead xmlFileRead = {0};
i32 result = platform_readFileToBuffer( i32 result = platform_readFileToBuffer(
@ -1267,15 +1285,11 @@ void asset_unitTest(MemoryArena *arena)
else else
{ {
/* Tokenise buffer */ /* Tokenise buffer */
i32 memBefore = arena->bytesAllocated;
i32 numTokens = 0; i32 numTokens = 0;
XmlToken *xmlTokens = tokeniseXmlBuffer(arena, xmlFileRead.buffer, XmlToken *xmlTokens = tokeniseXmlBuffer(arena, xmlFileRead.buffer,
xmlFileRead.size, &numTokens); xmlFileRead.size, &numTokens);
/* Build XML tree from tokens */ /* Build XML tree from tokens */
XmlNode *xmlTree = buildXmlTree(arena, xmlTokens, numTokens); XmlNode *xmlTree = buildXmlTree(arena, xmlTokens, numTokens);
freeXmlData(arena, xmlTokens, numTokens, xmlTree); freeXmlData(arena, xmlTokens, numTokens, xmlTree);
i32 memAfter = arena->bytesAllocated;
ASSERT(memBefore == memAfter);
} }
} }

View File

@ -7,7 +7,6 @@
#include "Dengine/Audio.h" #include "Dengine/Audio.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/MemoryArena.h" #include "Dengine/MemoryArena.h"
#include "dengine/Platform.h"
#define AL_CHECK_ERROR() alCheckError_(__FILE__, __LINE__); #define AL_CHECK_ERROR() alCheckError_(__FILE__, __LINE__);
void alCheckError_(const char *file, int line) void alCheckError_(const char *file, int line)
@ -116,7 +115,7 @@ INTERNAL inline u32 getSourceId(AudioManager *audioManager,
return result; return result;
} }
INTERNAL i32 rendererAcquire(MemoryArena *arena, AudioManager *audioManager, INTERNAL i32 rendererAcquire(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer) AudioRenderer *audioRenderer)
{ {
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
@ -162,7 +161,7 @@ INTERNAL i32 rendererAcquire(MemoryArena *arena, AudioManager *audioManager,
return 0; return 0;
} }
INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManager, INTERNAL const i32 rendererRelease(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer) AudioRenderer *audioRenderer)
{ {
@ -212,7 +211,9 @@ INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManage
if (audioRenderer->isStreaming) if (audioRenderer->isStreaming)
{ {
stb_vorbis_close(audioRenderer->audio->file); stb_vorbis_close(audioRenderer->audio->file);
PLATFORM_MEM_FREE(arena, audioRenderer->audio, sizeof(AudioVorbis));
// TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, audioRenderer->audio, sizeof(AudioVorbis));
} }
u32 sourceIndexToFree = audioRenderer->sourceIndex; u32 sourceIndexToFree = audioRenderer->sourceIndex;
@ -229,7 +230,7 @@ INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManage
return result; return result;
} }
INTERNAL i32 initRendererForPlayback(MemoryArena *arena, INTERNAL i32 initRendererForPlayback(MemoryArena_ *arena,
AudioManager *audioManager, AudioManager *audioManager,
AudioRenderer *audioRenderer, AudioRenderer *audioRenderer,
AudioVorbis *vorbis, i32 numPlays) AudioVorbis *vorbis, i32 numPlays)
@ -267,7 +268,7 @@ INTERNAL i32 initRendererForPlayback(MemoryArena *arena,
} }
#include <stdlib.h> #include <stdlib.h>
const i32 audio_playVorbis(MemoryArena *arena, AudioManager *audioManager, const i32 audio_playVorbis(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer, AudioVorbis *vorbis, AudioRenderer *audioRenderer, AudioVorbis *vorbis,
i32 numPlays) i32 numPlays)
{ {
@ -293,7 +294,7 @@ const i32 audio_playVorbis(MemoryArena *arena, AudioManager *audioManager,
return result; return result;
} }
const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, const i32 audio_streamPlayVorbis(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer, AudioRenderer *audioRenderer,
AudioVorbis *vorbis, i32 numPlays) AudioVorbis *vorbis, i32 numPlays)
{ {
@ -304,7 +305,7 @@ const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager,
// data except the file pointer. If the same sound is playing twice // data except the file pointer. If the same sound is playing twice
// simultaneously, we need unique file pointers into the data to track song // simultaneously, we need unique file pointers into the data to track song
// position uniquely // position uniquely
AudioVorbis *copyAudio = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis); AudioVorbis *copyAudio = MEMORY_PUSH_STRUCT(arena, AudioVorbis);
*copyAudio = *vorbis; *copyAudio = *vorbis;
i32 error; i32 error;
@ -318,7 +319,7 @@ const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager,
return result; return result;
} }
const i32 audio_stopVorbis(MemoryArena *arena, AudioManager *audioManager, const i32 audio_stopVorbis(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer) AudioRenderer *audioRenderer)
{ {
i32 result = 0; i32 result = 0;
@ -388,21 +389,12 @@ const i32 audio_resumeVorbis(AudioManager *audioManager,
} }
#define AUDIO_CHUNK_SIZE_ 65536 #define AUDIO_CHUNK_SIZE_ 65536
const i32 audio_updateAndPlay(MemoryArena *arena, AudioManager *audioManager, const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer) AudioRenderer *audioRenderer)
{ {
AudioVorbis *audio = audioRenderer->audio; AudioVorbis *audio = audioRenderer->audio;
if (!audio) return 0; if (!audio) return 0;
#if 0
if (audioRenderer->numPlays != AUDIO_REPEAT_INFINITE &&
audioRenderer->numPlays <= 0)
{
i32 result = rendererRelease(arena, audioManager, audioRenderer);
return result;
}
#endif
u32 alSourceId = getSourceId(audioManager, audioRenderer); u32 alSourceId = getSourceId(audioManager, audioRenderer);
if (alIsSource(alSourceId) == AL_FALSE) if (alIsSource(alSourceId) == AL_FALSE)
{ {

View File

@ -75,10 +75,11 @@ inline char *debug_entityattack_string(i32 val)
return string; return string;
} }
void debug_init(MemoryArena *arena, v2 windowSize, Font font) void debug_init(MemoryArena_ *arena, v2 windowSize, Font font)
{ {
GLOBAL_debug.font = font; GLOBAL_debug.font = font;
GLOBAL_debug.callCount = PLATFORM_MEM_ALLOC(arena, debugcount_num, i32); GLOBAL_debug.callCount =
memory_pushBytes(arena, debugcount_num * sizeof(i32));
GLOBAL_debug.stringLineGap = CAST(f32) font.verticalSpacing; GLOBAL_debug.stringLineGap = CAST(f32) font.verticalSpacing;
/* Init debug string stack */ /* Init debug string stack */
@ -268,7 +269,7 @@ void debug_pushString(char *formatString, void *data, char *dataType)
} }
} }
INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena *arena, INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena_ *arena,
f32 dt) f32 dt)
{ {
for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++) for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++)
@ -299,7 +300,7 @@ INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena *arena,
} }
INTERNAL void renderConsole(Renderer *renderer, MemoryArena *arena) INTERNAL void renderConsole(Renderer *renderer, MemoryArena_ *arena)
{ {
i32 maxConsoleLines = ARRAY_COUNT(GLOBAL_debug.console); i32 maxConsoleLines = ARRAY_COUNT(GLOBAL_debug.console);
v2 consoleStrP = GLOBAL_debug.initialConsoleP; v2 consoleStrP = GLOBAL_debug.initialConsoleP;
@ -320,6 +321,7 @@ void debug_drawUi(GameState *state, f32 dt)
Renderer *renderer = &state->renderer; Renderer *renderer = &state->renderer;
World *const world = &state->world[state->currWorldIndex]; World *const world = &state->world[state->currWorldIndex];
Entity *hero = &world->entities[entity_getIndex(world, world->heroId)]; Entity *hero = &world->entities[entity_getIndex(world, world->heroId)];
MemoryArena_ *transientArena = &state->transientArena;
// TODO(doyle): Dumb copy function from game so we don't expose api // TODO(doyle): Dumb copy function from game so we don't expose api
Rect camera = {world->cameraPos, renderer->size}; Rect camera = {world->cameraPos, renderer->size};
@ -347,7 +349,7 @@ void debug_drawUi(GameState *state, f32 dt)
CAST(f32)(font->maxSize.w * common_strlen(battleStr)); CAST(f32)(font->maxSize.w * common_strlen(battleStr));
v2 strPos = V2((renderer->size.w * 0.5f) - (strLenInPixels * 0.5f), v2 strPos = V2((renderer->size.w * 0.5f) - (strLenInPixels * 0.5f),
renderer->size.h - 300.0f); renderer->size.h - 300.0f);
renderer_staticString(&state->renderer, &state->arena, font, battleStr, renderer_staticString(&state->renderer, transientArena, font, battleStr,
strPos, V2(0, 0), 0, color); strPos, V2(0, 0), 0, color);
} }
@ -386,7 +388,7 @@ void debug_drawUi(GameState *state, f32 dt)
i32 indexOfLowerAInMetrics = 'a' - CAST(i32) font->codepointRange.x; i32 indexOfLowerAInMetrics = 'a' - CAST(i32) font->codepointRange.x;
strPos.y += font->charMetrics[indexOfLowerAInMetrics].offset.y; strPos.y += font->charMetrics[indexOfLowerAInMetrics].offset.y;
renderer_string(&state->renderer, &state->arena, camera, font, renderer_string(&state->renderer, transientArena, camera, font,
debugString, strPos, V2(0, 0), 0, color); debugString, strPos, V2(0, 0), 0, color);
f32 stringLineGap = 1.1f * font->verticalSpacing; f32 stringLineGap = 1.1f * font->verticalSpacing;
@ -395,14 +397,14 @@ void debug_drawUi(GameState *state, f32 dt)
char entityPosStr[128]; char entityPosStr[128];
snprintf(entityPosStr, ARRAY_COUNT(entityPosStr), "%06.2f, %06.2f", snprintf(entityPosStr, ARRAY_COUNT(entityPosStr), "%06.2f, %06.2f",
entity->pos.x, entity->pos.y); entity->pos.x, entity->pos.y);
renderer_string(&state->renderer, &state->arena, camera, font, renderer_string(&state->renderer, transientArena, camera, font,
entityPosStr, strPos, V2(0, 0), 0, color); entityPosStr, strPos, V2(0, 0), 0, color);
strPos.y -= GLOBAL_debug.stringLineGap; strPos.y -= GLOBAL_debug.stringLineGap;
char entityIDStr[32]; char entityIDStr[32];
snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entity->id, snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entity->id,
world->uniqueIdAccumulator-1); world->uniqueIdAccumulator-1);
renderer_string(&state->renderer, &state->arena, camera, font, renderer_string(&state->renderer, transientArena, camera, font,
entityIDStr, strPos, V2(0, 0), 0, color); entityIDStr, strPos, V2(0, 0), 0, color);
if (entity->stats) if (entity->stats)
@ -411,27 +413,27 @@ void debug_drawUi(GameState *state, f32 dt)
char entityHealth[32]; char entityHealth[32];
snprintf(entityHealth, ARRAY_COUNT(entityHealth), "HP: %3.0f/%3.0f", snprintf(entityHealth, ARRAY_COUNT(entityHealth), "HP: %3.0f/%3.0f",
entity->stats->health, entity->stats->maxHealth); entity->stats->health, entity->stats->maxHealth);
renderer_string(&state->renderer, &state->arena, camera, renderer_string(&state->renderer, transientArena, camera,
font, entityHealth, strPos, V2(0, 0), 0, color); font, entityHealth, strPos, V2(0, 0), 0, color);
strPos.y -= GLOBAL_debug.stringLineGap; strPos.y -= GLOBAL_debug.stringLineGap;
char entityTimer[32]; char entityTimer[32];
snprintf(entityTimer, ARRAY_COUNT(entityTimer), "ATB: %3.0f/%3.0f", snprintf(entityTimer, ARRAY_COUNT(entityTimer), "ATB: %3.0f/%3.0f",
entity->stats->actionTimer, entity->stats->actionRate); entity->stats->actionTimer, entity->stats->actionRate);
renderer_string(&state->renderer, &state->arena, camera, renderer_string(&state->renderer, transientArena, camera,
font, entityTimer, strPos, V2(0, 0), 0, color); font, entityTimer, strPos, V2(0, 0), 0, color);
strPos.y -= GLOBAL_debug.stringLineGap; strPos.y -= GLOBAL_debug.stringLineGap;
char entityIdTarget[32]; char entityIdTarget[32];
snprintf(entityIdTarget, ARRAY_COUNT(entityIdTarget), snprintf(entityIdTarget, ARRAY_COUNT(entityIdTarget),
"Targetting ID: %d", entity->stats->entityIdToAttack); "Targetting ID: %d", entity->stats->entityIdToAttack);
renderer_string(&state->renderer, &state->arena, camera, renderer_string(&state->renderer, transientArena, camera,
font, entityIdTarget, strPos, V2(0, 0), 0, color); font, entityIdTarget, strPos, V2(0, 0), 0, color);
} }
strPos.y -= GLOBAL_debug.stringLineGap; strPos.y -= GLOBAL_debug.stringLineGap;
char *entityStateStr = debug_entitystate_string(entity->state); char *entityStateStr = debug_entitystate_string(entity->state);
renderer_string(&state->renderer, &state->arena, camera, font, renderer_string(&state->renderer, transientArena, camera, font,
entityStateStr, strPos, V2(0, 0), 0, color); entityStateStr, strPos, V2(0, 0), 0, color);
if (entity->audioRenderer) if (entity->audioRenderer)
@ -442,7 +444,7 @@ void debug_drawUi(GameState *state, f32 dt)
ARRAY_COUNT(entityAudioSourceIndex), ARRAY_COUNT(entityAudioSourceIndex),
"AudioSource Index: %d", "AudioSource Index: %d",
entity->audioRenderer->sourceIndex); entity->audioRenderer->sourceIndex);
renderer_string(&state->renderer, &state->arena, camera, renderer_string(&state->renderer, transientArena, camera,
font, entityAudioSourceIndex, strPos, V2(0, 0), font, entityAudioSourceIndex, strPos, V2(0, 0),
0, color); 0, color);
} }
@ -498,12 +500,25 @@ void debug_drawUi(GameState *state, f32 dt)
DEBUG_PUSH_VAR("Mouse Pos: %06.2f, %06.2f", state->input.mouseP, "v2"); DEBUG_PUSH_VAR("Mouse Pos: %06.2f, %06.2f", state->input.mouseP, "v2");
i32 debug_bAllocated = state->arena.bytesAllocated; /*
DEBUG_PUSH_VAR("TotalMemoryAllocated: %db", debug_bAllocated, "i32"); *****************
i32 debug_kbAllocated = state->arena.bytesAllocated / 1024; * MEMORY DISPLAY
*****************
*/
i32 debug_bAllocated = transientArena->used;
i32 debug_kbAllocated = debug_bAllocated / 1024;
i32 debug_mbAllocated = debug_kbAllocated / 1024; i32 debug_mbAllocated = debug_kbAllocated / 1024;
DEBUG_PUSH_VAR("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32"); DEBUG_PUSH_VAR("TransientArena Used: %db", debug_bAllocated, "i32");
DEBUG_PUSH_VAR("TotalMemoryAllocated: %dmb", debug_mbAllocated, "i32"); DEBUG_PUSH_VAR("TransientArena Used: %dkb", debug_kbAllocated, "i32");
DEBUG_PUSH_VAR("TransientArena Used: %dmb", debug_mbAllocated, "i32");
DEBUG_PUSH_STRING("");
debug_bAllocated = state->arena_.used;
debug_kbAllocated = debug_bAllocated / 1024;
debug_mbAllocated = debug_kbAllocated / 1024;
DEBUG_PUSH_VAR("PersistentArena Used: %db", debug_bAllocated, "i32");
DEBUG_PUSH_VAR("PersistentArena Used: %dkb", debug_kbAllocated, "i32");
DEBUG_PUSH_VAR("PersistentArena Used: %dmb", debug_mbAllocated, "i32");
DEBUG_PUSH_STRING(""); DEBUG_PUSH_STRING("");
AudioManager *audioManager = &state->audioManager; AudioManager *audioManager = &state->audioManager;
@ -533,7 +548,7 @@ void debug_drawUi(GameState *state, f32 dt)
DEBUG_PUSH_STRING("-none-"); DEBUG_PUSH_STRING("-none-");
} }
updateAndRenderDebugStack(&state->renderer, &state->arena, dt); updateAndRenderDebugStack(&state->renderer, transientArena, dt);
renderConsole(&state->renderer, &state->arena); renderConsole(&state->renderer, transientArena);
debug_clearCounter(); debug_clearCounter();
} }

View File

@ -1,6 +1,7 @@
#include "Dengine/Entity.h" #include "Dengine/Entity.h"
#include "Dengine/AssetManager.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/Platform.h" #include "Dengine/MemoryArena.h"
#include "Dengine/WorldTraveller.h" #include "Dengine/WorldTraveller.h"
SubTexture entity_getActiveSubTexture(Entity *const entity) SubTexture entity_getActiveSubTexture(Entity *const entity)
@ -108,7 +109,7 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
DEBUG_LOG("No more free entity animation slots"); DEBUG_LOG("No more free entity animation slots");
} }
Entity *const entity_add(MemoryArena *const arena, World *const world, Entity *const entity_add(MemoryArena_ *const arena, World *const world,
const v2 pos, const v2 size, const f32 scale, const v2 pos, const v2 size, const f32 scale,
const enum EntityType type, const enum EntityType type,
const enum Direction direction, Texture *const tex, const enum Direction direction, Texture *const tex,
@ -135,7 +136,7 @@ Entity *const entity_add(MemoryArena *const arena, World *const world,
switch (type) switch (type)
{ {
case entitytype_hero: case entitytype_hero:
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats);
entity.stats->maxHealth = 100; entity.stats->maxHealth = 100;
entity.stats->health = entity.stats->maxHealth; entity.stats->health = entity.stats->maxHealth;
entity.stats->actionRate = 100; entity.stats->actionRate = 100;
@ -148,7 +149,7 @@ Entity *const entity_add(MemoryArena *const arena, World *const world,
break; break;
case entitytype_mob: case entitytype_mob:
{ {
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats);
entity.stats->maxHealth = 100; entity.stats->maxHealth = 100;
entity.stats->health = entity.stats->maxHealth; entity.stats->health = entity.stats->maxHealth;
entity.stats->actionRate = 80; entity.stats->actionRate = 80;
@ -162,12 +163,12 @@ Entity *const entity_add(MemoryArena *const arena, World *const world,
} }
case entitytype_projectile: case entitytype_projectile:
case entitytype_attackObject: case entitytype_attackObject:
entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats);
entity.stats->maxHealth = 100; entity.stats->maxHealth = 100;
entity.stats->health = entity.stats->maxHealth; entity.stats->health = entity.stats->maxHealth;
entity.stats->actionRate = 100; entity.stats->actionRate = 100;
entity.stats->actionTimer = entity.stats->actionRate; entity.stats->actionTimer = entity.stats->actionRate;
entity.stats->actionSpdMul = 100; entity.stats->actionSpdMul = 100;
entity.stats->entityIdToAttack = -1; entity.stats->entityIdToAttack = -1;
entity.stats->queuedAttack = entityattack_invalid; entity.stats->queuedAttack = entityattack_invalid;
entity.state = entitystate_idle; entity.state = entitystate_idle;
@ -183,15 +184,19 @@ Entity *const entity_add(MemoryArena *const arena, World *const world,
return result; return result;
} }
void entity_clearData(MemoryArena *const arena, World *const world, void entity_clearData(MemoryArena_ *const arena, World *const world,
Entity *const entity) Entity *const entity)
{ {
// TODO(doyle): Mem free// memory leak!!
/*
if (entity->stats) if (entity->stats)
PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats)); PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats));
if (entity->audioRenderer) if (entity->audioRenderer)
PLATFORM_MEM_FREE(arena, entity->audioRenderer, PLATFORM_MEM_FREE(arena, entity->audioRenderer,
sizeof(AudioRenderer) * entity->numAudioRenderers); sizeof(AudioRenderer) * entity->numAudioRenderers);
*/
entity->type = entitytype_null; entity->type = entitytype_null;
} }

8
src/MemoryArena.c Normal file
View File

@ -0,0 +1,8 @@
#include "Dengine/MemoryArena.h"
void memory_arenaInit(MemoryArena_ *arena, void *base, size_t size)
{
arena->size = size;
arena->used = 0;
arena->base = CAST(u8 *)base;
}

View File

@ -3,37 +3,38 @@
#include <stdlib.h> #include <stdlib.h>
#include "Dengine/Platform.h" #include "Dengine/Platform.h"
#include "Dengine/MemoryArena.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/MemoryArena.h"
void platform_memoryFree(MemoryArena *arena, void *data, i32 numBytes) void platform_memoryFree(MemoryArena_ *arena, void *data, i32 numBytes)
{ {
if (data) free(data); if (data) free(data);
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
debug_countIncrement(debugcount_platformMemFree); debug_countIncrement(debugcount_platformMemFree);
arena->bytesAllocated -= numBytes; arena->used -= numBytes;
#endif #endif
} }
void *platform_memoryAlloc(MemoryArena *arena, i32 numBytes) void *platform_memoryAlloc(MemoryArena_ *arena, i32 numBytes)
{ {
void *result = calloc(1, numBytes); void *result = calloc(1, numBytes);
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
debug_countIncrement(debugcount_platformMemAlloc); debug_countIncrement(debugcount_platformMemAlloc);
if (result) if (result && arena)
arena->bytesAllocated += numBytes; arena->used += numBytes;
#endif #endif
return result; return result;
} }
void platform_closeFileRead(MemoryArena *arena, PlatformFileRead *file) void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file)
{ {
PLATFORM_MEM_FREE(arena, file->buffer, file->size); // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, file->buffer, file->size);
} }
i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath, i32 platform_readFileToBuffer(MemoryArena_ *arena, const char *const filePath,
PlatformFileRead *file) PlatformFileRead *file)
{ {
HANDLE fileHandle = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, HANDLE fileHandle = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ,
@ -55,8 +56,8 @@ i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath,
} }
// TODO(doyle): Warning we assume files less than 4GB // TODO(doyle): Warning we assume files less than 4GB
file->buffer = PLATFORM_MEM_ALLOC(arena, fileSize.LowPart, char); file->buffer = memory_pushBytes(arena, fileSize.LowPart * sizeof(char));
file->size = fileSize.LowPart; file->size = fileSize.LowPart;
DWORD numBytesRead = 0; DWORD numBytesRead = 0;
@ -66,7 +67,19 @@ i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath,
{ {
printf("ReadFile() failed: %d error number\n", printf("ReadFile() failed: %d error number\n",
status); status);
PLATFORM_MEM_FREE(arena, file->buffer, file->size);
char msgBuffer[512] = {0};
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)msgBuffer, 0, NULL);
// TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, file->buffer, file->size);
return status; return status;
} }
else if (numBytesRead != file->size) else if (numBytesRead != file->size)
@ -74,7 +87,8 @@ i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath,
printf( printf(
"ReadFile() failed: Number of bytes read doesn't match file " "ReadFile() failed: Number of bytes read doesn't match file "
"size\n"); "size\n");
PLATFORM_MEM_FREE(arena, file->buffer, file->size); // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, file->buffer, file->size);
return -1; return -1;
} }

View File

@ -3,8 +3,8 @@
#include "Dengine/Assets.h" #include "Dengine/Assets.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/Entity.h" #include "Dengine/Entity.h"
#include "Dengine/MemoryArena.h"
#include "Dengine/OpenGL.h" #include "Dengine/OpenGL.h"
#include "Dengine/Platform.h"
#include "Dengine/Shader.h" #include "Dengine/Shader.h"
#include "Dengine/Texture.h" #include "Dengine/Texture.h"
@ -301,7 +301,7 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size,
addRenderQuadToRenderGroup(renderer, quad, renderTex.tex, color); addRenderQuadToRenderGroup(renderer, quad, renderTex.tex, color);
} }
void renderer_string(Renderer *const renderer, MemoryArena *arena, Rect camera, void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
Font *const font, const char *const string, v2 pos, Font *const font, const char *const string, v2 pos,
v2 pivotPoint, f32 rotate, v4 color) v2 pivotPoint, f32 rotate, v4 color)
{ {
@ -322,7 +322,7 @@ void renderer_string(Renderer *const renderer, MemoryArena *arena, Rect camera,
i32 numVertexPerQuad = 4; i32 numVertexPerQuad = 4;
i32 numVertexesToAlloc = (strLen * (numVertexPerQuad + 2)); i32 numVertexesToAlloc = (strLen * (numVertexPerQuad + 2));
Vertex *vertexList = Vertex *vertexList =
PLATFORM_MEM_ALLOC(arena, numVertexesToAlloc, Vertex); memory_pushBytes(arena, numVertexesToAlloc * sizeof(Vertex));
v2 posInCameraSpace = v2_sub(pos, camera.pos); v2 posInCameraSpace = v2_sub(pos, camera.pos);
pos = posInCameraSpace; pos = posInCameraSpace;
@ -362,8 +362,9 @@ void renderer_string(Renderer *const renderer, MemoryArena *arena, Rect camera,
addVertexToRenderGroup(renderer, tex, color, vertexList, addVertexToRenderGroup(renderer, tex, color, vertexList,
numVertexesToAlloc); numVertexesToAlloc);
PLATFORM_MEM_FREE(arena, vertexList, // TODO(doyle): Mem free
sizeof(Vertex) * numVertexesToAlloc); // PLATFORM_MEM_FREE(arena, vertexList,
// sizeof(Vertex) * numVertexesToAlloc);
} }
} }

View File

@ -1,5 +1,5 @@
#include "Dengine/String.h" #include "Dengine/String.h"
#include "Dengine/Platform.h" #include "Dengine/MemoryArena.h"
/* /*
* +-------------------------------------+ * +-------------------------------------+
@ -51,7 +51,7 @@ i32 string_len(String *const string)
return result; return result;
} }
String *const string_append(MemoryArena *const arena, String *oldString, String *const string_append(MemoryArena_ *const arena, String *oldString,
char *appendString, i32 appendLen) char *appendString, i32 appendLen)
{ {
@ -74,7 +74,7 @@ String *const string_append(MemoryArena *const arena, String *oldString,
return newString; return newString;
} }
void string_free(MemoryArena *arena, String *string) void string_free(MemoryArena_ *arena, String *string)
{ {
if (!string || !arena) return; if (!string || !arena) return;
@ -82,11 +82,14 @@ void string_free(MemoryArena *arena, String *string)
i32 bytesToFree = sizeof(StringHeader) + header->len; i32 bytesToFree = sizeof(StringHeader) + header->len;
common_memset((u8 *)header, 0, bytesToFree); common_memset((u8 *)header, 0, bytesToFree);
PLATFORM_MEM_FREE(arena, header, bytesToFree);
// TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, header, bytesToFree);
string = NULL; string = NULL;
} }
String *const string_make(MemoryArena *const arena, char *string) String *const string_make(MemoryArena_ *const arena, char *string)
{ {
if (!arena) return NULL; if (!arena) return NULL;
@ -97,7 +100,7 @@ String *const string_make(MemoryArena *const arena, char *string)
return result; return result;
} }
String *const string_makeLen(MemoryArena *const arena, i32 len) String *const string_makeLen(MemoryArena_ *const arena, i32 len)
{ {
if (!arena) return NULL; if (!arena) return NULL;
@ -107,7 +110,7 @@ String *const string_makeLen(MemoryArena *const arena, i32 len)
// character. Whilst the len of a string counts up to the last character // character. Whilst the len of a string counts up to the last character
// _not_ including null-terminator. // _not_ including null-terminator.
i32 bytesToAllocate = sizeof(StringHeader) + len; i32 bytesToAllocate = sizeof(StringHeader) + len;
void *chunk = PLATFORM_MEM_ALLOC(arena, bytesToAllocate, u8); void *chunk = memory_pushBytes(arena, bytesToAllocate * sizeof(u8));
if (!chunk) return NULL; if (!chunk) return NULL;
StringHeader *header = CAST(StringHeader *) chunk; StringHeader *header = CAST(StringHeader *) chunk;

View File

@ -1,16 +1,14 @@
#include "Dengine/UserInterface.h" #include "Dengine/UserInterface.h"
#include "Dengine/AssetManager.h" #include "Dengine/AssetManager.h"
#include "Dengine/Assets.h" #include "Dengine/Assets.h"
#include "Dengine/Renderer.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/Renderer.h"
i32 userInterface_button(UiState *const uiState, i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
MemoryArena *const arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Renderer *const renderer, Font *const font,
Font *const font, const KeyInput input, const i32 id, const Rect rect,
const KeyInput input, const char *const label)
const i32 id, const Rect rect, const char *const label)
{ {
if (math_pointInRect(rect, input.mouseP)) if (math_pointInRect(rect, input.mouseP))
{ {
@ -251,7 +249,7 @@ i32 userInterface_scrollbar(UiState *const uiState,
return 0; return 0;
} }
i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena, i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Font *const font, Renderer *const renderer, Font *const font,
KeyInput input, const i32 id, const Rect rect, KeyInput input, const i32 id, const Rect rect,
@ -352,7 +350,7 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena,
return 0; return 0;
} }
i32 userInterface_window(UiState *const uiState, MemoryArena *const arena, i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Font *const font, Renderer *const renderer, Font *const font,
const KeyInput input, WindowState *window) const KeyInput input, WindowState *window)

View File

@ -19,7 +19,7 @@ INTERNAL Entity *getHeroEntity(World *world)
return result; return result;
} }
INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena *arena, INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena_ *arena,
AssetManager *assetManager, World *world, v2 pos) AssetManager *assetManager, World *world, v2 pos)
{ {
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
@ -39,7 +39,7 @@ INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena *arena,
mob->numAudioRenderers = 4; mob->numAudioRenderers = 4;
mob->audioRenderer = mob->audioRenderer =
PLATFORM_MEM_ALLOC(arena, mob->numAudioRenderers, AudioRenderer); memory_pushBytes(arena, mob->numAudioRenderers * sizeof(AudioRenderer));
for (i32 i = 0; i < mob->numAudioRenderers; i++) for (i32 i = 0; i < mob->numAudioRenderers; i++)
mob->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED; mob->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED;
@ -104,8 +104,8 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize)
renderer->groupCapacity = 4096; renderer->groupCapacity = 4096;
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++) for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
{ {
renderer->groups[i].vertexList = renderer->groups[i].vertexList = memory_pushBytes(
PLATFORM_MEM_ALLOC(&state->arena, renderer->groupCapacity, Vertex); &state->arena_, renderer->groupCapacity * sizeof(Vertex));
} }
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
@ -116,27 +116,27 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize)
INTERNAL void assetInit(GameState *state) INTERNAL void assetInit(GameState *state)
{ {
AssetManager *assetManager = &state->assetManager; AssetManager *assetManager = &state->assetManager;
MemoryArena *arena = &state->arena; MemoryArena_ *arena = &state->arena_;
i32 audioEntries = 32; i32 audioEntries = 32;
assetManager->audio.size = audioEntries; assetManager->audio.size = audioEntries;
assetManager->audio.entries = assetManager->audio.entries =
PLATFORM_MEM_ALLOC(arena, audioEntries, HashTableEntry); memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry));
i32 texAtlasEntries = 8; i32 texAtlasEntries = 8;
assetManager->texAtlas.size = texAtlasEntries; assetManager->texAtlas.size = texAtlasEntries;
assetManager->texAtlas.entries = assetManager->texAtlas.entries =
PLATFORM_MEM_ALLOC(arena, texAtlasEntries, HashTableEntry); memory_pushBytes(arena, texAtlasEntries * sizeof(HashTableEntry));
i32 texEntries = 32; i32 texEntries = 32;
assetManager->textures.size = texEntries; assetManager->textures.size = texEntries;
assetManager->textures.entries = assetManager->textures.entries =
PLATFORM_MEM_ALLOC(arena, texEntries, HashTableEntry); memory_pushBytes(arena, texEntries * sizeof(HashTableEntry));
i32 animEntries = 1024; i32 animEntries = 1024;
assetManager->anims.size = animEntries; assetManager->anims.size = animEntries;
assetManager->anims.entries = assetManager->anims.entries =
PLATFORM_MEM_ALLOC(arena, animEntries, HashTableEntry); memory_pushBytes(arena, animEntries * sizeof(HashTableEntry));
/* Create empty 1x1 4bpp black texture */ /* Create empty 1x1 4bpp black texture */
u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0); u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0);
@ -438,7 +438,7 @@ INTERNAL void assetInit(GameState *state)
/* Load sound */ /* Load sound */
i32 before = arena->bytesAllocated; i32 before = arena->used;
char *sfxListPath = "data/audio/sfx/sfx.txt"; char *sfxListPath = "data/audio/sfx/sfx.txt";
PlatformFileRead sfxList = {0}; PlatformFileRead sfxList = {0};
@ -459,7 +459,7 @@ INTERNAL void assetInit(GameState *state)
{ {
i32 actualStrLen = common_strlen(string) + 1; i32 actualStrLen = common_strlen(string) + 1;
sfxAudioNames[sfxAudioIndex] = sfxAudioNames[sfxAudioIndex] =
PLATFORM_MEM_ALLOC(arena, actualStrLen, char); memory_pushBytes(arena, actualStrLen * sizeof(char));
common_strncpy(sfxAudioNames[sfxAudioIndex++], string, common_strncpy(sfxAudioNames[sfxAudioIndex++], string,
actualStrLen); actualStrLen);
@ -490,7 +490,8 @@ INTERNAL void assetInit(GameState *state)
i32 sfxNameLen = common_strlen(sfxName); i32 sfxNameLen = common_strlen(sfxName);
i32 sfxFullPathLen = sfxDirLen + sfxExtensionLen + sfxNameLen + 1; i32 sfxFullPathLen = sfxDirLen + sfxExtensionLen + sfxNameLen + 1;
char *sfxFullPath = PLATFORM_MEM_ALLOC(arena, sfxFullPathLen, char); char *sfxFullPath =
memory_pushBytes(arena, sfxFullPathLen * sizeof(char));
common_strncat(sfxFullPath, sfxDir, sfxDirLen); common_strncat(sfxFullPath, sfxDir, sfxDirLen);
common_strncat(sfxFullPath, sfxName, sfxNameLen); common_strncat(sfxFullPath, sfxName, sfxNameLen);
@ -503,11 +504,13 @@ INTERNAL void assetInit(GameState *state)
// character, having to remember to +1 on allocation AND freeing since // character, having to remember to +1 on allocation AND freeing since
// strlen only counts until null char is going to leave memory leaks // strlen only counts until null char is going to leave memory leaks
// everywhere // everywhere
PLATFORM_MEM_FREE(arena, sfxName, sfxNameLen * sizeof(char) + 1); // TODO(doyle): Free mem
PLATFORM_MEM_FREE(arena, sfxFullPath, sfxFullPathLen * sizeof(char)); // PLATFORM_MEM_FREE(arena, sfxName, sfxNameLen * sizeof(char) + 1);
// PLATFORM_MEM_FREE(arena, sfxFullPath, sfxFullPathLen * sizeof(char));
} }
platform_closeFileRead(arena, &sfxList); // TODO(doyle): Free mem
// platform_closeFileRead(arena, &sfxList);
char *audioPath = char *audioPath =
"data/audio/Motoi Sakuraba - Stab the sword of justice.ogg"; "data/audio/Motoi Sakuraba - Stab the sword of justice.ogg";
@ -525,7 +528,7 @@ INTERNAL void assetInit(GameState *state)
INTERNAL void entityInit(GameState *state, v2 windowSize) INTERNAL void entityInit(GameState *state, v2 windowSize)
{ {
AssetManager *assetManager = &state->assetManager; AssetManager *assetManager = &state->assetManager;
MemoryArena *arena = &state->arena; MemoryArena_ *arena = &state->arena_;
/* Init world */ /* Init world */
const i32 targetWorldWidth = 100 * METERS_TO_PIXEL; const i32 targetWorldWidth = 100 * METERS_TO_PIXEL;
@ -544,9 +547,10 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
{ {
World *const world = &state->world[i]; World *const world = &state->world[i];
world->maxEntities = 16384; world->maxEntities = 16384;
world->entities = PLATFORM_MEM_ALLOC(arena, world->maxEntities, Entity); world->entities =
memory_pushBytes(arena, world->maxEntities * sizeof(Entity));
world->entityIdInBattle = world->entityIdInBattle =
PLATFORM_MEM_ALLOC(arena, world->maxEntities, i32); memory_pushBytes(arena, world->maxEntities * sizeof(i32));
world->numEntitiesInBattle = 0; world->numEntitiesInBattle = 0;
world->bounds = world->bounds =
math_getRect(V2(0, 0), v2_scale(worldDimensionInTiles, math_getRect(V2(0, 0), v2_scale(worldDimensionInTiles,
@ -600,8 +604,8 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
world->soundscape = soundscape; world->soundscape = soundscape;
soundscape->numAudioRenderers = 1; soundscape->numAudioRenderers = 1;
soundscape->audioRenderer = soundscape->audioRenderer = memory_pushBytes(
PLATFORM_MEM_ALLOC(arena, soundscape->numAudioRenderers, AudioRenderer); arena, soundscape->numAudioRenderers * sizeof(AudioRenderer));
for (i32 i = 0; i < soundscape->numAudioRenderers; i++) for (i32 i = 0; i < soundscape->numAudioRenderers; i++)
soundscape->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED; soundscape->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED;
@ -626,8 +630,8 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
hero->stats->weapon = heroWeapon; hero->stats->weapon = heroWeapon;
hero->numAudioRenderers = 4; hero->numAudioRenderers = 4;
hero->audioRenderer = hero->audioRenderer = memory_pushBytes(arena, hero->numAudioRenderers *
PLATFORM_MEM_ALLOC(arena, hero->numAudioRenderers, AudioRenderer); sizeof(AudioRenderer));
for (i32 i = 0; i < hero->numAudioRenderers; i++) for (i32 i = 0; i < hero->numAudioRenderers; i++)
hero->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED; hero->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED;
@ -725,7 +729,7 @@ INTERNAL v2 getPosRelativeToRect(Rect rect, v2 offset,
return result; return result;
} }
INTERNAL void unitTest(MemoryArena *arena) INTERNAL void unitTest(MemoryArena_ *arena)
{ {
ASSERT(common_atoi("-2", common_strlen("-2")) == -2); ASSERT(common_atoi("-2", common_strlen("-2")) == -2);
ASSERT(common_atoi("100", common_strlen("100")) == 100); ASSERT(common_atoi("100", common_strlen("100")) == 100);
@ -738,7 +742,7 @@ INTERNAL void unitTest(MemoryArena *arena)
ASSERT(common_atoi("+ 32", common_strlen("+ 32")) == 0); ASSERT(common_atoi("+ 32", common_strlen("+ 32")) == 0);
asset_unitTest(arena); asset_unitTest(arena);
i32 memBefore = arena->bytesAllocated; i32 memBefore = arena->used;
String *hello = string_make(arena, "hello, "); String *hello = string_make(arena, "hello, ");
String *world = string_make(arena, "world"); String *world = string_make(arena, "world");
ASSERT(string_len(hello) == 7); ASSERT(string_len(hello) == 7);
@ -758,18 +762,23 @@ INTERNAL void unitTest(MemoryArena *arena)
string_free(arena, hello); string_free(arena, hello);
string_free(arena, world); string_free(arena, world);
i32 memAfter = arena->bytesAllocated; i32 memAfter = arena->used;
ASSERT(memBefore == memAfter);
} }
// TODO(doyle): Remove and implement own random generator! // TODO(doyle): Remove and implement own random generator!
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
void worldTraveller_gameInit(GameState *state, v2 windowSize) void worldTraveller_gameInit(GameState *state, v2 windowSize, Memory *memory)
{ {
state->memory = memory;
memory_arenaInit(&state->arena_, memory->persistent,
memory->persistentSize);
memory_arenaInit(&state->transientArena, memory->transient,
memory->transientSize);
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
unitTest(&state->arena); unitTest(&state->arena_);
#endif #endif
i32 result = audio_init(&state->audioManager); i32 result = audio_init(&state->audioManager);
@ -1157,7 +1166,7 @@ typedef struct AttackSpec
i32 damage; i32 damage;
} AttackSpec; } AttackSpec;
INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena, INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena_ *arena,
EventQueue *eventQueue, World *world, EventQueue *eventQueue, World *world,
Entity *attacker) Entity *attacker)
{ {
@ -1308,7 +1317,7 @@ INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena,
// TODO(doyle): MemArena here is temporary until we incorporate AttackSpec to // TODO(doyle): MemArena here is temporary until we incorporate AttackSpec to
// battle in general! // battle in general!
INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue, INTERNAL void endAttack(MemoryArena_ *arena, EventQueue *eventQueue,
World *world, Entity *attacker) World *world, Entity *attacker)
{ {
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
@ -1336,7 +1345,7 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
case entityattack_claudeEnergySword: case entityattack_claudeEnergySword:
attacker->stats->health += 80; attacker->stats->health += 80;
AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec); AttackSpec *attackSpec = MEMORY_PUSH_STRUCT(arena, AttackSpec);
attackSpec->attacker = attacker; attackSpec->attacker = attacker;
attackSpec->defender = attacker; attackSpec->defender = attacker;
attackSpec->damage = 30; attackSpec->damage = 30;
@ -1389,7 +1398,7 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue,
{ {
i32 damage = 25; i32 damage = 25;
AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec); AttackSpec *attackSpec = MEMORY_PUSH_STRUCT(arena, AttackSpec);
attackSpec->attacker = attacker; attackSpec->attacker = attacker;
attackSpec->defender = defender; attackSpec->defender = defender;
attackSpec->damage = damage; attackSpec->damage = damage;
@ -1606,12 +1615,16 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
if (dt >= 1.0f) dt = 1.0f; if (dt >= 1.0f) dt = 1.0f;
GL_CHECK_ERROR(); GL_CHECK_ERROR();
AssetManager *assetManager = &state->assetManager; memory_arenaInit(&state->transientArena, state->memory->transient,
Renderer *renderer = &state->renderer; state->memory->transientSize);
World *const world = &state->world[state->currWorldIndex];
Font *font = &assetManager->font; AssetManager *assetManager = &state->assetManager;
MemoryArena *arena = &state->arena; Renderer *renderer = &state->renderer;
EventQueue *eventQueue = &state->eventQueue; World *const world = &state->world[state->currWorldIndex];
Font *font = &assetManager->font;
MemoryArena_ *arena = &state->arena_;
MemoryArena_ *transientArena = &state->transientArena;
EventQueue *eventQueue = &state->eventQueue;
/* /*
********************** **********************
@ -1691,7 +1704,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
v2 pos = v2 pos =
V2(renderer->size.w - (renderer->size.w / xModifier), yPos); V2(renderer->size.w - (renderer->size.w / xModifier), yPos);
addGenericMob(eventQueue, &state->arena, &state->assetManager, world, pos); addGenericMob(eventQueue, &state->arena_, &state->assetManager, world, pos);
} }
} }
@ -2050,7 +2063,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
} }
/* Launch up attack animation */ /* Launch up attack animation */
beginAttack(assetManager, &state->arena, eventQueue, world, beginAttack(assetManager, &state->arena_, eventQueue, world,
entity); entity);
} }
} }
@ -2062,7 +2075,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
if (stats->busyDuration <= 0) if (stats->busyDuration <= 0)
{ {
/* Apply attack damage */ /* Apply attack damage */
endAttack(&state->arena, eventQueue, world, entity); endAttack(transientArena, eventQueue, world, entity);
} }
} }
} }
@ -2074,7 +2087,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
*/ */
for (i32 i = 0; i < entity->numAudioRenderers; i++) for (i32 i = 0; i < entity->numAudioRenderers; i++)
{ {
audio_updateAndPlay(&state->arena, &state->audioManager, audio_updateAndPlay(&state->arena_, &state->audioManager,
&entity->audioRenderer[i]); &entity->audioRenderer[i]);
} }
@ -2227,8 +2240,6 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
break; break;
} }
} }
PLATFORM_MEM_FREE(&state->arena, attackSpec, sizeof(AttackSpec));
break; break;
} }
// NOTE(doyle): We delete dead entities at the end of the update // NOTE(doyle): We delete dead entities at the end of the update
@ -2244,10 +2255,10 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
Entity *entity = (CAST(Entity *) event.data); Entity *entity = (CAST(Entity *) event.data);
for (i32 i = 0; i < entity->numAudioRenderers; i++) for (i32 i = 0; i < entity->numAudioRenderers; i++)
{ {
audio_stopVorbis(&state->arena, audioManager, audio_stopVorbis(&state->arena_, audioManager,
&entity->audioRenderer[i]); &entity->audioRenderer[i]);
} }
entity_clearData(&state->arena, world, entity); entity_clearData(&state->arena_, world, entity);
numDeadEntities++; numDeadEntities++;
for (i32 i = 0; i < entity->numChilds; i++) for (i32 i = 0; i < entity->numChilds; i++)
@ -2257,10 +2268,10 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
{ {
for (i32 i = 0; i < child->numAudioRenderers; i++) for (i32 i = 0; i < child->numAudioRenderers; i++)
{ {
audio_stopVorbis(&state->arena, audioManager, audio_stopVorbis(&state->arena_, audioManager,
&child->audioRenderer[i]); &child->audioRenderer[i]);
} }
entity_clearData(&state->arena, world, child); entity_clearData(&state->arena_, world, child);
numDeadEntities++; numDeadEntities++;
} }
else else
@ -2332,7 +2343,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
// TODO(doyle): Incorporate UI into entity list or it's own list // TODO(doyle): Incorporate UI into entity list or it's own list
// with a rendering lifetime value // with a rendering lifetime value
renderer_string(renderer, &state->arena, camera, font, renderer_string(renderer, transientArena, camera, font,
damageString, damagePos, V2(0, 0), 0, damageString, damagePos, V2(0, 0), 0,
V4(1, 1, 1, lifetime)); V4(1, 1, 1, lifetime));
} }
@ -2351,14 +2362,14 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
if (state->config.showStatMenu) if (state->config.showStatMenu)
{ {
WindowState *statWindow = &state->uiState.statWindow; WindowState *statWindow = &state->uiState.statWindow;
userInterface_window(&state->uiState, &state->arena, assetManager, userInterface_window(&state->uiState, transientArena, assetManager,
renderer, font, state->input, statWindow); renderer, font, state->input, statWindow);
} }
/* Draw debug window */ /* Draw debug window */
WindowState *debugWindow = &state->uiState.debugWindow; WindowState *debugWindow = &state->uiState.debugWindow;
i32 activeId = i32 activeId =
userInterface_window(&state->uiState, &state->arena, assetManager, userInterface_window(&state->uiState, transientArena, assetManager,
renderer, font, state->input, debugWindow); renderer, font, state->input, debugWindow);
// TODO(doyle): Name lookup to user interface id // TODO(doyle): Name lookup to user interface id
@ -2408,10 +2419,10 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
CAST(f32)(font->maxSize.w * common_strlen(heroAvatarStr)); CAST(f32)(font->maxSize.w * common_strlen(heroAvatarStr));
v2 strPos = v2 strPos =
V2(heroAvatarP.x, heroAvatarP.y - (0.5f * heroAvatarRect.rect.size.h)); V2(heroAvatarP.x, heroAvatarP.y - (0.5f * heroAvatarRect.rect.size.h));
renderer_staticString(&state->renderer, &state->arena, font, heroAvatarStr, renderer_staticString(&state->renderer, transientArena, font, heroAvatarStr,
strPos, V2(0, 0), 0, V4(0, 0, 1, 1)); strPos, V2(0, 0), 0, V4(0, 0, 1, 1));
renderer_staticString(&state->renderer, &state->arena, font, heroAvatarStr, renderer_staticString(&state->renderer, transientArena, font, heroAvatarStr,
strPos, V2(0, 0), 0, V4(0, 0, 1, 1)); strPos, V2(0, 0), 0, V4(0, 0, 1, 1));
for (i32 i = 0; i < world->maxEntities; i++) for (i32 i = 0; i < world->maxEntities; i++)

View File

@ -160,11 +160,22 @@ i32 main(void)
* INITIALISE GAME * INITIALISE GAME
******************* *******************
*/ */
Memory memory = {0};
size_t persistentSize = MEGABYTES(128);
size_t transientSize = MEGABYTES(128);
memory.persistentSize = persistentSize;
memory.persistent = PLATFORM_MEM_ALLOC_(NULL, persistentSize, u8);
memory.transientSize = transientSize;
memory.transient = PLATFORM_MEM_ALLOC_(NULL, transientSize, u8);
GameState worldTraveller = {0}; GameState worldTraveller = {0};
worldTraveller_gameInit(&worldTraveller, worldTraveller_gameInit(&worldTraveller,
V2i(frameBufferWidth, frameBufferHeight)); V2i(frameBufferWidth, frameBufferHeight), &memory);
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
debug_init(&worldTraveller.arena, V2i(windowWidth, windowHeight), debug_init(&worldTraveller.arena_, V2i(windowWidth, windowHeight),
worldTraveller.assetManager.font); worldTraveller.assetManager.font);
#endif #endif

View File

@ -6,7 +6,7 @@
#include "Dengine/Texture.h" #include "Dengine/Texture.h"
/* Forward declaration */ /* Forward declaration */
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
typedef struct PlatformFileRead PlatformFileRead; typedef struct PlatformFileRead PlatformFileRead;
typedef struct AssetManager typedef struct AssetManager
@ -32,13 +32,13 @@ const SubTexture asset_getAtlasSubTex(TexAtlas *const atlas,
const char *const key); const char *const key);
Texture *asset_getTex(AssetManager *const assetManager, const char *const key); Texture *asset_getTex(AssetManager *const assetManager, const char *const key);
TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager, TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager,
MemoryArena *arena, const char *const key, MemoryArena_ *arena, const char *const key,
i32 numSubTex); i32 numSubTex);
TexAtlas *asset_getTexAtlas(AssetManager *const assetManager, TexAtlas *asset_getTexAtlas(AssetManager *const assetManager,
const char *const key); const char *const key);
Texture *asset_getFreeTexSlot(AssetManager *const assetManager, Texture *asset_getFreeTexSlot(AssetManager *const assetManager,
MemoryArena *const arena, const char *const key); MemoryArena_ *const arena, const char *const key);
Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena, Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena_ *arena,
const char *const path, const char *const key); const char *const path, const char *const key);
/* /*
@ -47,7 +47,7 @@ Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena,
********************************* *********************************
*/ */
void asset_addAnimation(AssetManager *const assetManager, void asset_addAnimation(AssetManager *const assetManager,
MemoryArena *const arena, const char *const animName, MemoryArena_ *const arena, const char *const animName,
TexAtlas *const atlas, char **const subTextureNames, TexAtlas *const atlas, char **const subTextureNames,
const i32 numSubTextures, const f32 frameDuration); const i32 numSubTextures, const f32 frameDuration);
Animation *asset_getAnim(AssetManager *const assetManager, Animation *asset_getAnim(AssetManager *const assetManager,
@ -60,7 +60,7 @@ Animation *asset_getAnim(AssetManager *const assetManager,
*/ */
AudioVorbis *const asset_getVorbis(AssetManager *const assetManager, AudioVorbis *const asset_getVorbis(AssetManager *const assetManager,
const char *const key); const char *const key);
const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena_ *arena,
const char *const path, const char *const key); const char *const path, const char *const key);
/* /*
@ -69,20 +69,20 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
********************************* *********************************
*/ */
const i32 asset_loadXmlFile(AssetManager *const assetManager, const i32 asset_loadXmlFile(AssetManager *const assetManager,
MemoryArena *const arena, MemoryArena_ *const arena,
const PlatformFileRead *const fileRead); const PlatformFileRead *const fileRead);
Shader *const asset_getShader(AssetManager *assetManager, const enum ShaderList type); Shader *const asset_getShader(AssetManager *assetManager, const enum ShaderList type);
const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena,
const char *const vertexPath, const char *const vertexPath,
const char *const fragmentPath, const char *const fragmentPath,
const enum ShaderList type); const enum ShaderList type);
const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
const char *filePath); const char *filePath);
const v2 asset_stringDimInPixels(const Font *const font, const v2 asset_stringDimInPixels(const Font *const font,
const char *const string); const char *const string);
void asset_unitTest(MemoryArena *arena); void asset_unitTest(MemoryArena_ *arena);
#endif #endif

View File

@ -6,7 +6,7 @@
#include "Dengine/Common.h" #include "Dengine/Common.h"
/* Forward Declaration */ /* Forward Declaration */
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
#define AUDIO_NO_FREE_SOURCE -1 #define AUDIO_NO_FREE_SOURCE -1
typedef struct AudioSourceEntry typedef struct AudioSourceEntry
@ -49,18 +49,18 @@ typedef struct AudioRenderer
const i32 audio_init(AudioManager *audioManager); const i32 audio_init(AudioManager *audioManager);
const i32 audio_playVorbis(MemoryArena *arena, AudioManager *audioManager, const i32 audio_playVorbis(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer, AudioVorbis *vorbis, AudioRenderer *audioRenderer, AudioVorbis *vorbis,
i32 numPlays); i32 numPlays);
const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, const i32 audio_streamPlayVorbis(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer, AudioRenderer *audioRenderer,
AudioVorbis *vorbis, i32 numPlays); AudioVorbis *vorbis, i32 numPlays);
const i32 audio_stopVorbis(MemoryArena *arena, AudioManager *audioManager, const i32 audio_stopVorbis(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer); AudioRenderer *audioRenderer);
const i32 audio_pauseVorbis(AudioManager *audioManager, const i32 audio_pauseVorbis(AudioManager *audioManager,
AudioRenderer *audioRenderer); AudioRenderer *audioRenderer);
const i32 audio_resumeVorbis(AudioManager *audioManager, const i32 audio_resumeVorbis(AudioManager *audioManager,
AudioRenderer *audioRenderer); AudioRenderer *audioRenderer);
const i32 audio_updateAndPlay(MemoryArena *arena, AudioManager *audioManager, const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager,
AudioRenderer *audioRenderer); AudioRenderer *audioRenderer);
#endif #endif

View File

@ -26,6 +26,10 @@ typedef double f64;
#define ASSERT(expr) if (!(expr)) { *(int *)0 = 0; } #define ASSERT(expr) if (!(expr)) { *(int *)0 = 0; }
#define IS_EVEN(value) (((value) & 1) == 0) #define IS_EVEN(value) (((value) & 1) == 0)
#define KILOBYTES(val) (val * 1024)
#define MEGABYTES(val) ((KILOBYTES(val)) * 1024)
#define GIGABYTES(val) ((MEGABYTES(val)) * 1024)
#define DENGINE_DEBUG #define DENGINE_DEBUG
i32 common_strlen(const char *const string); i32 common_strlen(const char *const string);

View File

@ -7,7 +7,7 @@
/* Forward Declaration */ /* Forward Declaration */
typedef struct GameState GameState; typedef struct GameState GameState;
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
#define INVALID_CODE_PATH 0 #define INVALID_CODE_PATH 0
enum DebugCount enum DebugCount
@ -20,7 +20,7 @@ enum DebugCount
debugcount_num, debugcount_num,
}; };
void debug_init(MemoryArena *arena, v2 windowSize, Font font); void debug_init(MemoryArena_ *arena, v2 windowSize, Font font);
#define DEBUG_RECURSIVE_PRINT_XML_TREE(sig) debug_recursivePrintXmlTree(sig, 1) #define DEBUG_RECURSIVE_PRINT_XML_TREE(sig) debug_recursivePrintXmlTree(sig, 1)
void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep); void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep);

View File

@ -7,7 +7,7 @@
typedef struct AssetManager AssetManager; typedef struct AssetManager AssetManager;
typedef struct AudioRenderer AudioRenderer; typedef struct AudioRenderer AudioRenderer;
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
typedef struct World World; typedef struct World World;
typedef struct EventQueue EventQueue; typedef struct EventQueue EventQueue;
@ -135,12 +135,12 @@ void entity_updateAnim(EventQueue *eventQueue, Entity *const entity,
const f32 dt); const f32 dt);
void entity_addAnim(AssetManager *const assetManager, Entity *const entity, void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
const char *const animName); const char *const animName);
Entity *const entity_add(MemoryArena *const arena, World *const world, Entity *const entity_add(MemoryArena_ *const arena, World *const world,
const v2 pos, const v2 size, const f32 scale, const v2 pos, const v2 size, const f32 scale,
const enum EntityType type, const enum EntityType type,
const enum Direction direction, Texture *const tex, const enum Direction direction, Texture *const tex,
const b32 collides); const b32 collides);
void entity_clearData(MemoryArena *const arena, World *const world, void entity_clearData(MemoryArena_ *const arena, World *const world,
Entity *const entity); Entity *const entity);
Entity *entity_get(World *const world, const i32 entityId); Entity *entity_get(World *const world, const i32 entityId);
i32 entity_getIndex(World *const world, const i32 entityId); i32 entity_getIndex(World *const world, const i32 entityId);

View File

@ -3,9 +3,35 @@
#include "Dengine/Common.h" #include "Dengine/Common.h"
struct MemoryArena typedef struct MemoryArena
{ {
i32 bytesAllocated; size_t size;
}; size_t used;
u8 *base;
} MemoryArena_;
typedef struct Memory
{
void *persistent;
size_t persistentSize;
void *transient;
size_t transientSize;
b32 init;
} Memory;
#define MEMORY_PUSH_STRUCT(arena, type) (type *)memory_pushBytes(arena, sizeof(type))
#define MEMORY_PUSH_ARRAY(arena, count, type) (type *)memory_pushBytes(arena, (count)*sizeof(type))
inline void *memory_pushBytes(MemoryArena_ *arena, size_t size)
{
ASSERT((arena->used + size) <= arena->size);
void *result = arena->base + arena->used;
arena->used += size;
return result;
}
void memory_arenaInit(MemoryArena_ *arena, void *base, size_t size);
#endif #endif

View File

@ -5,7 +5,7 @@
#include "Dengine/Math.h" #include "Dengine/Math.h"
/* Forward Declaration */ /* Forward Declaration */
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
// TODO(doyle): Revise key code system -- should we store the extraneous keys or // TODO(doyle): Revise key code system -- should we store the extraneous keys or
// have a mapping function to map it back to ascii? // have a mapping function to map it back to ascii?
@ -140,17 +140,17 @@ typedef struct PlatformFileRead
} PlatformFileRead; } PlatformFileRead;
// TODO(doyle): Create own custom memory allocator // TODO(doyle): Create own custom memory allocator
#define PLATFORM_MEM_FREE(arena, ptr, bytes) platform_memoryFree(arena, CAST(void *) ptr, bytes) #define PLATFORM_MEM_FREE_(arena, ptr, bytes) platform_memoryFree(arena, CAST(void *) ptr, bytes)
// TODO(doyle): numBytes in mem free is temporary until we create custom // TODO(doyle): numBytes in mem free is temporary until we create custom
// allocator since we haven't put in a system to track memory usage per // allocator since we haven't put in a system to track memory usage per
// allocation // allocation
void platform_memoryFree(MemoryArena *arena, void *data, i32 numBytes); void platform_memoryFree(MemoryArena_ *arena, void *data, i32 numBytes);
#define PLATFORM_MEM_ALLOC(arena, num, type) CAST(type *) platform_memoryAlloc(arena, num * sizeof(type)) #define PLATFORM_MEM_ALLOC_(arena, num, type) CAST(type *) platform_memoryAlloc(arena, num * sizeof(type))
void *platform_memoryAlloc(MemoryArena *arena, i32 numBytes); void *platform_memoryAlloc(MemoryArena_ *arena, i32 numBytes);
void platform_closeFileRead(MemoryArena *arena, PlatformFileRead *file); void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file);
i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath, i32 platform_readFileToBuffer(MemoryArena_ *arena, const char *const filePath,
PlatformFileRead *file); PlatformFileRead *file);
#endif #endif

View File

@ -8,7 +8,7 @@
typedef struct AssetManager AssetManager; typedef struct AssetManager AssetManager;
typedef struct Entity Entity; typedef struct Entity Entity;
typedef struct Font Font; typedef struct Font Font;
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
typedef struct Shader Shader; typedef struct Shader Shader;
typedef struct Texture Texture; typedef struct Texture Texture;
@ -68,12 +68,12 @@ inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size,
renderTex, color); renderTex, color);
} }
void renderer_string(Renderer *const renderer, MemoryArena *arena, void renderer_string(Renderer *const renderer, MemoryArena_ *arena,
Rect camera, Font *const font, Rect camera, Font *const font,
const char *const string, v2 pos, v2 pivotPoint, const char *const string, v2 pos, v2 pivotPoint,
f32 rotate, v4 color); f32 rotate, v4 color);
inline void renderer_staticString(Renderer *const renderer, MemoryArena *arena, inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena,
Font *const font, const char *const string, Font *const font, const char *const string,
v2 pos, v2 pivotPoint, f32 rotate, v4 color) v2 pos, v2 pivotPoint, f32 rotate, v4 color)
{ {

View File

@ -3,15 +3,14 @@
#include "Dengine/Common.h" #include "Dengine/Common.h"
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
typedef char String; typedef char String;
i32 string_len(String *const string); i32 string_len(String *const string);
String *const string_append(MemoryArena *const arena, String *oldString, String *const string_append(MemoryArena_ *const arena, String *oldString,
String *appendString, i32 appendLen); String *appendString, i32 appendLen);
void string_free(MemoryArena *arena, String *string); void string_free(MemoryArena_ *arena, String *string);
String *const string_make(MemoryArena *const arena, char *string); String *const string_make(MemoryArena_ *const arena, char *string);
String *const string_makeLen(MemoryArena *const arena, i32 len); String *const string_makeLen(MemoryArena_ *const arena, i32 len);
#endif #endif

View File

@ -8,7 +8,7 @@
/* Forward Declaration */ /* Forward Declaration */
typedef struct AssetManager AssetManager; typedef struct AssetManager AssetManager;
typedef struct Font Font; typedef struct Font Font;
typedef struct MemoryArena MemoryArena; typedef struct MemoryArena MemoryArena_;
typedef struct Renderer Renderer; typedef struct Renderer Renderer;
enum UiType enum UiType
@ -76,17 +76,13 @@ inline i32 userInterface_generateId(UiState *const uiState)
return result; return result;
} }
i32 userInterface_button(UiState *const uiState, i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
MemoryArena *const arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Renderer *const renderer, Font *const font,
Font *const font, const KeyInput input, const i32 id, const Rect rect,
const KeyInput input,
const i32 id, const Rect rect,
const char *const label); const char *const label);
i32 userInterface_textField(UiState *const uiState, i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
MemoryArena *const arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Font *const font, Renderer *const renderer, Font *const font,
KeyInput input, const i32 id, const Rect rect, KeyInput input, const i32 id, const Rect rect,
@ -98,7 +94,7 @@ i32 userInterface_scrollbar(UiState *const uiState,
const i32 id, const Rect scrollBarRect, const i32 id, const Rect scrollBarRect,
i32 *const value, const i32 maxValue); i32 *const value, const i32 maxValue);
i32 userInterface_window(UiState *const uiState, MemoryArena *const arena, i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Font *const font, Renderer *const renderer, Font *const font,
const KeyInput input, WindowState *window); const KeyInput input, WindowState *window);

View File

@ -81,6 +81,10 @@ typedef struct World
typedef struct GameState typedef struct GameState
{ {
Memory *memory;
MemoryArena_ arena_;
MemoryArena_ transientArena;
enum State state; enum State state;
KeyInput input; KeyInput input;
v2 mouse; v2 mouse;
@ -94,12 +98,11 @@ typedef struct GameState
AssetManager assetManager; AssetManager assetManager;
AudioManager audioManager; AudioManager audioManager;
Config config; Config config;
MemoryArena arena;
UiState uiState; UiState uiState;
EventQueue eventQueue; EventQueue eventQueue;
} GameState; } GameState;
void worldTraveller_gameInit(GameState *state, v2 windowSize); void worldTraveller_gameInit(GameState *state, v2 windowSize, Memory *memory);
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt); void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt);
void worldTraveller_registerEvent(EventQueue *eventQueue, enum EventType type, void worldTraveller_registerEvent(EventQueue *eventQueue, enum EventType type,
void *data); void *data);