--- BasiliskII/src/SDL/video_sdl.cpp 2006/05/13 16:58:44 1.26 +++ BasiliskII/src/SDL/video_sdl.cpp 2007/01/21 19:33:13 1.30 @@ -27,16 +27,15 @@ * Ctrl-F5 = grab mouse (in windowed mode) * * FIXMEs and TODOs: + * - Windows requires an extra mouse event to update the actual cursor image? * - Ctr-Tab for suspend/resume but how? SDL does not support that for non-Linux * - Ctrl-Fn doesn't generate SDL_KEYDOWN events (SDL bug?) * - Mouse acceleration, there is no API in SDL yet for that * - Force relative mode in Grab mode even if SDL provides absolute coordinates? - * - Fullscreen mode * - Gamma tables support is likely to be broken here * - Events processing is bound to the general emulation thread as SDL requires * to PumpEvents() within the same thread as the one that called SetVideoMode(). * Besides, there can't seem to be a way to call SetVideoMode() from a child thread. - * - Refresh performance is still slow. Use SDL_CreateRGBSurface()? * - Backport hw cursor acceleration to Basilisk II? * - Factor out code */ @@ -49,6 +48,10 @@ #include #include +#ifdef WIN32 +#include /* alloca() */ +#endif + #include "cpu_emulation.h" #include "main.h" #include "adb.h" @@ -716,6 +719,8 @@ void driver_base::restore_mouse_accel(vo * Windowed display driver */ +static int SDL_display_opened = FALSE; + // Open display driver_window::driver_window(SDL_monitor_desc &m) : driver_base(m), mouse_grabbed(false) @@ -727,11 +732,23 @@ driver_window::driver_window(SDL_monitor // Set absolute mouse mode ADBSetRelMouseMode(mouse_grabbed); + // This is ugly: + // If we're switching resolutions (ie, not setting it for the first time), + // there's a bug in SDL where the SDL_Surface created will not be properly + // setup. The solution is to SDL_Quit() before calling SDL_SetVideoMode for + // the second time (SDL_SetVideoMode will call SDL_Init() and all will be + // well). Without this, the video becomes corrupted (at least on Mac OS X), + // after the resolution switch (for the second and subsequent times). + if (SDL_display_opened) + SDL_Quit(); + // Create surface int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); if ((s = SDL_SetVideoMode(width, height, depth, SDL_HWSURFACE)) == NULL) return; + SDL_display_opened = TRUE; + #ifdef ENABLE_VOSF use_vosf = true; // Allocate memory for frame buffer (SIZE is extended to page-boundary) @@ -2186,8 +2203,19 @@ static inline void do_video_refresh(void LOCK_EVENTS; SDL_FreeCursor(sdl_cursor); sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); - if (sdl_cursor) + if (sdl_cursor) { SDL_SetCursor(sdl_cursor); +#ifdef WIN32 + // XXX Windows apparently needs an extra mouse event to + // make the new cursor image visible + int visible = SDL_ShowCursor(-1); + if (visible) { + int x, y; + SDL_GetMouseState(&x, &y); + SDL_WarpMouse(x, y); + } +#endif + } UNLOCK_EVENTS; } #endif @@ -2262,7 +2290,7 @@ void video_set_dirty_area(int x, int y, #ifdef ENABLE_VOSF if (use_vosf) { - vosf_set_dirty_area(x, y, w, h, screen_width, bytes_per_row); + vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); return; } #endif