101 |
|
static uint32 the_buffer_size; // Size of allocated the_buffer |
102 |
|
|
103 |
|
static bool redraw_thread_active = false; // Flag: Redraw thread installed |
104 |
+ |
#ifndef USE_CPU_EMUL_SERVICES |
105 |
|
static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread |
106 |
|
static SDL_Thread *redraw_thread = NULL; // Redraw thread |
107 |
+ |
#ifdef SHEEPSHAVER |
108 |
|
static volatile bool thread_stop_req = false; |
109 |
|
static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req |
110 |
+ |
#endif |
111 |
+ |
#endif |
112 |
|
|
113 |
|
#ifdef ENABLE_VOSF |
114 |
|
static bool use_vosf = false; // Flag: VOSF enabled |
135 |
|
static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors |
136 |
|
static const int sdl_eventmask = SDL_MOUSEBUTTONDOWNMASK | SDL_MOUSEBUTTONUPMASK | SDL_MOUSEMOTIONMASK | SDL_KEYUPMASK | SDL_KEYDOWNMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK; |
137 |
|
|
138 |
+ |
// Mutex to protect SDL events |
139 |
+ |
static SDL_mutex *sdl_events_lock = NULL; |
140 |
+ |
#define LOCK_EVENTS SDL_LockMutex(sdl_events_lock) |
141 |
+ |
#define UNLOCK_EVENTS SDL_UnlockMutex(sdl_events_lock) |
142 |
+ |
|
143 |
|
// Mutex to protect palette |
144 |
|
static SDL_mutex *sdl_palette_lock = NULL; |
145 |
|
#define LOCK_PALETTE SDL_LockMutex(sdl_palette_lock) |
163 |
|
|
164 |
|
|
165 |
|
/* |
166 |
+ |
* SDL surface locking glue |
167 |
+ |
*/ |
168 |
+ |
|
169 |
+ |
#ifdef ENABLE_VOSF |
170 |
+ |
#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ |
171 |
+ |
if ((SURFACE)->flags & (SDL_HWSURFACE | SDL_FULLSCREEN)) \ |
172 |
+ |
the_host_buffer = (uint8 *)(SURFACE)->pixels; \ |
173 |
+ |
} while (0) |
174 |
+ |
#else |
175 |
+ |
#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) |
176 |
+ |
#endif |
177 |
+ |
|
178 |
+ |
#define SDL_VIDEO_LOCK_SURFACE(SURFACE) do { \ |
179 |
+ |
if (SDL_MUSTLOCK(SURFACE)) { \ |
180 |
+ |
SDL_LockSurface(SURFACE); \ |
181 |
+ |
SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE); \ |
182 |
+ |
} \ |
183 |
+ |
} while (0) |
184 |
+ |
|
185 |
+ |
#define SDL_VIDEO_UNLOCK_SURFACE(SURFACE) do { \ |
186 |
+ |
if (SDL_MUSTLOCK(SURFACE)) \ |
187 |
+ |
SDL_UnlockSurface(SURFACE); \ |
188 |
+ |
} while (0) |
189 |
+ |
|
190 |
+ |
|
191 |
+ |
/* |
192 |
|
* Framebuffer allocation routines |
193 |
|
*/ |
194 |
|
|
195 |
|
static void *vm_acquire_framebuffer(uint32 size) |
196 |
|
{ |
162 |
– |
#ifdef SHEEPSHAVER |
163 |
– |
#ifdef DIRECT_ADDRESSING_HACK |
164 |
– |
const uint32 FRAME_BUFFER_BASE = 0x61000000; |
165 |
– |
uint8 *fb = Mac2HostAddr(FRAME_BUFFER_BASE); |
166 |
– |
if (vm_acquire_fixed(fb, size) < 0) |
167 |
– |
fb = VM_MAP_FAILED; |
168 |
– |
return fb; |
169 |
– |
#endif |
170 |
– |
#endif |
197 |
|
return vm_acquire(size); |
198 |
|
} |
199 |
|
|
204 |
|
|
205 |
|
|
206 |
|
/* |
207 |
+ |
* Windows message handler |
208 |
+ |
*/ |
209 |
+ |
|
210 |
+ |
#ifdef WIN32 |
211 |
+ |
#include <dbt.h> |
212 |
+ |
static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL |
213 |
+ |
|
214 |
+ |
extern void SysMediaArrived(void); |
215 |
+ |
extern void SysMediaRemoved(void); |
216 |
+ |
extern HWND GetMainWindowHandle(void); |
217 |
+ |
|
218 |
+ |
static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) |
219 |
+ |
{ |
220 |
+ |
switch (msg) { |
221 |
+ |
case WM_DEVICECHANGE: |
222 |
+ |
if (wParam == DBT_DEVICEREMOVECOMPLETE) { |
223 |
+ |
DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; |
224 |
+ |
if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) |
225 |
+ |
SysMediaRemoved(); |
226 |
+ |
} |
227 |
+ |
else if (wParam == DBT_DEVICEARRIVAL) { |
228 |
+ |
DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; |
229 |
+ |
if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) |
230 |
+ |
SysMediaArrived(); |
231 |
+ |
} |
232 |
+ |
return 0; |
233 |
+ |
|
234 |
+ |
default: |
235 |
+ |
if (sdl_window_proc) |
236 |
+ |
return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); |
237 |
+ |
} |
238 |
+ |
|
239 |
+ |
return DefWindowProc(hwnd, msg, wParam, lParam); |
240 |
+ |
} |
241 |
+ |
#endif |
242 |
+ |
|
243 |
+ |
|
244 |
+ |
/* |
245 |
|
* SheepShaver glue |
246 |
|
*/ |
247 |
|
|
1063 |
|
return false; |
1064 |
|
} |
1065 |
|
|
1066 |
+ |
#ifdef WIN32 |
1067 |
+ |
// Chain in a new message handler for WM_DEVICECHANGE |
1068 |
+ |
HWND the_window = GetMainWindowHandle(); |
1069 |
+ |
sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); |
1070 |
+ |
SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); |
1071 |
+ |
#endif |
1072 |
+ |
|
1073 |
|
// Initialize VideoRefresh function |
1074 |
|
VideoRefreshInit(); |
1075 |
|
|
1077 |
|
LOCK_FRAME_BUFFER; |
1078 |
|
|
1079 |
|
// Start redraw/input thread |
1080 |
+ |
#ifndef USE_CPU_EMUL_SERVICES |
1081 |
|
redraw_thread_cancel = false; |
1082 |
|
redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, NULL)) != NULL); |
1083 |
|
if (!redraw_thread_active) { |
1084 |
|
printf("FATAL: cannot create redraw thread\n"); |
1085 |
|
return false; |
1086 |
|
} |
1087 |
+ |
#else |
1088 |
+ |
redraw_thread_active = true; |
1089 |
+ |
#endif |
1090 |
|
return true; |
1091 |
|
} |
1092 |
|
|
1107 |
|
#endif |
1108 |
|
|
1109 |
|
// Create Mutexes |
1110 |
+ |
if ((sdl_events_lock = SDL_CreateMutex()) == NULL) |
1111 |
+ |
return false; |
1112 |
|
if ((sdl_palette_lock = SDL_CreateMutex()) == NULL) |
1113 |
|
return false; |
1114 |
|
if ((frame_buffer_lock = SDL_CreateMutex()) == NULL) |
1304 |
|
{ |
1305 |
|
D(bug("video_close()\n")); |
1306 |
|
|
1307 |
+ |
#ifdef WIN32 |
1308 |
+ |
// Remove message handler for WM_DEVICECHANGE |
1309 |
+ |
HWND the_window = GetMainWindowHandle(); |
1310 |
+ |
SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); |
1311 |
+ |
#endif |
1312 |
+ |
|
1313 |
|
// Stop redraw thread |
1314 |
+ |
#ifndef USE_CPU_EMUL_SERVICES |
1315 |
|
if (redraw_thread_active) { |
1316 |
|
redraw_thread_cancel = true; |
1317 |
|
SDL_WaitThread(redraw_thread, NULL); |
1318 |
|
} |
1319 |
+ |
#endif |
1320 |
|
redraw_thread_active = false; |
1321 |
|
|
1322 |
|
// Unlock frame buffer |
1340 |
|
SDL_DestroyMutex(frame_buffer_lock); |
1341 |
|
if (sdl_palette_lock) |
1342 |
|
SDL_DestroyMutex(sdl_palette_lock); |
1343 |
+ |
if (sdl_events_lock) |
1344 |
+ |
SDL_DestroyMutex(sdl_events_lock); |
1345 |
|
} |
1346 |
|
|
1347 |
|
|
1511 |
|
void SDL_monitor_desc::switch_to_current_mode(void) |
1512 |
|
{ |
1513 |
|
// Close and reopen display |
1514 |
+ |
LOCK_EVENTS; |
1515 |
|
video_close(); |
1516 |
|
video_open(); |
1517 |
+ |
UNLOCK_EVENTS; |
1518 |
|
|
1519 |
|
if (drv == NULL) { |
1520 |
|
ErrorAlert(STR_OPEN_WINDOW_ERR); |
2124 |
|
} |
2125 |
|
} |
2126 |
|
|
2127 |
+ |
static inline void do_video_refresh(void) |
2128 |
+ |
{ |
2129 |
+ |
// Handle SDL events |
2130 |
+ |
handle_events(); |
2131 |
+ |
|
2132 |
+ |
// Update display |
2133 |
+ |
video_refresh(); |
2134 |
+ |
|
2135 |
+ |
#ifdef SHEEPSHAVER |
2136 |
+ |
// Set new cursor image if it was changed |
2137 |
+ |
if (cursor_changed && sdl_cursor) { |
2138 |
+ |
cursor_changed = false; |
2139 |
+ |
LOCK_EVENTS; |
2140 |
+ |
SDL_FreeCursor(sdl_cursor); |
2141 |
+ |
sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); |
2142 |
+ |
if (sdl_cursor) |
2143 |
+ |
SDL_SetCursor(sdl_cursor); |
2144 |
+ |
UNLOCK_EVENTS; |
2145 |
+ |
} |
2146 |
+ |
#endif |
2147 |
+ |
|
2148 |
+ |
// Set new palette if it was changed |
2149 |
+ |
handle_palette_changes(); |
2150 |
+ |
} |
2151 |
+ |
|
2152 |
+ |
// This function is called on non-threaded platforms from a timer interrupt |
2153 |
+ |
void VideoRefresh(void) |
2154 |
+ |
{ |
2155 |
+ |
// We need to check redraw_thread_active to inhibit refreshed during |
2156 |
+ |
// mode changes on non-threaded platforms |
2157 |
+ |
if (!redraw_thread_active) |
2158 |
+ |
return; |
2159 |
+ |
|
2160 |
+ |
// Process pending events and update display |
2161 |
+ |
do_video_refresh(); |
2162 |
+ |
} |
2163 |
+ |
|
2164 |
|
const int VIDEO_REFRESH_HZ = 60; |
2165 |
|
const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; |
2166 |
|
|
2167 |
+ |
#ifndef USE_CPU_EMUL_SERVICES |
2168 |
|
static int redraw_func(void *arg) |
2169 |
|
{ |
2170 |
|
uint64 start = GetTicks_usec(); |
2190 |
|
} |
2191 |
|
#endif |
2192 |
|
|
2193 |
< |
// Handle SDL events |
2194 |
< |
handle_events(); |
2068 |
< |
|
2069 |
< |
// Refresh display |
2070 |
< |
video_refresh(); |
2071 |
< |
|
2072 |
< |
#ifdef SHEEPSHAVER |
2073 |
< |
// Set new cursor image if it was changed |
2074 |
< |
if (cursor_changed && sdl_cursor) { |
2075 |
< |
cursor_changed = false; |
2076 |
< |
SDL_FreeCursor(sdl_cursor); |
2077 |
< |
sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); |
2078 |
< |
if (sdl_cursor) |
2079 |
< |
SDL_SetCursor(sdl_cursor); |
2080 |
< |
} |
2081 |
< |
#endif |
2082 |
< |
|
2083 |
< |
// Set new palette if it was changed |
2084 |
< |
handle_palette_changes(); |
2193 |
> |
// Process pending events and update display |
2194 |
> |
do_video_refresh(); |
2195 |
|
} |
2196 |
|
|
2197 |
|
uint64 end = GetTicks_usec(); |
2198 |
|
D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); |
2199 |
|
return 0; |
2200 |
|
} |
2201 |
+ |
#endif |