From 3cb5606382f08fa4f5ea180383e96b53351fcfac Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Thu, 31 Oct 2024 21:11:13 -0400 Subject: [PATCH] Scale the screen based on DPI --- ui.c | 8 ++++---- window.c | 58 +++++++++++++++++++++++++++++++++++--------------------- window.h | 7 +++++-- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/ui.c b/ui.c index 8fcb4ff..18d914b 100644 --- a/ui.c +++ b/ui.c @@ -134,8 +134,8 @@ int uiRun(UIContext *ui) { if (windowGuiBegin(&ui->win, "Shrooms VB")) { windowMenubarBegin(&ui->win, MENU_ITEMS); - if (nk_menu_begin_label(ctx, "File", NK_TEXT_ALIGN_CENTERED, nk_vec2(120, windowGetScreenHeight(&ui->win)))) { - nk_layout_row_dynamic(ctx, MENU_HEIGHT + 2, 1); + if (nk_menu_begin_label(ctx, "File", NK_TEXT_ALIGN_CENTERED, nk_vec2(windowScaleX(&ui->win, 100), windowGetScreenHeight(&ui->win)))) { + nk_layout_row_dynamic(ctx, windowGetMenuHeight(&ui->win), 1); if (nk_menu_item_label(ctx, "Open ROM", NK_TEXT_ALIGN_LEFT)) { char *file = tinyfd_openFileDialog("Pick a ROM", NULL, 1, ROM_EXTENSIONS, "Virtual Boy ROM files", false); if (file) { @@ -152,9 +152,9 @@ int uiRun(UIContext *ui) { nk_menu_end(ctx); } - if (nk_menu_begin_label(ctx, "Emulation", NK_TEXT_ALIGN_CENTERED, nk_vec2(120, windowGetScreenHeight(&ui->win)))) { + if (nk_menu_begin_label(ctx, "Emulation", NK_TEXT_ALIGN_CENTERED, nk_vec2(windowScaleX(&ui->win, 100), windowGetScreenHeight(&ui->win)))) { const char *label = status == status_paused ? "Resume" : "Pause"; - nk_layout_row_dynamic(ctx, MENU_HEIGHT + 2, 1); + nk_layout_row_dynamic(ctx, windowGetMenuHeight(&ui->win), 1); if (nk_menu_item_label(ctx, label, NK_TEXT_ALIGN_LEFT)) { if (status == status_paused) status = status_running; diff --git a/window.c b/window.c index 4ec8d61..2e65a47 100644 --- a/window.c +++ b/window.c @@ -1,12 +1,10 @@ #include "nuklear.h" #include "window.h" +#define MENU_HEIGHT 20 #define SCREEN_WIDTH 384 #define SCREEN_HEIGHT 224 -#define WINDOW_WIDTH SCREEN_WIDTH -#define WINDOW_HEIGHT (SCREEN_HEIGHT + MENU_HEIGHT) - static void setColorTable(struct nk_color *table) { table[NK_COLOR_TEXT] = nk_rgb(80, 80, 80); table[NK_COLOR_WINDOW] = nk_rgb(255, 255, 255); @@ -42,7 +40,7 @@ static void setColorTable(struct nk_color *table) { table[NK_COLOR_KNOB_CURSOR_ACTIVE] = nk_rgb(150, 150, 150); } -static void applyStyles(struct nk_context *ctx) { +static void applyStyles(struct nk_context *ctx, float scaleX, float scaleY) { struct nk_color table[NK_COLOR_COUNT]; setColorTable(table); nk_style_from_table(ctx, table); @@ -53,15 +51,14 @@ static void applyStyles(struct nk_context *ctx) { ctx->style.menu_button.hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]); ctx->style.menu_button.active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]); - ctx->style.contextual_button.padding = nk_vec2(20, 4); + ctx->style.menu_button.padding = nk_vec2(2 * scaleX, 4 * scaleY); + ctx->style.contextual_button.padding = nk_vec2(20 * scaleX, 4 * scaleY); } int windowInit(WindowContext *win, const char *title) { - float fontScale; - win->window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + SCREEN_WIDTH, SCREEN_HEIGHT + MENU_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); if (!win->window) { fprintf(stderr, "Error creating window: %s\n", SDL_GetError()); return -1; @@ -88,21 +85,28 @@ int windowInit(WindowContext *win, const char *title) { SDL_SetTextureColorMod(win->rightEye, 0, 0xc6, 0xf0); SDL_SetTextureBlendMode(win->rightEye, SDL_BLENDMODE_ADD); - /* scale the renderer output for High-DPI displays */ + /* scale the window and renderer for High-DPI displays */ { int renderW, renderH; int windowW, windowH; float scaleX, scaleY; + float hdpi, vdpi; SDL_GetRendererOutputSize(win->renderer, &renderW, &renderH); SDL_GetWindowSize(win->window, &windowW, &windowH); + SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(win->window), NULL, &hdpi, &vdpi); scaleX = (float)(renderW) / (float)(windowW); scaleY = (float)(renderH) / (float)(windowH); - SDL_RenderSetScale(win->renderer, scaleX, scaleY); - fontScale = scaleY; + + win->winWidth = SCREEN_WIDTH * (hdpi / 96) / scaleX; + win->winHeight = (SCREEN_HEIGHT + MENU_HEIGHT) * (vdpi / 96) / scaleY; + win->screenScaleX = (hdpi / 96) * scaleX; + win->screenScaleY = (vdpi / 96) * scaleY; + + SDL_SetWindowSize(win->window, win->winWidth, win->winHeight); } win->nk = nk_sdl_init(win->window, win->renderer); - applyStyles(win->nk); + applyStyles(win->nk, win->screenScaleX, win->screenScaleY); /* tell nuklear the mouse moved somewhere so it doesn't think we're hovering in the top left */ nk_input_motion(win->nk, 1024, 1024); @@ -111,10 +115,9 @@ int windowInit(WindowContext *win, const char *title) { struct nk_font_config config = nk_font_config(0); nk_sdl_font_stash_begin(&atlas); - win->font = nk_font_atlas_add_default(atlas, 13 * fontScale, &config); + win->font = nk_font_atlas_add_default(atlas, 11 * win->screenScaleY, &config); nk_sdl_font_stash_end(); - win->font->handle.height /= fontScale; nk_style_set_font(win->nk, &win->font->handle); } @@ -166,17 +169,28 @@ void windowUpdate(WindowContext *win, const uint8_t *left, const uint8_t *right) updateEye(win->rightEye, right); } +int windowScaleX(WindowContext *win, int x) { + return x * win->screenScaleX; +} + +int windowScaleY(WindowContext *win, int y) { + return y * win->screenScaleY; +} + +int windowGetMenuHeight(WindowContext *win) { + return (MENU_HEIGHT + 2) * win->screenScaleY; +} + int windowGetScreenHeight(WindowContext *win) { - (void) win; - return SCREEN_HEIGHT; + return SCREEN_HEIGHT * win->screenScaleY; } void windowDisplayBegin(WindowContext *win) { SDL_Rect dst; dst.x = 0; - dst.y = MENU_HEIGHT; - dst.w = SCREEN_WIDTH; - dst.h = SCREEN_HEIGHT; + dst.y = MENU_HEIGHT * win->screenScaleY; + dst.w = SCREEN_WIDTH * win->screenScaleX; + dst.h = SCREEN_HEIGHT * win->screenScaleY; SDL_RenderClear(win->renderer); SDL_RenderCopy(win->renderer, win->leftEye, NULL, &dst); @@ -189,7 +203,7 @@ void windowDisplayEnd(WindowContext *win) { } bool windowGuiBegin(WindowContext *win, const char *title) { - return nk_begin(win->nk, title, nk_rect(0, 0, SCREEN_WIDTH, MENU_HEIGHT), NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND); + return nk_begin(win->nk, title, nk_rect(0, 0, SCREEN_WIDTH * win->screenScaleX, MENU_HEIGHT * win->screenScaleY), NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND); } void windowGuiEnd(WindowContext *win) { @@ -199,14 +213,14 @@ void windowGuiEnd(WindowContext *win) { void windowMenubarBegin(WindowContext *win, const char **items) { const char **item; nk_menubar_begin(win->nk); - nk_layout_row_template_begin(win->nk, MENU_HEIGHT); + nk_layout_row_template_begin(win->nk, MENU_HEIGHT * win->screenScaleY); for (item = items; *item != NULL; item++) { struct nk_user_font *handle; int len; float width; handle = &win->font->handle; len = nk_strlen(*item); - width = handle->width(handle->userdata, handle->height, *item, len) + 16; + width = handle->width(handle->userdata, handle->height, *item, len) + (16 * win->screenScaleX); nk_layout_row_template_push_static(win->nk, width); } nk_layout_row_template_end(win->nk); diff --git a/window.h b/window.h index fb159f1..394c816 100644 --- a/window.h +++ b/window.h @@ -4,10 +4,10 @@ #include #include "nuklear.h" -#define MENU_HEIGHT 20 - typedef struct WindowContext { SDL_Window *window; + int winWidth, winHeight; + float screenScaleX, screenScaleY; SDL_Renderer *renderer; SDL_Texture *leftEye; SDL_Texture *rightEye; @@ -20,6 +20,9 @@ void windowDestroy(WindowContext *win); void windowUpdate(WindowContext *win, const uint8_t *left, const uint8_t *right); +int windowScaleX(WindowContext *win, int x); +int windowScaleY(WindowContext *win, int y); +int windowGetMenuHeight(WindowContext *win); int windowGetScreenHeight(WindowContext *win); void windowDisplayBegin(WindowContext *win);