/** * 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 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] ); } } }