Scale the screen based on DPI
This commit is contained in:
		
							parent
							
								
									c45cd14236
								
							
						
					
					
						commit
						3cb5606382
					
				
							
								
								
									
										8
									
								
								ui.c
								
								
								
								
							
							
						
						
									
										8
									
								
								ui.c
								
								
								
								
							|  | @ -134,8 +134,8 @@ int uiRun(UIContext *ui) { | ||||||
|         if (windowGuiBegin(&ui->win, "Shrooms VB")) { |         if (windowGuiBegin(&ui->win, "Shrooms VB")) { | ||||||
|             windowMenubarBegin(&ui->win, MENU_ITEMS); |             windowMenubarBegin(&ui->win, MENU_ITEMS); | ||||||
| 
 | 
 | ||||||
|             if (nk_menu_begin_label(ctx, "File", NK_TEXT_ALIGN_CENTERED, nk_vec2(120, windowGetScreenHeight(&ui->win)))) { |             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, MENU_HEIGHT + 2, 1); |                 nk_layout_row_dynamic(ctx, windowGetMenuHeight(&ui->win), 1); | ||||||
|                 if (nk_menu_item_label(ctx, "Open ROM", NK_TEXT_ALIGN_LEFT)) { |                 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); |                     char *file = tinyfd_openFileDialog("Pick a ROM", NULL, 1, ROM_EXTENSIONS, "Virtual Boy ROM files", false); | ||||||
|                     if (file) { |                     if (file) { | ||||||
|  | @ -152,9 +152,9 @@ int uiRun(UIContext *ui) { | ||||||
|                 nk_menu_end(ctx); |                 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"; |                 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 (nk_menu_item_label(ctx, label, NK_TEXT_ALIGN_LEFT)) { | ||||||
|                     if (status == status_paused) |                     if (status == status_paused) | ||||||
|                         status = status_running; |                         status = status_running; | ||||||
|  |  | ||||||
							
								
								
									
										58
									
								
								window.c
								
								
								
								
							
							
						
						
									
										58
									
								
								window.c
								
								
								
								
							|  | @ -1,12 +1,10 @@ | ||||||
| #include "nuklear.h" | #include "nuklear.h" | ||||||
| #include "window.h" | #include "window.h" | ||||||
| 
 | 
 | ||||||
|  | #define MENU_HEIGHT 20 | ||||||
| #define SCREEN_WIDTH 384 | #define SCREEN_WIDTH 384 | ||||||
| #define SCREEN_HEIGHT 224 | #define SCREEN_HEIGHT 224 | ||||||
| 
 | 
 | ||||||
| #define WINDOW_WIDTH SCREEN_WIDTH |  | ||||||
| #define WINDOW_HEIGHT (SCREEN_HEIGHT + MENU_HEIGHT) |  | ||||||
| 
 |  | ||||||
| static void setColorTable(struct nk_color *table) { | static void setColorTable(struct nk_color *table) { | ||||||
|     table[NK_COLOR_TEXT] = nk_rgb(80, 80, 80); |     table[NK_COLOR_TEXT] = nk_rgb(80, 80, 80); | ||||||
|     table[NK_COLOR_WINDOW] = nk_rgb(255, 255, 255); |     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); |     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]; |     struct nk_color table[NK_COLOR_COUNT]; | ||||||
|     setColorTable(table); |     setColorTable(table); | ||||||
|     nk_style_from_table(ctx, 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.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.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) { | int windowInit(WindowContext *win, const char *title) { | ||||||
|     float fontScale; |  | ||||||
| 
 |  | ||||||
|     win->window = SDL_CreateWindow(title, |     win->window = SDL_CreateWindow(title, | ||||||
|         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, |         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) { |     if (!win->window) { | ||||||
|         fprintf(stderr, "Error creating window: %s\n", SDL_GetError()); |         fprintf(stderr, "Error creating window: %s\n", SDL_GetError()); | ||||||
|         return -1; |         return -1; | ||||||
|  | @ -88,21 +85,28 @@ int windowInit(WindowContext *win, const char *title) { | ||||||
|     SDL_SetTextureColorMod(win->rightEye, 0, 0xc6, 0xf0); |     SDL_SetTextureColorMod(win->rightEye, 0, 0xc6, 0xf0); | ||||||
|     SDL_SetTextureBlendMode(win->rightEye, SDL_BLENDMODE_ADD); |     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 renderW, renderH; | ||||||
|         int windowW, windowH; |         int windowW, windowH; | ||||||
|         float scaleX, scaleY; |         float scaleX, scaleY; | ||||||
|  |         float hdpi, vdpi; | ||||||
|         SDL_GetRendererOutputSize(win->renderer, &renderW, &renderH); |         SDL_GetRendererOutputSize(win->renderer, &renderW, &renderH); | ||||||
|         SDL_GetWindowSize(win->window, &windowW, &windowH); |         SDL_GetWindowSize(win->window, &windowW, &windowH); | ||||||
|  |         SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(win->window), NULL, &hdpi, &vdpi); | ||||||
|         scaleX = (float)(renderW) / (float)(windowW); |         scaleX = (float)(renderW) / (float)(windowW); | ||||||
|         scaleY = (float)(renderH) / (float)(windowH); |         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); |     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 */ |     /* 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); |     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); |         struct nk_font_config config = nk_font_config(0); | ||||||
|          |          | ||||||
|         nk_sdl_font_stash_begin(&atlas); |         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(); |         nk_sdl_font_stash_end(); | ||||||
| 
 | 
 | ||||||
|         win->font->handle.height /= fontScale; |  | ||||||
|         nk_style_set_font(win->nk, &win->font->handle); |         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); |     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) { | int windowGetScreenHeight(WindowContext *win) { | ||||||
|     (void) win; |     return SCREEN_HEIGHT * win->screenScaleY; | ||||||
|     return SCREEN_HEIGHT; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void windowDisplayBegin(WindowContext *win) { | void windowDisplayBegin(WindowContext *win) { | ||||||
|     SDL_Rect dst; |     SDL_Rect dst; | ||||||
|     dst.x = 0; |     dst.x = 0; | ||||||
|     dst.y = MENU_HEIGHT; |     dst.y = MENU_HEIGHT * win->screenScaleY; | ||||||
|     dst.w = SCREEN_WIDTH; |     dst.w = SCREEN_WIDTH * win->screenScaleX; | ||||||
|     dst.h = SCREEN_HEIGHT; |     dst.h = SCREEN_HEIGHT * win->screenScaleY; | ||||||
| 
 | 
 | ||||||
|     SDL_RenderClear(win->renderer); |     SDL_RenderClear(win->renderer); | ||||||
|     SDL_RenderCopy(win->renderer, win->leftEye, NULL, &dst); |     SDL_RenderCopy(win->renderer, win->leftEye, NULL, &dst); | ||||||
|  | @ -189,7 +203,7 @@ void windowDisplayEnd(WindowContext *win) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool windowGuiBegin(WindowContext *win, const char *title) { | 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) { | void windowGuiEnd(WindowContext *win) { | ||||||
|  | @ -199,14 +213,14 @@ void windowGuiEnd(WindowContext *win) { | ||||||
| void windowMenubarBegin(WindowContext *win, const char **items) { | void windowMenubarBegin(WindowContext *win, const char **items) { | ||||||
|     const char **item; |     const char **item; | ||||||
|     nk_menubar_begin(win->nk); |     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++) { |     for (item = items; *item != NULL; item++) { | ||||||
|         struct nk_user_font *handle; |         struct nk_user_font *handle; | ||||||
|         int len; |         int len; | ||||||
|         float width; |         float width; | ||||||
|         handle = &win->font->handle; |         handle = &win->font->handle; | ||||||
|         len = nk_strlen(*item); |         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_push_static(win->nk, width); | ||||||
|     } |     } | ||||||
|     nk_layout_row_template_end(win->nk); |     nk_layout_row_template_end(win->nk); | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								window.h
								
								
								
								
							
							
						
						
									
										7
									
								
								window.h
								
								
								
								
							|  | @ -4,10 +4,10 @@ | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include "nuklear.h" | #include "nuklear.h" | ||||||
| 
 | 
 | ||||||
| #define MENU_HEIGHT 20 |  | ||||||
| 
 |  | ||||||
| typedef struct WindowContext { | typedef struct WindowContext { | ||||||
|     SDL_Window *window; |     SDL_Window *window; | ||||||
|  |     int winWidth, winHeight; | ||||||
|  |     float screenScaleX, screenScaleY; | ||||||
|     SDL_Renderer *renderer; |     SDL_Renderer *renderer; | ||||||
|     SDL_Texture *leftEye; |     SDL_Texture *leftEye; | ||||||
|     SDL_Texture *rightEye; |     SDL_Texture *rightEye; | ||||||
|  | @ -20,6 +20,9 @@ void windowDestroy(WindowContext *win); | ||||||
| 
 | 
 | ||||||
| void windowUpdate(WindowContext *win, const uint8_t *left, const uint8_t *right); | 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); | int windowGetScreenHeight(WindowContext *win); | ||||||
| 
 | 
 | ||||||
| void windowDisplayBegin(WindowContext *win); | void windowDisplayBegin(WindowContext *win); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue