From 332888f3b598bd13cdb7b3b5b8eaf657d57777fc Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Sat, 24 Sep 2016 14:43:59 +1000 Subject: [PATCH] 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. --- Dengine.vcxproj | 1 + Dengine.vcxproj.filters | 3 + src/AssetManager.c | 122 +++++++++++++++------------ src/Audio.c | 30 +++---- src/Debug.c | 55 +++++++----- src/Entity.c | 33 +++++--- src/MemoryArena.c | 8 ++ src/Platform.c | 40 ++++++--- src/Renderer.c | 11 +-- src/String.c | 17 ++-- src/UserInterface.c | 16 ++-- src/WorldTraveller.c | 119 ++++++++++++++------------ src/dengine.c | 15 +++- src/include/Dengine/AssetManager.h | 20 ++--- src/include/Dengine/Audio.h | 10 +-- src/include/Dengine/Common.h | 4 + src/include/Dengine/Debug.h | 4 +- src/include/Dengine/Entity.h | 6 +- src/include/Dengine/MemoryArena.h | 32 ++++++- src/include/Dengine/Platform.h | 14 +-- src/include/Dengine/Renderer.h | 6 +- src/include/Dengine/String.h | 11 ++- src/include/Dengine/UserInterface.h | 16 ++-- src/include/Dengine/WorldTraveller.h | 7 +- 24 files changed, 352 insertions(+), 248 deletions(-) create mode 100644 src/MemoryArena.c diff --git a/Dengine.vcxproj b/Dengine.vcxproj index 0275641..0b3c0cf 100644 --- a/Dengine.vcxproj +++ b/Dengine.vcxproj @@ -126,6 +126,7 @@ + diff --git a/Dengine.vcxproj.filters b/Dengine.vcxproj.filters index 36ba4a9..e50c137 100644 --- a/Dengine.vcxproj.filters +++ b/Dengine.vcxproj.filters @@ -54,6 +54,9 @@ Source Files + + Source Files + diff --git a/src/AssetManager.c b/src/AssetManager.c index 6318b9b..54eb151 100644 --- a/src/AssetManager.c +++ b/src/AssetManager.c @@ -28,7 +28,7 @@ ********************************* */ INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table, - MemoryArena *const arena, + MemoryArena_ *const arena, const char *const key) { u32 hashIndex = common_getHashIndex(key, table->size); @@ -45,7 +45,7 @@ INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table, result = result->next; } - result->next = PLATFORM_MEM_ALLOC(arena, 1, HashTableEntry); + result->next = MEMORY_PUSH_STRUCT(arena, HashTableEntry); result = result->next; } @@ -56,7 +56,7 @@ INTERNAL HashTableEntry *const getFreeHashSlot(HashTable *const table, { // +1 Null terminator 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); } @@ -83,14 +83,14 @@ INTERNAL HashTableEntry *const getEntryFromHash(HashTable *const table, ********************************* */ INTERNAL SubTexture *getFreeAtlasSubTexSlot(TexAtlas *const atlas, - MemoryArena *const arena, + MemoryArena_ *const arena, const char *const key) { HashTableEntry *entry = getFreeHashSlot(&atlas->subTex, arena, key); if (entry) { - entry->data = PLATFORM_MEM_ALLOC(arena, 1, SubTexture); + entry->data = MEMORY_PUSH_STRUCT(arena, SubTexture); SubTexture *result = CAST(SubTexture *)entry->data; return result; } @@ -127,7 +127,7 @@ Texture *asset_getTex(AssetManager *const assetManager, const char *const key) } TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager, - MemoryArena *arena, const char *const key, + MemoryArena_ *arena, const char *const key, i32 numSubTex) { @@ -136,19 +136,22 @@ TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager, if (entry) { - entry->data = PLATFORM_MEM_ALLOC(arena, 1, TexAtlas); + entry->data = MEMORY_PUSH_STRUCT(arena, TexAtlas); TexAtlas *result = CAST(TexAtlas *) entry->data; if (result) { result->subTex.size = numSubTex; result->subTex.entries = - PLATFORM_MEM_ALLOC(arena, numSubTex, HashTableEntry); + memory_pushBytes(arena, numSubTex * sizeof(HashTableEntry)); if (!result->subTex.entries) { + // TODO(doyle): Mem free + /* PLATFORM_MEM_FREE(arena, result, sizeof(TexAtlas)); result = NULL; + */ } } @@ -174,7 +177,7 @@ TexAtlas *asset_getTexAtlas(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 = @@ -182,7 +185,7 @@ Texture *asset_getFreeTexSlot(AssetManager *const assetManager, if (entry) { - entry->data = PLATFORM_MEM_ALLOC(arena, 1, Texture); + entry->data = MEMORY_PUSH_STRUCT(arena, Texture); Texture *result = CAST(Texture *) entry->data; 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) { /* Open the texture image */ @@ -232,14 +235,14 @@ Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena, ********************************* */ INTERNAL Animation *getFreeAnimationSlot(AssetManager *const assetManager, - MemoryArena *const arena, + MemoryArena_ *const arena, const char *const key) { HashTableEntry *entry = getFreeHashSlot(&assetManager->anims, arena, key); if (entry) { - entry->data = PLATFORM_MEM_ALLOC(arena, 1, Animation); + entry->data = MEMORY_PUSH_STRUCT(arena, Animation); Animation *result = CAST(Animation *) entry->data; return result; } @@ -250,7 +253,7 @@ INTERNAL Animation *getFreeAnimationSlot(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, const i32 numSubTextures, const f32 frameDuration) @@ -265,7 +268,7 @@ void asset_addAnimation(AssetManager *const assetManager, anim->frameDuration = frameDuration; 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++) { anim->frameList[i] = subTextureNames[i]; @@ -310,12 +313,12 @@ typedef struct XmlToken i32 len; } XmlToken; -INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena *const arena, +INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena_ *const arena, const char *const buffer, const i32 bufferSize, int *const numTokens) { - XmlToken *xmlTokens = PLATFORM_MEM_ALLOC(arena, 8192, XmlToken); + XmlToken *xmlTokens = memory_pushBytes(arena, 8192 * sizeof(XmlToken)); i32 tokenIndex = 0; for (i32 i = 0; i < bufferSize; i++) { @@ -417,11 +420,11 @@ INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena *const arena, return xmlTokens; } -INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, +INTERNAL XmlNode *const buildXmlTree(MemoryArena_ *const arena, XmlToken *const xmlTokens, const i32 numTokens) { - XmlNode *root = PLATFORM_MEM_ALLOC(arena, 1, XmlNode); + XmlNode *root = MEMORY_PUSH_STRUCT(arena, XmlNode); if (!root) return NULL; XmlNode *node = root; @@ -457,7 +460,8 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, } 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; } else @@ -496,7 +500,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, while (attribute->next) attribute = attribute->next; - attribute->next = PLATFORM_MEM_ALLOC(arena, 1, XmlAttribute); + attribute->next = MEMORY_PUSH_STRUCT(arena, XmlAttribute); attribute = attribute->next; } @@ -531,7 +535,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, if (!node->child) { // 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 = node->child; } @@ -541,7 +545,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, while (nodeToCheck->next) nodeToCheck = nodeToCheck->next; - nodeToCheck->next = PLATFORM_MEM_ALLOC(arena, 1, XmlNode); + nodeToCheck->next = MEMORY_PUSH_STRUCT(arena, XmlNode); nodeToCheck->next->parent = node; node = nodeToCheck->next; } @@ -560,7 +564,7 @@ INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena, return root; } -INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena, +INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena_ *arena, XmlNode *root) { XmlNode *node = root; @@ -606,7 +610,8 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena, i32 imageNameLen = common_strlen(imageName); 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, imageName, imageNameLen); @@ -616,13 +621,15 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena, if (!tex) { DEBUG_LOG("parseXmlTreeToGame() failed: Could not load image"); - PLATFORM_MEM_FREE(arena, imagePath, - totalPathLen * sizeof(char)); + // TODO(doyle): Mem free + //PLATFORM_MEM_FREE(arena, imagePath, + // totalPathLen * sizeof(char)); return; } - PLATFORM_MEM_FREE(arena, imagePath, - totalPathLen * sizeof(char)); + // TODO(doyle): Mem free + //PLATFORM_MEM_FREE(arena, imagePath, + // totalPathLen * sizeof(char)); 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) { if (!node) @@ -775,7 +782,8 @@ INTERNAL void recursiveFreeXmlTree(MemoryArena *const arena, attrib->name = NULL; attrib->value = NULL; - PLATFORM_MEM_FREE(arena, attrib, sizeof(XmlAttribute)); + // TODO(doyle): Mem free + // PLATFORM_MEM_FREE(arena, attrib, sizeof(XmlAttribute)); attrib = next; } @@ -784,16 +792,18 @@ INTERNAL void recursiveFreeXmlTree(MemoryArena *const arena, node->name = NULL; node->isClosed = FALSE; - PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode)); + // TODO(doyle): Mem free + // PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode)); node = NULL; } } -INTERNAL void freeXmlData(MemoryArena *const arena, XmlToken *tokens, +INTERNAL void freeXmlData(MemoryArena_ *const arena, XmlToken *tokens, const i32 numTokens, XmlNode *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, - MemoryArena *const arena, - const PlatformFileRead *const fileRead) + MemoryArena_ *const arena, + const PlatformFileRead *const fileRead) { i32 result = 0; /* Tokenise buffer */ @@ -842,7 +852,7 @@ AudioVorbis *const asset_getVorbis(AssetManager *const assetManager, 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) { HashTableEntry *entry = getFreeHashSlot(&assetManager->audio, arena, key); @@ -852,7 +862,7 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, PlatformFileRead fileRead = {0}; platform_readFileToBuffer(arena, path, &fileRead); - entry->data = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis); + entry->data = MEMORY_PUSH_STRUCT(arena, AudioVorbis); i32 error; AudioVorbis *audio = CAST(AudioVorbis *) entry->data; @@ -862,7 +872,8 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, if (!audio->file) { 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); return 0; } @@ -877,11 +888,12 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, return 0; } -INTERNAL GLuint createShaderFromPath(MemoryArena *arena, const char *const path, +INTERNAL GLuint createShaderFromPath(MemoryArena_ *arena, const char *const path, GLuint shadertype) { PlatformFileRead file = {0}; + // TODO(doyle): Revise platform reads i32 status = platform_readFileToBuffer(arena, path, &file); if (status) return status; @@ -942,7 +954,7 @@ Shader *const asset_getShader(AssetManager *assetManager, 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 fragmentPath, const enum ShaderList type) @@ -968,7 +980,7 @@ typedef struct GlyphBitmap i32 codepoint; } GlyphBitmap; -const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, +const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena, const char *filePath) { PlatformFileRead fontFileRead = {0}; @@ -990,7 +1002,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x); GlyphBitmap *glyphBitmaps = - PLATFORM_MEM_ALLOC(arena, numGlyphs, GlyphBitmap); + memory_pushBytes(arena, numGlyphs * sizeof(GlyphBitmap)); v2 largestGlyphDimension = V2(0, 0); 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->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); u8 *source = monoBitmap; - u32 *colorBitmap = PLATFORM_MEM_ALLOC(arena, width * height, u32); + u32 *colorBitmap = + memory_pushBytes(arena, width * height * sizeof(u32)); u32 *dest = colorBitmap; // 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 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; // 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, MAX_TEXTURE_SIZE * 4); #endif - PLATFORM_MEM_FREE(arena, fontBitmap, bitmapSize); + + // TODO(doyle): Mem free + // PLATFORM_MEM_FREE(arena, fontBitmap, bitmapSize); fontAtlas->tex = tex; font->atlas = fontAtlas; @@ -1222,10 +1238,12 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, i32 glyphBitmapSizeInBytes = CAST(i32) glyphBitmaps[i].dimensions.w * CAST(i32) glyphBitmaps[i].dimensions.h * 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); return 0; @@ -1254,7 +1272,7 @@ const v2 asset_stringDimInPixels(const Font *const font, return stringDim; } -void asset_unitTest(MemoryArena *arena) +void asset_unitTest(MemoryArena_ *arena) { PlatformFileRead xmlFileRead = {0}; i32 result = platform_readFileToBuffer( @@ -1267,15 +1285,11 @@ void asset_unitTest(MemoryArena *arena) else { /* Tokenise buffer */ - i32 memBefore = arena->bytesAllocated; i32 numTokens = 0; XmlToken *xmlTokens = tokeniseXmlBuffer(arena, xmlFileRead.buffer, xmlFileRead.size, &numTokens); /* Build XML tree from tokens */ XmlNode *xmlTree = buildXmlTree(arena, xmlTokens, numTokens); freeXmlData(arena, xmlTokens, numTokens, xmlTree); - i32 memAfter = arena->bytesAllocated; - - ASSERT(memBefore == memAfter); } } diff --git a/src/Audio.c b/src/Audio.c index dbb8429..b159a40 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -7,7 +7,6 @@ #include "Dengine/Audio.h" #include "Dengine/Debug.h" #include "Dengine/MemoryArena.h" -#include "dengine/Platform.h" #define AL_CHECK_ERROR() alCheckError_(__FILE__, __LINE__); void alCheckError_(const char *file, int line) @@ -116,7 +115,7 @@ INTERNAL inline u32 getSourceId(AudioManager *audioManager, return result; } -INTERNAL i32 rendererAcquire(MemoryArena *arena, AudioManager *audioManager, +INTERNAL i32 rendererAcquire(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer) { #ifdef DENGINE_DEBUG @@ -162,7 +161,7 @@ INTERNAL i32 rendererAcquire(MemoryArena *arena, AudioManager *audioManager, return 0; } -INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManager, +INTERNAL const i32 rendererRelease(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer) { @@ -212,7 +211,9 @@ INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManage if (audioRenderer->isStreaming) { 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; @@ -229,7 +230,7 @@ INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManage return result; } -INTERNAL i32 initRendererForPlayback(MemoryArena *arena, +INTERNAL i32 initRendererForPlayback(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer, AudioVorbis *vorbis, i32 numPlays) @@ -267,7 +268,7 @@ INTERNAL i32 initRendererForPlayback(MemoryArena *arena, } #include -const i32 audio_playVorbis(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_playVorbis(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer, AudioVorbis *vorbis, i32 numPlays) { @@ -293,7 +294,7 @@ const i32 audio_playVorbis(MemoryArena *arena, AudioManager *audioManager, return result; } -const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_streamPlayVorbis(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer, 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 // simultaneously, we need unique file pointers into the data to track song // position uniquely - AudioVorbis *copyAudio = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis); + AudioVorbis *copyAudio = MEMORY_PUSH_STRUCT(arena, AudioVorbis); *copyAudio = *vorbis; i32 error; @@ -318,7 +319,7 @@ const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, return result; } -const i32 audio_stopVorbis(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_stopVorbis(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer) { i32 result = 0; @@ -388,21 +389,12 @@ const i32 audio_resumeVorbis(AudioManager *audioManager, } #define AUDIO_CHUNK_SIZE_ 65536 -const i32 audio_updateAndPlay(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer) { AudioVorbis *audio = audioRenderer->audio; 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); if (alIsSource(alSourceId) == AL_FALSE) { diff --git a/src/Debug.c b/src/Debug.c index 67b9fab..f1d8131 100644 --- a/src/Debug.c +++ b/src/Debug.c @@ -75,10 +75,11 @@ inline char *debug_entityattack_string(i32 val) 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.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; /* 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) { 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); v2 consoleStrP = GLOBAL_debug.initialConsoleP; @@ -320,6 +321,7 @@ void debug_drawUi(GameState *state, f32 dt) Renderer *renderer = &state->renderer; World *const world = &state->world[state->currWorldIndex]; 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 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)); v2 strPos = V2((renderer->size.w * 0.5f) - (strLenInPixels * 0.5f), 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); } @@ -386,7 +388,7 @@ void debug_drawUi(GameState *state, f32 dt) i32 indexOfLowerAInMetrics = 'a' - CAST(i32) font->codepointRange.x; 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); f32 stringLineGap = 1.1f * font->verticalSpacing; @@ -395,14 +397,14 @@ void debug_drawUi(GameState *state, f32 dt) char entityPosStr[128]; snprintf(entityPosStr, ARRAY_COUNT(entityPosStr), "%06.2f, %06.2f", 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); strPos.y -= GLOBAL_debug.stringLineGap; char entityIDStr[32]; snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entity->id, 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); if (entity->stats) @@ -411,27 +413,27 @@ void debug_drawUi(GameState *state, f32 dt) char entityHealth[32]; snprintf(entityHealth, ARRAY_COUNT(entityHealth), "HP: %3.0f/%3.0f", 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); strPos.y -= GLOBAL_debug.stringLineGap; char entityTimer[32]; snprintf(entityTimer, ARRAY_COUNT(entityTimer), "ATB: %3.0f/%3.0f", 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); strPos.y -= GLOBAL_debug.stringLineGap; char entityIdTarget[32]; snprintf(entityIdTarget, ARRAY_COUNT(entityIdTarget), "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); } strPos.y -= GLOBAL_debug.stringLineGap; 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); if (entity->audioRenderer) @@ -442,7 +444,7 @@ void debug_drawUi(GameState *state, f32 dt) ARRAY_COUNT(entityAudioSourceIndex), "AudioSource Index: %d", entity->audioRenderer->sourceIndex); - renderer_string(&state->renderer, &state->arena, camera, + renderer_string(&state->renderer, transientArena, camera, font, entityAudioSourceIndex, strPos, V2(0, 0), 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"); - 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; - DEBUG_PUSH_VAR("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32"); - DEBUG_PUSH_VAR("TotalMemoryAllocated: %dmb", debug_mbAllocated, "i32"); + DEBUG_PUSH_VAR("TransientArena Used: %db", debug_bAllocated, "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(""); AudioManager *audioManager = &state->audioManager; @@ -533,7 +548,7 @@ void debug_drawUi(GameState *state, f32 dt) DEBUG_PUSH_STRING("-none-"); } - updateAndRenderDebugStack(&state->renderer, &state->arena, dt); - renderConsole(&state->renderer, &state->arena); + updateAndRenderDebugStack(&state->renderer, transientArena, dt); + renderConsole(&state->renderer, transientArena); debug_clearCounter(); } diff --git a/src/Entity.c b/src/Entity.c index b5b9e80..ea9deeb 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -1,6 +1,7 @@ #include "Dengine/Entity.h" +#include "Dengine/AssetManager.h" #include "Dengine/Debug.h" -#include "Dengine/Platform.h" +#include "Dengine/MemoryArena.h" #include "Dengine/WorldTraveller.h" 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"); } -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 enum EntityType type, const enum Direction direction, Texture *const tex, @@ -135,7 +136,7 @@ Entity *const entity_add(MemoryArena *const arena, World *const world, switch (type) { case entitytype_hero: - entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); + entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats); entity.stats->maxHealth = 100; entity.stats->health = entity.stats->maxHealth; entity.stats->actionRate = 100; @@ -148,7 +149,7 @@ Entity *const entity_add(MemoryArena *const arena, World *const world, break; case entitytype_mob: { - entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); + entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats); entity.stats->maxHealth = 100; entity.stats->health = entity.stats->maxHealth; entity.stats->actionRate = 80; @@ -162,12 +163,12 @@ Entity *const entity_add(MemoryArena *const arena, World *const world, } case entitytype_projectile: case entitytype_attackObject: - entity.stats = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); - entity.stats->maxHealth = 100; - entity.stats->health = entity.stats->maxHealth; - entity.stats->actionRate = 100; - entity.stats->actionTimer = entity.stats->actionRate; - entity.stats->actionSpdMul = 100; + entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats); + entity.stats->maxHealth = 100; + entity.stats->health = entity.stats->maxHealth; + entity.stats->actionRate = 100; + entity.stats->actionTimer = entity.stats->actionRate; + entity.stats->actionSpdMul = 100; entity.stats->entityIdToAttack = -1; entity.stats->queuedAttack = entityattack_invalid; entity.state = entitystate_idle; @@ -183,15 +184,19 @@ Entity *const entity_add(MemoryArena *const arena, World *const world, return result; } -void entity_clearData(MemoryArena *const arena, World *const world, +void entity_clearData(MemoryArena_ *const arena, World *const world, Entity *const entity) { + // TODO(doyle): Mem free// memory leak!! + + /* if (entity->stats) - PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats)); + PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats)); if (entity->audioRenderer) - PLATFORM_MEM_FREE(arena, entity->audioRenderer, - sizeof(AudioRenderer) * entity->numAudioRenderers); + PLATFORM_MEM_FREE(arena, entity->audioRenderer, + sizeof(AudioRenderer) * entity->numAudioRenderers); + */ entity->type = entitytype_null; } diff --git a/src/MemoryArena.c b/src/MemoryArena.c new file mode 100644 index 0000000..c498a7d --- /dev/null +++ b/src/MemoryArena.c @@ -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; +} diff --git a/src/Platform.c b/src/Platform.c index d366f54..26d7e26 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -3,37 +3,38 @@ #include #include "Dengine/Platform.h" -#include "Dengine/MemoryArena.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); #ifdef DENGINE_DEBUG debug_countIncrement(debugcount_platformMemFree); - arena->bytesAllocated -= numBytes; + arena->used -= numBytes; #endif } -void *platform_memoryAlloc(MemoryArena *arena, i32 numBytes) +void *platform_memoryAlloc(MemoryArena_ *arena, i32 numBytes) { void *result = calloc(1, numBytes); #ifdef DENGINE_DEBUG debug_countIncrement(debugcount_platformMemAlloc); - if (result) - arena->bytesAllocated += numBytes; + if (result && arena) + arena->used += numBytes; #endif 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) { 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 - file->buffer = PLATFORM_MEM_ALLOC(arena, fileSize.LowPart, char); - file->size = fileSize.LowPart; + file->buffer = memory_pushBytes(arena, fileSize.LowPart * sizeof(char)); + file->size = fileSize.LowPart; DWORD numBytesRead = 0; @@ -66,7 +67,19 @@ i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath, { printf("ReadFile() failed: %d error number\n", 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; } else if (numBytesRead != file->size) @@ -74,7 +87,8 @@ i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath, printf( "ReadFile() failed: Number of bytes read doesn't match file " "size\n"); - PLATFORM_MEM_FREE(arena, file->buffer, file->size); + // TODO(doyle): Mem free + // PLATFORM_MEM_FREE(arena, file->buffer, file->size); return -1; } diff --git a/src/Renderer.c b/src/Renderer.c index 74c0b9d..90abc50 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -3,8 +3,8 @@ #include "Dengine/Assets.h" #include "Dengine/Debug.h" #include "Dengine/Entity.h" +#include "Dengine/MemoryArena.h" #include "Dengine/OpenGL.h" -#include "Dengine/Platform.h" #include "Dengine/Shader.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); } -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, v2 pivotPoint, f32 rotate, v4 color) { @@ -322,7 +322,7 @@ void renderer_string(Renderer *const renderer, MemoryArena *arena, Rect camera, i32 numVertexPerQuad = 4; i32 numVertexesToAlloc = (strLen * (numVertexPerQuad + 2)); Vertex *vertexList = - PLATFORM_MEM_ALLOC(arena, numVertexesToAlloc, Vertex); + memory_pushBytes(arena, numVertexesToAlloc * sizeof(Vertex)); v2 posInCameraSpace = v2_sub(pos, camera.pos); pos = posInCameraSpace; @@ -362,8 +362,9 @@ void renderer_string(Renderer *const renderer, MemoryArena *arena, Rect camera, addVertexToRenderGroup(renderer, tex, color, vertexList, numVertexesToAlloc); - PLATFORM_MEM_FREE(arena, vertexList, - sizeof(Vertex) * numVertexesToAlloc); + // TODO(doyle): Mem free + // PLATFORM_MEM_FREE(arena, vertexList, + // sizeof(Vertex) * numVertexesToAlloc); } } diff --git a/src/String.c b/src/String.c index 0161f5d..9e63ee6 100644 --- a/src/String.c +++ b/src/String.c @@ -1,5 +1,5 @@ #include "Dengine/String.h" -#include "Dengine/Platform.h" +#include "Dengine/MemoryArena.h" /* * +-------------------------------------+ @@ -51,7 +51,7 @@ i32 string_len(String *const string) return result; } -String *const string_append(MemoryArena *const arena, String *oldString, +String *const string_append(MemoryArena_ *const arena, String *oldString, char *appendString, i32 appendLen) { @@ -74,7 +74,7 @@ String *const string_append(MemoryArena *const arena, String *oldString, return newString; } -void string_free(MemoryArena *arena, String *string) +void string_free(MemoryArena_ *arena, String *string) { if (!string || !arena) return; @@ -82,11 +82,14 @@ void string_free(MemoryArena *arena, String *string) i32 bytesToFree = sizeof(StringHeader) + header->len; 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 *const string_make(MemoryArena *const arena, char *string) +String *const string_make(MemoryArena_ *const arena, char *string) { if (!arena) return NULL; @@ -97,7 +100,7 @@ String *const string_make(MemoryArena *const arena, char *string) return result; } -String *const string_makeLen(MemoryArena *const arena, i32 len) +String *const string_makeLen(MemoryArena_ *const arena, i32 len) { 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 // _not_ including null-terminator. 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; StringHeader *header = CAST(StringHeader *) chunk; diff --git a/src/UserInterface.c b/src/UserInterface.c index be27ca7..382132f 100644 --- a/src/UserInterface.c +++ b/src/UserInterface.c @@ -1,16 +1,14 @@ #include "Dengine/UserInterface.h" #include "Dengine/AssetManager.h" #include "Dengine/Assets.h" -#include "Dengine/Renderer.h" #include "Dengine/Debug.h" +#include "Dengine/Renderer.h" -i32 userInterface_button(UiState *const uiState, - MemoryArena *const arena, +i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena, AssetManager *const assetManager, - Renderer *const renderer, - Font *const font, - const KeyInput input, - const i32 id, const Rect rect, const char *const label) + Renderer *const renderer, Font *const font, + const KeyInput input, const i32 id, const Rect rect, + const char *const label) { if (math_pointInRect(rect, input.mouseP)) { @@ -251,7 +249,7 @@ i32 userInterface_scrollbar(UiState *const uiState, return 0; } -i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena, +i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena, AssetManager *const assetManager, Renderer *const renderer, Font *const font, KeyInput input, const i32 id, const Rect rect, @@ -352,7 +350,7 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena, return 0; } -i32 userInterface_window(UiState *const uiState, MemoryArena *const arena, +i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena, AssetManager *const assetManager, Renderer *const renderer, Font *const font, const KeyInput input, WindowState *window) diff --git a/src/WorldTraveller.c b/src/WorldTraveller.c index b61d6ff..7b80b0e 100644 --- a/src/WorldTraveller.c +++ b/src/WorldTraveller.c @@ -19,7 +19,7 @@ INTERNAL Entity *getHeroEntity(World *world) return result; } -INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena *arena, +INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena_ *arena, AssetManager *assetManager, World *world, v2 pos) { #ifdef DENGINE_DEBUG @@ -39,7 +39,7 @@ INTERNAL void addGenericMob(EventQueue *eventQueue, MemoryArena *arena, mob->numAudioRenderers = 4; mob->audioRenderer = - PLATFORM_MEM_ALLOC(arena, mob->numAudioRenderers, AudioRenderer); + memory_pushBytes(arena, mob->numAudioRenderers * sizeof(AudioRenderer)); for (i32 i = 0; i < mob->numAudioRenderers; i++) mob->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED; @@ -104,8 +104,8 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize) renderer->groupCapacity = 4096; for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++) { - renderer->groups[i].vertexList = - PLATFORM_MEM_ALLOC(&state->arena, renderer->groupCapacity, Vertex); + renderer->groups[i].vertexList = memory_pushBytes( + &state->arena_, renderer->groupCapacity * sizeof(Vertex)); } #ifdef DENGINE_DEBUG @@ -116,27 +116,27 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize) INTERNAL void assetInit(GameState *state) { AssetManager *assetManager = &state->assetManager; - MemoryArena *arena = &state->arena; + MemoryArena_ *arena = &state->arena_; i32 audioEntries = 32; assetManager->audio.size = audioEntries; assetManager->audio.entries = - PLATFORM_MEM_ALLOC(arena, audioEntries, HashTableEntry); + memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry)); i32 texAtlasEntries = 8; assetManager->texAtlas.size = texAtlasEntries; assetManager->texAtlas.entries = - PLATFORM_MEM_ALLOC(arena, texAtlasEntries, HashTableEntry); + memory_pushBytes(arena, texAtlasEntries * sizeof(HashTableEntry)); i32 texEntries = 32; assetManager->textures.size = texEntries; assetManager->textures.entries = - PLATFORM_MEM_ALLOC(arena, texEntries, HashTableEntry); + memory_pushBytes(arena, texEntries * sizeof(HashTableEntry)); i32 animEntries = 1024; assetManager->anims.size = animEntries; assetManager->anims.entries = - PLATFORM_MEM_ALLOC(arena, animEntries, HashTableEntry); + memory_pushBytes(arena, animEntries * sizeof(HashTableEntry)); /* Create empty 1x1 4bpp black texture */ u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0); @@ -438,7 +438,7 @@ INTERNAL void assetInit(GameState *state) /* Load sound */ - i32 before = arena->bytesAllocated; + i32 before = arena->used; char *sfxListPath = "data/audio/sfx/sfx.txt"; PlatformFileRead sfxList = {0}; @@ -459,7 +459,7 @@ INTERNAL void assetInit(GameState *state) { i32 actualStrLen = common_strlen(string) + 1; sfxAudioNames[sfxAudioIndex] = - PLATFORM_MEM_ALLOC(arena, actualStrLen, char); + memory_pushBytes(arena, actualStrLen * sizeof(char)); common_strncpy(sfxAudioNames[sfxAudioIndex++], string, actualStrLen); @@ -490,7 +490,8 @@ INTERNAL void assetInit(GameState *state) i32 sfxNameLen = common_strlen(sfxName); 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, sfxName, sfxNameLen); @@ -503,11 +504,13 @@ INTERNAL void assetInit(GameState *state) // character, having to remember to +1 on allocation AND freeing since // strlen only counts until null char is going to leave memory leaks // everywhere - PLATFORM_MEM_FREE(arena, sfxName, sfxNameLen * sizeof(char) + 1); - PLATFORM_MEM_FREE(arena, sfxFullPath, sfxFullPathLen * sizeof(char)); + // TODO(doyle): Free mem + // 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 = "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) { AssetManager *assetManager = &state->assetManager; - MemoryArena *arena = &state->arena; + MemoryArena_ *arena = &state->arena_; /* Init world */ 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->maxEntities = 16384; - world->entities = PLATFORM_MEM_ALLOC(arena, world->maxEntities, Entity); + world->entities = + memory_pushBytes(arena, world->maxEntities * sizeof(Entity)); world->entityIdInBattle = - PLATFORM_MEM_ALLOC(arena, world->maxEntities, i32); + memory_pushBytes(arena, world->maxEntities * sizeof(i32)); world->numEntitiesInBattle = 0; world->bounds = math_getRect(V2(0, 0), v2_scale(worldDimensionInTiles, @@ -600,8 +604,8 @@ INTERNAL void entityInit(GameState *state, v2 windowSize) world->soundscape = soundscape; soundscape->numAudioRenderers = 1; - soundscape->audioRenderer = - PLATFORM_MEM_ALLOC(arena, soundscape->numAudioRenderers, AudioRenderer); + soundscape->audioRenderer = memory_pushBytes( + arena, soundscape->numAudioRenderers * sizeof(AudioRenderer)); for (i32 i = 0; i < soundscape->numAudioRenderers; i++) soundscape->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED; @@ -626,8 +630,8 @@ INTERNAL void entityInit(GameState *state, v2 windowSize) hero->stats->weapon = heroWeapon; hero->numAudioRenderers = 4; - hero->audioRenderer = - PLATFORM_MEM_ALLOC(arena, hero->numAudioRenderers, AudioRenderer); + hero->audioRenderer = memory_pushBytes(arena, hero->numAudioRenderers * + sizeof(AudioRenderer)); for (i32 i = 0; i < hero->numAudioRenderers; i++) hero->audioRenderer[i].sourceIndex = AUDIO_SOURCE_UNASSIGNED; @@ -725,7 +729,7 @@ INTERNAL v2 getPosRelativeToRect(Rect rect, v2 offset, return result; } -INTERNAL void unitTest(MemoryArena *arena) +INTERNAL void unitTest(MemoryArena_ *arena) { ASSERT(common_atoi("-2", common_strlen("-2")) == -2); 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); asset_unitTest(arena); - i32 memBefore = arena->bytesAllocated; + i32 memBefore = arena->used; String *hello = string_make(arena, "hello, "); String *world = string_make(arena, "world"); ASSERT(string_len(hello) == 7); @@ -758,18 +762,23 @@ INTERNAL void unitTest(MemoryArena *arena) string_free(arena, hello); string_free(arena, world); - i32 memAfter = arena->bytesAllocated; - - ASSERT(memBefore == memAfter); + i32 memAfter = arena->used; } // TODO(doyle): Remove and implement own random generator! #include #include -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 - unitTest(&state->arena); + unitTest(&state->arena_); #endif i32 result = audio_init(&state->audioManager); @@ -1157,7 +1166,7 @@ typedef struct AttackSpec i32 damage; } AttackSpec; -INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena, +INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena_ *arena, EventQueue *eventQueue, World *world, Entity *attacker) { @@ -1308,7 +1317,7 @@ INTERNAL void beginAttack(AssetManager *assetManager, MemoryArena *arena, // TODO(doyle): MemArena here is temporary until we incorporate AttackSpec to // battle in general! -INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue, +INTERNAL void endAttack(MemoryArena_ *arena, EventQueue *eventQueue, World *world, Entity *attacker) { #ifdef DENGINE_DEBUG @@ -1336,7 +1345,7 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue, case entityattack_claudeEnergySword: attacker->stats->health += 80; - AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec); + AttackSpec *attackSpec = MEMORY_PUSH_STRUCT(arena, AttackSpec); attackSpec->attacker = attacker; attackSpec->defender = attacker; attackSpec->damage = 30; @@ -1389,7 +1398,7 @@ INTERNAL void endAttack(MemoryArena *arena, EventQueue *eventQueue, { i32 damage = 25; - AttackSpec *attackSpec = PLATFORM_MEM_ALLOC(arena, 1, AttackSpec); + AttackSpec *attackSpec = MEMORY_PUSH_STRUCT(arena, AttackSpec); attackSpec->attacker = attacker; attackSpec->defender = defender; attackSpec->damage = damage; @@ -1606,12 +1615,16 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) if (dt >= 1.0f) dt = 1.0f; GL_CHECK_ERROR(); - AssetManager *assetManager = &state->assetManager; - Renderer *renderer = &state->renderer; - World *const world = &state->world[state->currWorldIndex]; - Font *font = &assetManager->font; - MemoryArena *arena = &state->arena; - EventQueue *eventQueue = &state->eventQueue; + memory_arenaInit(&state->transientArena, state->memory->transient, + state->memory->transientSize); + + AssetManager *assetManager = &state->assetManager; + Renderer *renderer = &state->renderer; + 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(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 */ - beginAttack(assetManager, &state->arena, eventQueue, world, + beginAttack(assetManager, &state->arena_, eventQueue, world, entity); } } @@ -2062,7 +2075,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) if (stats->busyDuration <= 0) { /* 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++) { - audio_updateAndPlay(&state->arena, &state->audioManager, + audio_updateAndPlay(&state->arena_, &state->audioManager, &entity->audioRenderer[i]); } @@ -2227,8 +2240,6 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) break; } } - - PLATFORM_MEM_FREE(&state->arena, attackSpec, sizeof(AttackSpec)); break; } // 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); for (i32 i = 0; i < entity->numAudioRenderers; i++) { - audio_stopVorbis(&state->arena, audioManager, + audio_stopVorbis(&state->arena_, audioManager, &entity->audioRenderer[i]); } - entity_clearData(&state->arena, world, entity); + entity_clearData(&state->arena_, world, entity); numDeadEntities++; 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++) { - audio_stopVorbis(&state->arena, audioManager, + audio_stopVorbis(&state->arena_, audioManager, &child->audioRenderer[i]); } - entity_clearData(&state->arena, world, child); + entity_clearData(&state->arena_, world, child); numDeadEntities++; } else @@ -2332,7 +2343,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) // TODO(doyle): Incorporate UI into entity list or it's own list // with a rendering lifetime value - renderer_string(renderer, &state->arena, camera, font, + renderer_string(renderer, transientArena, camera, font, damageString, damagePos, V2(0, 0), 0, V4(1, 1, 1, lifetime)); } @@ -2351,14 +2362,14 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) if (state->config.showStatMenu) { WindowState *statWindow = &state->uiState.statWindow; - userInterface_window(&state->uiState, &state->arena, assetManager, + userInterface_window(&state->uiState, transientArena, assetManager, renderer, font, state->input, statWindow); } /* Draw debug window */ WindowState *debugWindow = &state->uiState.debugWindow; i32 activeId = - userInterface_window(&state->uiState, &state->arena, assetManager, + userInterface_window(&state->uiState, transientArena, assetManager, renderer, font, state->input, debugWindow); // 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)); v2 strPos = 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)); - 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)); for (i32 i = 0; i < world->maxEntities; i++) diff --git a/src/dengine.c b/src/dengine.c index 10aff3e..a276c8f 100644 --- a/src/dengine.c +++ b/src/dengine.c @@ -160,11 +160,22 @@ i32 main(void) * 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}; worldTraveller_gameInit(&worldTraveller, - V2i(frameBufferWidth, frameBufferHeight)); + V2i(frameBufferWidth, frameBufferHeight), &memory); #ifdef DENGINE_DEBUG - debug_init(&worldTraveller.arena, V2i(windowWidth, windowHeight), + debug_init(&worldTraveller.arena_, V2i(windowWidth, windowHeight), worldTraveller.assetManager.font); #endif diff --git a/src/include/Dengine/AssetManager.h b/src/include/Dengine/AssetManager.h index 41dc01a..12b3636 100644 --- a/src/include/Dengine/AssetManager.h +++ b/src/include/Dengine/AssetManager.h @@ -6,7 +6,7 @@ #include "Dengine/Texture.h" /* Forward declaration */ -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; typedef struct PlatformFileRead PlatformFileRead; typedef struct AssetManager @@ -32,13 +32,13 @@ const SubTexture asset_getAtlasSubTex(TexAtlas *const atlas, const char *const key); Texture *asset_getTex(AssetManager *const assetManager, const char *const key); TexAtlas *asset_getFreeTexAtlasSlot(AssetManager *const assetManager, - MemoryArena *arena, const char *const key, + MemoryArena_ *arena, const char *const key, i32 numSubTex); TexAtlas *asset_getTexAtlas(AssetManager *const assetManager, const char *const key); Texture *asset_getFreeTexSlot(AssetManager *const assetManager, - MemoryArena *const arena, const char *const key); -Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena, + MemoryArena_ *const arena, const char *const key); +Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena_ *arena, 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, - MemoryArena *const arena, const char *const animName, + MemoryArena_ *const arena, const char *const animName, TexAtlas *const atlas, char **const subTextureNames, const i32 numSubTextures, const f32 frameDuration); Animation *asset_getAnim(AssetManager *const assetManager, @@ -60,7 +60,7 @@ Animation *asset_getAnim(AssetManager *const assetManager, */ AudioVorbis *const asset_getVorbis(AssetManager *const assetManager, 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); /* @@ -69,20 +69,20 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, ********************************* */ const i32 asset_loadXmlFile(AssetManager *const assetManager, - MemoryArena *const arena, + MemoryArena_ *const arena, const PlatformFileRead *const fileRead); 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 fragmentPath, const enum ShaderList type); -const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, +const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena, const char *filePath); const v2 asset_stringDimInPixels(const Font *const font, const char *const string); -void asset_unitTest(MemoryArena *arena); +void asset_unitTest(MemoryArena_ *arena); #endif diff --git a/src/include/Dengine/Audio.h b/src/include/Dengine/Audio.h index 3256b4d..f5fa0d7 100644 --- a/src/include/Dengine/Audio.h +++ b/src/include/Dengine/Audio.h @@ -6,7 +6,7 @@ #include "Dengine/Common.h" /* Forward Declaration */ -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; #define AUDIO_NO_FREE_SOURCE -1 typedef struct AudioSourceEntry @@ -49,18 +49,18 @@ typedef struct AudioRenderer 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, i32 numPlays); -const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_streamPlayVorbis(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer, AudioVorbis *vorbis, i32 numPlays); -const i32 audio_stopVorbis(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_stopVorbis(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer); const i32 audio_pauseVorbis(AudioManager *audioManager, AudioRenderer *audioRenderer); const i32 audio_resumeVorbis(AudioManager *audioManager, AudioRenderer *audioRenderer); -const i32 audio_updateAndPlay(MemoryArena *arena, AudioManager *audioManager, +const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager, AudioRenderer *audioRenderer); #endif diff --git a/src/include/Dengine/Common.h b/src/include/Dengine/Common.h index 141e26c..5281a5c 100644 --- a/src/include/Dengine/Common.h +++ b/src/include/Dengine/Common.h @@ -26,6 +26,10 @@ typedef double f64; #define ASSERT(expr) if (!(expr)) { *(int *)0 = 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 i32 common_strlen(const char *const string); diff --git a/src/include/Dengine/Debug.h b/src/include/Dengine/Debug.h index ac52e18..7c88e29 100644 --- a/src/include/Dengine/Debug.h +++ b/src/include/Dengine/Debug.h @@ -7,7 +7,7 @@ /* Forward Declaration */ typedef struct GameState GameState; -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; #define INVALID_CODE_PATH 0 enum DebugCount @@ -20,7 +20,7 @@ enum DebugCount 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) void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep); diff --git a/src/include/Dengine/Entity.h b/src/include/Dengine/Entity.h index 123e34d..842d488 100644 --- a/src/include/Dengine/Entity.h +++ b/src/include/Dengine/Entity.h @@ -7,7 +7,7 @@ typedef struct AssetManager AssetManager; typedef struct AudioRenderer AudioRenderer; -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; typedef struct World World; typedef struct EventQueue EventQueue; @@ -135,12 +135,12 @@ void entity_updateAnim(EventQueue *eventQueue, Entity *const entity, const f32 dt); void entity_addAnim(AssetManager *const assetManager, Entity *const entity, 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 enum EntityType type, const enum Direction direction, Texture *const tex, 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 *entity_get(World *const world, const i32 entityId); i32 entity_getIndex(World *const world, const i32 entityId); diff --git a/src/include/Dengine/MemoryArena.h b/src/include/Dengine/MemoryArena.h index 255249b..17f60cd 100644 --- a/src/include/Dengine/MemoryArena.h +++ b/src/include/Dengine/MemoryArena.h @@ -3,9 +3,35 @@ #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 diff --git a/src/include/Dengine/Platform.h b/src/include/Dengine/Platform.h index 5366bd0..01e2eb6 100644 --- a/src/include/Dengine/Platform.h +++ b/src/include/Dengine/Platform.h @@ -5,7 +5,7 @@ #include "Dengine/Math.h" /* Forward Declaration */ -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; // TODO(doyle): Revise key code system -- should we store the extraneous keys or // have a mapping function to map it back to ascii? @@ -140,17 +140,17 @@ typedef struct PlatformFileRead } PlatformFileRead; // 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 // allocator since we haven't put in a system to track memory usage per // 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)) -void *platform_memoryAlloc(MemoryArena *arena, i32 numBytes); +#define PLATFORM_MEM_ALLOC_(arena, num, type) CAST(type *) platform_memoryAlloc(arena, num * sizeof(type)) +void *platform_memoryAlloc(MemoryArena_ *arena, i32 numBytes); -void platform_closeFileRead(MemoryArena *arena, PlatformFileRead *file); -i32 platform_readFileToBuffer(MemoryArena *arena, const char *const filePath, +void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file); +i32 platform_readFileToBuffer(MemoryArena_ *arena, const char *const filePath, PlatformFileRead *file); #endif diff --git a/src/include/Dengine/Renderer.h b/src/include/Dengine/Renderer.h index 71b4196..aad3dee 100644 --- a/src/include/Dengine/Renderer.h +++ b/src/include/Dengine/Renderer.h @@ -8,7 +8,7 @@ typedef struct AssetManager AssetManager; typedef struct Entity Entity; typedef struct Font Font; -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; typedef struct Shader Shader; typedef struct Texture Texture; @@ -68,12 +68,12 @@ inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, renderTex, color); } -void renderer_string(Renderer *const renderer, MemoryArena *arena, +void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, Font *const font, const char *const string, v2 pos, v2 pivotPoint, 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, v2 pos, v2 pivotPoint, f32 rotate, v4 color) { diff --git a/src/include/Dengine/String.h b/src/include/Dengine/String.h index 07f1c17..8671745 100644 --- a/src/include/Dengine/String.h +++ b/src/include/Dengine/String.h @@ -3,15 +3,14 @@ #include "Dengine/Common.h" -typedef struct MemoryArena MemoryArena; - +typedef struct MemoryArena MemoryArena_; typedef char 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); -void string_free(MemoryArena *arena, String *string); -String *const string_make(MemoryArena *const arena, char *string); -String *const string_makeLen(MemoryArena *const arena, i32 len); +void string_free(MemoryArena_ *arena, String *string); +String *const string_make(MemoryArena_ *const arena, char *string); +String *const string_makeLen(MemoryArena_ *const arena, i32 len); #endif diff --git a/src/include/Dengine/UserInterface.h b/src/include/Dengine/UserInterface.h index 7fe36a7..e469514 100644 --- a/src/include/Dengine/UserInterface.h +++ b/src/include/Dengine/UserInterface.h @@ -8,7 +8,7 @@ /* Forward Declaration */ typedef struct AssetManager AssetManager; typedef struct Font Font; -typedef struct MemoryArena MemoryArena; +typedef struct MemoryArena MemoryArena_; typedef struct Renderer Renderer; enum UiType @@ -76,17 +76,13 @@ inline i32 userInterface_generateId(UiState *const uiState) return result; } -i32 userInterface_button(UiState *const uiState, - MemoryArena *const arena, +i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena, AssetManager *const assetManager, - Renderer *const renderer, - Font *const font, - const KeyInput input, - const i32 id, const Rect rect, + Renderer *const renderer, Font *const font, + const KeyInput input, const i32 id, const Rect rect, const char *const label); -i32 userInterface_textField(UiState *const uiState, - MemoryArena *const arena, +i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena, AssetManager *const assetManager, Renderer *const renderer, Font *const font, KeyInput input, const i32 id, const Rect rect, @@ -98,7 +94,7 @@ i32 userInterface_scrollbar(UiState *const uiState, const i32 id, const Rect scrollBarRect, 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, Renderer *const renderer, Font *const font, const KeyInput input, WindowState *window); diff --git a/src/include/Dengine/WorldTraveller.h b/src/include/Dengine/WorldTraveller.h index 308346d..7f38bfc 100644 --- a/src/include/Dengine/WorldTraveller.h +++ b/src/include/Dengine/WorldTraveller.h @@ -81,6 +81,10 @@ typedef struct World typedef struct GameState { + Memory *memory; + MemoryArena_ arena_; + MemoryArena_ transientArena; + enum State state; KeyInput input; v2 mouse; @@ -94,12 +98,11 @@ typedef struct GameState AssetManager assetManager; AudioManager audioManager; Config config; - MemoryArena arena; UiState uiState; EventQueue eventQueue; } 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_registerEvent(EventQueue *eventQueue, enum EventType type, void *data);