390 lines
8.4 KiB
C++
390 lines
8.4 KiB
C++
/**
|
|
* Copyright (c) 2025 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "uiframe.hpp"
|
|
#include "display/spritebatch.hpp"
|
|
#include "assert/Assert.hpp"
|
|
#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,
|
|
const bool_t drawInner,
|
|
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
|
|
if(drawInner) {
|
|
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,
|
|
const bool_t drawInner,
|
|
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)
|
|
if(!drawInner) return;
|
|
|
|
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]
|
|
);
|
|
}
|
|
}
|
|
} |