This commit is contained in:
2025-10-02 18:53:47 -05:00
parent 4b04fc65ad
commit c0cd4ead04
34 changed files with 684 additions and 35 deletions

View File

@@ -5,6 +5,7 @@
set(DUSK_GAME_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL ${DUSK_CACHE_TARGET})
add_subdirectory(palette)# Palette asset needs to be added before any images.
# Palette asset needs to be added before any images.
add_subdirectory(palette)
add_subdirectory(config)
add_subdirectory(ui)

View File

@@ -14,4 +14,6 @@ bind enter accept;
bind q cancel;
bind esc quit;
fps 1;
fps 1;
scene sweep;

View File

@@ -14,4 +14,6 @@ bind lstick_positive_y down;
bind lstick_negative_x left;
bind lstick_positive_x right;
fps 1;
fps 1;
scene sweep;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

After

Width:  |  Height:  |  Size: 145 B

View File

@@ -2,5 +2,3 @@
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_asset(PALETTE palette0.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -3,4 +3,6 @@
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_asset(TILESET minogram.png type=ALPHA tileWidth=6 tileHeight=10 columns=16 rows=6)
add_asset(TILESET minogram.png type=ALPHA tileWidth=6 tileHeight=10 columns=16 rows=6)
add_asset(TILESET ui.png type=PALETTIZED tileWidth=16 tileHeight=16)
add_asset(TILESET ui_frame.png type=PALETTIZED tileWidth=16 tileHeight=16)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

View File

@@ -8,7 +8,7 @@
#pragma once
#include "asset.h"
#define ASSET_MANAGER_ASSET_COUNT_MAX 256
#define ASSET_MANAGER_ASSET_COUNT_MAX 32
#if ASSET_TYPE == wad
#else

View File

@@ -9,8 +9,8 @@
#include "error/error.h"
#include "display/texture/texture.h"
#define ASSET_PALETTE_IMAGE_WIDTH_MAX 256
#define ASSET_PALETTE_IMAGE_HEIGHT_MAX 256
#define ASSET_PALETTE_IMAGE_WIDTH_MAX 128
#define ASSET_PALETTE_IMAGE_HEIGHT_MAX 128
#define ASSET_PALETTE_IMAGE_SIZE_MAX ( \
ASSET_PALETTE_IMAGE_WIDTH_MAX * ASSET_PALETTE_IMAGE_HEIGHT_MAX \
)

View File

@@ -0,0 +1,38 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "console/console.h"
#include "engine/engine.h"
#include "scene/scenemanager.h"
void cmdScene(const consolecmdexec_t *exec) {
if(exec->argc < 1) {
consolePrint("Usage: scene <name>");
return;
}
scene_t *scene = sceneManagerGetSceneByName(exec->argv[0]);
if(scene == NULL) {
consolePrint("Error: Scene '%s' not found.", exec->argv[0]);
return;
}
if((scene->flags & SCENE_FLAG_INITIALIZED) == 0) {
if(scene->init) {
errorret_t ret = errorPrint(scene->init());
if(ret.code != ERROR_OK) {
errorCatch(ret);
consolePrint("Error: Failed to initialize scene '%s'.", exec->argv[0]);
return;
}
}
scene->flags |= SCENE_FLAG_INITIALIZED;
}
sceneManagerSetScene(scene);
}

View File

@@ -19,6 +19,7 @@
#include "console/cmd/cmdbind.h"
#include "console/cmd/cmdtoggleconsole.h"
#include "console/cmd/cmdalias.h"
#include "console/cmd/cmdscene.h"
console_t CONSOLE;
@@ -34,6 +35,7 @@ void consoleInit() {
consoleRegCmd("bind", cmdBind);
consoleRegCmd("toggleconsole", cmdToggleConsole);
consoleRegCmd("alias", cmdAlias);
consoleRegCmd("scene", cmdScene);
#if CONSOLE_POSIX
threadInit(&CONSOLE.thread, consoleInputThread);

View File

@@ -58,6 +58,7 @@ errorret_t engineUpdate(void) {
errorret_t engineDispose(void) {
gameDispose();
sceneManagerDispose();
errorChain(displayDispose());
assetManagerDispose();
consoleDispose();

View File

@@ -57,6 +57,11 @@ errorret_t errorThrowImpl(
}
errorret_t errorOkImpl() {
assertTrue(
ERROR_STATE.code == ERROR_OK,
"Global error state is not OK (Likely missing errorCatch)"
);
return (errorret_t) {
.code = ERROR_OK,
.state = NULL

View File

@@ -10,4 +10,5 @@ target_sources(${DUSK_TARGET_NAME}
)
# Subdirs
add_subdirectory(scene)
add_subdirectory(ui)

View File

@@ -7,9 +7,14 @@
#include "game/game.h"
#include "game/minesweeper/ui/ui.h"
#include "game/minesweeper/scene/scenesweep.h"
#include "scene/scenemanager.h"
#include "console/console.h"
errorret_t gameInit(void) {
uiInit();
errorChain(uiInit());
sceneManagerRegisterScene(&SCENE_SWEEP);
errorOk();
}

View File

@@ -0,0 +1,12 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
scenesweep.c
)
# Subdirs

View File

@@ -6,22 +6,20 @@
*/
#include "scenesweep.h"
#include "game/minesweeper/ui/ui.h"
scene_t SCENE_SWEEP = {
.name = "sweep",
.init = sceneSweepInit,
.update = sceneSweepUpdate,
.render = sceneSweepRender,
.dispose = sceneSweepDispose,
.active = NULL,
.sleep = NULL,
.flags = 0
};
scenesweep_t SCENE_SWEEP_DATA;
errorret_t sceneSweepInit(void) {
// Initialize scene data here
errorOk();
}
@@ -31,8 +29,10 @@ void sceneSweepUpdate(void) {
void sceneSweepRender(void) {
// Render scene here
uiRender();
}
void sceneSweepDispose(void) {
// Clean up scene resources here
printf("Disposing sweep scene\n");
}

View File

@@ -9,7 +9,7 @@
#include "scene/scene.h"
typedef struct {
int32_t x;
} scenesweep_t;
extern scene_t SCENE_SWEEP;

View File

@@ -8,22 +8,41 @@
#include "ui.h"
#include "ui/uifps.h"
#include "ui/uiconsole.h"
#include "ui/uiframe.h"
#include "display/framebuffer/framebuffer.h"
#include "display/spritebatch/spritebatch.h"
#include "display/tileset/tileset_minogram.h"
#include "display/tileset/tileset_ui.h"
#include "display/tileset/tileset_ui_frame.h"
ui_t UI;
void uiInit(void) {
errorret_t uiInit(void) {
cameraInitOrthographic(&UI.camera);
UI.minogramTileset = (tileset_t*)&TILESET_MINOGRAM;
assetManagerLoadAsset(
errorChain(assetManagerLoadAsset(
UI.minogramTileset->image,
&UI.minogramAsset,
&UI.minogramRef
);
));
UI.uiTileset = (tileset_t*)&TILESET_UI;
errorChain(assetManagerLoadAsset(
UI.uiTileset->image,
&UI.uiAsset,
&UI.uiRef
));
UI.frameTileset = (tileset_t*)&TILESET_UI_FRAME;
errorChain(assetManagerLoadAsset(
UI.frameTileset->image,
&UI.frameAsset,
&UI.frameRef
));
errorOk();
}
void uiRender(void) {
@@ -38,7 +57,22 @@ void uiRender(void) {
cameraPushMatrix(&UI.camera);
uiFPSRender(UI.minogramTileset, &UI.minogramAsset->alphaImage.texture);
uiConsoleRender(UI.minogramTileset, &UI.minogramAsset->alphaImage.texture);
float_t x, y;
x = 32, y = 32;
uiFrameDrawTiled(
x, y,
256, 256,
UI.frameTileset,
0, 0,
&UI.frameAsset->paletteImage.texture
);
uiConsoleRender(
0, 0,
UI.minogramTileset, &UI.minogramAsset->alphaImage.texture
);
spriteBatchFlush();
cameraPopMatrix();
}

View File

@@ -17,14 +17,24 @@ typedef struct {
tileset_t *minogramTileset;
asset_t *minogramAsset;
ref_t minogramRef;
tileset_t *uiTileset;
asset_t *uiAsset;
ref_t uiRef;
tileset_t *frameTileset;
asset_t *frameAsset;
ref_t frameRef;
} ui_t;
extern ui_t UI;
/**
* Initializes the Minesweeper UI.
*
* @return Error code indicating success or failure.
*/
void uiInit(void);
errorret_t uiInit(void);
/**
* Renders the Minesweeper UI.

View File

@@ -10,8 +10,11 @@
#include "error/error.h"
#define SCENE_FLAG_ACTIVE (1 << 0)
#define SCENE_FLAG_INITIALIZED (1 << 1)
typedef struct {
const char_t *name;
errorret_t (*init)(void);
void (*update)(void);
void (*render)(void);

View File

@@ -8,47 +8,103 @@
#include "scenemanager.h"
#include "util/memory.h"
#include "assert/assert.h"
#include "console/console.h"
#include "util/string.h"
scenemanager_t SCENE_MANAGER;
errorret_t sceneManagerInit(void) {
memoryZero(&SCENE_MANAGER, sizeof(scenemanager_t));
errorOk();
}
scene_t * sceneManagerGetSceneByName(const char_t *name) {
assertNotNull(name, "Name is null");
for(uint8_t i = 0; i < SCENE_MANAGER.sceneCount; i++) {
if(strcmp(SCENE_MANAGER.scenes[i]->name, name) != 0) continue;
return SCENE_MANAGER.scenes[i];
}
return NULL;
}
void sceneManagerRegisterScene(scene_t *scene) {
assertNotNull(scene, "Scene is null");
assertTrue(
SCENE_MANAGER.sceneCount < SCENE_MANAGER_SCENE_COUNT_MAX,
"Scene count exceeded max"
);
assertNotNull(scene->name, "Scene name is null");
assertNull(
sceneManagerGetSceneByName(scene->name), "Scene name already registered"
);
SCENE_MANAGER.scenes[SCENE_MANAGER.sceneCount++] = scene;
}
void sceneManagerSetScene(scene_t *scene) {
if(SCENE_MANAGER.current) {
SCENE_MANAGER.current->sleep();
SCENE_MANAGER.current->flags &= ~SCENE_FLAG_ACTIVE;
if(SCENE_MANAGER.current->sleep) SCENE_MANAGER.current->sleep();
// TODO: Should dispose?
SCENE_MANAGER.current->flags &= ~(
SCENE_FLAG_INITIALIZED | SCENE_FLAG_ACTIVE
);
if(SCENE_MANAGER.current->dispose) SCENE_MANAGER.current->dispose();
}
SCENE_MANAGER.current = scene;
if(SCENE_MANAGER.current) {
SCENE_MANAGER.current->active();
SCENE_MANAGER.current->flags |= SCENE_FLAG_ACTIVE;
if(scene) {
assertTrue(
scene->flags & SCENE_FLAG_INITIALIZED,
"Scene not initialized"
);
if(scene->active) scene->active();
scene->flags |= SCENE_FLAG_ACTIVE;
}
}
void sceneManagerUpdate(void) {
if(!SCENE_MANAGER.current) return;
assertTrue(
SCENE_MANAGER.current->flags & SCENE_FLAG_ACTIVE,
"Current scene not active"
);
SCENE_MANAGER.current->update();
assertTrue(
SCENE_MANAGER.current->flags & SCENE_FLAG_INITIALIZED,
"Current scene not initialized"
);
if(SCENE_MANAGER.current->update) SCENE_MANAGER.current->update();
}
void sceneManagerRender(void) {
if(!SCENE_MANAGER.current) return;
assertTrue(
SCENE_MANAGER.current->flags & SCENE_FLAG_ACTIVE,
"Current scene not active"
);
SCENE_MANAGER.current->render();
assertTrue(
SCENE_MANAGER.current->flags & SCENE_FLAG_INITIALIZED,
"Current scene not initialized"
);
if(SCENE_MANAGER.current->render) SCENE_MANAGER.current->render();
}
void sceneManagerDispose(void) {
assertNull(SCENE_MANAGER.current, "Current scene not null");
for(uint8_t i = 0; i < SCENE_MANAGER.sceneCount; i++) {
scene_t *scene = SCENE_MANAGER.scenes[i];
if(scene->flags & SCENE_FLAG_INITIALIZED) {
scene->dispose();
}
}
SCENE_MANAGER.sceneCount = 0;
}

View File

@@ -8,8 +8,12 @@
#pragma once
#include "scene.h"
#define SCENE_MANAGER_SCENE_COUNT_MAX 32
typedef struct {
scene_t *current;
scene_t *scenes[SCENE_MANAGER_SCENE_COUNT_MAX];
uint8_t sceneCount;
} scenemanager_t;
extern scenemanager_t SCENE_MANAGER;
@@ -19,6 +23,21 @@ extern scenemanager_t SCENE_MANAGER;
*/
errorret_t sceneManagerInit(void);
/**
* Retrieves a registered scene by its name.
*
* @param name The name of the scene to retrieve.
* @return The scene with the specified name, or NULL if not found.
*/
scene_t * sceneManagerGetSceneByName(const char_t *name);
/**
* Registers a scene with the scene manager.
*
* @param scene The scene to register.
*/
void sceneManagerRegisterScene(scene_t *scene);
/**
* Sets the current active scene.
*

View File

@@ -8,5 +8,6 @@ target_sources(${DUSK_TARGET_NAME}
PRIVATE
uitext.c
uifps.c
uiframe.c
uiconsole.c
)

View File

@@ -9,7 +9,12 @@
#include "uitext.h"
#include "console/console.h"
void uiConsoleRender(const tileset_t *tileset, texture_t *texture) {
void uiConsoleRender(
const float_t x,
const float_t y,
const tileset_t *tileset,
texture_t *texture
) {
if(!CONSOLE.visible) return;
int32_t i = CONSOLE_HISTORY_MAX - 1;
@@ -21,7 +26,7 @@ void uiConsoleRender(const tileset_t *tileset, texture_t *texture) {
continue;
}
uiTextDraw(
0, i * TILESET_MINOGRAM.tileHeight,
x, y + (i * TILESET_MINOGRAM.tileHeight),
line, COLOR_WHITE,
tileset, texture
);

View File

@@ -12,7 +12,14 @@
/**
* Renders the console UI.
*
* @param x The x-coordinate to start rendering the console.
* @param y The y-coordinate to start rendering the console.
* @param tileset The tileset to use for rendering text.
* @param texture The texture associated with the tileset.
*/
void uiConsoleRender(const tileset_t *tileset, texture_t *texture);
void uiConsoleRender(
const float_t x,
const float_t y,
const tileset_t *tileset,
texture_t *texture
);

384
src/ui/uiframe.c Normal file
View File

@@ -0,0 +1,384 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "uiframe.h"
#include "display/spritebatch/spritebatch.h"
#include "assert/assert.h"
#include <math.h>
void uiFrameDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height,
const tileset_t *tileset,
const uint16_t column,
const uint16_t row,
texture_t *texture
) {
assertNotNull(tileset, "Tileset cannot be NULL");
assertNotNull(texture, "Texture cannot be NULL");
if(height <= 0 || width <= 0) return;
// Top-Left
vec4 uv;
tilesetPositionGetUV(
tileset,
column,
row,
uv
);
spriteBatchPush(
texture,
x, y,
x + tileset->tileWidth,
y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Top-Center
tilesetPositionGetUV(
tileset,
column + 1,
row,
uv
);
spriteBatchPush(
texture,
x + tileset->tileWidth, y,
x + width - tileset->tileWidth, y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Top-Right
tilesetPositionGetUV(
tileset,
column + 2,
row,
uv
);
spriteBatchPush(
texture,
x + width - tileset->tileWidth, y,
x + width, y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Middle-Left
tilesetPositionGetUV(
tileset,
column,
row + 1,
uv
);
spriteBatchPush(
texture,
x, y + tileset->tileHeight,
x + tileset->tileWidth, y + height - tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Middle-Center
tilesetPositionGetUV(
tileset,
column + 1,
row + 1,
uv
);
spriteBatchPush(
texture,
x + tileset->tileWidth, y + tileset->tileHeight,
x + width - tileset->tileWidth, y + height - tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Middle-Right
tilesetPositionGetUV(
tileset,
column + 2,
row + 1,
uv
);
spriteBatchPush(
texture,
x + width - tileset->tileWidth, y + tileset->tileHeight,
x + width, y + height - tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Bottom-Left
tilesetPositionGetUV(
tileset,
column,
row + 2,
uv
);
spriteBatchPush(
texture,
x, y + height - tileset->tileHeight,
x + tileset->tileWidth, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Bottom-Center
tilesetPositionGetUV(
tileset,
column + 1,
row + 2,
uv
);
spriteBatchPush(
texture,
x + tileset->tileWidth, y + height - tileset->tileHeight,
x + width - tileset->tileWidth, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Bottom-Right
tilesetPositionGetUV(
tileset,
column + 2,
row + 2,
uv
);
spriteBatchPush(
texture,
x + width - tileset->tileWidth, y + height - tileset->tileHeight,
x + width, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
void uiFrameDrawTiled(
const float_t x,
const float_t y,
const float_t width,
const float_t height,
const tileset_t *tileset,
const uint16_t column,
const uint16_t row,
texture_t *texture
) {
assertNotNull(tileset, "Tileset cannot be NULL");
assertNotNull(texture, "Texture cannot be NULL");
if(height <= 0 || width <= 0) return;
uint32_t segmentsX, segmentsY;
float_t remainderX, remainderY;
segmentsX = (width - (tileset->tileWidth * 2)) / tileset->tileWidth;
segmentsY = (height - (tileset->tileHeight * 2)) / tileset->tileHeight;
remainderX = fmodf(width - (tileset->tileWidth * 2), tileset->tileWidth);
remainderY = fmodf(height - (tileset->tileHeight * 2), tileset->tileHeight);
// Corners
vec4 uv;
// Top-Left
tilesetPositionGetUV(
tileset,
column,
row,
uv
);
spriteBatchPush(
texture,
x, y,
x + tileset->tileWidth,
y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Top-Right
tilesetPositionGetUV(
tileset,
column + 2,
row,
uv
);
spriteBatchPush(
texture,
x + width - tileset->tileWidth, y,
x + width, y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Bottom-Left
tilesetPositionGetUV(
tileset,
column,
row + 2,
uv
);
spriteBatchPush(
texture,
x, y + height - tileset->tileHeight,
x + tileset->tileWidth, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Bottom-Right
tilesetPositionGetUV(
tileset,
column + 2,
row + 2,
uv
);
spriteBatchPush(
texture,
x + width - tileset->tileWidth, y + height - tileset->tileHeight,
x + width, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
// Top and Bottom Edges (Tiled)
tilesetPositionGetUV(tileset, column + 1, row, uv); // Top edge
float_t edgeX = x + tileset->tileWidth;
for(uint32_t i = 0; i < segmentsX; ++i, edgeX += tileset->tileWidth) {
spriteBatchPush(
texture,
edgeX, y,
edgeX + tileset->tileWidth, y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
if(remainderX) {
spriteBatchPush(
texture,
edgeX, y,
edgeX + remainderX, y + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
tilesetPositionGetUV(tileset, column + 1, row + 2, uv); // Bottom edge
edgeX = x + tileset->tileWidth;
for(uint32_t i = 0; i < segmentsX; ++i, edgeX += tileset->tileWidth) {
spriteBatchPush(
texture,
edgeX, y + height - tileset->tileHeight,
edgeX + tileset->tileWidth, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
if(remainderX) {
spriteBatchPush(
texture,
edgeX, y + height - tileset->tileHeight,
edgeX + remainderX, y + height,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
// Left and Right Edges (Tiled)
tilesetPositionGetUV(tileset, column, row + 1, uv); // Left edge
float_t edgeY = y + tileset->tileHeight;
for(uint32_t i = 0; i < segmentsY; ++i, edgeY += tileset->tileHeight) {
spriteBatchPush(
texture,
x, edgeY,
x + tileset->tileWidth, edgeY + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
if(remainderY) {
spriteBatchPush(
texture,
x, edgeY,
x + tileset->tileWidth, edgeY + remainderY,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
tilesetPositionGetUV(tileset, column + 2, row + 1, uv); // Right edge
edgeY = y + tileset->tileHeight;
for(uint32_t i = 0; i < segmentsY; ++i, edgeY += tileset->tileHeight) {
spriteBatchPush(
texture,
x + width - tileset->tileWidth, edgeY,
x + width, edgeY + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
if(remainderY) {
spriteBatchPush(
texture,
x + width - tileset->tileWidth, edgeY,
x + width, edgeY + remainderY,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
// Center (Tiled)
tilesetPositionGetUV(tileset, column + 1, row + 1, uv); // Center tile
float_t centerY = y + tileset->tileHeight;
for(uint32_t j = 0; j < segmentsY; ++j, centerY += tileset->tileHeight) {
float_t centerX = x + tileset->tileWidth;
for(uint32_t i = 0; i < segmentsX; ++i, centerX += tileset->tileWidth) {
spriteBatchPush(
texture,
centerX, centerY,
centerX + tileset->tileWidth, centerY + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
if(remainderX) {
spriteBatchPush(
texture,
centerX, centerY,
centerX + remainderX, centerY + tileset->tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
}
if(remainderY) {
float_t centerX = x + tileset->tileWidth;
for(uint32_t i = 0; i < segmentsX; ++i, centerX += tileset->tileWidth) {
spriteBatchPush(
texture,
centerX, centerY,
centerX + tileset->tileWidth, centerY + remainderY,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
if(remainderX) {
spriteBatchPush(
texture,
centerX, centerY,
centerX + remainderX, centerY + remainderY,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
}
}

57
src/ui/uiframe.h Normal file
View File

@@ -0,0 +1,57 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/tileset.h"
#include "display/texture/texture.h"
/**
* Draw a UI Frame (using the 9-slice technique).
*
* @param x The x position to draw the frame at.
* @param y The y position to draw the frame at.
* @param width The width of the frame.
* @param height The height of the frame.
* @param tileset The tileset to use for rendering the frame.
* @param column The column in the tileset to use for the frame.
* @param row The row in the tileset to use for the frame.
* @param texture The texture associated with the tileset.
*/
void uiFrameDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height,
const tileset_t *tileset,
const uint16_t column,
const uint16_t row,
texture_t *texture
);
/**
* Draw a tiled UI Frame (using the 9-slice technique). This will tile the
* center components to allow them to repeat without distortion.
*
* @param x The x position to draw the frame at.
* @param y The y position to draw the frame at.
* @param width The width of the frame.
* @param height The height of the frame.
* @param tileset The tileset to use for rendering the frame.
* @param column The column in the tileset to use for the frame.
* @param row The row in the tileset to use for the frame.
* @param texture The texture associated with the tileset.
*/
void uiFrameDrawTiled(
const float_t x,
const float_t y,
const float_t width,
const float_t height,
const tileset_t *tileset,
const uint16_t column,
const uint16_t row,
texture_t *texture
);

View File

@@ -39,11 +39,15 @@ def processPalettizedImage(asset):
if all(color in palette['pixels'] for color in imagePalette):
break
else:
palette = palettes[0] # Just to avoid reference error
print(f"No matching palette found for {assetPath}!")
# Find which pixel is missing
for color in imagePalette:
if color not in palette:
print(f"Missing color: {color}")
if color in palette['pixels']:
continue
# Convert to hex (with alpha)
hexColor = '#{:02x}{:02x}{:02x}{:02x}'.format(color[0], color[1], color[2], color[3])
print(f"Missing color: {hexColor} in palette {palette['paletteName']}")
sys.exit(1)
print(f"Converting image {assetPath} to use palette")