From 19e093e554aee459f89befb2a65b4ed5351b9ee8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 28 Nov 2020 07:04:40 +0100 Subject: [PATCH] Renderer fixes and improvements. --- src/include/86box/86box.h | 1 + src/include/86box/rom.h | 4 + src/include/86box/win.h | 3 +- src/include/86box/win_sdl.h | 5 +- src/pc.c | 7 + src/win/win.c | 88 +++++----- src/win/win_sdl.c | 323 ++++++++++++++---------------------- src/win/win_ui.c | 239 ++++++++++++++------------ 8 files changed, 313 insertions(+), 357 deletions(-) diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 627a293c6..297c60c99 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -152,6 +152,7 @@ extern void pclog_toggle_suppr(void); extern void pclog(const char *fmt, ...); extern void fatal(const char *fmt, ...); extern void set_screen_size(int x, int y); +extern void reset_screen_size(void); extern void set_screen_size_natural(void); #if 0 extern void pc_reload(wchar_t *fn); diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index ee9d9e95f..d06864ca0 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -49,6 +49,8 @@ extern FILE *rom_fopen(wchar_t *fn, wchar_t *mode); extern int rom_getfile(wchar_t *fn, wchar_t *s, int size); extern int rom_present(wchar_t *fn); +extern int rom_load_linear_oddeven(wchar_t *fn, uint32_t addr, int sz, + int off, uint8_t *ptr); extern int rom_load_linear(wchar_t *fn, uint32_t addr, int sz, int off, uint8_t *ptr); extern int rom_load_interleaved(wchar_t *fnl, wchar_t *fnh, uint32_t addr, @@ -68,6 +70,8 @@ extern int bios_load_linear_combined2(wchar_t *fn1, wchar_t *fn2, extern int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +extern int rom_init_oddeven(rom_t *rom, wchar_t *fn, uint32_t address, int size, + int mask, int file_offset, uint32_t flags); extern int rom_init_interleaved(rom_t *rom, wchar_t *fn_low, wchar_t *fn_high, uint32_t address, int size, int mask, int file_offset, diff --git a/src/include/86box/win.h b/src/include/86box/win.h index 4aceae0be..ceb06f1ba 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -55,6 +55,8 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); #define SB_CLASS_NAME L"86BoxStatusBar" #define SB_MENU_NAME L"StatusBarMenu" #define FS_CLASS_NAME L"86BoxFullScreen" +#define SDL_CLASS_NAME L"86BoxSDLWnd" +#define SDL_SUB_CLASS_NAME L"86BoxSDLSubWnd" #define FLOPPY_SUBMENU_NAME L"FloppySubmenu" #define CDROM_SUBMENU_NAME L"CdromSubmenu" @@ -155,7 +157,6 @@ extern int hard_disk_was_added(void); /* Platform UI support functions. */ extern int ui_init(int nCmdShow); -extern void plat_set_input(HWND h); /* Functions in win_about.c: */ diff --git a/src/include/86box/win_sdl.h b/src/include/86box/win_sdl.h index 4f6bca231..cc61142be 100644 --- a/src/include/86box/win_sdl.h +++ b/src/include/86box/win_sdl.h @@ -54,13 +54,10 @@ extern void sdl_close(void); extern int sdl_inits(HWND h); extern int sdl_inith(HWND h); extern int sdl_initho(HWND h); -extern int sdl_inits_fs(HWND h); -extern int sdl_inith_fs(HWND h); -extern int sdl_initho_fs(HWND h); extern int sdl_pause(void); extern void sdl_resize(int x, int y); extern void sdl_enable(int enable); -extern void sdl_reinit_texture(); +extern void sdl_set_fs(int fs); #endif /*WIN_SDL_H*/ diff --git a/src/pc.c b/src/pc.c index 1f25eba14..31586a4b3 100644 --- a/src/pc.c +++ b/src/pc.c @@ -1132,6 +1132,13 @@ set_screen_size(int x, int y) } +void +reset_screen_size(void) +{ + set_screen_size(unscaled_size_x, efscrnsz_y); +} + + void set_screen_size_natural(void) { diff --git a/src/win/win.c b/src/win/win.c index 0d465f2f3..50c87d015 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -86,23 +86,14 @@ static const struct { void (*resize)(int x, int y); int (*pause)(void); void (*enable)(int enable); -} vid_apis[2][RENDERERS_NUM] = { - { - { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable }, - { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable }, - { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable } + void (*set_fs)(int fs); +} vid_apis[RENDERERS_NUM] = { + { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs }, + { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs }, + { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs } #ifdef USE_VNC - ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL } + ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } #endif - }, - { - { "SDL_Software", 1, (int(*)(void*))sdl_inits_fs, sdl_close, sdl_resize, sdl_pause, sdl_enable }, - { "SDL_Hardware", 1, (int(*)(void*))sdl_inith_fs, sdl_close, sdl_resize, sdl_pause, sdl_enable }, - { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho_fs, sdl_close, sdl_resize, sdl_pause, sdl_enable } -#ifdef USE_VNC - ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL } -#endif - }, }; @@ -681,8 +672,8 @@ plat_vidapi(char *name) if (!strcasecmp(name, "ddraw") || !strcasecmp(name, "sdl")) return(1); for (i = 0; i < RENDERERS_NUM; i++) { - if (vid_apis[0][i].name && - !strcasecmp(vid_apis[0][i].name, name)) return(i); + if (vid_apis[i].name && + !strcasecmp(vid_apis[i].name, name)) return(i); } /* Default value. */ @@ -730,16 +721,16 @@ plat_setvid(int api) video_wait_for_blit(); /* Close the (old) API. */ - vid_apis[0][vid_api].close(); + vid_apis[vid_api].close(); vid_api = api; - if (vid_apis[0][vid_api].local) + if (vid_apis[vid_api].local) ShowWindow(hwndRender, SW_SHOW); else ShowWindow(hwndRender, SW_HIDE); /* Initialize the (new) API. */ - i = vid_apis[0][vid_api].init((void *)hwndRender); + i = vid_apis[vid_api].init((void *)hwndRender); endblit(); if (! i) return(0); @@ -755,11 +746,11 @@ plat_setvid(int api) void plat_vidsize(int x, int y) { - if (!vid_api_inited || !vid_apis[video_fullscreen][vid_api].resize) return; + if (!vid_api_inited || !vid_apis[vid_api].resize) return; startblit(); video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(x, y); + vid_apis[vid_api].resize(x, y); endblit(); } @@ -769,66 +760,61 @@ plat_vidapi_enable(int enable) { int i = 1; - if (!vid_api_inited || !vid_apis[video_fullscreen][vid_api].enable) return; + if (!vid_api_inited || !vid_apis[vid_api].enable) + return; - startblit(); video_wait_for_blit(); + vid_apis[vid_api].enable(enable != 0); - vid_apis[video_fullscreen][vid_api].enable(enable & 1); + if (! i) + return; - endblit(); - - if (! i) return; - - if (enable) + if (enable) device_force_redraw(); } + int get_vidpause(void) { - return(vid_apis[video_fullscreen][vid_api].pause()); + return(vid_apis[vid_api].pause()); } void plat_setfullscreen(int on) { - HWND *hw; - - /* Want off and already off? */ - if (!on && !video_fullscreen) return; - - /* Want on and already on? */ - if (on && video_fullscreen) return; + /* Are we changing from the same state to the same state? */ + if ((!!on) == (!!video_fullscreen)) + return; if (on && video_fullscreen_first) { + video_fullscreen |= 2; if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2134, (wchar_t *) IDS_2052) == 10) { video_fullscreen_first = 0; config_save(); } + video_fullscreen &= 1; } /* OK, claim the video. */ - startblit(); video_wait_for_blit(); - - plat_vidapi_enable(0); - win_mouse_close(); /* Close the current mode, and open the new one. */ - vid_apis[video_fullscreen][vid_api].close(); - video_fullscreen = on; - hw = (video_fullscreen) ? &hwndMain : &hwndRender; - vid_apis[video_fullscreen][vid_api].init((void *) *hw); + video_fullscreen = on | 2; + if (vid_apis[vid_api].set_fs) + vid_apis[vid_api].set_fs(on); + if (!on) + plat_resize(scrnsz_x, scrnsz_y); + video_fullscreen &= 1; + video_force_resize_set(1); + if (!on) + doresize = 1; win_mouse_init(); - plat_vidapi_enable(1); - /* Release video and make it redraw the screen. */ - endblit(); device_force_redraw(); /* Send a CTRL break code so CTRL does not get stuck. */ @@ -837,6 +823,10 @@ plat_setfullscreen(int on) /* Finally, handle the host's mouse cursor. */ /* win_log("%s full screen, %s cursor\n", on ? "enter" : "leave", on ? "hide" : "show"); */ show_cursor(video_fullscreen ? 0 : -1); + + /* This is needed for OpenGL. */ + plat_vidapi_enable(0); + plat_vidapi_enable(1); } diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index db12f2cc8..7e29d6381 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -82,7 +82,6 @@ static SDL_Window *sdl_win = NULL; static SDL_Renderer *sdl_render = NULL; static SDL_Texture *sdl_tex = NULL; static HWND sdl_parent_hwnd = NULL; -static HWND sdl_hwnd = NULL; static int sdl_w, sdl_h; static int sdl_fs, sdl_flags = -1; static int cur_w, cur_h; @@ -181,6 +180,7 @@ sdl_stretch(int *w, int *h, int *x, int *y) switch (video_fullscreen_scale) { case FULLSCR_SCALE_FULL: + default: *w = sdl_w; *h = sdl_h; *x = 0; @@ -225,8 +225,6 @@ sdl_stretch(int *w, int *h, int *x, int *y) *y = (int) dy; break; } - - sdl_reinit_texture(); } @@ -236,17 +234,7 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) SDL_Rect r_src; int ret; - if (!sdl_enabled) { - video_blit_complete(); - return; - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; - } - - if (render_buffer == NULL) { + if (!sdl_enabled || (y1 == y2) || (h <= 0) || (render_buffer == NULL)) { video_blit_complete(); return; } @@ -260,13 +248,6 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) SDL_UpdateTexture(sdl_tex, &r_src, &(render_buffer->dat)[y1 * w], w * 4); video_blit_complete(); - if (sdl_fs) { - sdl_log("sdl_blit(%i, %i, %i, %i, %i, %i) (%i, %i)\n", x, y, y1, y2, w, h, unscaled_size_x, efscrnsz_y); - if (w == unscaled_size_x) - sdl_resize(w, h); - sdl_log("(%08X, %08X, %08X)\n", sdl_win, sdl_render, sdl_tex); - } - SDL_RenderClear(sdl_render); r_src.x = 0; @@ -279,11 +260,31 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError()); SDL_RenderPresent(sdl_render); - SDL_UnlockMutex(sdl_mutex); } +static void +sdl_destroy_window(void) +{ + if (sdl_win != NULL) { + SDL_DestroyWindow(sdl_win); + sdl_win = NULL; + } +} + + +static void +sdl_destroy_texture(void) +{ + /* SDL_DestroyRenderer also automatically destroys all associated textures. */ + if (sdl_render != NULL) { + SDL_DestroyRenderer(sdl_render); + sdl_render = NULL; + } +} + + void sdl_close(void) { @@ -300,32 +301,10 @@ sdl_close(void) sdl_mutex = NULL; } - if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; - } - - if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; - } - - if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; - } - - if (sdl_hwnd != NULL) { - plat_set_input(hwndMain); - - ShowWindow(hwndRender, TRUE); - - SetFocus(hwndMain); - - if (sdl_fs) - DestroyWindow(sdl_hwnd); - sdl_hwnd = NULL; - } + sdl_destroy_texture(); + sdl_destroy_window(); + ImmAssociateContext(hwndMain, NULL); + SetFocus(hwndMain); if (sdl_parent_hwnd != NULL) { DestroyWindow(sdl_parent_hwnd); @@ -334,7 +313,6 @@ sdl_close(void) /* Quit. */ SDL_Quit(); - sdl_flags = -1; } @@ -359,13 +337,87 @@ sdl_select_best_hw_driver(void) } +static void +sdl_reinit_texture(void) +{ + if (sdl_flags == -1) + return; + + sdl_destroy_texture(); + + if (sdl_flags & RENDERER_HARDWARE) { + sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); + } else + sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); + + sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, 2048, 2048); +} + + +void +sdl_set_fs(int fs) +{ + int w = 0, h = 0, x = 0, y = 0; + RECT rect; + + SDL_LockMutex(sdl_mutex); + sdl_enabled = 0; + sdl_destroy_texture(); + + if (fs) { + ShowWindow(sdl_parent_hwnd, TRUE); + SetParent(hwndRender, sdl_parent_hwnd); + ShowWindow(hwndRender, TRUE); + MoveWindow(sdl_parent_hwnd, 0, 0, sdl_w, sdl_h, TRUE); + + /* Show the window, make it topmost, and give it focus. */ + w = unscaled_size_x; + h = efscrnsz_y; + sdl_stretch(&w, &h, &x, &y); + MoveWindow(hwndRender, x, y, w, h, TRUE); + ImmAssociateContext(sdl_parent_hwnd, NULL); + SetFocus(sdl_parent_hwnd); + + /* Redirect RawInput to this new window. */ + old_capture = mouse_capture; + GetWindowRect(hwndRender, &rect); + ClipCursor(&rect); + mouse_capture = 1; + } else { + SetParent(hwndRender, hwndMain); + ShowWindow(sdl_parent_hwnd, FALSE); + ShowWindow(hwndRender, TRUE); + ImmAssociateContext(hwndMain, NULL); + SetFocus(hwndMain); + mouse_capture = old_capture; + + if (mouse_capture) { + GetWindowRect(hwndRender, &rect); + ClipCursor(&rect); + } else + ClipCursor(&oldclip); + } + + sdl_fs = fs; + + if (fs) + sdl_flags |= RENDERER_FULL_SCREEN; + else + sdl_flags &= ~RENDERER_FULL_SCREEN; + + sdl_reinit_texture(); + sdl_enabled = 1; + SDL_UnlockMutex(sdl_mutex); +} + + static int sdl_init_common(int flags) { wchar_t temp[128]; SDL_version ver; - int w = 0, h = 0, x = 0, y = 0; - RECT rect; sdl_log("SDL: init (fs=%d)\n", fs); @@ -386,111 +438,24 @@ sdl_init_common(int flags) sdl_select_best_hw_driver(); } - if (flags & RENDERER_FULL_SCREEN) { - /* Get the size of the (current) desktop. */ - sdl_w = GetSystemMetrics(SM_CXSCREEN); - sdl_h = GetSystemMetrics(SM_CYSCREEN); + /* Get the size of the (current) desktop. */ + sdl_w = GetSystemMetrics(SM_CXSCREEN); + sdl_h = GetSystemMetrics(SM_CYSCREEN); - /* Create the desktop-covering window. */ - _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); - sdl_parent_hwnd = CreateWindow(SUB_CLASS_NAME, - temp, - WS_POPUP, - 0, 0, sdl_w, sdl_h, - HWND_DESKTOP, - NULL, - hinstance, - NULL); + /* Create the desktop-covering window. */ + _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); + sdl_parent_hwnd = CreateWindow(SDL_CLASS_NAME, temp, WS_POPUP, 0, 0, sdl_w, sdl_h, + HWND_DESKTOP, NULL, hinstance, NULL); + ShowWindow(sdl_parent_hwnd, FALSE); - SetWindowPos(sdl_parent_hwnd, HWND_TOPMOST, - 0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW); + sdl_flags = flags; - /* Create the actual rendering window. */ - _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); - sdl_hwnd = CreateWindow(SUB_CLASS_NAME, - temp, - WS_POPUP, - 0, 0, sdl_w, sdl_h, - sdl_parent_hwnd, - NULL, - hinstance, - NULL); - sdl_log("SDL: FS %dx%d window at %08lx\n", sdl_w, sdl_h, sdl_hwnd); - - /* Redirect RawInput to this new window. */ - plat_set_input(sdl_hwnd); - - SetFocus(sdl_hwnd); - - /* Show the window, make it topmost, and give it focus. */ - w = unscaled_size_x; - h = efscrnsz_y; - sdl_stretch(&w, &h, &x, &y); - SetWindowPos(sdl_hwnd, sdl_parent_hwnd, - x, y, w, h, SWP_SHOWWINDOW); - - /* Now create the SDL window from that. */ - sdl_win = SDL_CreateWindowFrom((void *)sdl_hwnd); - - old_capture = mouse_capture; - - GetWindowRect(sdl_hwnd, &rect); - - ClipCursor(&rect); - - mouse_capture = 1; - } else { - /* Create the SDL window from the render window. */ - sdl_win = SDL_CreateWindowFrom((void *)hwndRender); - - mouse_capture = old_capture; - - if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - - ClipCursor(&rect); - } else { - ClipCursor(&oldclip); - } - } if (sdl_win == NULL) { sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError()); - sdl_close(); - return(0); } - /* - * TODO: - * SDL_RENDERER_SOFTWARE, because SDL tries to do funky stuff - * otherwise (it turns off Win7 Aero and it looks like it's - * trying to switch to fullscreen even though the window is - * not a fullscreen window?) - */ - if (flags & RENDERER_HARDWARE) { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); - } else - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); - - if (sdl_render == NULL) { - sdl_log("SDL: unable to create renderer (%s)\n", SDL_GetError()); - sdl_close(); - return(0); - } - - /* - * TODO: - * Actually the source is (apparently) XRGB8888, but the alpha - * channel seems to be set to 255 everywhere, so ARGB8888 works - * just as well. - */ - sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); - if (sdl_tex == NULL) { - sdl_log("SDL: unable to create texture (%s)\n", SDL_GetError()); - sdl_close(); - return(0); - } + sdl_win = SDL_CreateWindowFrom((void *)hwndRender); + sdl_set_fs(video_fullscreen & 1); /* Make sure we get a clean exit. */ atexit(sdl_close); @@ -498,14 +463,9 @@ sdl_init_common(int flags) /* Register our renderer! */ video_setblit(sdl_blit); - sdl_fs = !!(flags & RENDERER_FULL_SCREEN); - sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); - sdl_flags = flags; - return(1); } @@ -531,47 +491,6 @@ sdl_initho(HWND h) } -int -sdl_inits_fs(HWND h) -{ - return sdl_init_common(RENDERER_FULL_SCREEN); -} - - -int -sdl_inith_fs(HWND h) -{ - return sdl_init_common(RENDERER_FULL_SCREEN | RENDERER_HARDWARE); -} - - -int -sdl_initho_fs(HWND h) -{ - return sdl_init_common(RENDERER_FULL_SCREEN | RENDERER_HARDWARE | RENDERER_OPENGL); -} - - -void -sdl_reinit_texture() -{ - if ((sdl_render == NULL) || (sdl_flags == -1)) - return; - - SDL_DestroyTexture(sdl_tex); - SDL_DestroyRenderer(sdl_render); - if (sdl_flags & RENDERER_HARDWARE) { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); - } else - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); - sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy); -} - - int sdl_pause(void) { @@ -584,6 +503,9 @@ sdl_resize(int x, int y) { int ww = 0, wh = 0, wx = 0, wy = 0; + if (video_fullscreen & 2) + return; + if ((x == cur_w) && (y == cur_h)) return; @@ -594,7 +516,7 @@ sdl_resize(int x, int y) if (sdl_fs) { sdl_stretch(&ww, &wh, &wx, &wy); - MoveWindow(sdl_hwnd, wx, wy, ww, wh, TRUE); + MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); } cur_w = x; @@ -605,6 +527,9 @@ sdl_resize(int x, int y) cur_ww = ww; cur_wh = wh; + SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); + SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy); + sdl_reinit_texture(); SDL_UnlockMutex(sdl_mutex); @@ -619,7 +544,11 @@ sdl_enable(int enable) SDL_LockMutex(sdl_mutex); sdl_enabled = enable; - if (enable) + + if (enable == 1) { + SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); sdl_reinit_texture(); + } + SDL_UnlockMutex(sdl_mutex); } diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 5dd4026c5..f4cf7047f 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -28,6 +28,7 @@ #include #include #include +#include <86box/plat.h> #include <86box/86box.h> #include <86box/config.h> #include "../cpu/cpu.h" @@ -38,7 +39,6 @@ #include <86box/nvr.h> #include <86box/video.h> #include <86box/vid_ega.h> // for update_overscan -#include <86box/plat.h> #include <86box/plat_midi.h> #include <86box/plat_dynld.h> #include <86box/ui.h> @@ -373,6 +373,85 @@ plat_power_off(void) } +/* Catch WM_INPUT messages for 'current focus' window. */ +#if defined(__amd64__) || defined(__aarch64__) +static LRESULT CALLBACK +#else +static BOOL CALLBACK +#endif +input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_INPUT: + if (infocus) { + UINT size = 0; + PRAWINPUT raw = NULL; + + /* Here we read the raw input data */ + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + raw = (PRAWINPUT)malloc(size); + if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { + switch(raw->header.dwType) + { + case RIM_TYPEKEYBOARD: + keyboard_handle(raw); + break; + case RIM_TYPEMOUSE: + win_mouse_handle(raw); + break; + case RIM_TYPEHID: + win_joystick_handle(raw); + break; + } + } + free(raw); + } + break; + case WM_SETFOCUS: + infocus = 1; +#ifndef NO_KEYBOARD_HOOK + if (! hook_enabled) { + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, + LowLevelKeyboardProc, + GetModuleHandle(NULL), + 0); + hook_enabled = 1; + } +#endif + break; + + case WM_KILLFOCUS: + infocus = 0; + plat_mouse_capture(0); +#ifndef NO_KEYBOARD_HOOK + if (hook_enabled) { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } +#endif + break; + + case WM_LBUTTONUP: + pclog("video_fullscreen = %i\n", video_fullscreen); + if (! video_fullscreen) + plat_mouse_capture(1); + break; + + case WM_MBUTTONUP: + if (mouse_get_buttons() < 3) + plat_mouse_capture(0); + break; + + default: + return(1); + /* return(CallWindowProc((WNDPROC)input_orig_proc, + hwnd, message, wParam, lParam)); */ + } + + return(0); +} + + static LRESULT CALLBACK MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -383,6 +462,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) int temp_x, temp_y; + if (input_proc(hwnd, message, wParam, lParam) == 0) + return(0); + switch (message) { case WM_CREATE: SetTimer(hwnd, TIMER_1SEC, 1000, NULL); @@ -571,6 +653,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) CheckMenuItem(hmenu, IDM_VID_SCALE_1X+scale, MF_UNCHECKED); scale = LOWORD(wParam) - IDM_VID_SCALE_1X; CheckMenuItem(hmenu, IDM_VID_SCALE_1X+scale, MF_CHECKED); + reset_screen_size(); device_force_redraw(); video_force_resize_set(1); config_save(); @@ -716,11 +799,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GetWindowRect(hwndSBAR, &rect); sbar_height = rect.bottom - rect.top; rect_p = (RECT*)lParam; - if (vid_resize) { + if (vid_resize) MoveWindow(hwnd, rect_p->left, rect_p->top, rect_p->right - rect_p->left, rect_p->bottom - rect_p->top, TRUE); - } else if (!user_resize) { + else if (!user_resize) doresize = 1; - } break; case WM_SIZE: @@ -773,6 +855,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } plat_vidapi_enable(1); + plat_vidapi_enable(0); + plat_vidapi_enable(1); + config_save(); break; @@ -939,7 +1024,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_ACTIVATE: - if (wParam != WA_INACTIVE) { + if ((wParam != WA_INACTIVE) && !(video_fullscreen & 2)) { video_force_resize_set(1); plat_vidapi_enable(0); plat_vidapi_enable(1); @@ -966,6 +1051,38 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK SubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_LBUTTONUP: + if (! video_fullscreen) + plat_mouse_capture(1); + break; + + case WM_MBUTTONUP: + if (mouse_get_buttons() < 3) + plat_mouse_capture(0); + break; + + default: + return(DefWindowProc(hwnd, message, wParam, lParam)); + } + + return(0); +} + + +static LRESULT CALLBACK +SDLMainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (input_proc(hwnd, message, wParam, lParam) == 0) + return(0); + + return(DefWindowProc(hwnd, message, wParam, lParam)); +} + + +static LRESULT CALLBACK +SDLSubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { return(DefWindowProc(hwnd, message, wParam, lParam)); } @@ -1056,6 +1173,14 @@ ui_init(int nCmdShow) return(2); wincl.lpszClassName = SUB_CLASS_NAME; wincl.lpfnWndProc = SubWindowProcedure; + if (! RegisterClassEx(&wincl)) + return(2); + wincl.lpszClassName = SDL_CLASS_NAME; + wincl.lpfnWndProc = SDLMainWindowProcedure; + if (! RegisterClassEx(&wincl)) + return(2); + wincl.lpszClassName = SDL_SUB_CLASS_NAME; + wincl.lpfnWndProc = SDLSubWindowProcedure; if (! RegisterClassEx(&wincl)) return(2); @@ -1128,9 +1253,6 @@ ui_init(int nCmdShow) } keyboard_getkeymap(); - /* Set up the main window for RawInput. */ - plat_set_input(hwndMain); - /* Load the accelerator table */ haccel = LoadAccelerators(hinstance, ACCEL_NAME); if (haccel == NULL) { @@ -1149,7 +1271,7 @@ ui_init(int nCmdShow) ghMutex = CreateMutex(NULL, FALSE, NULL); /* Create the Machine Rendering window. */ - hwndRender = CreateWindow(L"STATIC", NULL, WS_CHILD|SS_BITMAP, + hwndRender = CreateWindow(/*L"STATIC"*/ SUB_CLASS_NAME, NULL, WS_CHILD|SS_BITMAP, 0, 0, 1, 1, hwnd, NULL, hinstance, NULL); MoveWindow(hwndRender, 0, 0, scrnsz_x, scrnsz_y, TRUE); @@ -1241,6 +1363,8 @@ ui_init(int nCmdShow) /* Close down the emulator. */ do_stop(); + UnregisterClass(SDL_SUB_CLASS_NAME, hinstance); + UnregisterClass(SDL_CLASS_NAME, hinstance); UnregisterClass(SUB_CLASS_NAME, hinstance); UnregisterClass(CLASS_NAME, hinstance); @@ -1384,100 +1508,3 @@ plat_mouse_capture(int on) mouse_capture = 0; } } - - -/* Catch WM_INPUT messages for 'current focus' window. */ -static LONG_PTR input_orig_proc; -static HWND input_orig_hwnd = NULL; -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_INPUT: - if (infocus) { - UINT size = 0; - PRAWINPUT raw = NULL; - - /* Here we read the raw input data */ - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - raw = (PRAWINPUT)malloc(size); - if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { - switch(raw->header.dwType) - { - case RIM_TYPEKEYBOARD: - keyboard_handle(raw); - break; - case RIM_TYPEMOUSE: - win_mouse_handle(raw); - break; - case RIM_TYPEHID: - win_joystick_handle(raw); - break; - } - } - free(raw); - } - break; - case WM_SETFOCUS: - infocus = 1; -#ifndef NO_KEYBOARD_HOOK - if (! hook_enabled) { - hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, - LowLevelKeyboardProc, - GetModuleHandle(NULL), - 0); - hook_enabled = 1; - } -#endif - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); -#ifndef NO_KEYBOARD_HOOK - if (hook_enabled) { - UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } -#endif - break; - - case WM_LBUTTONUP: - if (! video_fullscreen) - plat_mouse_capture(1); - break; - - case WM_MBUTTONUP: - if (mouse_get_buttons() < 3) - plat_mouse_capture(0); - break; - - default: - return(CallWindowProc((WNDPROC)input_orig_proc, - hwnd, message, wParam, lParam)); - } - - return(0); -} - - -/* Set up a handler for the 'currently active' window. */ -void -plat_set_input(HWND h) -{ - /* If needed, rest the old one first. */ - if (input_orig_hwnd != NULL) { - SetWindowLongPtr(input_orig_hwnd, GWLP_WNDPROC, - (LONG_PTR)input_orig_proc); - } - - /* Redirect the window procedure so we can catch WM_INPUT. */ - input_orig_proc = GetWindowLongPtr(h, GWLP_WNDPROC); - input_orig_hwnd = h; - SetWindowLongPtr(h, GWLP_WNDPROC, (LONG_PTR)&input_proc); - ImmAssociateContext(h, NULL); -}