Renderer fixes and improvements.
This commit is contained in:
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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: */
|
||||
|
@@ -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*/
|
||||
|
7
src/pc.c
7
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)
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
239
src/win/win_ui.c
239
src/win/win_ui.c
@@ -28,6 +28,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user