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