NUked archive

This commit is contained in:
2026-06-25 18:01:11 -05:00
parent a9e33660cb
commit 335d79f2c4
156 changed files with 293 additions and 8158 deletions
@@ -7,4 +7,5 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
spritebatch.c
spritebatchsprite.c
)
+1 -7
View File
@@ -6,6 +6,7 @@
*/
#pragma once
#include "spritebatchsprite.h"
#include "display/mesh/quad.h"
#include "display/texture/texture.h"
#include "display/shader/shadermaterial.h"
@@ -17,13 +18,6 @@
SPRITEBATCH_SPRITES_MAX / SPRITEBATCH_FLUSH_COUNT \
)
typedef struct {
vec3 min;
vec3 max;
vec2 uvMin;
vec2 uvMax;
} spritebatchsprite_t;
typedef struct {
mesh_t mesh;
int32_t spriteCount;
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "spritebatchsprite.h"
#include "util/memory.h"
spritebatchsprite_t spriteBatchSpriteTilesetPosition(
const tileset_t *tileset,
const uint16_t column,
const uint16_t row,
const float_t x,
const float_t y,
const float_t width,
const float_t height
) {
spritebatchsprite_t sprite;
if(width == 0 || height == 0) {
memoryZero(sprite.min, sizeof(vec3));
memoryZero(sprite.max, sizeof(vec3));
return sprite;
}
vec4 uv;
tilesetPositionGetUV(tileset, column, row, uv);
sprite.min[0] = x;
sprite.min[1] = y;
sprite.min[2] = 0.0f;
sprite.max[0] = x + width;
sprite.max[1] = y + height;
sprite.max[2] = 0.0f;
sprite.uvMin[0] = uv[0];
sprite.uvMin[1] = uv[1];
sprite.uvMax[0] = uv[2];
sprite.uvMax[1] = uv[3];
return sprite;
}
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#include "display/texture/tileset.h"
typedef struct {
vec3 min;
vec3 max;
vec2 uvMin;
vec2 uvMax;
} spritebatchsprite_t;
/**
* Builds a sprite from a tileset tile at a given column/row, positioned and
* sized in screen space.
*
* @param tileset Tileset to read UV coordinates from.
* @param column Column of the tile within the tileset.
* @param row Row of the tile within the tileset.
* @param x Screen x position of the sprite's top-left corner.
* @param y Screen y position of the sprite's top-left corner.
* @param width Width of the sprite in screen space.
* @param height Height of the sprite in screen space.
* @returns The populated sprite.
*/
spritebatchsprite_t spriteBatchSpriteTilesetPosition(
const tileset_t *tileset,
const uint16_t column,
const uint16_t row,
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
+2
View File
@@ -81,6 +81,8 @@ errorret_t textDraw(
font_t *font
) {
assertNotNull(text, "Text cannot be NULL");
if(font == NULL) font = &FONT_DEFAULT;
spritebatchsprite_t sprite;
shadermaterial_t material = {
+11 -1
View File
@@ -233,4 +233,14 @@ void inputBind(const inputbutton_t button, const inputaction_t act);
* @param deadzone The deadzone threshold (0.0f to 1.0f).
* @return The input value after applying the deadzone.
*/
float_t inputDeadzone(const float_t rawValue, const float_t deadzone);
float_t inputDeadzone(const float_t rawValue, const float_t deadzone);
#ifdef DUSK_TIME_DYNAMIC
#define inputPressedIfDynamic(action) inputPressedDynamic(action)
#define inputReleasedIfDynamic(action) inputReleasedDynamic(action)
#define inputDownIfDynamic(action) inputIsDownDynamic(action)
#else
#define inputPressedIfDynamic(action) inputPressed(action)
#define inputReleasedIfDynamic(action) inputReleased(action)
#define inputDownIfDynamic(action) inputIsDown(action)
#endif
+6
View File
@@ -10,6 +10,7 @@
#include "rpg/rpgcamera.h"
#include "util/memory.h"
#include "time/time.h"
#include "ui/focus/uifocus.h"
void playerInit(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
@@ -17,6 +18,11 @@ void playerInit(entity_t *entity) {
void playerInput(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
// Can player act?
if(UI_FOCUS.count > 0) {
return;
}
// Turn
const playerinputdirmap_t *dirMap = PLAYER_INPUT_DIR_MAP;
+71 -69
View File
@@ -25,7 +25,7 @@ void uiFocusInit(void) {
memoryZero(&UI_FOCUS, sizeof(uifocus_t));
}
void uiFocusPush(
uifocusitem_t * uiFocusPush(
const uint8_t cols,
const uint8_t rows,
uifocusitemcallback_t selected,
@@ -36,6 +36,8 @@ void uiFocusPush(
UI_FOCUS.count < UI_FOCUS_STACK_MAX,
"UI focus stack overflow"
);
assertTrue(cols > 0, "Focus item cols must be > 0");
assertTrue(rows > 0, "Focus item rows must be > 0");
uifocusitem_t *item = &UI_FOCUS.items[UI_FOCUS.count];
memoryZero(item, sizeof(uifocusitem_t));
@@ -45,6 +47,7 @@ void uiFocusPush(
item->changed = changed;
item->closed = closed;
UI_FOCUS.count++;
return item;
}
void uiFocusPop(void) {
@@ -55,17 +58,25 @@ void uiFocusPop(void) {
UI_FOCUS.count--;
}
void uiFocusPopTo(const int32_t depth) {
assertTrue(depth >= 0, "Focus depth must be >= 0");
assertTrue(depth <= UI_FOCUS.count, "Focus depth exceeds current depth");
while(UI_FOCUS.count > depth) uiFocusPop();
void uiFocusPopItem(uifocusitem_t *item) {
assertTrue(UI_FOCUS.count > 0, "UI focus stack underflow");
assertTrue(item >= UI_FOCUS.items, "Item is not on the focus stack");
assertTrue(
item < UI_FOCUS.items + UI_FOCUS.count,
"Item is not on the focus stack"
);
while(&UI_FOCUS.items[UI_FOCUS.count - 1] != item) {
uiFocusPop();
}
uiFocusPop();
}
void uiFocusSelect(const uint8_t x, const uint8_t y) {
void uiFocusSetPosition(uifocusitem_t *item, const uint8_t x, const uint8_t y) {
assertTrue(UI_FOCUS.count > 0, "No active focus item");
uifocusitem_t *item = &UI_FOCUS.items[UI_FOCUS.count - 1];
assertTrue(item->cols > 0, "Focus item cols must be > 0");
assertTrue(item->rows > 0, "Focus item rows must be > 0");
uint8_t newX = x % item->cols;
uint8_t newY = y % item->rows;
@@ -89,91 +100,82 @@ void uiFocusMoveDirection(
uifocusitem_t *item,
const uifocusdirection_t dir
) {
const uifocusdirmap_t *m = UI_FOCUS_DIR_MAP;
while(m->action != INPUT_ACTION_NULL) {
if(m->direction == dir) {
uint8_t x = (uint8_t)(
(item->x + item->cols + m->dx) % item->cols
);
uint8_t y = (uint8_t)(
(item->y + item->rows + m->dy) % item->rows
);
uiFocusSelect(x, y);
return;
}
m++;
for(
const uifocusdirmap_t *m = UI_FOCUS_DIR_MAP;
m->action != INPUT_ACTION_NULL;
m++
) {
if(m->direction != dir) continue;
uint8_t x = (uint8_t)(item->x + m->dx);
uint8_t y = (uint8_t)(item->y + m->dy);
uiFocusSetPosition(item, x, y);
break;
}
}
void uiFocusUpdate(void) {
if(UI_FOCUS.count == 0) return;
// Current item
uifocusitem_t *item = &UI_FOCUS.items[UI_FOCUS.count - 1];
#ifdef DUSK_TIME_DYNAMIC
#define PRESSED(a) inputPressedDynamic(a)
#define IS_DOWN(a) inputIsDownDynamic(a)
#else
#define PRESSED(a) inputPressed(a)
#define IS_DOWN(a) inputIsDown(a)
#endif
if(PRESSED(INPUT_ACTION_ACCEPT)) {
// Accept
if(inputPressedIfDynamic(INPUT_ACTION_ACCEPT)) {
if(item->selected != NULL) item->selected(item);
goto done;
return;
}
if(PRESSED(INPUT_ACTION_CANCEL)) {
if(item->closed != NULL && item->closed(item)) {
UI_FOCUS.count--;
}
goto done;
// Return
if(inputPressedIfDynamic(INPUT_ACTION_CANCEL)) {
uiFocusPop();
return;
}
{
// Handle pressed directions
for(
const uifocusdirmap_t *m = UI_FOCUS_DIR_MAP;
while(m->action != INPUT_ACTION_NULL) {
if(PRESSED(m->action)) {
UI_FOCUS.direction = m->direction;
UI_FOCUS.timeHeld = 0.0f;
uiFocusMoveDirection(item, m->direction);
goto done;
}
m++;
}
m->action != INPUT_ACTION_NULL;
m++
) {
if(!inputPressedIfDynamic(m->action)) continue;
UI_FOCUS.direction = m->direction;
UI_FOCUS.timeHeld = 0.0f;
uiFocusMoveDirection(item, m->direction);
return;
}
{
bool_t held = false;
// Handle held directions
bool_t held = false;
for(
const uifocusdirmap_t *m = UI_FOCUS_DIR_MAP;
while(m->action != INPUT_ACTION_NULL) {
if(m->direction == UI_FOCUS.direction) {
held = IS_DOWN(m->action);
break;
}
m++;
}
m->action != INPUT_ACTION_NULL;
m++
) {
if(m->direction != UI_FOCUS.direction) continue;
if(!held) {
UI_FOCUS.direction = UI_FOCUS_DIRECTION_NONE;
UI_FOCUS.timeHeld = 0.0f;
goto done;
}
held = inputDownIfDynamic(m->action);
break;
}
// Are we still holding?
if(!held) {
UI_FOCUS.direction = UI_FOCUS_DIRECTION_NONE;
UI_FOCUS.timeHeld = 0.0f;
return;
}
#ifdef DUSK_TIME_DYNAMIC
UI_FOCUS.timeHeld += TIME.dynamicDelta;
#else
UI_FOCUS.timeHeld += TIME.delta;
#endif
if(UI_FOCUS.timeHeld < UI_FOCUS_HOLD_DELAY) goto done;
if(UI_FOCUS.timeHeld >= UI_FOCUS_HOLD_DELAY + UI_FOCUS_HOLD_REPEAT) {
UI_FOCUS.timeHeld = UI_FOCUS_HOLD_DELAY;
uiFocusMoveDirection(item, UI_FOCUS.direction);
}
done:
#undef PRESSED
#undef IS_DOWN
// Can tick?
if(UI_FOCUS.timeHeld < UI_FOCUS_HOLD_DELAY) return;
if(UI_FOCUS.timeHeld < UI_FOCUS_HOLD_DELAY + UI_FOCUS_HOLD_REPEAT) return;
UI_FOCUS.timeHeld = UI_FOCUS_HOLD_DELAY;
uiFocusMoveDirection(item, UI_FOCUS.direction);
}
+11 -11
View File
@@ -50,7 +50,7 @@ extern const uifocusdirmap_t UI_FOCUS_DIR_MAP[];
*/
typedef struct {
uifocusitem_t items[UI_FOCUS_STACK_MAX];
int32_t count;
uint8_t count;
uifocusdirection_t direction;
float_t timeHeld;
} uifocus_t;
@@ -71,8 +71,9 @@ void uiFocusInit(void);
* @param selected Called when the user selects the focused cell.
* @param changed Called when the focused cell position changes.
* @param closed Called when this focus item is popped.
* @returns Pointer to the newly pushed focus item.
*/
void uiFocusPush(
uifocusitem_t * uiFocusPush(
const uint8_t cols,
const uint8_t rows,
uifocusitemcallback_t selected,
@@ -87,28 +88,27 @@ void uiFocusPush(
void uiFocusPop(void);
/**
* Pops focus items until the stack depth reaches the given value.
* Each popped item has its closed callback invoked as normal.
*
* @param depth Target stack depth to pop back to.
* Pops an item and anything that was pushed after it from the focus stack.
*
* @param item The focus item to pop to. Must be on the stack.
*/
void uiFocusPopTo(const int32_t depth);
void uiFocusPopItem(uifocusitem_t *item);
/**
* Manually sets the cursor position of the topmost focus item and
* fires its changed callback.
*
* @param x Column to move to.
* @param y Row to move to.
* @param x Column to move to.
* @param y Row to move to.
*/
void uiFocusSelect(const uint8_t x, const uint8_t y);
void uiFocusSetPosition(uifocusitem_t *item, const uint8_t x, const uint8_t y);
/**
* Moves the topmost focus item one step in the given direction,
* wrapping at the grid edges, and fires its changed callback.
*
* @param item The focus item to move.
* @param dir Direction to move.
* @param dir Direction to move.
*/
void uiFocusMoveDirection(
uifocusitem_t *item,
+46 -117
View File
@@ -19,25 +19,25 @@ errorret_t uiFrameInit(void) {
memoryZero(&UI_FRAME, sizeof(uiframe_t));
// Init texture.
color_t border = color4b(0, 100, 220, 200);
color_t center = color4b(0, 100, 220, 50);
color_t border = color4b(0, 100, 220, 255);
color_t center = color4b(0, 100, 220, 200);
for(uint8_t y = 0; y < UIFRAME_DUMMY_HEIGHT; y++) {
for(uint8_t x = 0; x < UIFRAME_DUMMY_WIDTH; x++) {
for(uint8_t y = 0; y < UIFRAME_BORDER_HEIGHT; y++) {
for(uint8_t x = 0; x < UIFRAME_BORDER_WIDTH; x++) {
color_t c;
if(x >= 12 || y >= 12) {
if(x >= 12 || y >= 12) {// Because power of two is required.
c = COLOR_TRANSPARENT;
} else if(y < 4 || y >= 8 || x < 4 || x >= 8) {
c = border;
} else {
c = center;
}
UI_FRAME.pixels[y * UIFRAME_DUMMY_WIDTH + x] = c;
UI_FRAME.pixels[y * UIFRAME_BORDER_WIDTH + x] = c;
}
}
errorChain(textureInit(
&UI_FRAME.texture, UIFRAME_DUMMY_WIDTH, UIFRAME_DUMMY_HEIGHT,
&UI_FRAME.texture, UIFRAME_BORDER_WIDTH, UIFRAME_BORDER_HEIGHT,
TEXTURE_FORMAT_RGBA,
(texturedata_t){ .rgbaColors = UI_FRAME.pixels }
));
@@ -47,8 +47,8 @@ errorret_t uiFrameInit(void) {
UI_FRAME.tileset.columns = 3;
UI_FRAME.tileset.rows = 3;
UI_FRAME.tileset.tileCount = 9;
UI_FRAME.tileset.uv[0] = 4.0f / UIFRAME_DUMMY_WIDTH;
UI_FRAME.tileset.uv[1] = 4.0f / UIFRAME_DUMMY_HEIGHT;
UI_FRAME.tileset.uv[0] = 4.0f / UIFRAME_BORDER_WIDTH;
UI_FRAME.tileset.uv[1] = 4.0f / UIFRAME_BORDER_HEIGHT;
errorOk();
}
@@ -68,115 +68,44 @@ errorret_t uiFrameDraw(
spritebatchsprite_t sprites[9];
float_t tileW = (float_t)UI_FRAME.tileset.tileWidth;
float_t tileH = (float_t)UI_FRAME.tileset.tileHeight;
vec4 uv;
tilesetPositionGetUV(&UI_FRAME.tileset, 0, 0, uv);
sprites[0].min[0] = x;
sprites[0].min[1] = y;
sprites[0].min[2] = 0.0f;
sprites[0].max[0] = x + tileW;
sprites[0].max[1] = y + tileH;
sprites[0].max[2] = 0.0f;
sprites[0].uvMin[0] = uv[0];
sprites[0].uvMin[1] = uv[1];
sprites[0].uvMax[0] = uv[2];
sprites[0].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 1, 0, uv);
sprites[1].min[0] = x + tileW;
sprites[1].min[1] = y;
sprites[1].min[2] = 0.0f;
sprites[1].max[0] = x + width - tileW;
sprites[1].max[1] = y + tileH;
sprites[1].max[2] = 0.0f;
sprites[1].uvMin[0] = uv[0];
sprites[1].uvMin[1] = uv[1];
sprites[1].uvMax[0] = uv[2];
sprites[1].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 2, 0, uv);
sprites[2].min[0] = x + width - tileW;
sprites[2].min[1] = y;
sprites[2].min[2] = 0.0f;
sprites[2].max[0] = x + width;
sprites[2].max[1] = y + tileH;
sprites[2].max[2] = 0.0f;
sprites[2].uvMin[0] = uv[0];
sprites[2].uvMin[1] = uv[1];
sprites[2].uvMax[0] = uv[2];
sprites[2].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 0, 1, uv);
sprites[3].min[0] = x;
sprites[3].min[1] = y + tileH;
sprites[3].min[2] = 0.0f;
sprites[3].max[0] = x + tileW;
sprites[3].max[1] = y + height - tileH;
sprites[3].max[2] = 0.0f;
sprites[3].uvMin[0] = uv[0];
sprites[3].uvMin[1] = uv[1];
sprites[3].uvMax[0] = uv[2];
sprites[3].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 1, 1, uv);
sprites[4].min[0] = x + tileW;
sprites[4].min[1] = y + tileH;
sprites[4].min[2] = 0.0f;
sprites[4].max[0] = x + width - tileW;
sprites[4].max[1] = y + height - tileH;
sprites[4].max[2] = 0.0f;
sprites[4].uvMin[0] = uv[0];
sprites[4].uvMin[1] = uv[1];
sprites[4].uvMax[0] = uv[2];
sprites[4].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 2, 1, uv);
sprites[5].min[0] = x + width - tileW;
sprites[5].min[1] = y + tileH;
sprites[5].min[2] = 0.0f;
sprites[5].max[0] = x + width;
sprites[5].max[1] = y + height - tileH;
sprites[5].max[2] = 0.0f;
sprites[5].uvMin[0] = uv[0];
sprites[5].uvMin[1] = uv[1];
sprites[5].uvMax[0] = uv[2];
sprites[5].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 0, 2, uv);
sprites[6].min[0] = x;
sprites[6].min[1] = y + height - tileH;
sprites[6].min[2] = 0.0f;
sprites[6].max[0] = x + tileW;
sprites[6].max[1] = y + height;
sprites[6].max[2] = 0.0f;
sprites[6].uvMin[0] = uv[0];
sprites[6].uvMin[1] = uv[1];
sprites[6].uvMax[0] = uv[2];
sprites[6].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 1, 2, uv);
sprites[7].min[0] = x + tileW;
sprites[7].min[1] = y + height - tileH;
sprites[7].min[2] = 0.0f;
sprites[7].max[0] = x + width - tileW;
sprites[7].max[1] = y + height;
sprites[7].max[2] = 0.0f;
sprites[7].uvMin[0] = uv[0];
sprites[7].uvMin[1] = uv[1];
sprites[7].uvMax[0] = uv[2];
sprites[7].uvMax[1] = uv[3];
tilesetPositionGetUV(&UI_FRAME.tileset, 2, 2, uv);
sprites[8].min[0] = x + width - tileW;
sprites[8].min[1] = y + height - tileH;
sprites[8].min[2] = 0.0f;
sprites[8].max[0] = x + width;
sprites[8].max[1] = y + height;
sprites[8].max[2] = 0.0f;
sprites[8].uvMin[0] = uv[0];
sprites[8].uvMin[1] = uv[1];
sprites[8].uvMax[0] = uv[2];
sprites[8].uvMax[1] = uv[3];
sprites[0] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 0, 0,
x, y, tileW, tileH
);
sprites[1] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 1, 0,
x + tileW, y, width - (tileW * 2.0f), tileH
);
sprites[2] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 2, 0,
x + width - tileW, y, tileW, tileH
);
sprites[3] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 0, 1,
x, y + tileH, tileW, height - (tileH * 2.0f)
);
sprites[4] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 1, 1,
x + tileW, y + tileH,
width - (tileW * 2.0f), height - (tileH * 2.0f)
);
sprites[5] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 2, 1,
x + width - tileW, y + tileH, tileW, height - (tileH * 2.0f)
);
sprites[6] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 0, 2,
x, y + height - tileH, tileW, tileH
);
sprites[7] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 1, 2,
x + tileW, y + height - tileH, width - (tileW * 2.0f), tileH
);
sprites[8] = spriteBatchSpriteTilesetPosition(
&UI_FRAME.tileset, 2, 2,
x + width - tileW, y + height - tileH, tileW, tileH
);
return spriteBatchBuffer(sprites, 9, &SHADER_UNLIT, material);
}
+3 -3
View File
@@ -10,13 +10,13 @@
#include "display/texture/texture.h"
#include "display/texture/tileset.h"
#define UIFRAME_DUMMY_WIDTH 16
#define UIFRAME_DUMMY_HEIGHT 16
#define UIFRAME_BORDER_WIDTH 16
#define UIFRAME_BORDER_HEIGHT 16
typedef struct {
tileset_t tileset;
texture_t texture;
color_t pixels[UIFRAME_DUMMY_WIDTH * UIFRAME_DUMMY_HEIGHT];
color_t pixels[UIFRAME_BORDER_WIDTH * UIFRAME_BORDER_HEIGHT];
} uiframe_t;
extern uiframe_t UI_FRAME;
+48 -3
View File
@@ -8,6 +8,9 @@
#include "uisettings.h"
#include "ui/frame/uiframe.h"
#include "util/memory.h"
#include "display/spritebatch/spritebatch.h"
#include "display/text/text.h"
#include "input/input.h"
uisettings_t UI_SETTINGS;
@@ -17,18 +20,60 @@ errorret_t uiSettingsInit(void) {
}
errorret_t uiSettingsUpdate(void) {
// if(!UI_SETTINGS.visible) errorOk();
if(!inputPressedIfDynamic(INPUT_ACTION_PAUSE)) errorOk();
if(UI_SETTINGS.item == NULL) {
uiSettingsOpen();
} else {
uiSettingsClose();
}
errorOk();
}
errorret_t uiSettingsDraw(void) {
// if(!UI_SETTINGS.visible) errorOk();
if(UI_SETTINGS.item == NULL) errorOk();
const char_t *texts[] = {
"Settings",
"Settings two",
"Settings three"
};
const uint8_t textCount = sizeof(texts) / sizeof(texts[0]);
errorChain(uiFrameDraw(
100.0f, 100.0f, 1.0f, 1.0f
0.0f, 0.0f, 100.0f, FONT_DEFAULT.tileset->tileHeight * textCount + (UIFRAME_BORDER_HEIGHT * 2)
));
for(uint8_t i = 0; i < textCount; i++) {
const char_t *c = texts[i];
errorChain(textDraw(
UIFRAME_BORDER_WIDTH,
UIFRAME_BORDER_HEIGHT + (i * FONT_DEFAULT.tileset->tileHeight),
c,
UI_SETTINGS.item->y == i ? COLOR_RED : COLOR_WHITE, NULL
));
}
errorChain(spriteBatchFlush());
errorOk();
}
void uiSettingsOpen() {
if(UI_SETTINGS.item != NULL) return;
UI_SETTINGS.item = uiFocusPush(
1, 3, NULL, NULL, NULL
);
}
void uiSettingsClose() {
if(UI_SETTINGS.item == NULL) return;
uiFocusPopItem(UI_SETTINGS.item);
UI_SETTINGS.item = NULL;
}
errorret_t uiSettingsDispose(void) {
errorOk();
}
+12 -1
View File
@@ -7,9 +7,10 @@
#pragma once
#include "error/error.h"
#include "ui/focus/uifocus.h"
typedef struct {
bool_t visible;
uifocusitem_t *item;
} uisettings_t;
extern uisettings_t UI_SETTINGS;
@@ -35,6 +36,16 @@ errorret_t uiSettingsUpdate(void);
*/
errorret_t uiSettingsDraw(void);
/**
* Opens the settings panel. No-op when already open.
*/
void uiSettingsOpen();
/**
* Closes the settings panel. No-op when already closed.
*/
void uiSettingsClose();
/**
* Disposes of the settings panel.
*