rg_display+rg_gui: Added safe area and visible area concepts to replace margins and rounded corner const

rg_gui's behavior hasn't been improved yet. This commit only makes it possible to preemptively define the safe area in `config.h`.

Ideally future me should also add a type for margins, I just didn't know where to put it right now....
This commit is contained in:
Alex Duchesne 2025-05-30 20:55:31 -04:00
parent 4fc7c2290c
commit 6699690589
17 changed files with 58 additions and 84 deletions

View File

@ -142,3 +142,11 @@
#ifndef RG_SCREEN_PARTIAL_UPDATES
#define RG_SCREEN_PARTIAL_UPDATES 1
#endif
#ifndef RG_SCREEN_SAFE_AREA
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#endif
#ifndef RG_SCREEN_VISIBLE_AREA
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#endif

View File

@ -188,8 +188,8 @@ static inline void write_update(const rg_surface_t *update)
if (need_update)
{
int left = display.screen.margin_left + draw_left;
int top = display.screen.margin_top + draw_top + y - lines_to_copy;
int left = display.screen.margins.left + draw_left;
int top = display.screen.margins.top + draw_top + y - lines_to_copy;
if (top != window_top)
lcd_set_window(left, top, draw_width, lines_remaining);
lcd_send_buffer(line_buffer, draw_width * lines_to_copy);
@ -352,11 +352,13 @@ rg_display_counters_t rg_display_get_counters(void)
int rg_display_get_width(void)
{
// return display.screen.real_width - (display.screen.margins.left + display.screen.margins.right);
return display.screen.width;
}
int rg_display_get_height(void)
{
// return display.screen.real_height - (display.screen.margins.top + display.screen.margins.bottom);
return display.screen.height;
}
@ -498,7 +500,7 @@ void rg_display_write_rect(int left, int top, int width, int height, int stride,
for (size_t y = 0; y < height; ++y)
screen_line_checksum[top + y] = 0;
lcd_set_window(left + display.screen.margin_left, top + display.screen.margin_top, width, height);
lcd_set_window(left + display.screen.margins.left, top + display.screen.margins.top, width, height);
for (size_t y = 0; y < height;)
{
@ -534,7 +536,7 @@ void rg_display_clear_rect(int left, int top, int width, int height, uint16_t co
int pixels_remaining = width * height;
if (pixels_remaining > 0)
{
lcd_set_window(left + display.screen.margin_left, top + display.screen.margin_top, width, height);
lcd_set_window(left + display.screen.margins.left, top + display.screen.margins.top, width, height);
while (pixels_remaining > 0)
{
uint16_t *buffer = lcd_get_buffer(LCD_BUFFER_LENGTH);
@ -551,8 +553,8 @@ void rg_display_clear_except(int left, int top, int width, int height, uint16_t
{
// Clear everything except the specified area
// FIXME: Do not ignore left/top...
int left_offset = -display.screen.margin_left;
int top_offset = -display.screen.margin_top;
int left_offset = -display.screen.margins.left;
int top_offset = -display.screen.margins.top;
int horiz = (display.screen.real_width - width + 1) / 2;
int vert = (display.screen.real_height - height + 1) / 2;
rg_display_clear_rect(left_offset, top_offset, horiz, display.screen.real_height, color_le); // Left
@ -564,7 +566,7 @@ void rg_display_clear_except(int left, int top, int width, int height, uint16_t
void rg_display_clear(uint16_t color_le)
{
// We ignore margins here, we want to fill the entire screen
rg_display_clear_rect(-display.screen.margin_left, -display.screen.margin_top, display.screen.real_width,
rg_display_clear_rect(-display.screen.margins.left, -display.screen.margins.top, display.screen.real_width,
display.screen.real_height, color_le);
}
@ -590,14 +592,13 @@ void rg_display_init(void)
display = (rg_display_t){
.screen.real_width = RG_SCREEN_WIDTH,
.screen.real_height = RG_SCREEN_HEIGHT,
.screen.margin_top = RG_SCREEN_MARGIN_TOP,
.screen.margin_bottom = RG_SCREEN_MARGIN_BOTTOM,
.screen.margin_left = RG_SCREEN_MARGIN_LEFT,
.screen.margin_right = RG_SCREEN_MARGIN_RIGHT,
.screen.width = RG_SCREEN_WIDTH - RG_SCREEN_MARGIN_LEFT - RG_SCREEN_MARGIN_RIGHT,
.screen.height = RG_SCREEN_HEIGHT - RG_SCREEN_MARGIN_TOP - RG_SCREEN_MARGIN_BOTTOM,
.screen.width = RG_SCREEN_WIDTH,
.screen.height = RG_SCREEN_HEIGHT,
.screen.margins = RG_SCREEN_VISIBLE_AREA,
.changed = true,
};
display.screen.width -= display.screen.margins.left + display.screen.margins.right;
display.screen.height -= display.screen.margins.top + display.screen.margins.bottom;
lcd_init();
display_task_queue = rg_task_create("rg_display", &display_task, NULL, 4 * 1024, RG_TASK_PRIORITY_6, 1);
if (config.border_file)

View File

@ -79,8 +79,8 @@ typedef struct
struct
{
int real_width, real_height; // Real physical resolution
int margin_top, margin_bottom, margin_left, margin_right;
int width, height; // Visible resolution (minus margins)
struct {int left, top, right, bottom;} margins;
int format;
} screen;
struct

View File

@ -16,7 +16,7 @@ static struct
uint16_t *screen_buffer, *draw_buffer;
size_t draw_buffer_size;
int screen_width, screen_height;
int screen_safezone; // rg_rect_t
struct {int left, top, right, bottom;} margins;
struct
{
const rg_font_t *font;
@ -105,11 +105,9 @@ void rg_gui_init(void)
{
gui.screen_width = rg_display_get_width();
gui.screen_height = rg_display_get_height();
#ifdef RG_SCREEN_HAS_ROUND_CORNERS
gui.screen_safezone = 20;
#else
gui.screen_safezone = 0;
#endif
// FIXME: RG_SCREEN_SAFE_AREA being added on top of RG_SCREEN_VISIBLE_AREA might not be super intuitive
// because of how this is defined in config.h. It should be documented somewhere...
gui.margins = (__typeof__(gui.margins))RG_SCREEN_SAFE_AREA;
gui.draw_buffer = get_draw_buffer(gui.screen_width, 18, C_BLACK);
rg_gui_set_language_id(rg_settings_get_number(NS_GLOBAL, SETTING_LANGUAGE, RG_LANG_EN));
rg_gui_set_font(rg_settings_get_number(NS_GLOBAL, SETTING_FONTTYPE, RG_FONT_VERA_12));
@ -520,7 +518,7 @@ void rg_gui_draw_icons(void)
int bar_height = txt.height;
int icon_height = RG_MAX(8, bar_height - 4);
int icon_top = RG_MAX(0, (bar_height - icon_height - 1) / 2);
int right = gui.screen_safezone;
int right = gui.margins.right;
if (battery.present)
{
@ -616,7 +614,7 @@ void rg_gui_draw_status_bars(void)
else
snprintf(footer, max_len, "Retro-Go %s", app->version);
// FIXME: Respect gui.safezone (draw black background full screen_width, but pad the text if needed)
// FIXME: Respect gui.margins (draw black background full screen_width, but pad the text if needed)
rg_gui_draw_text(0, RG_GUI_TOP, gui.screen_width, header, C_WHITE, C_BLACK, 0);
rg_gui_draw_text(0, RG_GUI_BOTTOM, gui.screen_width, footer, C_WHITE, C_BLACK, 0);

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xEF, 0x03, 0x80, 0x02); \
ILI9341_CMD(0xCF, 0x00, 0xc1, 0x30); \

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xCF, 0x00, 0xc3, 0x30); \
ILI9341_CMD(0xED, 0x64, 0x03, 0x12, 0x81); \

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xCF, 0x00, 0x83, 0X30); \
ILI9341_CMD(0xED, 0x64, 0x03, 0X12, 0X81); \

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xC5, 0x1A); /* VCOM */ \
ILI9341_CMD(0x36, 0x60); /* Display Rotation */ \

View File

@ -27,10 +27,8 @@
#define RG_SCREEN_WIDTH 296
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define ST7789_MADCTL 0x36 // Memory Access Control
#define ST7789_MADCTL_MV 0x20

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 240
#define RG_SCREEN_HEIGHT 320
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 28
#define RG_SCREEN_MARGIN_BOTTOM 68
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 28, 0, 68}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0x36, 0x00); \
ILI9341_CMD(0xB1, 0x00, 0x10); \

View File

@ -21,10 +21,9 @@
#define RG_SCREEN_WIDTH 240
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 38
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 38, 0, 10} /* Fullscreen for plastic case. Black bar on bottom for metal case. */
// #define RG_SCREEN_VISIBLE_AREA {0, 38, 0, 0} /* Fullscreen for metal case. Cropped on bottom for plastic case. */
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xB7, 0x72); \
ILI9341_CMD(0xBB, 0x3d); \
@ -38,13 +37,6 @@
ILI9341_CMD(0xE1, 0xD0, 0x00, 0x05, 0x0D, 0x0C, 0x06, 0x2D, 0x44, 0x40, 0x0E, 0x1C, 0x18, 0x16, 0x19); \
ILI9341_CMD(0x21);
// Screen margin
// Uncomment the following line if using a plastic case
#define RG_SCREEN_MARGIN_BOTTOM 10 // Fullscreen for plastic case. Black bar on bottom for metal case.
// Uncomment the following line if using a metal case
// #define RG_SCREEN_MARGIN_BOTTOM 0 // Fullscreen for metal case. Cropped on bottom for plastic case.
// Input
/**
* The Stock firmware, left to right is: Start, Select, Menu, Power

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xCF, 0x00, 0xc3, 0x30); \
ILI9341_CMD(0xED, 0x64, 0x03, 0x12, 0x81); \

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 240
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP +80
#define RG_SCREEN_MARGIN_BOTTOM -80
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 80, 0, 80}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0x36, 0xC0); \
ILI9341_CMD(0x21); /* Invert colors */

View File

@ -19,13 +19,11 @@
#define RG_SCREEN_HOST SPI2_HOST
#define RG_SCREEN_SPEED SPI_MASTER_FREQ_40M // SPI_MASTER_FREQ_80M
#define RG_SCREEN_BACKLIGHT 1
#define RG_SCREEN_WIDTH 240 //1.3 inch 240 2.4 inch 320
#define RG_SCREEN_WIDTH 240 //1.3 inch 240 2.4 inch 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0x01); \
ILI9341_CMD(0x3A, 0x55); \
@ -49,7 +47,7 @@
ILI9341_CMD(0xE0, 0xD0, 0x00, 0x02, 0x07, 0x0a, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0e, 0x12, 0x14, 0x17); \
ILI9341_CMD(0xE1, 0xD0, 0x00, 0x02, 0x07, 0x0a, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1b, 0x1e); \
ILI9341_CMD(0x11); \
ILI9341_CMD(0x29);
ILI9341_CMD(0x29);
// Input
// Refer to rg_input.h to see all available RG_KEY_* and RG_GAMEPAD_*_MAP types

View File

@ -21,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 15
#define RG_SCREEN_MARGIN_RIGHT 20
#define RG_SCREEN_VISIBLE_AREA {15, 0, 20, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xCF, 0x00, 0xc3, 0x30); \
ILI9341_CMD(0xED, 0x64, 0x03, 0x12, 0x81); \

View File

@ -14,7 +14,6 @@
#define RG_AUDIO_USE_EXT_DAC 0 // 0 = Disable, 1 = Enable
// Video
#define RG_SCREEN_HAS_ROUND_CORNERS
#define RG_SCREEN_DRIVER 0 // 0 = ILI9341
#define RG_SCREEN_HOST SPI2_HOST
#define RG_SCREEN_SPEED SPI_MASTER_FREQ_40M
@ -22,10 +21,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 20
#define RG_SCREEN_MARGIN_RIGHT 20
#define RG_SCREEN_VISIBLE_AREA {20, 0, 20, 0}
#define RG_SCREEN_SAFE_AREA {20, 0, 20, 0}
#define RG_SCREEN_INIT() \
ILI9341_CMD(0xCF, 0x00, 0xc3, 0x30); \
ILI9341_CMD(0xED, 0x64, 0x03, 0x12, 0x81); \

View File

@ -17,10 +17,8 @@
#define RG_SCREEN_WIDTH 320
#define RG_SCREEN_HEIGHT 240
#define RG_SCREEN_ROTATE 0
#define RG_SCREEN_MARGIN_TOP 0
#define RG_SCREEN_MARGIN_BOTTOM 0
#define RG_SCREEN_MARGIN_LEFT 0
#define RG_SCREEN_MARGIN_RIGHT 0
#define RG_SCREEN_VISIBLE_AREA {0, 0, 0, 0}
#define RG_SCREEN_SAFE_AREA {0, 0, 0, 0}
#define RG_SCREEN_INIT()
// Input