Support resizing the screen
This commit is contained in:
		
							parent
							
								
									486ab96ab2
								
							
						
					
					
						commit
						4aae6927e3
					
				
							
								
								
									
										22
									
								
								ui.c
								
								
								
								
							
							
						
						
									
										22
									
								
								ui.c
								
								
								
								
							|  | @ -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); | ||||
|  |  | |||
							
								
								
									
										70
									
								
								window.c
								
								
								
								
							
							
						
						
									
										70
									
								
								window.c
								
								
								
								
							|  | @ -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) { | ||||
|  |  | |||
							
								
								
									
										4
									
								
								window.h
								
								
								
								
							
							
						
						
									
										4
									
								
								window.h
								
								
								
								
							|  | @ -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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue