NUked archive
This commit is contained in:
@@ -7,4 +7,5 @@
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
spritebatch.c
|
||||
spritebatchsprite.c
|
||||
)
|
||||
@@ -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
|
||||
);
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user