35 |
|
* - Events processing is bound to the general emulation thread as SDL requires |
36 |
|
* to PumpEvents() within the same thread as the one that called SetVideoMode(). |
37 |
|
* Besides, there can't seem to be a way to call SetVideoMode() from a child thread. |
38 |
+ |
* - Refresh performance is still slow. Use SDL_CreateRGBSurface()? |
39 |
+ |
* - Backport hw cursor acceleration to Basilisk II? |
40 |
+ |
* - Move generic Native QuickDraw acceleration routines to gfxaccel.cpp |
41 |
|
*/ |
42 |
|
|
43 |
|
#include "sysdeps.h" |
99 |
|
static SDL_Thread *redraw_thread = NULL; // Redraw thread |
100 |
|
|
101 |
|
#ifdef ENABLE_VOSF |
102 |
< |
static bool use_vosf = true; // Flag: VOSF enabled |
102 |
> |
static bool use_vosf = false; // Flag: VOSF enabled |
103 |
|
#else |
104 |
|
static const bool use_vosf = false; // VOSF not possible |
105 |
|
#endif |
117 |
|
|
118 |
|
// SDL variables |
119 |
|
static int screen_depth; // Depth of current screen |
120 |
+ |
static SDL_Cursor *sdl_cursor; // Copy of Mac cursor |
121 |
+ |
static volatile bool cursor_changed = false; // Flag: cursor changed, redraw_func must update the cursor |
122 |
|
static SDL_Color sdl_palette[256]; // Color palette to be used as CLUT and gamma table |
123 |
|
static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors |
124 |
|
static const int sdl_eventmask = SDL_MOUSEBUTTONDOWNMASK | SDL_MOUSEBUTTONUPMASK | SDL_MOUSEMOTIONMASK | SDL_KEYUPMASK | SDL_KEYDOWNMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK; |
260 |
|
{ |
261 |
|
ErrorAlert(GetString(error)); |
262 |
|
} |
263 |
+ |
|
264 |
+ |
// Display warning alert |
265 |
+ |
static void WarningAlert(int warning) |
266 |
+ |
{ |
267 |
+ |
WarningAlert(GetString(warning)); |
268 |
+ |
} |
269 |
|
#endif |
270 |
|
|
271 |
|
|
353 |
|
return depth; |
354 |
|
} |
355 |
|
|
356 |
< |
// Add mode to list of supported modes |
357 |
< |
static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) |
356 |
> |
// Check wether specified mode is available |
357 |
> |
static bool has_mode(int type, int width, int height) |
358 |
|
{ |
359 |
< |
VIDEO_MODE mode; |
359 |
> |
// FIXME: no fullscreen support yet |
360 |
> |
if (type == DISPLAY_SCREEN) |
361 |
> |
return false; |
362 |
> |
|
363 |
|
#ifdef SHEEPSHAVER |
364 |
< |
// Don't add 512x384 modes |
364 |
> |
// Filter out Classic resolutiosn |
365 |
|
if (width == 512 && height == 384) |
366 |
+ |
return false; |
367 |
+ |
|
368 |
+ |
// Read window modes prefs |
369 |
+ |
static uint32 window_modes = 0; |
370 |
+ |
static uint32 screen_modes = 0; |
371 |
+ |
if (window_modes == 0 || screen_modes == 0) { |
372 |
+ |
window_modes = PrefsFindInt32("windowmodes"); |
373 |
+ |
screen_modes = PrefsFindInt32("screenmodes"); |
374 |
+ |
if (window_modes == 0 || screen_modes == 0) |
375 |
+ |
window_modes |= 3; // Allow at least 640x480 and 800x600 window modes |
376 |
+ |
} |
377 |
+ |
|
378 |
+ |
if (type == DISPLAY_WINDOW) { |
379 |
+ |
int apple_mask, apple_id = find_apple_resolution(width, height); |
380 |
+ |
switch (apple_id) { |
381 |
+ |
case APPLE_640x480: apple_mask = 0x01; break; |
382 |
+ |
case APPLE_800x600: apple_mask = 0x02; break; |
383 |
+ |
case APPLE_1024x768: apple_mask = 0x04; break; |
384 |
+ |
case APPLE_1152x768: apple_mask = 0x40; break; |
385 |
+ |
case APPLE_1152x900: apple_mask = 0x08; break; |
386 |
+ |
case APPLE_1280x1024: apple_mask = 0x10; break; |
387 |
+ |
case APPLE_1600x1200: apple_mask = 0x20; break; |
388 |
+ |
default: apple_mask = 0x00; break; |
389 |
+ |
} |
390 |
+ |
return (window_modes & apple_mask); |
391 |
+ |
} |
392 |
+ |
#else |
393 |
+ |
return true; |
394 |
+ |
#endif |
395 |
+ |
return false; |
396 |
+ |
} |
397 |
+ |
|
398 |
+ |
// Add mode to list of supported modes |
399 |
+ |
static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) |
400 |
+ |
{ |
401 |
+ |
// Filter out unsupported modes |
402 |
+ |
if (!has_mode(type, width, height)) |
403 |
|
return; |
404 |
|
|
405 |
+ |
// Fill in VideoMode entry |
406 |
+ |
VIDEO_MODE mode; |
407 |
+ |
#ifdef SHEEPSHAVER |
408 |
|
// Recalculate dimensions to fit Apple modes |
409 |
|
resolution_id = match_apple_resolution(width, height); |
410 |
|
mode.viType = type; |
630 |
|
the_buffer = (uint8 *)vm_acquire(the_buffer_size); |
631 |
|
the_buffer_copy = (uint8 *)malloc(the_buffer_size); |
632 |
|
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); |
633 |
+ |
|
634 |
+ |
// Check whether we can initialize the VOSF subsystem and it's profitable |
635 |
+ |
if (!video_vosf_init(m)) { |
636 |
+ |
WarningAlert(STR_VOSF_INIT_ERR); |
637 |
+ |
use_vosf = false; |
638 |
+ |
} |
639 |
+ |
else if (!video_vosf_profitable()) { |
640 |
+ |
video_vosf_exit(); |
641 |
+ |
printf("VOSF acceleration is not profitable on this platform, disabling it\n"); |
642 |
+ |
use_vosf = false; |
643 |
+ |
} |
644 |
+ |
if (!use_vosf) { |
645 |
+ |
free(the_buffer_copy); |
646 |
+ |
vm_release(the_buffer, the_buffer_size); |
647 |
+ |
the_host_buffer = NULL; |
648 |
+ |
} |
649 |
+ |
#endif |
650 |
+ |
if (!use_vosf) { |
651 |
+ |
// Allocate memory for frame buffer |
652 |
+ |
the_buffer_size = (aligned_height + 2) * s->pitch; |
653 |
+ |
the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); |
654 |
+ |
the_buffer = (uint8 *)calloc(1, the_buffer_size); |
655 |
+ |
D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); |
656 |
+ |
} |
657 |
+ |
|
658 |
+ |
#ifdef SHEEPSHAVER |
659 |
+ |
// Create cursor |
660 |
+ |
if ((sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, 0, 0)) != NULL) { |
661 |
+ |
SDL_SetCursor(sdl_cursor); |
662 |
+ |
cursor_changed = false; |
663 |
+ |
} |
664 |
|
#else |
665 |
< |
// Allocate memory for frame buffer |
666 |
< |
the_buffer_size = (aligned_height + 2) * s->pitch; |
582 |
< |
the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); |
583 |
< |
the_buffer = (uint8 *)calloc(1, the_buffer_size); |
584 |
< |
D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); |
665 |
> |
// Hide cursor |
666 |
> |
SDL_ShowCursor(0); |
667 |
|
#endif |
668 |
|
|
669 |
|
// Set window name/class |
670 |
|
set_window_name(STR_WINDOW_TITLE); |
671 |
|
|
590 |
– |
// Hide cursor |
591 |
– |
SDL_ShowCursor(0); |
592 |
– |
|
672 |
|
// Init blitting routines |
673 |
|
SDL_PixelFormat *f = s->format; |
674 |
|
VisualFormat visualFormat; |
827 |
|
{ |
828 |
|
D(bug("video_open()\n")); |
829 |
|
const VIDEO_MODE &mode = get_current_mode(); |
830 |
+ |
#if DEBUG |
831 |
+ |
D(bug("Current video mode:\n")); |
832 |
+ |
D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f))); |
833 |
+ |
#endif |
834 |
|
|
835 |
|
// Create display driver object of requested type |
836 |
|
switch (display_type) { |
846 |
|
return false; |
847 |
|
} |
848 |
|
|
766 |
– |
#ifdef ENABLE_VOSF |
767 |
– |
if (use_vosf) { |
768 |
– |
// Initialize the VOSF system |
769 |
– |
if (!video_vosf_init(*this)) { |
770 |
– |
ErrorAlert(STR_VOSF_INIT_ERR); |
771 |
– |
return false; |
772 |
– |
} |
773 |
– |
} |
774 |
– |
#endif |
775 |
– |
|
849 |
|
// Initialize VideoRefresh function |
850 |
|
VideoRefreshInit(); |
851 |
|
|
893 |
|
mouse_wheel_lines = PrefsFindInt32("mousewheellines"); |
894 |
|
|
895 |
|
// Get screen mode from preferences |
896 |
< |
const char *mode_str; |
896 |
> |
const char *mode_str = NULL; |
897 |
> |
#ifndef SHEEPSHAVER |
898 |
|
if (classic_mode) |
899 |
|
mode_str = "win/512/342"; |
900 |
|
else |
901 |
|
mode_str = PrefsFindString("screen"); |
902 |
+ |
#endif |
903 |
|
|
904 |
|
// Determine display type and default dimensions |
905 |
|
int default_width, default_height; |
917 |
|
display_type = DISPLAY_WINDOW; |
918 |
|
} |
919 |
|
int max_width = 640, max_height = 480; |
920 |
< |
if (display_type == DISPLAY_SCREEN) { |
921 |
< |
SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); |
922 |
< |
if (modes && modes != (SDL_Rect **)-1) { |
923 |
< |
max_width = modes[0]->w; |
924 |
< |
max_height = modes[0]->h; |
925 |
< |
} |
920 |
> |
SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); |
921 |
> |
if (modes && modes != (SDL_Rect **)-1) { |
922 |
> |
max_width = modes[0]->w; |
923 |
> |
max_height = modes[0]->h; |
924 |
> |
if (default_width > max_width) |
925 |
> |
default_width = max_width; |
926 |
> |
if (default_height > max_height) |
927 |
> |
default_height = max_height; |
928 |
|
} |
929 |
|
if (default_width <= 0) |
930 |
|
default_width = max_width; |
991 |
|
} |
992 |
|
|
993 |
|
#ifdef SHEEPSHAVER |
994 |
< |
for (int i = 0; i < VideoModes.size(); ++i) |
994 |
> |
for (int i = 0; i < VideoModes.size(); i++) |
995 |
|
VModes[i] = VideoModes[i]; |
996 |
< |
|
997 |
< |
const VIDEO_MODE & mode = VideoModes[cur_mode]; |
998 |
< |
D(bug("Current video mode\n")); |
999 |
< |
D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH - 0x80))); |
996 |
> |
VideoInfo *p = &VModes[VideoModes.size()]; |
997 |
> |
p->viType = DIS_INVALID; // End marker |
998 |
> |
p->viRowBytes = 0; |
999 |
> |
p->viXsize = p->viYsize = 0; |
1000 |
> |
p->viAppleMode = 0; |
1001 |
> |
p->viAppleID = 0; |
1002 |
|
#endif |
1003 |
|
|
1004 |
|
#if DEBUG |
1172 |
|
} |
1173 |
|
|
1174 |
|
#ifdef ENABLE_VOSF |
1175 |
< |
// We have to redraw everything because the interpretation of pixel values changed |
1176 |
< |
LOCK_VOSF; |
1177 |
< |
PFLAG_SET_ALL; |
1178 |
< |
UNLOCK_VOSF; |
1179 |
< |
memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); |
1175 |
> |
if (use_vosf) { |
1176 |
> |
// We have to redraw everything because the interpretation of pixel values changed |
1177 |
> |
LOCK_VOSF; |
1178 |
> |
PFLAG_SET_ALL; |
1179 |
> |
UNLOCK_VOSF; |
1180 |
> |
memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); |
1181 |
> |
} |
1182 |
|
#endif |
1183 |
|
} |
1184 |
|
|
1249 |
|
#ifdef SHEEPSHAVER |
1250 |
|
bool video_can_change_cursor(void) |
1251 |
|
{ |
1252 |
< |
// return hw_mac_cursor_accl && (display_type != DISPLAY_SCREEN); |
1172 |
< |
return false; |
1252 |
> |
return (display_type == DISPLAY_WINDOW); |
1253 |
|
} |
1254 |
|
#endif |
1255 |
|
|
1261 |
|
#ifdef SHEEPSHAVER |
1262 |
|
void video_set_cursor(void) |
1263 |
|
{ |
1264 |
< |
// cursor_changed = true; |
1264 |
> |
cursor_changed = true; |
1265 |
|
} |
1266 |
|
#endif |
1267 |
|
|
2185 |
|
// Refresh display |
2186 |
|
video_refresh(); |
2187 |
|
|
2188 |
+ |
#ifdef SHEEPSHAVER |
2189 |
+ |
// Set new cursor image if it was changed |
2190 |
+ |
if (cursor_changed && sdl_cursor) { |
2191 |
+ |
cursor_changed = false; |
2192 |
+ |
SDL_FreeCursor(sdl_cursor); |
2193 |
+ |
sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); |
2194 |
+ |
if (sdl_cursor) |
2195 |
+ |
SDL_SetCursor(sdl_cursor); |
2196 |
+ |
} |
2197 |
+ |
#endif |
2198 |
+ |
|
2199 |
|
// Set new palette if it was changed |
2200 |
|
handle_palette_changes(); |
2201 |
|
} |