mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-27 00:29:40 +00:00
SDL Video updates:
- Properly handle migration from "screenmodes" and "windowmodes" to "screen" - Fix has_mode() logic to really test for actual mode availability. i.e. no longer start in large screen mode if user specified a max size.
This commit is contained in:
parent
484469962b
commit
5019174a22
@ -286,69 +286,21 @@ static vector<monitor_desc *> VideoMonitors;
|
|||||||
// Find Apple mode matching best specified dimensions
|
// Find Apple mode matching best specified dimensions
|
||||||
static int find_apple_resolution(int xsize, int ysize)
|
static int find_apple_resolution(int xsize, int ysize)
|
||||||
{
|
{
|
||||||
int apple_id;
|
if (xsize == 640 && ysize == 480)
|
||||||
if (xsize < 800)
|
return APPLE_640x480;
|
||||||
apple_id = APPLE_640x480;
|
if (xsize == 800 && ysize == 600)
|
||||||
else if (xsize < 1024)
|
return APPLE_800x600;
|
||||||
apple_id = APPLE_800x600;
|
if (xsize == 1024 && ysize == 768)
|
||||||
else if (xsize < 1152)
|
return APPLE_1024x768;
|
||||||
apple_id = APPLE_1024x768;
|
if (xsize == 1152 && ysize == 768)
|
||||||
else if (xsize < 1280) {
|
return APPLE_1152x768;
|
||||||
if (ysize < 900)
|
if (xsize == 1152 && ysize == 900)
|
||||||
apple_id = APPLE_1152x768;
|
return APPLE_1152x900;
|
||||||
else
|
if (xsize == 1280 && ysize == 1024)
|
||||||
apple_id = APPLE_1152x900;
|
return APPLE_1280x1024;
|
||||||
}
|
if (xsize == 1600 && ysize == 1200)
|
||||||
else if (xsize < 1600)
|
return APPLE_1600x1200;
|
||||||
apple_id = APPLE_1280x1024;
|
return APPLE_CUSTOM;
|
||||||
else
|
|
||||||
apple_id = APPLE_1600x1200;
|
|
||||||
return apple_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set parameters to specified Apple mode
|
|
||||||
static void set_apple_resolution(int apple_id, int &xsize, int &ysize)
|
|
||||||
{
|
|
||||||
switch (apple_id) {
|
|
||||||
case APPLE_640x480:
|
|
||||||
xsize = 640;
|
|
||||||
ysize = 480;
|
|
||||||
break;
|
|
||||||
case APPLE_800x600:
|
|
||||||
xsize = 800;
|
|
||||||
ysize = 600;
|
|
||||||
break;
|
|
||||||
case APPLE_1024x768:
|
|
||||||
xsize = 1024;
|
|
||||||
ysize = 768;
|
|
||||||
break;
|
|
||||||
case APPLE_1152x768:
|
|
||||||
xsize = 1152;
|
|
||||||
ysize = 768;
|
|
||||||
break;
|
|
||||||
case APPLE_1152x900:
|
|
||||||
xsize = 1152;
|
|
||||||
ysize = 900;
|
|
||||||
break;
|
|
||||||
case APPLE_1280x1024:
|
|
||||||
xsize = 1280;
|
|
||||||
ysize = 1024;
|
|
||||||
break;
|
|
||||||
case APPLE_1600x1200:
|
|
||||||
xsize = 1600;
|
|
||||||
ysize = 1200;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match Apple mode matching best specified dimensions
|
|
||||||
static int match_apple_resolution(int &xsize, int &ysize)
|
|
||||||
{
|
|
||||||
int apple_id = find_apple_resolution(xsize, ysize);
|
|
||||||
set_apple_resolution(apple_id, xsize, ysize);
|
|
||||||
return apple_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display error alert
|
// Display error alert
|
||||||
@ -455,69 +407,74 @@ static int sdl_depth_of_video_depth(int video_depth)
|
|||||||
return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth);
|
return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get screen dimensions
|
||||||
|
static void sdl_display_dimensions(int &width, int &height)
|
||||||
|
{
|
||||||
|
static int max_width, max_height;
|
||||||
|
if (max_width == 0 && max_height == 0) {
|
||||||
|
max_width = 640 ; max_height = 480;
|
||||||
|
SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
|
||||||
|
if (modes && modes != (SDL_Rect **)-1) {
|
||||||
|
// It turns out that on some implementations, and contrary to the documentation,
|
||||||
|
// the returned list is not sorted from largest to smallest (e.g. Windows)
|
||||||
|
for (int i = 0; modes[i] != NULL; i++) {
|
||||||
|
const int w = modes[i]->w;
|
||||||
|
const int h = modes[i]->h;
|
||||||
|
if (w > max_width && h > max_height) {
|
||||||
|
max_width = w;
|
||||||
|
max_height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width = max_width;
|
||||||
|
height = max_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int sdl_display_width(void)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
sdl_display_dimensions(width, height);
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int sdl_display_height(void)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
sdl_display_dimensions(width, height);
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
// Check wether specified mode is available
|
// Check wether specified mode is available
|
||||||
static bool has_mode(int type, int width, int height)
|
static bool has_mode(int type, int width, int height, int depth)
|
||||||
{
|
{
|
||||||
#ifdef SHEEPSHAVER
|
#ifdef SHEEPSHAVER
|
||||||
// Filter out Classic resolutiosn
|
// Filter out Classic resolutions
|
||||||
if (width == 512 && height == 384)
|
if (width == 512 && height == 384)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// "screen" prefs items always succeeds
|
|
||||||
if (PrefsFindString("screen"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Read window & screen modes prefs
|
|
||||||
static uint32 window_modes = 0;
|
|
||||||
static uint32 screen_modes = 0;
|
|
||||||
if (window_modes == 0 || screen_modes == 0) {
|
|
||||||
window_modes = PrefsFindInt32("windowmodes");
|
|
||||||
screen_modes = PrefsFindInt32("screenmodes");
|
|
||||||
if (window_modes == 0 || screen_modes == 0)
|
|
||||||
window_modes |= 3; // Allow at least 640x480 and 800x600 window modes
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_modes;
|
|
||||||
switch (type) {
|
|
||||||
case DISPLAY_WINDOW:
|
|
||||||
test_modes = window_modes;
|
|
||||||
break;
|
|
||||||
case DISPLAY_SCREEN:
|
|
||||||
test_modes = screen_modes;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
test_modes = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int apple_mask;
|
|
||||||
switch (find_apple_resolution(width, height)) {
|
|
||||||
case APPLE_640x480: apple_mask = 0x01; break;
|
|
||||||
case APPLE_800x600: apple_mask = 0x02; break;
|
|
||||||
case APPLE_1024x768: apple_mask = 0x04; break;
|
|
||||||
case APPLE_1152x768: apple_mask = 0x40; break;
|
|
||||||
case APPLE_1152x900: apple_mask = 0x08; break;
|
|
||||||
case APPLE_1280x1024: apple_mask = 0x10; break;
|
|
||||||
case APPLE_1600x1200: apple_mask = 0x20; break;
|
|
||||||
default: apple_mask = 0x00; break;
|
|
||||||
}
|
|
||||||
return (test_modes & apple_mask);
|
|
||||||
#endif
|
#endif
|
||||||
return true;
|
|
||||||
|
// Filter out out-of-bounds resolutions
|
||||||
|
if (width > sdl_display_width() || height > sdl_display_height())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Rely on SDL capabilities
|
||||||
|
return SDL_VideoModeOK(width, height,
|
||||||
|
sdl_depth_of_video_depth(depth),
|
||||||
|
SDL_HWSURFACE | (type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add mode to list of supported modes
|
// Add mode to list of supported modes
|
||||||
static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth)
|
static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth)
|
||||||
{
|
{
|
||||||
// Filter out unsupported modes
|
// Filter out unsupported modes
|
||||||
if (!has_mode(type, width, height))
|
if (!has_mode(type, width, height, depth))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Fill in VideoMode entry
|
// Fill in VideoMode entry
|
||||||
VIDEO_MODE mode;
|
VIDEO_MODE mode;
|
||||||
#ifdef SHEEPSHAVER
|
#ifdef SHEEPSHAVER
|
||||||
// Recalculate dimensions to fit Apple modes
|
resolution_id = find_apple_resolution(width, height);
|
||||||
resolution_id = match_apple_resolution(width, height);
|
|
||||||
mode.viType = type;
|
mode.viType = type;
|
||||||
#endif
|
#endif
|
||||||
VIDEO_MODE_X = width;
|
VIDEO_MODE_X = width;
|
||||||
@ -528,19 +485,6 @@ static void add_mode(int type, int width, int height, int resolution_id, int byt
|
|||||||
VideoModes.push_back(mode);
|
VideoModes.push_back(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add standard list of windowed modes for given color depth
|
|
||||||
static void add_window_modes(int depth)
|
|
||||||
{
|
|
||||||
video_depth vdepth = (video_depth)depth;
|
|
||||||
add_mode(DISPLAY_WINDOW, 512, 384, 0x80, TrivialBytesPerRow(512, vdepth), depth);
|
|
||||||
add_mode(DISPLAY_WINDOW, 640, 480, 0x81, TrivialBytesPerRow(640, vdepth), depth);
|
|
||||||
add_mode(DISPLAY_WINDOW, 800, 600, 0x82, TrivialBytesPerRow(800, vdepth), depth);
|
|
||||||
add_mode(DISPLAY_WINDOW, 1024, 768, 0x83, TrivialBytesPerRow(1024, vdepth), depth);
|
|
||||||
add_mode(DISPLAY_WINDOW, 1152, 870, 0x84, TrivialBytesPerRow(1152, vdepth), depth);
|
|
||||||
add_mode(DISPLAY_WINDOW, 1280, 1024, 0x85, TrivialBytesPerRow(1280, vdepth), depth);
|
|
||||||
add_mode(DISPLAY_WINDOW, 1600, 1200, 0x86, TrivialBytesPerRow(1600, vdepth), depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
|
// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
|
||||||
static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order)
|
static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order)
|
||||||
{
|
{
|
||||||
@ -584,6 +528,55 @@ static SDL_GrabMode set_grab_mode(SDL_GrabMode mode)
|
|||||||
return (vi && vi->wm_available ? SDL_WM_GrabInput(mode) : SDL_GRAB_OFF);
|
return (vi && vi->wm_available ? SDL_WM_GrabInput(mode) : SDL_GRAB_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate preferences items (XXX to be handled in MigratePrefs())
|
||||||
|
static void migrate_screen_prefs(void)
|
||||||
|
{
|
||||||
|
#ifdef SHEEPSHAVER
|
||||||
|
// Look-up priorities are: "screen", "screenmodes", "windowmodes".
|
||||||
|
if (PrefsFindString("screen"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 window_modes = PrefsFindInt32("windowmodes");
|
||||||
|
uint32 screen_modes = PrefsFindInt32("screenmodes");
|
||||||
|
int width = 0, height = 0;
|
||||||
|
if (screen_modes) {
|
||||||
|
static const struct {
|
||||||
|
int id;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
}
|
||||||
|
modes[] = {
|
||||||
|
{ 1, 640, 480 },
|
||||||
|
{ 2, 800, 600 },
|
||||||
|
{ 4, 1024, 768 },
|
||||||
|
{ 64, 1152, 768 },
|
||||||
|
{ 8, 1152, 900 },
|
||||||
|
{ 16, 1280, 1024 },
|
||||||
|
{ 32, 1600, 1200 },
|
||||||
|
{ 0, }
|
||||||
|
};
|
||||||
|
for (int i = 0; modes[i].id != 0; i++) {
|
||||||
|
if (screen_modes & modes[i].id) {
|
||||||
|
if (width < modes[i].width && height < modes[i].height) {
|
||||||
|
width = modes[i].width;
|
||||||
|
height = modes[i].height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (window_modes & 1)
|
||||||
|
width = 640, height = 480;
|
||||||
|
if (window_modes & 2)
|
||||||
|
width = 800, height = 600;
|
||||||
|
}
|
||||||
|
if (width && height) {
|
||||||
|
char str[32];
|
||||||
|
sprintf(str, "%s/%d/%d", screen_modes ? "dga" : "win", width, height);
|
||||||
|
PrefsReplaceString("screen", str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display "driver" classes
|
* Display "driver" classes
|
||||||
@ -1123,6 +1116,7 @@ bool VideoInit(bool classic)
|
|||||||
mouse_wheel_lines = PrefsFindInt32("mousewheellines");
|
mouse_wheel_lines = PrefsFindInt32("mousewheellines");
|
||||||
|
|
||||||
// Get screen mode from preferences
|
// Get screen mode from preferences
|
||||||
|
migrate_screen_prefs();
|
||||||
const char *mode_str = NULL;
|
const char *mode_str = NULL;
|
||||||
if (classic_mode)
|
if (classic_mode)
|
||||||
mode_str = "win/512/342";
|
mode_str = "win/512/342";
|
||||||
@ -1146,28 +1140,14 @@ bool VideoInit(bool classic)
|
|||||||
else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2)
|
else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2)
|
||||||
display_type = DISPLAY_SCREEN;
|
display_type = DISPLAY_SCREEN;
|
||||||
}
|
}
|
||||||
int max_width = 640, max_height = 480;
|
|
||||||
SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
|
|
||||||
if (modes && modes != (SDL_Rect **)-1) {
|
|
||||||
// It turns out that on some implementations, and contrary to the documentation,
|
|
||||||
// the returned list is not sorted from largest to smallest (e.g. Windows)
|
|
||||||
for (int i = 0; modes[i] != NULL; i++) {
|
|
||||||
const int w = modes[i]->w;
|
|
||||||
const int h = modes[i]->h;
|
|
||||||
if (w > max_width && h > max_height) {
|
|
||||||
max_width = w;
|
|
||||||
max_height = h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (default_width > max_width)
|
|
||||||
default_width = max_width;
|
|
||||||
if (default_height > max_height)
|
|
||||||
default_height = max_height;
|
|
||||||
}
|
|
||||||
if (default_width <= 0)
|
if (default_width <= 0)
|
||||||
default_width = max_width;
|
default_width = sdl_display_width();
|
||||||
|
else if (default_width > sdl_display_width())
|
||||||
|
default_width = sdl_display_width();
|
||||||
if (default_height <= 0)
|
if (default_height <= 0)
|
||||||
default_height = max_height;
|
default_height = sdl_display_height();
|
||||||
|
else if (default_height > sdl_display_height())
|
||||||
|
default_height = sdl_display_height();
|
||||||
|
|
||||||
// Mac screen depth follows X depth
|
// Mac screen depth follows X depth
|
||||||
screen_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
screen_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
||||||
@ -1187,47 +1167,51 @@ bool VideoInit(bool classic)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize list of video modes to try
|
||||||
|
struct {
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
int resolution_id;
|
||||||
|
}
|
||||||
|
video_modes[] = {
|
||||||
|
{ -1, -1, 0x80 },
|
||||||
|
{ 512, 384, 0x80 },
|
||||||
|
{ 640, 480, 0x81 },
|
||||||
|
{ 800, 600, 0x82 },
|
||||||
|
{ 1024, 768, 0x83 },
|
||||||
|
{ 1152, 870, 0x84 },
|
||||||
|
{ 1280, 1024, 0x85 },
|
||||||
|
{ 1600, 1200, 0x86 },
|
||||||
|
{ 0, }
|
||||||
|
};
|
||||||
|
video_modes[0].w = default_width;
|
||||||
|
video_modes[0].h = default_height;
|
||||||
|
|
||||||
// Construct list of supported modes
|
// Construct list of supported modes
|
||||||
if (display_type == DISPLAY_WINDOW) {
|
if (display_type == DISPLAY_WINDOW) {
|
||||||
if (classic)
|
if (classic)
|
||||||
add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT);
|
add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT);
|
||||||
else {
|
else {
|
||||||
for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) {
|
for (int i = 0; video_modes[i].w != 0; i++) {
|
||||||
int bpp = sdl_depth_of_video_depth(d);
|
const int w = video_modes[i].w;
|
||||||
if (SDL_VideoModeOK(max_width, max_height, bpp, SDL_HWSURFACE))
|
const int h = video_modes[i].h;
|
||||||
add_window_modes(video_depth(d));
|
if (i > 0 && (w >= default_width || h >= default_height))
|
||||||
|
continue;
|
||||||
|
for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++)
|
||||||
|
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (display_type == DISPLAY_SCREEN) {
|
} else if (display_type == DISPLAY_SCREEN) {
|
||||||
struct {
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
int resolution_id;
|
|
||||||
}
|
|
||||||
video_modes[] = {
|
|
||||||
{ -1, -1, 0x80 },
|
|
||||||
{ 640, 480, 0x81 },
|
|
||||||
{ 800, 600, 0x82 },
|
|
||||||
{ 1024, 768, 0x83 },
|
|
||||||
{ 1152, 870, 0x84 },
|
|
||||||
{ 1280, 1024, 0x85 },
|
|
||||||
{ 1600, 1200, 0x86 },
|
|
||||||
{ 0, }
|
|
||||||
};
|
|
||||||
video_modes[0].w = default_width;
|
|
||||||
video_modes[0].h = default_height;
|
|
||||||
|
|
||||||
for (int i = 0; video_modes[i].w != 0; i++) {
|
for (int i = 0; video_modes[i].w != 0; i++) {
|
||||||
const int w = video_modes[i].w;
|
const int w = video_modes[i].w;
|
||||||
const int h = video_modes[i].h;
|
const int h = video_modes[i].h;
|
||||||
if (i > 0 && (w >= default_width || h >= default_height))
|
if (i > 0 && (w >= default_width || h >= default_height))
|
||||||
continue;
|
continue;
|
||||||
|
if (w == 512 && h == 384)
|
||||||
|
continue;
|
||||||
#ifdef ENABLE_VOSF
|
#ifdef ENABLE_VOSF
|
||||||
for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) {
|
for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++)
|
||||||
int bpp = sdl_depth_of_video_depth(d);
|
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d);
|
||||||
if (SDL_VideoModeOK(w, h, bpp, SDL_HWSURFACE | SDL_FULLSCREEN))
|
|
||||||
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)default_depth), default_depth);
|
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)default_depth), default_depth);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user