Add UI cropping
This commit is contained in:
@@ -12,9 +12,6 @@
|
|||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
#include "display/shader/shaderunlit.h"
|
|
||||||
#include "display/text/text.h"
|
|
||||||
#include "display/spritebatch/spritebatch.h"
|
|
||||||
|
|
||||||
console_t CONSOLE;
|
console_t CONSOLE;
|
||||||
|
|
||||||
@@ -63,20 +60,6 @@ void consoleUpdate(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t consoleDraw(void) {
|
|
||||||
if(!CONSOLE.visible) errorOk();
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < CONSOLE_HISTORY_MAX; i++) {
|
|
||||||
errorChain(textDraw(
|
|
||||||
0, FONT_DEFAULT.tileset->tileHeight * i,
|
|
||||||
CONSOLE.line[i],
|
|
||||||
COLOR_RED,
|
|
||||||
&FONT_DEFAULT
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return spriteBatchFlush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void consoleDispose(void) {
|
void consoleDispose(void) {
|
||||||
#ifdef DUSK_CONSOLE_POSIX
|
#ifdef DUSK_CONSOLE_POSIX
|
||||||
threadMutexDispose(&CONSOLE.printMutex);
|
threadMutexDispose(&CONSOLE.printMutex);
|
||||||
|
|||||||
@@ -45,13 +45,6 @@ void consolePrint(const char_t *message, ...);
|
|||||||
*/
|
*/
|
||||||
void consoleUpdate(void);
|
void consoleUpdate(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the console history to the screen (UI space).
|
|
||||||
*
|
|
||||||
* @return The error return value.
|
|
||||||
*/
|
|
||||||
errorret_t consoleDraw(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the console.
|
* Disposes of the console.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13,6 +13,13 @@
|
|||||||
|
|
||||||
screen_t SCREEN;
|
screen_t SCREEN;
|
||||||
|
|
||||||
|
const screencropaspectinfo_t SCREEN_CROP_ASPECTS[SCREEN_CROP_ASPECT_COUNT] = {
|
||||||
|
[SCREEN_CROP_ASPECT_4_3] = { .ratio = 4.0f / 3.0f },
|
||||||
|
[SCREEN_CROP_ASPECT_3_2] = { .ratio = 3.0f / 2.0f },
|
||||||
|
[SCREEN_CROP_ASPECT_16_10] = { .ratio = 16.0f / 10.0f },
|
||||||
|
[SCREEN_CROP_ASPECT_16_9] = { .ratio = 16.0f / 9.0f },
|
||||||
|
};
|
||||||
|
|
||||||
errorret_t screenInit() {
|
errorret_t screenInit() {
|
||||||
memoryZero(&SCREEN, sizeof(screen_t));
|
memoryZero(&SCREEN, sizeof(screen_t));
|
||||||
|
|
||||||
@@ -53,10 +60,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
SCREEN.width = frameBufferGetWidth(FRAMEBUFFER_BOUND);
|
||||||
SCREEN.height = frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
SCREEN.height = frameBufferGetHeight(FRAMEBUFFER_BOUND);
|
||||||
SCREEN.aspect = frameBufferGetAspect(FRAMEBUFFER_BOUND);
|
SCREEN.aspect = frameBufferGetAspect(FRAMEBUFFER_BOUND);
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
|
|
||||||
// No needd for a framebuffer.
|
// No needd for a framebuffer.
|
||||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
@@ -73,10 +77,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = SCREEN.fixedSize.width;
|
SCREEN.width = SCREEN.fixedSize.width;
|
||||||
SCREEN.height = SCREEN.fixedSize.height;
|
SCREEN.height = SCREEN.fixedSize.height;
|
||||||
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
|
|
||||||
if(SCREEN.framebufferReady) {
|
if(SCREEN.framebufferReady) {
|
||||||
// Is current framebuffer the correct size?
|
// Is current framebuffer the correct size?
|
||||||
@@ -114,10 +115,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = fbWidth;
|
SCREEN.width = fbWidth;
|
||||||
SCREEN.height = fbHeight;
|
SCREEN.height = fbHeight;
|
||||||
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
|
|
||||||
if(SCREEN.framebufferReady) {
|
if(SCREEN.framebufferReady) {
|
||||||
errorChain(frameBufferDispose(&SCREEN.framebuffer));
|
errorChain(frameBufferDispose(&SCREEN.framebuffer));
|
||||||
@@ -148,10 +146,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = newFbWidth;
|
SCREEN.width = newFbWidth;
|
||||||
SCREEN.height = newFbHeight;
|
SCREEN.height = newFbHeight;
|
||||||
SCREEN.aspect = curFbAspect;
|
SCREEN.aspect = curFbAspect;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
errorChain(frameBufferBind(&SCREEN.framebuffer));
|
errorChain(frameBufferBind(&SCREEN.framebuffer));
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -168,10 +163,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = newFbWidth;
|
SCREEN.width = newFbWidth;
|
||||||
SCREEN.height = newFbHeight;
|
SCREEN.height = newFbHeight;
|
||||||
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
SCREEN.framebufferReady = true;
|
SCREEN.framebufferReady = true;
|
||||||
|
|
||||||
// Bind FB
|
// Bind FB
|
||||||
@@ -191,10 +183,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = newFbWidth;
|
SCREEN.width = newFbWidth;
|
||||||
SCREEN.height = newFbHeight;
|
SCREEN.height = newFbHeight;
|
||||||
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
|
|
||||||
if(fbWidth == newFbWidth && fbHeight == newFbHeight) {
|
if(fbWidth == newFbWidth && fbHeight == newFbHeight) {
|
||||||
// No need to use framebuffer.
|
// No need to use framebuffer.
|
||||||
@@ -241,10 +230,7 @@ errorret_t screenBind() {
|
|||||||
SCREEN.width = newFbWidth;
|
SCREEN.width = newFbWidth;
|
||||||
SCREEN.height = newFbHeight;
|
SCREEN.height = newFbHeight;
|
||||||
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
|
|
||||||
if(fbWidth == newFbWidth && fbHeight == newFbHeight) {
|
if(fbWidth == newFbWidth && fbHeight == newFbHeight) {
|
||||||
// No need to use framebuffer.
|
// No need to use framebuffer.
|
||||||
@@ -286,10 +272,7 @@ errorret_t screenBind() {
|
|||||||
float_t fbAspect = fbWidth / fbHeight;
|
float_t fbAspect = fbWidth / fbHeight;
|
||||||
SCREEN.width = (int32_t)floorf(SCREEN.height * fbAspect);
|
SCREEN.width = (int32_t)floorf(SCREEN.height * fbAspect);
|
||||||
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height;
|
||||||
SCREEN.scanX = 0;
|
screenUpdateScan();
|
||||||
SCREEN.scanY = 0;
|
|
||||||
SCREEN.scanWidth = SCREEN.width;
|
|
||||||
SCREEN.scanHeight = SCREEN.height;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,6 +406,46 @@ errorret_t screenRender() {
|
|||||||
errorThrow("Invalid screen mode.");
|
errorThrow("Invalid screen mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void screenUpdateScan(void) {
|
||||||
|
SCREEN.scanX = 0;
|
||||||
|
SCREEN.scanY = 0;
|
||||||
|
SCREEN.scanWidth = SCREEN.width;
|
||||||
|
SCREEN.scanHeight = SCREEN.height;
|
||||||
|
|
||||||
|
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
|
// Find the smallest standard ratio >= the screen aspect.
|
||||||
|
float_t targetRatio = -1.0f;
|
||||||
|
for(int32_t i = 0; i < SCREEN_CROP_ASPECT_COUNT; i++) {
|
||||||
|
if(SCREEN_CROP_ASPECTS[i].ratio >= SCREEN.aspect) {
|
||||||
|
targetRatio = SCREEN_CROP_ASPECTS[i].ratio;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(targetRatio < 0.0f) {
|
||||||
|
// Wider than all entries: cap at last (16:9).
|
||||||
|
targetRatio = SCREEN_CROP_ASPECTS[
|
||||||
|
SCREEN_CROP_ASPECT_COUNT - 1
|
||||||
|
].ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(targetRatio > SCREEN.aspect) {
|
||||||
|
// Letterbox: target is wider, restrict height.
|
||||||
|
int32_t targetH = (int32_t)floorf(
|
||||||
|
(float_t)SCREEN.width / targetRatio
|
||||||
|
);
|
||||||
|
SCREEN.scanY = (SCREEN.height - targetH) / 2;
|
||||||
|
SCREEN.scanHeight = targetH;
|
||||||
|
} else if(targetRatio < SCREEN.aspect) {
|
||||||
|
// Pillarbox: target is narrower, restrict width.
|
||||||
|
int32_t targetW = (int32_t)floorf(
|
||||||
|
(float_t)SCREEN.height * targetRatio
|
||||||
|
);
|
||||||
|
SCREEN.scanX = (SCREEN.width - targetW) / 2;
|
||||||
|
SCREEN.scanWidth = targetW;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
errorret_t screenDispose() {
|
errorret_t screenDispose() {
|
||||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
if(SCREEN.framebufferReady) {
|
if(SCREEN.framebufferReady) {
|
||||||
|
|||||||
@@ -17,6 +17,27 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCREEN_CROP_ASPECT_4_3,
|
||||||
|
SCREEN_CROP_ASPECT_3_2,
|
||||||
|
SCREEN_CROP_ASPECT_16_10,
|
||||||
|
SCREEN_CROP_ASPECT_16_9,
|
||||||
|
SCREEN_CROP_ASPECT_COUNT
|
||||||
|
} screencropaspect_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float_t ratio;
|
||||||
|
} screencropaspectinfo_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard crop aspect ratios, sorted narrowest to widest.
|
||||||
|
* screenUpdateScan() selects the smallest ratio >= the current
|
||||||
|
* screen aspect; screens wider than the widest entry are capped
|
||||||
|
* at the last entry (16:9).
|
||||||
|
*/
|
||||||
|
extern const screencropaspectinfo_t
|
||||||
|
SCREEN_CROP_ASPECTS[SCREEN_CROP_ASPECT_COUNT];
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SCREEN_MODE_BACKBUFFER,
|
SCREEN_MODE_BACKBUFFER,
|
||||||
|
|
||||||
@@ -116,6 +137,17 @@ errorret_t screenUnbind();
|
|||||||
*/
|
*/
|
||||||
errorret_t screenRender();
|
errorret_t screenRender();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the scan area for the current screen dimensions.
|
||||||
|
* Defaults to the full viewport. On dynamic displays, finds the
|
||||||
|
* smallest SCREEN_CROP_ASPECTS entry whose ratio is >= the
|
||||||
|
* screen aspect and centers a crop window of that ratio.
|
||||||
|
* Screens narrower than the target are letterboxed; screens
|
||||||
|
* wider than the target are pillarboxed. Screens wider than
|
||||||
|
* all entries are pillarboxed to the last entry (16:9).
|
||||||
|
*/
|
||||||
|
void screenUpdateScan(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes the screen system.
|
* Disposes the screen system.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
ui.c
|
ui.c
|
||||||
|
uiconsole.c
|
||||||
|
uicrop.c
|
||||||
uifps.c
|
uifps.c
|
||||||
uielement.c
|
uielement.c
|
||||||
uiframe.c
|
uiframe.c
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "ui/uielement.h"
|
#include "ui/uielement.h"
|
||||||
#include "ui/uifullbox.h"
|
#include "ui/uifullbox.h"
|
||||||
#include "ui/uiloading.h"
|
#include "ui/uiloading.h"
|
||||||
|
#include "ui/uicrop.h"
|
||||||
#include "time/time.h"
|
#include "time/time.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ ui_t UI;
|
|||||||
|
|
||||||
errorret_t uiInit(void) {
|
errorret_t uiInit(void) {
|
||||||
memoryZero(&UI, sizeof(ui_t));
|
memoryZero(&UI, sizeof(ui_t));
|
||||||
|
uiCropInit();
|
||||||
uiFullboxInit(&UI_FULLBOX_UNDER);
|
uiFullboxInit(&UI_FULLBOX_UNDER);
|
||||||
uiFullboxInit(&UI_FULLBOX_OVER);
|
uiFullboxInit(&UI_FULLBOX_OVER);
|
||||||
uiLoadingInit();
|
uiLoadingInit();
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uiconsole.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "display/screen/screen.h"
|
||||||
|
#include "display/text/text.h"
|
||||||
|
#include "display/spritebatch/spritebatch.h"
|
||||||
|
|
||||||
|
errorret_t uiConsoleDraw(void) {
|
||||||
|
if(!CONSOLE.visible) errorOk();
|
||||||
|
|
||||||
|
float_t lineH = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
||||||
|
for(uint32_t i = 0; i < CONSOLE_HISTORY_MAX; i++) {
|
||||||
|
errorChain(textDraw(
|
||||||
|
(float_t)SCREEN.scanX,
|
||||||
|
(float_t)SCREEN.scanY + lineH * (float_t)i,
|
||||||
|
CONSOLE.line[i],
|
||||||
|
COLOR_RED,
|
||||||
|
&FONT_DEFAULT
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return spriteBatchFlush();
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the console history into the scan-safe area.
|
||||||
|
* No-ops when the console is not visible.
|
||||||
|
*
|
||||||
|
* @return Any error that occurs.
|
||||||
|
*/
|
||||||
|
errorret_t uiConsoleDraw(void);
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uicrop.h"
|
||||||
|
#include "display/screen/screen.h"
|
||||||
|
#include "display/spritebatch/spritebatch.h"
|
||||||
|
#include "display/shader/shaderunlit.h"
|
||||||
|
#include "display/texture/texture.h"
|
||||||
|
|
||||||
|
uicrop_t UI_CROP;
|
||||||
|
|
||||||
|
void uiCropInit(void) {
|
||||||
|
UI_CROP.color = COLOR_BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t uiCropDraw(void) {
|
||||||
|
if(
|
||||||
|
SCREEN.scanX == 0 &&
|
||||||
|
SCREEN.scanY == 0 &&
|
||||||
|
SCREEN.scanWidth == SCREEN.width &&
|
||||||
|
SCREEN.scanHeight == SCREEN.height
|
||||||
|
) errorOk();
|
||||||
|
|
||||||
|
float_t x0 = (float_t)SCREEN.scanX;
|
||||||
|
float_t y0 = (float_t)SCREEN.scanY;
|
||||||
|
float_t x1 = (float_t)(SCREEN.scanX + SCREEN.scanWidth);
|
||||||
|
float_t y1 = (float_t)(SCREEN.scanY + SCREEN.scanHeight);
|
||||||
|
float_t w = (float_t)SCREEN.width;
|
||||||
|
float_t h = (float_t)SCREEN.height;
|
||||||
|
|
||||||
|
spritebatchsprite_t sprites[4];
|
||||||
|
int32_t count = 0;
|
||||||
|
|
||||||
|
if(SCREEN.scanX > 0) {
|
||||||
|
sprites[count++] = (spritebatchsprite_t){
|
||||||
|
.min = { 0.0f, 0.0f, 0.0f },
|
||||||
|
.max = { x0, h, 0.0f },
|
||||||
|
.uvMin = { 0.0f, 0.0f },
|
||||||
|
.uvMax = { 1.0f, 1.0f }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SCREEN.scanX + SCREEN.scanWidth < SCREEN.width) {
|
||||||
|
sprites[count++] = (spritebatchsprite_t){
|
||||||
|
.min = { x1, 0.0f, 0.0f },
|
||||||
|
.max = { w, h, 0.0f },
|
||||||
|
.uvMin = { 0.0f, 0.0f },
|
||||||
|
.uvMax = { 1.0f, 1.0f }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SCREEN.scanY > 0) {
|
||||||
|
sprites[count++] = (spritebatchsprite_t){
|
||||||
|
.min = { x0, 0.0f, 0.0f },
|
||||||
|
.max = { x1, y0, 0.0f },
|
||||||
|
.uvMin = { 0.0f, 0.0f },
|
||||||
|
.uvMax = { 1.0f, 1.0f }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SCREEN.scanY + SCREEN.scanHeight < SCREEN.height) {
|
||||||
|
sprites[count++] = (spritebatchsprite_t){
|
||||||
|
.min = { x0, y1, 0.0f },
|
||||||
|
.max = { x1, h, 0.0f },
|
||||||
|
.uvMin = { 0.0f, 0.0f },
|
||||||
|
.uvMax = { 1.0f, 1.0f }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count == 0) errorOk();
|
||||||
|
|
||||||
|
shadermaterial_t material = {
|
||||||
|
.unlit = {
|
||||||
|
.color = UI_CROP.color,
|
||||||
|
.texture = &TEXTURE_WHITE
|
||||||
|
}
|
||||||
|
};
|
||||||
|
errorChain(spriteBatchBuffer(sprites, count, &SHADER_UNLIT, material));
|
||||||
|
return spriteBatchFlush();
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
#include "display/color.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
color_t color;
|
||||||
|
} uicrop_t;
|
||||||
|
|
||||||
|
extern uicrop_t UI_CROP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the crop bars to opaque black.
|
||||||
|
*/
|
||||||
|
void uiCropInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders solid-color bars covering every area outside the
|
||||||
|
* current scan-safe region. No-ops when the scan area equals
|
||||||
|
* the full viewport.
|
||||||
|
*
|
||||||
|
* @return Any error that occurs.
|
||||||
|
*/
|
||||||
|
errorret_t uiCropDraw(void);
|
||||||
@@ -7,15 +7,19 @@
|
|||||||
|
|
||||||
#include "uielement.h"
|
#include "uielement.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "console/console.h"
|
|
||||||
#include "ui/uifps.h"
|
#include "ui/uifps.h"
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
#include "ui/uitextbox.h"
|
#include "ui/uitextbox.h"
|
||||||
#include "ui/uifullbox.h"
|
#include "ui/uifullbox.h"
|
||||||
#include "ui/uiloading.h"
|
#include "ui/uiloading.h"
|
||||||
#include "ui/uiplayerpos.h"
|
#include "ui/uiplayerpos.h"
|
||||||
|
#include "ui/uicrop.h"
|
||||||
|
#include "ui/uiconsole.h"
|
||||||
|
|
||||||
uielement_t UI_ELEMENTS[] = {
|
uielement_t UI_ELEMENTS[] = {
|
||||||
|
// Crop bars: black bars outside the scan-safe area.
|
||||||
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiCropDraw },
|
||||||
|
|
||||||
// Fullbox under: above scene, below system UI.
|
// Fullbox under: above scene, below system UI.
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFullboxUnderDraw },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFullboxUnderDraw },
|
||||||
|
|
||||||
@@ -27,7 +31,7 @@ uielement_t UI_ELEMENTS[] = {
|
|||||||
|
|
||||||
|
|
||||||
// These render above the fullbox overlay.
|
// These render above the fullbox overlay.
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = consoleDraw },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiConsoleDraw },
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFPSDraw },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFPSDraw },
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiPlayerPosDraw },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiPlayerPosDraw },
|
||||||
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiLoadingDraw },
|
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiLoadingDraw },
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uiplayerpos.h"
|
#include "uiplayerpos.h"
|
||||||
|
#include "display/screen/screen.h"
|
||||||
#include "display/text/text.h"
|
#include "display/text/text.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
#include "rpg/entity/entity.h"
|
#include "rpg/entity/entity.h"
|
||||||
@@ -38,7 +39,10 @@ errorret_t uiPlayerPosDraw() {
|
|||||||
(int_t)chunkPos.z
|
(int_t)chunkPos.z
|
||||||
);
|
);
|
||||||
|
|
||||||
float_t y = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
float_t y = (float_t)SCREEN.scanY +
|
||||||
errorChain(textDraw(0, y, text, COLOR_GREEN, &FONT_DEFAULT));
|
(float_t)FONT_DEFAULT.tileset->tileHeight;
|
||||||
|
errorChain(textDraw(
|
||||||
|
(float_t)SCREEN.scanX, y, text, COLOR_GREEN, &FONT_DEFAULT
|
||||||
|
));
|
||||||
return spriteBatchFlush();
|
return spriteBatchFlush();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user