mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-23 04:33:24 +00:00
Fix DGA mode for emulated PPC targets. It currently doesn't work in native
mode as the stack is corrupted and we are jumping to garbage when moving the mouse. Also add 1152x768 resolution from PBG4, but make timing match the 1152x870 version. Cleanups, further merges from Basilisk II tree.
This commit is contained in:
parent
e6a05869ac
commit
fd474d041d
@ -597,6 +597,14 @@ static void tb_fs1024x768(GtkWidget *widget)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~4);
|
||||
}
|
||||
|
||||
static void tb_fs1152x768(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 64);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~64);
|
||||
}
|
||||
|
||||
static void tb_fs1152x900(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
@ -684,6 +692,7 @@ static void create_graphics_pane(GtkWidget *top)
|
||||
make_checkbox(vbox, STR_640x480_CTRL, PrefsFindInt32("screenmodes") & 1, GTK_SIGNAL_FUNC(tb_fs640x480));
|
||||
make_checkbox(vbox, STR_800x600_CTRL, PrefsFindInt32("screenmodes") & 2, GTK_SIGNAL_FUNC(tb_fs800x600));
|
||||
make_checkbox(vbox, STR_1024x768_CTRL, PrefsFindInt32("screenmodes") & 4, GTK_SIGNAL_FUNC(tb_fs1024x768));
|
||||
make_checkbox(vbox, STR_1152x768_CTRL, PrefsFindInt32("screenmodes") & 64, GTK_SIGNAL_FUNC(tb_fs1152x768));
|
||||
make_checkbox(vbox, STR_1152x900_CTRL, PrefsFindInt32("screenmodes") & 8, GTK_SIGNAL_FUNC(tb_fs1152x900));
|
||||
make_checkbox(vbox, STR_1280x1024_CTRL, PrefsFindInt32("screenmodes") & 16, GTK_SIGNAL_FUNC(tb_fs1280x1024));
|
||||
make_checkbox(vbox, STR_1600x1200_CTRL, PrefsFindInt32("screenmodes") & 32, GTK_SIGNAL_FUNC(tb_fs1600x1200));
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef ENABLE_XF86_DGA
|
||||
#include <X11/extensions/xf86dga.h>
|
||||
# include <X11/extensions/xf86dga.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_XF86_VIDMODE
|
||||
@ -63,6 +63,7 @@ static int32 frame_skip;
|
||||
static int16 mouse_wheel_mode;
|
||||
static int16 mouse_wheel_lines;
|
||||
static bool redraw_thread_active = false; // Flag: Redraw thread installed
|
||||
static pthread_attr_t redraw_thread_attr; // Redraw thread attributes
|
||||
static pthread_t redraw_thread; // Redraw thread
|
||||
|
||||
static bool local_X11; // Flag: X server running on local machine?
|
||||
@ -125,8 +126,6 @@ static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer
|
||||
static uint32 the_buffer_size; // Size of allocated the_buffer
|
||||
|
||||
// Variables for DGA mode
|
||||
static char *dga_screen_base;
|
||||
static int dga_fb_width;
|
||||
static int current_dga_cmap;
|
||||
|
||||
#ifdef ENABLE_XF86_VIDMODE
|
||||
@ -349,7 +348,7 @@ static void set_window_delete_protocol(Window w)
|
||||
}
|
||||
|
||||
// Wait until window is mapped/unmapped
|
||||
void wait_mapped(Window w)
|
||||
static void wait_mapped(Window w)
|
||||
{
|
||||
XEvent e;
|
||||
do {
|
||||
@ -357,7 +356,7 @@ void wait_mapped(Window w)
|
||||
} while ((e.type != MapNotify) || (e.xmap.event != w));
|
||||
}
|
||||
|
||||
void wait_unmapped(Window w)
|
||||
static void wait_unmapped(Window w)
|
||||
{
|
||||
XEvent e;
|
||||
do {
|
||||
@ -522,6 +521,19 @@ static bool open_dga(int width, int height)
|
||||
// Set relative mouse mode
|
||||
ADBSetRelMouseMode(true);
|
||||
|
||||
// Create window
|
||||
XSetWindowAttributes wattr;
|
||||
wattr.event_mask = eventmask = dga_eventmask;
|
||||
wattr.override_redirect = True;
|
||||
wattr.colormap = (depth == 1 ? DefaultColormap(x_display, screen) : cmap[0]);
|
||||
the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth,
|
||||
InputOutput, vis, CWEventMask | CWOverrideRedirect |
|
||||
(color_class == DirectColor ? CWColormap : 0), &wattr);
|
||||
|
||||
// Show window
|
||||
XMapRaised(x_display, the_win);
|
||||
wait_mapped(the_win);
|
||||
|
||||
#ifdef ENABLE_XF86_VIDMODE
|
||||
// Switch to best mode
|
||||
if (has_vidmode) {
|
||||
@ -538,19 +550,26 @@ static bool open_dga(int width, int height)
|
||||
#endif
|
||||
|
||||
// Establish direct screen connection
|
||||
XMoveResizeWindow(x_display, the_win, 0, 0, width, height);
|
||||
XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0);
|
||||
XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
||||
|
||||
int v_width, v_bank, v_size;
|
||||
XF86DGAGetVideo(x_display, screen, (char **)&the_buffer, &v_width, &v_bank, &v_size);
|
||||
XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
|
||||
XF86DGASetViewPort(x_display, screen, 0, 0);
|
||||
XF86DGASetVidPage(x_display, screen, 0);
|
||||
|
||||
// Set colormap
|
||||
if (depth == 8)
|
||||
if (!IsDirectMode(get_current_mode())) {
|
||||
XSetWindowColormap(x_display, the_win, cmap[current_dga_cmap = 0]);
|
||||
XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
|
||||
}
|
||||
XSync(x_display, false);
|
||||
|
||||
// Set bytes per row
|
||||
int bytes_per_row = TrivialBytesPerRow((dga_fb_width + 7) & ~7, DepthModeForPixelDepth(depth));
|
||||
|
||||
// Init blitting routines
|
||||
int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, DepthModeForPixelDepth(depth));
|
||||
#if ENABLE_VOSF
|
||||
bool native_byte_order;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
@ -569,16 +588,17 @@ static bool open_dga(int width, int height)
|
||||
the_buffer_size = page_extend((height + 2) * bytes_per_row);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
|
||||
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
|
||||
}
|
||||
#else
|
||||
use_vosf = false;
|
||||
the_buffer = dga_screen_base;
|
||||
#endif
|
||||
#endif
|
||||
screen_base = (uint32)the_buffer;
|
||||
|
||||
// Set frame buffer base
|
||||
D(bug("the_buffer = %p, use_vosf = %d\n", the_buffer, use_vosf));
|
||||
screen_base = (uint32)the_buffer;
|
||||
VModes[cur_mode].viRowBytes = bytes_per_row;
|
||||
XSync(x_display, false);
|
||||
return true;
|
||||
#else
|
||||
ErrorAlert("SheepShaver has been compiled with DGA support disabled.");
|
||||
@ -711,13 +731,6 @@ static void close_window(void)
|
||||
if (the_gc)
|
||||
XFreeGC(x_display, the_gc);
|
||||
|
||||
// Close window
|
||||
if (the_win) {
|
||||
XUnmapWindow(x_display, the_win);
|
||||
wait_unmapped(the_win);
|
||||
XDestroyWindow(x_display, the_win);
|
||||
}
|
||||
|
||||
XFlush(x_display);
|
||||
XSync(x_display, false);
|
||||
}
|
||||
@ -755,6 +768,13 @@ static void close_display(void)
|
||||
else if (display_type == DIS_WINDOW)
|
||||
close_window();
|
||||
|
||||
// Close window
|
||||
if (the_win) {
|
||||
XUnmapWindow(x_display, the_win);
|
||||
wait_unmapped(the_win);
|
||||
XDestroyWindow(x_display, the_win);
|
||||
}
|
||||
|
||||
// Free colormaps
|
||||
if (cmap[0]) {
|
||||
XFreeColormap(x_display, cmap[0]);
|
||||
@ -871,6 +891,39 @@ static void keycode_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Find Apple mode matching best specified dimensions
|
||||
static int find_apple_resolution(int xsize, int ysize)
|
||||
{
|
||||
int apple_id;
|
||||
if (xsize < 800)
|
||||
apple_id = APPLE_640x480;
|
||||
else if (xsize < 1024)
|
||||
apple_id = APPLE_800x600;
|
||||
else if (xsize < 1152)
|
||||
apple_id = APPLE_1024x768;
|
||||
else if (xsize < 1280) {
|
||||
if (ysize < 900)
|
||||
apple_id = APPLE_1152x768;
|
||||
else
|
||||
apple_id = APPLE_1152x900;
|
||||
}
|
||||
else if (xsize < 1600)
|
||||
apple_id = APPLE_1280x1024;
|
||||
else
|
||||
apple_id = APPLE_1600x1200;
|
||||
return apple_id;
|
||||
}
|
||||
|
||||
// Find mode in list of supported modes
|
||||
static int find_mode(int apple_mode, int apple_id, int type)
|
||||
{
|
||||
for (VideoInfo *p = VModes; p->viType != DIS_INVALID; p++) {
|
||||
if (p->viType == type && p->viAppleID == apple_id && p->viAppleMode == apple_mode)
|
||||
return p - VModes;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add mode to list of supported modes
|
||||
static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, int apple_mode, int apple_id, int type)
|
||||
{
|
||||
@ -891,6 +944,10 @@ static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, int apple_mode, i
|
||||
p->viXsize = 1024;
|
||||
p->viYsize = 768;
|
||||
break;
|
||||
case APPLE_1152x768:
|
||||
p->viXsize = 1152;
|
||||
p->viYsize = 768;
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
p->viXsize = 1152;
|
||||
p->viYsize = 900;
|
||||
@ -1037,6 +1094,8 @@ bool VideoInit(void)
|
||||
add_mode(p, screen_modes, 2, default_mode, APPLE_800x600, DIS_SCREEN);
|
||||
if (has_mode(1024, 768))
|
||||
add_mode(p, screen_modes, 4, default_mode, APPLE_1024x768, DIS_SCREEN);
|
||||
if (has_mode(1152, 768))
|
||||
add_mode(p, screen_modes, 64, default_mode, APPLE_1152x768, DIS_SCREEN);
|
||||
if (has_mode(1152, 900))
|
||||
add_mode(p, screen_modes, 8, default_mode, APPLE_1152x900, DIS_SCREEN);
|
||||
if (has_mode(1280, 1024))
|
||||
@ -1046,19 +1105,7 @@ bool VideoInit(void)
|
||||
} else if (screen_modes) {
|
||||
int xsize = DisplayWidth(x_display, screen);
|
||||
int ysize = DisplayHeight(x_display, screen);
|
||||
int apple_id;
|
||||
if (xsize < 800)
|
||||
apple_id = APPLE_640x480;
|
||||
else if (xsize < 1024)
|
||||
apple_id = APPLE_800x600;
|
||||
else if (xsize < 1152)
|
||||
apple_id = APPLE_1024x768;
|
||||
else if (xsize < 1280)
|
||||
apple_id = APPLE_1152x900;
|
||||
else if (xsize < 1600)
|
||||
apple_id = APPLE_1280x1024;
|
||||
else
|
||||
apple_id = APPLE_1600x1200;
|
||||
int apple_id = find_apple_resolution(xsize, ysize);
|
||||
p->viType = DIS_SCREEN;
|
||||
p->viRowBytes = 0;
|
||||
p->viXsize = xsize;
|
||||
@ -1075,14 +1122,15 @@ bool VideoInit(void)
|
||||
|
||||
// Find default mode (window 640x480)
|
||||
cur_mode = -1;
|
||||
for (p = VModes; p->viType != DIS_INVALID; p++) {
|
||||
if (p->viType == DIS_WINDOW
|
||||
&& p->viAppleID == APPLE_W_640x480
|
||||
&& p->viAppleMode == default_mode) {
|
||||
cur_mode = p - VModes;
|
||||
break;
|
||||
}
|
||||
if (has_dga && screen_modes) {
|
||||
int screen_width = DisplayWidth(x_display, screen);
|
||||
int screen_height = DisplayHeight(x_display, screen);
|
||||
int apple_id = find_apple_resolution(screen_width, screen_height);
|
||||
if (apple_id != -1)
|
||||
cur_mode = find_mode(default_mode, apple_id, DIS_SCREEN);
|
||||
}
|
||||
if (cur_mode == -1)
|
||||
cur_mode = find_mode(default_mode, APPLE_W_640x480, DIS_WINDOW);
|
||||
assert(cur_mode != -1);
|
||||
|
||||
#if DEBUG
|
||||
@ -1093,14 +1141,6 @@ bool VideoInit(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_XF86_DGA
|
||||
if (has_dga && screen_modes) {
|
||||
int v_bank, v_size;
|
||||
XF86DGAGetVideo(x_display, screen, &dga_screen_base, &dga_fb_width, &v_bank, &v_size);
|
||||
D(bug("DGA screen_base %p, v_width %d\n", dga_screen_base, dga_fb_width));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Open window/screen
|
||||
if (!open_display())
|
||||
return false;
|
||||
@ -1112,7 +1152,8 @@ bool VideoInit(void)
|
||||
|
||||
// Start periodic thread
|
||||
XSync(x_display, false);
|
||||
redraw_thread_active = (pthread_create(&redraw_thread, NULL, redraw_func, NULL) == 0);
|
||||
Set_pthread_attr(&redraw_thread_attr, 0);
|
||||
redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0);
|
||||
D(bug("Redraw thread installed (%ld)\n", redraw_thread));
|
||||
return true;
|
||||
}
|
||||
@ -1475,12 +1516,15 @@ static void handle_events(void)
|
||||
break;
|
||||
}
|
||||
|
||||
// Mouse moved
|
||||
// Mouse entered window
|
||||
case EnterNotify:
|
||||
ADBMouseMoved(((XMotionEvent *)&event)->x, ((XMotionEvent *)&event)->y);
|
||||
if (event.xcrossing.mode != NotifyGrab && event.xcrossing.mode != NotifyUngrab)
|
||||
ADBMouseMoved(event.xmotion.x, event.xmotion.y);
|
||||
break;
|
||||
|
||||
// Mouse moved
|
||||
case MotionNotify:
|
||||
ADBMouseMoved(((XMotionEvent *)&event)->x, ((XMotionEvent *)&event)->y);
|
||||
ADBMouseMoved(event.xmotion.x, event.xmotion.y);
|
||||
break;
|
||||
|
||||
// Keyboard
|
||||
@ -1999,6 +2043,9 @@ static void *redraw_func(void *arg)
|
||||
XF86DGADirectVideo(x_display, screen, 0);
|
||||
XUngrabPointer(x_display, CurrentTime);
|
||||
XUngrabKeyboard(x_display, CurrentTime);
|
||||
XUnmapWindow(x_display, the_win);
|
||||
wait_unmapped(the_win);
|
||||
XDestroyWindow(x_display, the_win);
|
||||
#endif
|
||||
XSync(x_display, false);
|
||||
XDisplayUnlock();
|
||||
|
@ -108,6 +108,7 @@ enum {
|
||||
STR_640x480_CTRL,
|
||||
STR_800x600_CTRL,
|
||||
STR_1024x768_CTRL,
|
||||
STR_1152x768_CTRL,
|
||||
STR_1152x900_CTRL,
|
||||
STR_1280x1024_CTRL,
|
||||
STR_1600x1200_CTRL,
|
||||
|
@ -86,6 +86,7 @@ enum { // viAppleID
|
||||
APPLE_800x600,
|
||||
APPLE_W_800x600,
|
||||
APPLE_1024x768,
|
||||
APPLE_1152x768,
|
||||
APPLE_1152x900,
|
||||
APPLE_1280x1024,
|
||||
APPLE_1600x1200,
|
||||
|
@ -690,6 +690,11 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave)
|
||||
WriteMacInt32(param + csVerticalLines, 768);
|
||||
WriteMacInt32(param + csRefreshRate, 75<<16);
|
||||
break;
|
||||
case APPLE_1152x768:
|
||||
WriteMacInt32(param + csHorizontalPixels, 1152);
|
||||
WriteMacInt32(param + csVerticalLines, 768);
|
||||
WriteMacInt32(param + csRefreshRate, 75<<16);
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
WriteMacInt32(param + csHorizontalPixels, 1152);
|
||||
WriteMacInt32(param + csVerticalLines, 900);
|
||||
@ -808,6 +813,9 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave)
|
||||
case APPLE_1024x768:
|
||||
timing = timingVESA_1024x768_75hz;
|
||||
break;
|
||||
case APPLE_1152x768:
|
||||
timing = timingApple_1152x870_75hz; // FIXME
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
timing = timingApple_1152x870_75hz;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user