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\dengine.c" />
<ClCompile Include="src\Entity.c" />
<ClCompile Include="src\MemoryArena.c" />
<ClCompile Include="src\Platform.c" />
<ClCompile Include="src\Renderer.c" />
<ClCompile Include="src\Shader.c" />

View File

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

View File

@ -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);
}
}

View File

@ -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 <stdlib.h>
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)
{

View File

@ -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();
}

View File

@ -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;
}

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 "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;
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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 <time.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
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++)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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);

View File

@ -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);