Frame
This commit is contained in:
@@ -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)
|
@@ -14,4 +14,6 @@ bind enter accept;
|
||||
bind q cancel;
|
||||
bind esc quit;
|
||||
|
||||
fps 1;
|
||||
fps 1;
|
||||
|
||||
scene sweep;
|
@@ -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 |
Binary file not shown.
@@ -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 |
@@ -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)
|
BIN
assets/minesweeper/ui/ui.png
Normal file
BIN
assets/minesweeper/ui/ui.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/minesweeper/ui/ui.pxo
Normal file
BIN
assets/minesweeper/ui/ui.pxo
Normal file
Binary file not shown.
BIN
assets/minesweeper/ui/ui_frame
Normal file
BIN
assets/minesweeper/ui/ui_frame
Normal file
Binary file not shown.
BIN
assets/minesweeper/ui/ui_frame.png
Normal file
BIN
assets/minesweeper/ui/ui_frame.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 293 B |
@@ -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
|
||||
|
@@ -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 \
|
||||
)
|
||||
|
38
src/console/cmd/cmdscene.h
Normal file
38
src/console/cmd/cmdscene.h
Normal 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);
|
||||
}
|
@@ -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);
|
||||
|
@@ -58,6 +58,7 @@ errorret_t engineUpdate(void) {
|
||||
|
||||
errorret_t engineDispose(void) {
|
||||
gameDispose();
|
||||
sceneManagerDispose();
|
||||
errorChain(displayDispose());
|
||||
assetManagerDispose();
|
||||
consoleDispose();
|
||||
|
@@ -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
|
||||
|
@@ -10,4 +10,5 @@ target_sources(${DUSK_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(scene)
|
||||
add_subdirectory(ui)
|
@@ -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();
|
||||
}
|
||||
|
12
src/game/minesweeper/scene/CMakeLists.txt
Normal file
12
src/game/minesweeper/scene/CMakeLists.txt
Normal 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
|
@@ -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");
|
||||
}
|
@@ -9,7 +9,7 @@
|
||||
#include "scene/scene.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
int32_t x;
|
||||
} scenesweep_t;
|
||||
|
||||
extern scene_t SCENE_SWEEP;
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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.
|
||||
*
|
||||
|
@@ -8,5 +8,6 @@ target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
uitext.c
|
||||
uifps.c
|
||||
uiframe.c
|
||||
uiconsole.c
|
||||
)
|
@@ -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
|
||||
);
|
||||
|
@@ -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
384
src/ui/uiframe.c
Normal 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
57
src/ui/uiframe.h
Normal 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
|
||||
);
|
@@ -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")
|
||||
|
Reference in New Issue
Block a user