Support resizing the screen

This commit is contained in:
Simon Gellis 2024-10-31 23:40:40 -04:00
parent 486ab96ab2
commit 4aae6927e3
3 changed files with 71 additions and 25 deletions

22
ui.c
View File

@ -89,9 +89,10 @@ int uiLoadGame(UIContext *ui, const char *path) {
return 0;
}
static const char *MENU_ITEMS[3] = {
static const char *MENU_ITEMS[4] = {
"File",
"Emulation",
"Video",
NULL
};
@ -169,6 +170,25 @@ int uiRun(UIContext *ui, bool running) {
nk_menu_end(ctx);
}
if (nk_menu_begin_label(ctx, "Video", NK_TEXT_ALIGN_CENTERED, nk_vec2(windowScaleX(&ui->win, 100), windowGetScreenHeight(&ui->win)))) {
float multiplier = windowGetScreenSizeMultiplier(&ui->win);
nk_layout_row_dynamic(ctx, windowGetMenuHeight(&ui->win), 1);
if (nk_menu_item_label(ctx, multiplier == 1.0f ? "x1 *" : "x1", NK_TEXT_ALIGN_LEFT)) {
windowSetScreenSizeMultiplier(&ui->win, 1.0f);
}
if (nk_menu_item_label(ctx, multiplier == 2.0f ? "x2 *" : "x2", NK_TEXT_ALIGN_LEFT)) {
windowSetScreenSizeMultiplier(&ui->win, 2.0f);
}
if (nk_menu_item_label(ctx, multiplier == 3.0f ? "x3 *" : "x3", NK_TEXT_ALIGN_LEFT)) {
windowSetScreenSizeMultiplier(&ui->win, 3.0f);
}
if (nk_menu_item_label(ctx, multiplier == 4.0f ? "x4 *" : "x4", NK_TEXT_ALIGN_LEFT)) {
windowSetScreenSizeMultiplier(&ui->win, 4.0f);
}
nk_menu_end(ctx);
}
windowMenubarEnd(&ui->win);
}
windowGuiEnd(&ui->win);

View File

@ -56,7 +56,37 @@ static void applyStyles(struct nk_context *ctx, float scaleX, float scaleY) {
ctx->style.contextual_button.padding = nk_vec2(20 * scaleX, 4 * scaleY);
}
/* scale the window for High-DPI displays */
static void scaleWindow(WindowContext *win) {
int renderW, renderH;
int oldWindowX, oldWindowY;
int newWindowX, newWindowY;
int oldWindowW, oldWindowH;
int newWindowW, newWindowH;
float scaleX, scaleY;
float hdpi, vdpi;
SDL_GetRendererOutputSize(win->renderer, &renderW, &renderH);
SDL_GetWindowPosition(win->window, &oldWindowX, &oldWindowY);
SDL_GetWindowSize(win->window, &oldWindowW, &oldWindowH);
SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(win->window), NULL, &hdpi, &vdpi);
scaleX = (float)(renderW) / (float)(oldWindowW);
scaleY = (float)(renderH) / (float)(oldWindowH);
win->screenScaleX = (hdpi / 96) * scaleX;
win->screenScaleY = (vdpi / 96) * scaleY;
newWindowW = SCREEN_WIDTH * win->screenSizeMultiplier * (hdpi / 96) / scaleX;
newWindowH = (SCREEN_HEIGHT * win->screenSizeMultiplier + MENU_HEIGHT) * (vdpi / 96) / scaleY;
newWindowX = oldWindowX - (newWindowW - oldWindowW) / 2;
newWindowY = oldWindowY - (newWindowH - oldWindowH) / 2;
if (newWindowX < 0) newWindowX = 0;
if (newWindowY < 0) newWindowY = 0;
SDL_SetWindowSize(win->window, newWindowW, newWindowH);
SDL_SetWindowPosition(win->window, newWindowX, newWindowY);
}
int windowInit(WindowContext *win, const char *title) {
win->screenSizeMultiplier = 1.0f;
win->window = SDL_CreateWindow(title,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT + MENU_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
@ -86,25 +116,7 @@ int windowInit(WindowContext *win, const char *title) {
SDL_SetTextureColorMod(win->rightEye, 0, 0xc6, 0xf0);
SDL_SetTextureBlendMode(win->rightEye, SDL_BLENDMODE_ADD);
/* 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);
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);
}
scaleWindow(win);
win->nk = nk_sdl_init(win->window, win->renderer);
applyStyles(win->nk, win->screenScaleX, win->screenScaleY);
@ -143,6 +155,16 @@ void windowDestroy(WindowContext *win) {
SDL_DestroyWindow(win->window);
}
float windowGetScreenSizeMultiplier(WindowContext *win) {
return win->screenSizeMultiplier;
}
void windowSetScreenSizeMultiplier(WindowContext *win, float multiplier) {
win->screenSizeMultiplier = multiplier;
scaleWindow(win);
applyStyles(win->nk, win->screenScaleX, win->screenScaleY);
}
static void copyScreenTexture(uint8_t *dst, const uint8_t *src, int pitch) {
int x, y, i;
uint8_t color;
@ -186,15 +208,15 @@ int windowGetMenuHeight(WindowContext *win) {
}
int windowGetScreenHeight(WindowContext *win) {
return SCREEN_HEIGHT * win->screenScaleY;
return SCREEN_HEIGHT * win->screenSizeMultiplier * win->screenScaleY;
}
void windowDisplayBegin(WindowContext *win) {
SDL_Rect dst;
dst.x = 0;
dst.y = MENU_HEIGHT * win->screenScaleY;
dst.w = SCREEN_WIDTH * win->screenScaleX;
dst.h = SCREEN_HEIGHT * win->screenScaleY;
dst.w = SCREEN_WIDTH * win->screenSizeMultiplier * win->screenScaleX;
dst.h = SCREEN_HEIGHT * win->screenSizeMultiplier * win->screenScaleY;
SDL_RenderClear(win->renderer);
SDL_RenderCopy(win->renderer, win->leftEye, NULL, &dst);
@ -207,7 +229,9 @@ void windowDisplayEnd(WindowContext *win) {
}
bool windowGuiBegin(WindowContext *win, const char *title) {
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);
return nk_begin(win->nk, title,
nk_rect(0, 0, SCREEN_WIDTH * win->screenSizeMultiplier * win->screenScaleX, MENU_HEIGHT * win->screenScaleY),
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND);
}
void windowGuiEnd(WindowContext *win) {

View File

@ -6,7 +6,7 @@
typedef struct WindowContext {
SDL_Window *window;
int winWidth, winHeight;
float screenSizeMultiplier;
float screenScaleX, screenScaleY;
SDL_Renderer *renderer;
SDL_Texture *leftEye;
@ -18,6 +18,8 @@ typedef struct WindowContext {
int windowInit(WindowContext *win, const char *title);
void windowDestroy(WindowContext *win);
float windowGetScreenSizeMultiplier(WindowContext *win);
void windowSetScreenSizeMultiplier(WindowContext *win, float multiplier);
void windowUpdate(WindowContext *win, const uint8_t *left, const uint8_t *right);
int windowScaleX(WindowContext *win, int x);