Scale the screen based on DPI

This commit is contained in:
Simon Gellis 2024-10-31 21:11:13 -04:00
parent c45cd14236
commit 3cb5606382
3 changed files with 45 additions and 28 deletions

8
ui.c
View File

@ -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;

View File

@ -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);

View File

@ -4,10 +4,10 @@
#include <SDL2/SDL.h>
#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);