Introduce temp memory to free memory leaks
This commit is contained in:
parent
3729ddf164
commit
ad14d6d822
@ -980,11 +980,15 @@ typedef struct GlyphBitmap
|
|||||||
i32 codepoint;
|
i32 codepoint;
|
||||||
} GlyphBitmap;
|
} GlyphBitmap;
|
||||||
|
|
||||||
const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
const i32 asset_loadTTFont(AssetManager *assetManager,
|
||||||
const char *filePath)
|
MemoryArena_ *persistentArena,
|
||||||
|
MemoryArena_ *transientArena, const char *filePath)
|
||||||
{
|
{
|
||||||
|
TempMemory tempRegion = memory_begin_temporary_region(transientArena);
|
||||||
|
|
||||||
PlatformFileRead fontFileRead = {0};
|
PlatformFileRead fontFileRead = {0};
|
||||||
i32 result = platform_readFileToBuffer(arena, filePath, &fontFileRead);
|
i32 result =
|
||||||
|
platform_readFileToBuffer(transientArena, filePath, &fontFileRead);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
|
|
||||||
stbtt_fontinfo fontInfo = {0};
|
stbtt_fontinfo fontInfo = {0};
|
||||||
@ -1002,7 +1006,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x);
|
const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x);
|
||||||
|
|
||||||
GlyphBitmap *glyphBitmaps =
|
GlyphBitmap *glyphBitmaps =
|
||||||
memory_pushBytes(arena, numGlyphs * sizeof(GlyphBitmap));
|
memory_pushBytes(transientArena, numGlyphs * sizeof(GlyphBitmap));
|
||||||
v2 largestGlyphDimension = V2(0, 0);
|
v2 largestGlyphDimension = V2(0, 0);
|
||||||
|
|
||||||
const f32 targetFontHeight = 15.0f;
|
const f32 targetFontHeight = 15.0f;
|
||||||
@ -1018,7 +1022,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
font->metrics = CAST(FontMetrics){ascent, descent, lineGap};
|
font->metrics = CAST(FontMetrics){ascent, descent, lineGap};
|
||||||
|
|
||||||
font->charMetrics =
|
font->charMetrics =
|
||||||
memory_pushBytes(arena, numGlyphs * sizeof(CharMetrics));
|
memory_pushBytes(persistentArena, numGlyphs * sizeof(CharMetrics));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
************************************************************
|
************************************************************
|
||||||
@ -1038,7 +1042,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
|
|
||||||
u8 *source = monoBitmap;
|
u8 *source = monoBitmap;
|
||||||
u32 *colorBitmap =
|
u32 *colorBitmap =
|
||||||
memory_pushBytes(arena, width * height * sizeof(u32));
|
memory_pushBytes(transientArena, width * height * sizeof(u32));
|
||||||
u32 *dest = colorBitmap;
|
u32 *dest = colorBitmap;
|
||||||
|
|
||||||
// NOTE(doyle): STB generates 1 byte per pixel bitmaps, we use 4bpp, so
|
// NOTE(doyle): STB generates 1 byte per pixel bitmaps, we use 4bpp, so
|
||||||
@ -1114,7 +1118,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
i32 bitmapSize = SQUARED(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL;
|
i32 bitmapSize = SQUARED(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL;
|
||||||
u32 *fontBitmap = memory_pushBytes(arena, bitmapSize * sizeof(u32));
|
u32 *fontBitmap =
|
||||||
|
memory_pushBytes(transientArena, bitmapSize * sizeof(u32));
|
||||||
const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL;
|
const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL;
|
||||||
|
|
||||||
// Check value to determine when a row of glyphs is completely printed
|
// Check value to determine when a row of glyphs is completely printed
|
||||||
@ -1131,8 +1136,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
char charToEncode = CAST(char)codepointRange.x;
|
char charToEncode = CAST(char)codepointRange.x;
|
||||||
|
|
||||||
i32 numSubTex = numGlyphs;
|
i32 numSubTex = numGlyphs;
|
||||||
TexAtlas *fontAtlas =
|
TexAtlas *fontAtlas = asset_getFreeTexAtlasSlot(
|
||||||
asset_getFreeTexAtlasSlot(assetManager, arena, "font", numSubTex);
|
assetManager, persistentArena, "font", numSubTex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*********************************************************
|
*********************************************************
|
||||||
@ -1159,7 +1164,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
// all ascii characters, charToEncode represents the character
|
// all ascii characters, charToEncode represents the character
|
||||||
// 1:1
|
// 1:1
|
||||||
const char key[2] = {charToEncode, 0};
|
const char key[2] = {charToEncode, 0};
|
||||||
SubTexture *subTex = getFreeAtlasSubTexSlot(fontAtlas, arena, key);
|
SubTexture *subTex =
|
||||||
|
getFreeAtlasSubTexSlot(fontAtlas, persistentArena, key);
|
||||||
subTex->rect = CAST(Rect){origin, font->maxSize};
|
subTex->rect = CAST(Rect){origin, font->maxSize};
|
||||||
charToEncode++;
|
charToEncode++;
|
||||||
}
|
}
|
||||||
@ -1213,7 +1219,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
* Generate and store font bitmap to assets
|
* Generate and store font bitmap to assets
|
||||||
*******************************************
|
*******************************************
|
||||||
*/
|
*/
|
||||||
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "font");
|
Texture *tex = asset_getFreeTexSlot(assetManager, persistentArena, "font");
|
||||||
*tex = texture_gen(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4,
|
*tex = texture_gen(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4,
|
||||||
CAST(u8 *) fontBitmap);
|
CAST(u8 *) fontBitmap);
|
||||||
|
|
||||||
@ -1238,14 +1244,9 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
i32 glyphBitmapSizeInBytes = CAST(i32) glyphBitmaps[i].dimensions.w *
|
i32 glyphBitmapSizeInBytes = CAST(i32) glyphBitmaps[i].dimensions.w *
|
||||||
CAST(i32) glyphBitmaps[i].dimensions.h *
|
CAST(i32) glyphBitmaps[i].dimensions.h *
|
||||||
sizeof(u32);
|
sizeof(u32);
|
||||||
// TODO(doyle): Mem free
|
|
||||||
// PLATFORM_MEM_FREE(arena, glyphBitmaps[i].pixels, glyphBitmapSizeInBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(doyle): Mem free
|
memory_end_temporary_region(tempRegion);
|
||||||
// PLATFORM_MEM_FREE(arena, glyphBitmaps, numGlyphs * sizeof(GlyphBitmap));
|
|
||||||
platform_closeFileRead(arena, &fontFileRead);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ void initAssetManager(GameState *state)
|
|||||||
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
|
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
|
||||||
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
|
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
|
||||||
|
|
||||||
i32 result = asset_loadTTFont(assetManager, arena,
|
i32 result =
|
||||||
|
asset_loadTTFont(assetManager, arena, &state->transientArena,
|
||||||
"C:/Windows/Fonts/Arialbd.ttf");
|
"C:/Windows/Fonts/Arialbd.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,20 +998,23 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
Renderer *renderer = &state->renderer;
|
Renderer *renderer = &state->renderer;
|
||||||
InputBuffer *inputBuffer = &state->input;
|
InputBuffer *inputBuffer = &state->input;
|
||||||
|
|
||||||
|
renderer_rect(renderer, world->camera, V2(0, 0), renderer->size,
|
||||||
|
V2(0, 0), 0, NULL, V4(0, 0, 0, 0.5f),
|
||||||
|
renderflag_no_texture);
|
||||||
|
|
||||||
|
v2 titleP = V2(20, renderer->size.h - 100);
|
||||||
|
renderer_staticString(renderer, transientArena, &assetManager->font,
|
||||||
|
"Asteroids", titleP, V2(0, 0), 0, V4(1, 0, 0, 1),
|
||||||
|
0);
|
||||||
|
|
||||||
userInterface_beginState(uiState);
|
userInterface_beginState(uiState);
|
||||||
|
|
||||||
WindowState window = {0};
|
Rect buttonRect = {V2(20, 20), V2(40, 40)};
|
||||||
window.id = userInterface_generateId(uiState);
|
|
||||||
|
|
||||||
Rect windowRect = {0};
|
#if 1
|
||||||
windowRect.min = V2(200, 200);
|
userInterface_button(uiState, transientArena, assetManager, renderer,
|
||||||
windowRect.max = V2(500, 500);
|
&assetManager->font, *inputBuffer, 0, buttonRect,
|
||||||
|
"test button");
|
||||||
window.rect = windowRect;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
userInterface_window(uiState, transientArena, assetManager, renderer,
|
|
||||||
&assetManager->font, *inputBuffer, &window);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
userInterface_endState(uiState, inputBuffer);
|
userInterface_endState(uiState, inputBuffer);
|
||||||
|
@ -272,7 +272,7 @@ const i32 audio_playVorbis(MemoryArena_ *arena, AudioManager *audioManager,
|
|||||||
AudioRenderer *audioRenderer, AudioVorbis *vorbis,
|
AudioRenderer *audioRenderer, AudioVorbis *vorbis,
|
||||||
i32 numPlays)
|
i32 numPlays)
|
||||||
{
|
{
|
||||||
if(vorbis) return -1;
|
if (vorbis == NULL) return -1;
|
||||||
|
|
||||||
i32 result = initRendererForPlayback(arena, audioManager, audioRenderer,
|
i32 result = initRendererForPlayback(arena, audioManager, audioRenderer,
|
||||||
vorbis, numPlays);
|
vorbis, numPlays);
|
||||||
@ -304,7 +304,7 @@ const i32 audio_streamPlayVorbis(MemoryArena_ *arena, AudioManager *audioManager
|
|||||||
// TODO(doyle): Streaming leaks memory, we don't free the "copy audio"
|
// TODO(doyle): Streaming leaks memory, we don't free the "copy audio"
|
||||||
ASSERT(INVALID_CODE_PATH);
|
ASSERT(INVALID_CODE_PATH);
|
||||||
|
|
||||||
if(vorbis) return -1;
|
if (vorbis == NULL) return -1;
|
||||||
|
|
||||||
i32 result = initRendererForPlayback(arena, audioManager, audioRenderer,
|
i32 result = initRendererForPlayback(arena, audioManager, audioRenderer,
|
||||||
vorbis, numPlays);
|
vorbis, numPlays);
|
||||||
|
@ -5,4 +5,27 @@ void memory_arenaInit(MemoryArena_ *arena, void *base, size_t size)
|
|||||||
arena->size = size;
|
arena->size = size;
|
||||||
arena->used = 0;
|
arena->used = 0;
|
||||||
arena->base = CAST(u8 *) base;
|
arena->base = CAST(u8 *) base;
|
||||||
|
arena->tempMemoryCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TempMemory memory_begin_temporary_region(MemoryArena_ *arena)
|
||||||
|
{
|
||||||
|
TempMemory result = {0};
|
||||||
|
result.arena = arena;
|
||||||
|
result.used = arena->used;
|
||||||
|
|
||||||
|
arena->tempMemoryCount++;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void memory_end_temporary_region(TempMemory tempMemory)
|
||||||
|
{
|
||||||
|
MemoryArena_ *arena = tempMemory.arena;
|
||||||
|
ASSERT(arena->used > tempMemory.used)
|
||||||
|
|
||||||
|
arena->used = tempMemory.used;
|
||||||
|
ASSERT(arena->tempMemoryCount > 0)
|
||||||
|
|
||||||
|
arena->tempMemoryCount--;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ void *platform_memoryAlloc(MemoryArena_ *arena, size_t numBytes)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(doyle): If we use arena temporary memory this is not necessary
|
||||||
void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file)
|
void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Mem free
|
// TODO(doyle): Mem free
|
||||||
@ -178,4 +179,3 @@ b32 platform_queryKey(KeyState *key, enum ReadKeyType readType,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +424,11 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size,
|
|||||||
v2 posInCameraSpace = v2_sub(pos, camera.min);
|
v2 posInCameraSpace = v2_sub(pos, camera.min);
|
||||||
|
|
||||||
RenderTex emptyRenderTex = {0};
|
RenderTex emptyRenderTex = {0};
|
||||||
if (!renderTex) renderTex = &emptyRenderTex;
|
if (!renderTex)
|
||||||
|
{
|
||||||
|
renderTex = &emptyRenderTex;
|
||||||
|
ASSERT(common_isSet(flags, renderflag_no_texture));
|
||||||
|
}
|
||||||
|
|
||||||
RenderQuad quad = createRenderQuad(renderer, posInCameraSpace, size,
|
RenderQuad quad = createRenderQuad(renderer, posInCameraSpace, size,
|
||||||
pivotPoint, rotate, *renderTex);
|
pivotPoint, rotate, *renderTex);
|
||||||
@ -496,7 +500,11 @@ void renderer_polygon(Renderer *const renderer, Rect camera,
|
|||||||
|
|
||||||
// TODO(doyle): Do something with render texture
|
// TODO(doyle): Do something with render texture
|
||||||
RenderTex emptyRenderTex = {0};
|
RenderTex emptyRenderTex = {0};
|
||||||
if (!renderTex) renderTex = &emptyRenderTex;
|
if (!renderTex)
|
||||||
|
{
|
||||||
|
renderTex = &emptyRenderTex;
|
||||||
|
ASSERT(common_isSet(flags, renderflag_no_texture));
|
||||||
|
}
|
||||||
|
|
||||||
v2 triangulationBaseP = polygonPoints[0];
|
v2 triangulationBaseP = polygonPoints[0];
|
||||||
RenderVertex triangulationBaseVertex = {0};
|
RenderVertex triangulationBaseVertex = {0};
|
||||||
|
@ -37,15 +37,7 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
if (math_pointInRect(rect, input.mouseP))
|
if (math_pointInRect(rect, input.mouseP))
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
|
if (uiState->activeItem == 0)
|
||||||
// NOTE(doyle): UI windows are drawn first, they steal focus on mouse
|
|
||||||
// click since window logic is paired with the window rendering. If
|
|
||||||
// a UI element resides over our mouse, we allow the element to override
|
|
||||||
// the windows focus
|
|
||||||
// TODO(doyle): Make a window list to iterate over window ids
|
|
||||||
if (uiState->activeItem == uiState->statWindow.id ||
|
|
||||||
uiState->activeItem == uiState->debugWindow.id ||
|
|
||||||
uiState->activeItem == 0)
|
|
||||||
{
|
{
|
||||||
if (common_isSet(input.keys[keycode_mouseLeft].flags,
|
if (common_isSet(input.keys[keycode_mouseLeft].flags,
|
||||||
keystateflag_ended_down))
|
keystateflag_ended_down))
|
||||||
@ -56,8 +48,6 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Draw shadow
|
// Draw shadow
|
||||||
renderer_staticRect(renderer, v2_add(V2(1, 1), rect.min), rect.size,
|
renderer_staticRect(renderer, v2_add(V2(1, 1), rect.min), rect.size,
|
||||||
@ -65,23 +55,23 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
v2 buttonOffset = V2(0, 0);
|
v2 buttonOffset = V2(0, 0);
|
||||||
v4 buttonColor = {0};
|
v4 buttonColor = V4(1, 1, 1, 1);
|
||||||
if (uiState->hotItem == id)
|
if (uiState->hotItem == id)
|
||||||
{
|
{
|
||||||
if (uiState->activeItem == id)
|
if (uiState->activeItem == id)
|
||||||
{
|
{
|
||||||
buttonOffset = V2(1, 1);
|
buttonOffset = V2(1, 1);
|
||||||
buttonColor = V4(1, 1, 1, 1);
|
buttonColor = V4(1.0f, 0, 0, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO(doyle): Optional add effect on button hover
|
// TODO(doyle): Optional add effect on button hover
|
||||||
buttonColor = V4(1, 1, 1, 1);
|
buttonColor = V4(1.0f, 0, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buttonColor = V4(0.5f, 0.5f, 0.5f, 1);
|
buttonColor = V4(1.0f, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no widget has keyboard focus, take it */
|
/* If no widget has keyboard focus, take it */
|
||||||
@ -94,12 +84,12 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
// Draw outline
|
// Draw outline
|
||||||
renderer_staticRect(renderer,
|
renderer_staticRect(renderer,
|
||||||
v2_add(V2(-2, -2), v2_add(buttonOffset, rect.min)),
|
v2_add(V2(-2, -2), v2_add(buttonOffset, rect.min)),
|
||||||
v2_add(V2(4, 4), rect.max), V2(0, 0), 0, &renderTex,
|
v2_add(V2(4, 4), rect.max), V2(0, 0), 0, NULL,
|
||||||
buttonColor, 0);
|
buttonColor, renderflag_no_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_staticRect(renderer, v2_add(buttonOffset, rect.min), rect.max,
|
renderer_staticRect(renderer, v2_add(buttonOffset, rect.min), rect.max,
|
||||||
V2(0, 0), 0, &renderTex, buttonColor, 0);
|
V2(0, 0), 0, NULL, buttonColor, renderflag_no_texture);
|
||||||
|
|
||||||
if (label)
|
if (label)
|
||||||
{
|
{
|
||||||
@ -172,9 +162,7 @@ i32 userInterface_scrollbar(UiState *const uiState,
|
|||||||
if (math_pointInRect(scrollBarRect, input.mouseP))
|
if (math_pointInRect(scrollBarRect, input.mouseP))
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
if (uiState->activeItem == uiState->statWindow.id ||
|
if (uiState->activeItem == 0)
|
||||||
uiState->activeItem == uiState->debugWindow.id ||
|
|
||||||
uiState->activeItem == 0)
|
|
||||||
{
|
{
|
||||||
if (common_isSet(input.keys[keycode_mouseLeft].flags,
|
if (common_isSet(input.keys[keycode_mouseLeft].flags,
|
||||||
keystateflag_ended_down))
|
keystateflag_ended_down))
|
||||||
@ -288,9 +276,7 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
if (math_pointInRect(rect, input.mouseP))
|
if (math_pointInRect(rect, input.mouseP))
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
if (uiState->activeItem == uiState->statWindow.id ||
|
if (uiState->activeItem == 0)
|
||||||
uiState->activeItem == uiState->debugWindow.id ||
|
|
||||||
uiState->activeItem == 0)
|
|
||||||
{
|
{
|
||||||
if (common_isSet(input.keys[keycode_mouseLeft].flags,
|
if (common_isSet(input.keys[keycode_mouseLeft].flags,
|
||||||
keystateflag_ended_down))
|
keystateflag_ended_down))
|
||||||
@ -304,29 +290,28 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
if (uiState->kbdItem == 0)
|
if (uiState->kbdItem == 0)
|
||||||
uiState->kbdItem = id;
|
uiState->kbdItem = id;
|
||||||
|
|
||||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
|
||||||
/* If we have keyboard focus, show it */
|
/* If we have keyboard focus, show it */
|
||||||
if (uiState->kbdItem == id)
|
if (uiState->kbdItem == id)
|
||||||
{
|
{
|
||||||
// Draw outline
|
// Draw outline
|
||||||
renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.min),
|
renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.min),
|
||||||
v2_add(V2(4, 4), rect.max), V2(0, 0), 0,
|
v2_add(V2(4, 4), rect.max), V2(0, 0), 0,
|
||||||
&renderTex, V4(1.0f, 0, 0, 1), 0);
|
NULL, V4(1.0f, 0, 0, 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render text field
|
// Render text field
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0, NULL,
|
||||||
&renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0);
|
V4(0.75f, 0.5f, 0.5f, 1), 0);
|
||||||
|
|
||||||
if (uiState->activeItem == id || uiState->hotItem == id)
|
if (uiState->activeItem == id || uiState->hotItem == id)
|
||||||
{
|
{
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
||||||
&renderTex, V4(0.75f, 0.75f, 0.0f, 1), 0);
|
NULL, V4(0.75f, 0.75f, 0.0f, 1), 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
||||||
&renderTex, V4(0.5f, 0.5f, 0.5f, 1), 0);
|
NULL, V4(0.5f, 0.5f, 0.5f, 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 strPos = rect.min;
|
v2 strPos = rect.min;
|
||||||
@ -377,124 +362,3 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
if (changed) return id;
|
if (changed) return id;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena,
|
|
||||||
AssetManager *const assetManager,
|
|
||||||
Renderer *const renderer, Font *const font,
|
|
||||||
const InputBuffer input, WindowState *window)
|
|
||||||
{
|
|
||||||
if (math_pointInRect(window->rect, input.mouseP))
|
|
||||||
{
|
|
||||||
uiState->hotItem = window->id;
|
|
||||||
if (uiState->activeItem == 0 &&
|
|
||||||
common_isSet(input.keys[keycode_mouseLeft].flags,
|
|
||||||
keystateflag_ended_down))
|
|
||||||
uiState->activeItem = window->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect rect = window->rect;
|
|
||||||
RenderTex nullRenderTex = renderer_createNullRenderTex(assetManager);
|
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
|
||||||
&nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f), 0);
|
|
||||||
|
|
||||||
v2 menuTitleP = v2_add(rect.min, V2(0, rect.max.h - 10));
|
|
||||||
renderer_staticString(renderer, arena, font, window->title, menuTitleP,
|
|
||||||
V2(0, 0), 0, V4(0, 0, 0, 1), 0);
|
|
||||||
|
|
||||||
/* Draw window elements */
|
|
||||||
i32 firstActiveChildId = -1;
|
|
||||||
for (i32 i = 0; i < window->numChildUiItems; i++)
|
|
||||||
{
|
|
||||||
UiItem *childUi = &window->childUiItems[i];
|
|
||||||
|
|
||||||
// TODO(doyle): Redundant? If we can only have 1 active child at a time
|
|
||||||
// What about overlapping elements?
|
|
||||||
i32 getChildActiveState = -1;
|
|
||||||
switch(childUi->type)
|
|
||||||
{
|
|
||||||
case uitype_button:
|
|
||||||
// TODO(doyle): Bug in font rendering once button reaches 700-800+
|
|
||||||
// pixels
|
|
||||||
getChildActiveState = userInterface_button(
|
|
||||||
uiState, arena, assetManager, renderer, font, input,
|
|
||||||
childUi->id, childUi->rect, childUi->label);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case uitype_scrollbar:
|
|
||||||
getChildActiveState = userInterface_scrollbar(
|
|
||||||
uiState, assetManager, renderer, input, childUi->id,
|
|
||||||
childUi->rect, &childUi->value, childUi->maxValue);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case uitype_textField:
|
|
||||||
getChildActiveState = userInterface_textField(
|
|
||||||
uiState, arena, assetManager, renderer, font, input,
|
|
||||||
childUi->id, childUi->rect, childUi->string);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DEBUG_LOG(
|
|
||||||
"userInterface_window() warning: Enum uitype unrecognised");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(doyle): Capture only the first active id, but keep loop going to
|
|
||||||
// render the rest of the window ui
|
|
||||||
if (firstActiveChildId == -1 && getChildActiveState > 0)
|
|
||||||
firstActiveChildId = getChildActiveState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstActiveChildId != -1)
|
|
||||||
return firstActiveChildId;
|
|
||||||
|
|
||||||
// NOTE(doyle): activeItem captures mouse click within the UI bounds, but if
|
|
||||||
// the user drags the mouse outside the bounds quicker than the game updates
|
|
||||||
// then we use a second flag which only "unclicks" when the mouse is let go
|
|
||||||
if (uiState->activeItem == window->id) window->windowHeld = TRUE;
|
|
||||||
|
|
||||||
if (window->windowHeld)
|
|
||||||
{
|
|
||||||
if (!common_isSet(input.keys[keycode_mouseLeft].flags,
|
|
||||||
keystateflag_ended_down))
|
|
||||||
{
|
|
||||||
window->windowHeld = FALSE;
|
|
||||||
window->prevFrameWindowHeld = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->windowHeld)
|
|
||||||
{
|
|
||||||
// NOTE(doyle): If this is the first window click we don't process
|
|
||||||
// movement and store the current position to delta from next cycle
|
|
||||||
if (window->prevFrameWindowHeld)
|
|
||||||
{
|
|
||||||
// NOTE(doyle): Window clicked and held
|
|
||||||
v2 deltaP = v2_sub(input.mouseP, window->prevMouseP);
|
|
||||||
|
|
||||||
for (i32 i = 0; i < window->numChildUiItems; i++)
|
|
||||||
{
|
|
||||||
UiItem *childUi = &window->childUiItems[i];
|
|
||||||
childUi->rect.min = v2_add(deltaP, childUi->rect.min);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_PUSH_VAR("Delta Pos %4.2f, %4.2f", deltaP, "v2");
|
|
||||||
window->rect.min = v2_add(deltaP, window->rect.min);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window->prevFrameWindowHeld = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->prevMouseP = input.mouseP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_isSet(input.keys[keycode_mouseLeft].flags,
|
|
||||||
keystateflag_ended_down) &&
|
|
||||||
uiState->hotItem == window->id && uiState->activeItem == window->id)
|
|
||||||
{
|
|
||||||
return window->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ i32 main(void)
|
|||||||
*/
|
*/
|
||||||
Memory memory = {0};
|
Memory memory = {0};
|
||||||
MemoryIndex persistentSize = MEGABYTES(32);
|
MemoryIndex persistentSize = MEGABYTES(32);
|
||||||
MemoryIndex transientSize = MEGABYTES(32);
|
MemoryIndex transientSize = MEGABYTES(64);
|
||||||
|
|
||||||
memory.persistentSize = persistentSize;
|
memory.persistentSize = persistentSize;
|
||||||
memory.persistent = PLATFORM_MEM_ALLOC_(NULL, persistentSize, u8);
|
memory.persistent = PLATFORM_MEM_ALLOC_(NULL, persistentSize, u8);
|
||||||
|
@ -78,8 +78,9 @@ const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
const char *const fragmentPath,
|
const char *const fragmentPath,
|
||||||
const enum ShaderList type);
|
const enum ShaderList type);
|
||||||
|
|
||||||
const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *arena,
|
const i32 asset_loadTTFont(AssetManager *assetManager,
|
||||||
const char *filePath);
|
MemoryArena_ *persistentArena,
|
||||||
|
MemoryArena_ *transientArena, const char *filePath);
|
||||||
const v2 asset_stringDimInPixels(const Font *const font,
|
const v2 asset_stringDimInPixels(const Font *const font,
|
||||||
const char *const string);
|
const char *const string);
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ typedef struct MemoryArena
|
|||||||
MemoryIndex size;
|
MemoryIndex size;
|
||||||
MemoryIndex used;
|
MemoryIndex used;
|
||||||
u8 *base;
|
u8 *base;
|
||||||
|
|
||||||
|
i32 tempMemoryCount;
|
||||||
} MemoryArena_;
|
} MemoryArena_;
|
||||||
|
|
||||||
typedef struct Memory
|
typedef struct Memory
|
||||||
@ -21,6 +23,15 @@ typedef struct Memory
|
|||||||
b32 init;
|
b32 init;
|
||||||
} Memory;
|
} Memory;
|
||||||
|
|
||||||
|
typedef struct TempMemory
|
||||||
|
{
|
||||||
|
MemoryArena_ *arena;
|
||||||
|
MemoryIndex used;
|
||||||
|
} TempMemory;
|
||||||
|
|
||||||
|
TempMemory memory_begin_temporary_region(MemoryArena_ *arena);
|
||||||
|
void memory_end_temporary_region(TempMemory tempMemory);
|
||||||
|
|
||||||
#define MEMORY_PUSH_STRUCT(arena, type) (type *)memory_pushBytes(arena, sizeof(type))
|
#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))
|
#define MEMORY_PUSH_ARRAY(arena, count, type) (type *)memory_pushBytes(arena, (count)*sizeof(type))
|
||||||
inline void *memory_pushBytes(MemoryArena_ *arena, MemoryIndex size)
|
inline void *memory_pushBytes(MemoryArena_ *arena, MemoryIndex size)
|
||||||
|
@ -35,22 +35,6 @@ typedef struct UiItem
|
|||||||
char string[80];
|
char string[80];
|
||||||
} UiItem;
|
} UiItem;
|
||||||
|
|
||||||
typedef struct WindowState
|
|
||||||
{
|
|
||||||
char title[64];
|
|
||||||
i32 id;
|
|
||||||
|
|
||||||
UiItem childUiItems[16];
|
|
||||||
i32 numChildUiItems;
|
|
||||||
|
|
||||||
Rect rect;
|
|
||||||
// TODO(doyle): Store this in the input data not window?
|
|
||||||
v2 prevMouseP;
|
|
||||||
|
|
||||||
b32 prevFrameWindowHeld;
|
|
||||||
b32 windowHeld;
|
|
||||||
} WindowState;
|
|
||||||
|
|
||||||
typedef struct UiState
|
typedef struct UiState
|
||||||
{
|
{
|
||||||
i32 uniqueId;
|
i32 uniqueId;
|
||||||
@ -66,9 +50,6 @@ typedef struct UiState
|
|||||||
enum KeyCode keyEntered;
|
enum KeyCode keyEntered;
|
||||||
enum KeyCode keyMod;
|
enum KeyCode keyMod;
|
||||||
enum KeyCode keyChar;
|
enum KeyCode keyChar;
|
||||||
|
|
||||||
WindowState statWindow;
|
|
||||||
WindowState debugWindow;
|
|
||||||
} UiState;
|
} UiState;
|
||||||
|
|
||||||
inline i32 userInterface_generateId(UiState *const uiState)
|
inline i32 userInterface_generateId(UiState *const uiState)
|
||||||
@ -97,9 +78,4 @@ i32 userInterface_scrollbar(UiState *const uiState,
|
|||||||
Renderer *const renderer, const InputBuffer input,
|
Renderer *const renderer, const InputBuffer input,
|
||||||
const i32 id, const Rect scrollBarRect,
|
const i32 id, const Rect scrollBarRect,
|
||||||
i32 *const value, const i32 maxValue);
|
i32 *const value, const i32 maxValue);
|
||||||
|
|
||||||
i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena,
|
|
||||||
AssetManager *const assetManager,
|
|
||||||
Renderer *const renderer, Font *const font,
|
|
||||||
const InputBuffer input, WindowState *window);
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user