- added support for platform-independant mutexes, currently only properly

implemented under Unix
- adb.cpp uses mutexes for thread-safe mouse handling
- video_x.cpp: pressing Ctrl-F5 in windowed mode switches to a "grabbed"
  relative mouse mode, useful for some games
- video_x.cpp: fixed some bugs relating to the hotkeys (key releases are no
  longer treated as hotkeys)
This commit is contained in:
cebix 2001-07-03 15:59:49 +00:00
parent 6aff4fb327
commit cf22cb032a
15 changed files with 356 additions and 75 deletions

View File

@ -3,8 +3,12 @@ V1.0 (snapshot) - <date>
and gamma tables
- fsave/frestore emulation under AmigaOS and NetBSD/m68k always behaves
like a 68882/68040 FPU, eliminating the need for 68060 FPU patches
- added support for platform-independant mutexes, used by adb.cpp for
thread-safe mouse handling
- Unix: windowed display mode supports different resolutions and color
depth, which can be switched on-the-fly
- Unix: Ctrl-F5 grabs mouse in windowed mode (enhanced compatibility
with games like flight simulators)
V0.9 (release 0.9-1) - 31.May 2001
- final adjustments for 0.9 release

View File

@ -471,6 +471,33 @@ void FlushCodeCache(void *start, uint32 size)
}
/*
* Mutexes
*/
struct B2_mutex {
int dummy; //!!
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
}
void B2_unlock_mutex(B2_mutex *mutex)
{
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
/*
* Interrupt flags (must be handled atomically!)
*/

View File

@ -468,6 +468,33 @@ void FlushCodeCache(void *start, uint32 size)
}
/*
* Mutexes
*/
struct B2_mutex {
int dummy; //!!
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
}
void B2_unlock_mutex(B2_mutex *mutex)
{
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
/*
* Interrupt flags (must be handled atomically!)
*/

View File

@ -124,8 +124,6 @@ static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = v;}
#define call_mem_put_func(func, addr, v) ((*func)(addr, v))
#define __inline__ inline
#define CPU_EMU_SIZE 0
#undef USE_MAPPED_MEMORY
#undef CAN_MAP_MEMORY
#undef NO_INLINE_MEMORY_ACCESS
#undef MD_HAVE_MEM_1_FUNCS
#undef USE_COMPILER

View File

@ -123,9 +123,15 @@ static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread
static pthread_t tick_thread; // 60Hz thread
static pthread_attr_t tick_thread_attr; // 60Hz thread attributes
#if EMULATED_68K
static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect InterruptFlags
#endif
#define LOCK_INTFLAGS pthread_mutex_lock(&intflag_lock)
#define UNLOCK_INTFLAGS pthread_mutex_unlock(&intflag_lock)
#else
#define LOCK_INTFLAGS
#define UNLOCK_INTFLAGS
#endif
#if !EMULATED_68K
@ -668,6 +674,7 @@ static void sigint_handler(...)
extern void m68k_dumpstate(uaecptr *nextpc);
m68k_dumpstate(&nextpc);
#endif
VideoQuitFullScreen();
char *arg[4] = {"mon", "-m", "-r", NULL};
mon(3, arg);
QuitEmulator();
@ -675,6 +682,65 @@ static void sigint_handler(...)
#endif
/*
* Mutexes
*/
#ifdef HAVE_PTHREADS
struct B2_mutex {
B2_mutex() { pthread_mutex_init(&m, NULL); }
~B2_mutex() { pthread_mutex_unlock(&m); pthread_mutex_destroy(&m); }
pthread_mutex_t m;
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
pthread_mutex_lock(&mutex->m);
}
void B2_unlock_mutex(B2_mutex *mutex)
{
pthread_mutex_unlock(&mutex->m);
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
#else
struct B2_mutex {
int dummy;
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
}
void B2_unlock_mutex(B2_mutex *mutex)
{
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
#endif
/*
* Interrupt flags (must be handled atomically!)
*/
@ -684,24 +750,16 @@ uint32 InterruptFlags = 0;
#if EMULATED_68K
void SetInterruptFlag(uint32 flag)
{
#ifdef HAVE_PTHREADS
pthread_mutex_lock(&intflag_lock);
LOCK_INTFLAGS;
InterruptFlags |= flag;
pthread_mutex_unlock(&intflag_lock);
#else
InterruptFlags |= flag; // Pray that this is an atomic operation...
#endif
UNLOCK_INTFLAGS;
}
void ClearInterruptFlag(uint32 flag)
{
#ifdef HAVE_PTHREADS
pthread_mutex_lock(&intflag_lock);
LOCK_INTFLAGS;
InterruptFlags &= ~flag;
pthread_mutex_unlock(&intflag_lock);
#else
InterruptFlags &= ~flag;
#endif
UNLOCK_INTFLAGS;
}
#endif
@ -1197,6 +1255,7 @@ ill: printf("SIGILL num %d, code %d\n", sig, code);
for (int i=0; i<8; i++)
printf(" a%d %08x\n", i, state->ss_frame.f_regs[i+8]);
VideoQuitFullScreen();
#ifdef ENABLE_MON
char *arg[4] = {"mon", "-m", "-r", NULL};
mon(3, arg);

View File

@ -288,8 +288,6 @@ static inline uae_u32 do_byteswap_16(uae_u32 v)
#define ENUMDECL typedef enum
#define ENUMNAME(name) name
#define write_log printf
#undef USE_MAPPED_MEMORY
#undef CAN_MAP_MEMORY
#ifdef X86_ASSEMBLY
#define ASM_SYM_FOR_FUNC(a) __asm__(a)

View File

@ -75,6 +75,8 @@ user_string_def platform_strings[] = {
{STR_MOUSEWHEELMODE_CURSOR_LAB, "Cursor Up/Down"},
{STR_MOUSEWHEELLINES_CTRL, "Lines To Scroll"},
{STR_WINDOW_TITLE_GRABBED, "Basilisk II (mouse grabbed, press Ctrl-F5 to release)"},
{-1, NULL} // End marker
};

View File

@ -64,7 +64,9 @@ enum {
STR_MOUSEWHEELMODE_CTRL,
STR_MOUSEWHEELMODE_PAGE_LAB,
STR_MOUSEWHEELMODE_CURSOR_LAB,
STR_MOUSEWHEELLINES_CTRL
STR_MOUSEWHEELLINES_CTRL,
STR_WINDOW_TITLE_GRABBED
};
#endif

View File

@ -265,6 +265,7 @@ static bool screen_fault_handler(sigsegv_address_t fault_address, sigsegv_addres
extern void m68k_dumpstate(uaecptr *nextpc);
m68k_dumpstate(&nextpc);
#endif
VideoQuitFullScreen();
#ifdef ENABLE_MON
char *arg[4] = {"mon", "-m", "-r", NULL};
mon(3, arg);

View File

@ -24,6 +24,7 @@
* Ctrl-Tab = suspend DGA mode
* Ctrl-Esc = emergency quit
* Ctrl-F1 = mount floppy
* Ctrl-F5 = grab mouse (in windowed mode)
*/
#include "sysdeps.h"
@ -73,7 +74,7 @@ enum {
// Constants
const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes";
static const int win_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | ExposureMask | StructureNotifyMask;
static const int win_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | StructureNotifyMask;
static const int dga_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask;
@ -322,6 +323,11 @@ public:
virtual void update_palette(void);
virtual void suspend(void) {}
virtual void resume(void) {}
virtual void toggle_mouse_grab(void) {}
virtual void mouse_moved(int x, int y) { ADBMouseMoved(x, y); }
virtual void grab_mouse(void) {}
virtual void ungrab_mouse(void) {}
public:
bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer)
@ -342,12 +348,20 @@ public:
driver_window(const video_mode &mode);
~driver_window();
void toggle_mouse_grab(void);
void mouse_moved(int x, int y);
void grab_mouse(void);
void ungrab_mouse(void);
private:
GC gc;
XImage *img;
bool have_shm; // Flag: SHM extensions available
bool have_shm; // Flag: SHM extensions available
XShmSegmentInfo shminfo;
Cursor mac_cursor;
bool mouse_grabbed; // Flag: mouse pointer grabbed, using relative mouse mode
int mouse_last_x, mouse_last_y; // Last mouse position (for relative mode)
};
static driver_base *drv = NULL; // Pointer to currently used driver object
@ -365,6 +379,8 @@ driver_base::driver_base()
driver_base::~driver_base()
{
ungrab_mouse();
if (w) {
XUnmapWindow(x_display, w);
wait_unmapped(w);
@ -421,14 +437,14 @@ void driver_base::update_palette(void)
// Open display
driver_window::driver_window(const video_mode &mode)
: gc(0), img(NULL), have_shm(false), mac_cursor(0)
: gc(0), img(NULL), have_shm(false), mouse_grabbed(false), mac_cursor(0)
{
int width = mode.x, height = mode.y;
int aligned_width = (width + 15) & ~15;
int aligned_height = (height + 15) & ~15;
// Set absolute mouse mode
ADBSetRelMouseMode(false);
ADBSetRelMouseMode(mouse_grabbed);
// Create window
XSetWindowAttributes wattr;
@ -561,6 +577,84 @@ driver_window::~driver_window()
XFreeGC(x_display, gc);
}
// Toggle mouse grab
void driver_window::toggle_mouse_grab(void)
{
if (mouse_grabbed)
ungrab_mouse();
else
grab_mouse();
}
// Grab mouse, switch to relative mouse mode
void driver_window::grab_mouse(void)
{
int result;
for (int i=0; i<10; i++) {
result = XGrabPointer(x_display, w, True, 0,
GrabModeAsync, GrabModeAsync, w, None, CurrentTime);
if (result != AlreadyGrabbed)
break;
Delay_usec(100000);
}
if (result == GrabSuccess) {
ADBSetRelMouseMode(mouse_grabbed = true);
XStoreName(x_display, w, GetString(STR_WINDOW_TITLE_GRABBED));
XSync(x_display, false);
}
}
// Ungrab mouse, switch to absolute mouse mode
void driver_window::ungrab_mouse(void)
{
if (mouse_grabbed) {
XUngrabPointer(x_display, CurrentTime);
XStoreName(x_display, w, GetString(STR_WINDOW_TITLE));
ADBSetRelMouseMode(mouse_grabbed = false);
}
}
// Mouse moved
void driver_window::mouse_moved(int x, int y)
{
if (!mouse_grabbed) {
mouse_last_x = x; mouse_last_y = y;
ADBMouseMoved(x, y);
return;
}
// Warped mouse motion (this code is taken from SDL)
// Post first mouse event
int width = VideoMonitor.mode.x, height = VideoMonitor.mode.y;
int delta_x = x - mouse_last_x, delta_y = y - mouse_last_y;
mouse_last_x = x; mouse_last_y = y;
ADBMouseMoved(delta_x, delta_y);
// Only warp the pointer when it has reached the edge
const int MOUSE_FUDGE_FACTOR = 8;
if (x < MOUSE_FUDGE_FACTOR || x > (width - MOUSE_FUDGE_FACTOR)
|| y < MOUSE_FUDGE_FACTOR || y > (height - MOUSE_FUDGE_FACTOR)) {
XEvent event;
while (XCheckTypedEvent(x_display, MotionNotify, &event)) {
delta_x = x - mouse_last_x; delta_y = y - mouse_last_y;
mouse_last_x = x; mouse_last_y = y;
ADBMouseMoved(delta_x, delta_y);
}
mouse_last_x = width/2;
mouse_last_y = height/2;
XWarpPointer(x_display, None, w, 0, 0, 0, 0, mouse_last_x, mouse_last_y);
for (int i=0; i<10; i++) {
XMaskEvent(x_display, PointerMotionMask, &event);
if (event.xmotion.x > (mouse_last_x - MOUSE_FUDGE_FACTOR)
&& event.xmotion.x < (mouse_last_x + MOUSE_FUDGE_FACTOR)
&& event.xmotion.y > (mouse_last_y - MOUSE_FUDGE_FACTOR)
&& event.xmotion.y < (mouse_last_y + MOUSE_FUDGE_FACTOR))
break;
}
}
}
#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA)
/*
@ -639,8 +733,8 @@ void driver_dga::resume(void)
XMapRaised(x_display, w);
wait_mapped(w);
XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0);
XGrabKeyboard(x_display, rootwin, 1, GrabModeAsync, GrabModeAsync, CurrentTime);
XGrabPointer(x_display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime);
XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
#ifdef ENABLE_XF86_DGA
XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
XF86DGASetViewPort(x_display, screen, 0, 0);
@ -1465,7 +1559,7 @@ void video_set_palette(uint8 *pal, int num_in)
// Recalculate pixel color expansion map
if (!IsDirectMode(VideoMonitor.mode) && (vis->c_class == TrueColor || vis->c_class == DirectColor)) {
for (int i=0; i<256; i++) {
int c = i % num_in; // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier)
int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier)
ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2]);
}
@ -1502,10 +1596,11 @@ void video_switch_to_mode(const video_mode &mode)
/*
* Translate key event to Mac keycode
* Translate key event to Mac keycode, returns -1 if no keycode was found
* and -2 if the key was recognized as a hotkey
*/
static int kc_decode(KeySym ks)
static int kc_decode(KeySym ks, bool key_down)
{
switch (ks) {
case XK_A: case XK_a: return 0x00;
@ -1558,11 +1653,7 @@ static int kc_decode(KeySym ks)
case XK_period: case XK_greater: return 0x2f;
case XK_slash: case XK_question: return 0x2c;
#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA)
case XK_Tab: if (ctrl_down) {drv->suspend(); return -1;} else return 0x30;
#else
case XK_Tab: return 0x30;
#endif
case XK_Tab: if (ctrl_down) {if (key_down) drv->suspend(); return -2;} else return 0x30;
case XK_Return: return 0x24;
case XK_space: return 0x31;
case XK_BackSpace: return 0x33;
@ -1596,13 +1687,13 @@ static int kc_decode(KeySym ks)
case XK_Left: return 0x3b;
case XK_Right: return 0x3c;
case XK_Escape: if (ctrl_down) {quit_full_screen = true; emerg_quit = true; return -1;} else return 0x35;
case XK_Escape: if (ctrl_down) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
case XK_F1: if (ctrl_down) {SysMountFirstFloppy(); return -1;} else return 0x7a;
case XK_F1: if (ctrl_down) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
case XK_F2: return 0x78;
case XK_F3: return 0x63;
case XK_F4: return 0x76;
case XK_F5: return 0x60;
case XK_F5: if (ctrl_down) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
case XK_F6: return 0x61;
case XK_F7: return 0x62;
case XK_F8: return 0x64;
@ -1650,16 +1741,17 @@ static int kc_decode(KeySym ks)
return -1;
}
static int event2keycode(XKeyEvent &ev)
static int event2keycode(XKeyEvent &ev, bool key_down)
{
KeySym ks;
int as;
int i = 0;
do {
ks = XLookupKeysym(&ev, i++);
as = kc_decode(ks);
if (as != -1)
int as = kc_decode(ks, key_down);
if (as >= 0)
return as;
if (as == -2)
return as;
} while (ks != NoSymbol);
@ -1706,20 +1798,19 @@ static void handle_events(void)
}
// Mouse moved
case EnterNotify:
case MotionNotify:
ADBMouseMoved(event.xmotion.x, event.xmotion.y);
drv->mouse_moved(event.xmotion.x, event.xmotion.y);
break;
// Keyboard
case KeyPress: {
int code;
int code = -1;
if (use_keycodes) {
event2keycode(event.xkey); // This is called to process the hotkeys
code = keycode_table[event.xkey.keycode & 0xff];
if (event2keycode(event.xkey, true) != -2) // This is called to process the hotkeys
code = keycode_table[event.xkey.keycode & 0xff];
} else
code = event2keycode(event.xkey);
if (code != -1) {
code = event2keycode(event.xkey, true);
if (code >= 0) {
if (!emul_suspended) {
if (code == 0x39) { // Caps Lock pressed
if (caps_on) {
@ -1741,13 +1832,13 @@ static void handle_events(void)
break;
}
case KeyRelease: {
int code;
int code = -1;
if (use_keycodes) {
event2keycode(event.xkey); // This is called to process the hotkeys
code = keycode_table[event.xkey.keycode & 0xff];
if (event2keycode(event.xkey, false) != -2) // This is called to process the hotkeys
code = keycode_table[event.xkey.keycode & 0xff];
} else
code = event2keycode(event.xkey);
if (code != -1 && code != 0x39) { // Don't propagate Caps Lock releases
code = event2keycode(event.xkey, false);
if (code >= 0 && code != 0x39) { // Don't propagate Caps Lock releases
ADBKeyUp(code);
if (code == 0x36)
ctrl_down = false;
@ -2011,7 +2102,8 @@ static void update_display_static(driver_window *drv)
static inline void possibly_quit_dga_mode()
{
// Quit DGA mode if requested
// Quit DGA mode if requested (something terrible has happened and we
// want to give control back to the user)
if (quit_full_screen) {
quit_full_screen = false;
delete drv;
@ -2019,6 +2111,17 @@ static inline void possibly_quit_dga_mode()
}
}
static inline void possibly_ungrab_mouse()
{
// Ungrab mouse if requested (something terrible has happened and we
// want to give control back to the user)
if (quit_full_screen) {
quit_full_screen = false;
if (drv)
drv->ungrab_mouse();
}
}
static inline void handle_palette_changes(void)
{
LOCK_PALETTE;
@ -2071,8 +2174,8 @@ static void video_refresh_dga_vosf(void)
static void video_refresh_window_vosf(void)
{
// Quit DGA mode if requested
possibly_quit_dga_mode();
// Ungrab mouse if requested
possibly_ungrab_mouse();
// Handle X events
handle_events();
@ -2096,6 +2199,9 @@ static void video_refresh_window_vosf(void)
static void video_refresh_window_static(void)
{
// Ungrab mouse if requested
possibly_ungrab_mouse();
// Handle X events
handle_events();
@ -2112,6 +2218,9 @@ static void video_refresh_window_static(void)
static void video_refresh_window_dynamic(void)
{
// Ungrab mouse if requested
possibly_ungrab_mouse();
// Handle X events
handle_events();

View File

@ -57,6 +57,32 @@ static uint8 mouse_reg_3[2] = {0x63, 0x01}; // Mouse ADB register 3
static uint8 key_reg_2[2] = {0xff, 0xff}; // Keyboard ADB register 2
static uint8 key_reg_3[2] = {0x62, 0x05}; // Keyboard ADB register 3
// ADB mouse input state lock (for platforms that use separate input thread)
static B2_mutex *mouse_lock;
/*
* Initialize ADB emulation
*/
void ADBInit(void)
{
mouse_lock = B2_create_mutex();
}
/*
* Exit ADB emulation
*/
void ADBExit(void)
{
if (mouse_lock) {
B2_delete_mutex(mouse_lock);
mouse_lock = NULL;
}
}
/*
* ADBOp() replacement
@ -198,11 +224,13 @@ void ADBOp(uint8 op, uint8 *data)
void ADBMouseMoved(int x, int y)
{
B2_lock_mutex(mouse_lock);
if (relative_mouse) {
mouse_x += x; mouse_y += y;
} else {
mouse_x = x; mouse_y = y;
}
B2_unlock_mutex(mouse_lock);
}
@ -212,7 +240,9 @@ void ADBMouseMoved(int x, int y)
void ADBMouseDown(int button)
{
B2_lock_mutex(mouse_lock);
mouse_button[button] = true;
B2_unlock_mutex(mouse_lock);
}
@ -222,7 +252,9 @@ void ADBMouseDown(int button)
void ADBMouseUp(int button)
{
B2_lock_mutex(mouse_lock);
mouse_button[button] = false;
B2_unlock_mutex(mouse_lock);
}
@ -280,9 +312,14 @@ void ADBInterrupt(void)
return;
uint32 tmp_data = adb_base + 0x163; // Temporary storage for faked ADB data
// Get position so that it won't change during processing
// Get mouse state
B2_lock_mutex(mouse_lock);
int mx = mouse_x;
int my = mouse_y;
if (relative_mouse)
mouse_x = mouse_y = 0;
int mb[3] = {mouse_button[0], mouse_button[1], mouse_button[2]};
B2_unlock_mutex(mouse_lock);
uint32 key_base = adb_base + 4;
uint32 mouse_base = adb_base + 16;
@ -290,20 +327,20 @@ void ADBInterrupt(void)
if (relative_mouse) {
// Mouse movement (relative) and buttons
if (mx != 0 || my != 0 || mouse_button[0] != old_mouse_button[0] || mouse_button[1] != old_mouse_button[1] || mouse_button[2] != old_mouse_button[2]) {
if (mx != 0 || my != 0 || mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) {
// Call mouse ADB handler
if (mouse_reg_3[1] == 4) {
// Extended mouse protocol
WriteMacInt8(tmp_data, 3);
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80));
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80));
WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mouse_button[2] ? 0x08 : 0x88));
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80));
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80));
WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mb[2] ? 0x08 : 0x88));
} else {
// 100/200 dpi mode
WriteMacInt8(tmp_data, 2);
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80));
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80));
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80));
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80));
}
r.a[0] = tmp_data;
r.a[1] = ReadMacInt32(mouse_base);
@ -312,10 +349,9 @@ void ADBInterrupt(void)
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
Execute68k(r.a[1], &r);
mouse_x = mouse_y = 0;
old_mouse_button[0] = mouse_button[0];
old_mouse_button[1] = mouse_button[1];
old_mouse_button[2] = mouse_button[2];
old_mouse_button[0] = mb[0];
old_mouse_button[1] = mb[1];
old_mouse_button[2] = mb[2];
}
} else {
@ -347,21 +383,21 @@ void ADBInterrupt(void)
}
// Send mouse button events
if (mouse_button[0] != old_mouse_button[0]) {
if (mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) {
uint32 mouse_base = adb_base + 16;
// Call mouse ADB handler
if (mouse_reg_3[1] == 4) {
// Extended mouse protocol
WriteMacInt8(tmp_data, 3);
WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80);
WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80);
WriteMacInt8(tmp_data + 3, mouse_button[2] ? 0x08 : 0x88);
WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80);
WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80);
WriteMacInt8(tmp_data + 3, mb[2] ? 0x08 : 0x88);
} else {
// 100/200 dpi mode
WriteMacInt8(tmp_data, 2);
WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80);
WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80);
WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80);
WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80);
}
r.a[0] = tmp_data;
r.a[1] = ReadMacInt32(mouse_base);
@ -370,9 +406,9 @@ void ADBInterrupt(void)
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
Execute68k(r.a[1], &r);
old_mouse_button[0] = mouse_button[0];
old_mouse_button[1] = mouse_button[1];
old_mouse_button[2] = mouse_button[2];
old_mouse_button[0] = mb[0];
old_mouse_button[1] = mb[1];
old_mouse_button[2] = mb[2];
}
}

View File

@ -68,6 +68,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7],
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7],
r->sr);
VideoQuitFullScreen();
#ifdef ENABLE_MON
char *arg[4] = {"mon", "-m", "-r", NULL};
mon(3, arg);

View File

@ -21,6 +21,9 @@
#ifndef ADB_H
#define ADB_H
extern void ADBInit(void);
extern void ADBExit(void);
extern void ADBOp(uint8 op, uint8 *data);
extern void ADBMouseMoved(int x, int y);

View File

@ -51,6 +51,13 @@ extern void WarningAlert(const char *text); // Display warning alert
extern void WarningAlert(int string_id);
extern bool ChoiceAlert(const char *text, const char *pos, const char *neg); // Display choice alert
// Mutexes (non-recursive)
struct B2_mutex;
extern B2_mutex *B2_create_mutex(void);
extern void B2_lock_mutex(B2_mutex *mutex);
extern void B2_unlock_mutex(B2_mutex *mutex);
extern void B2_delete_mutex(B2_mutex *mutex);
// Interrupt flags
enum {
INTFLAG_60HZ = 1, // 60.15Hz VBL

View File

@ -33,6 +33,7 @@
#include "serial.h"
#include "ether.h"
#include "clip.h"
#include "adb.h"
#include "rom_patches.h"
#include "user_strings.h"
#include "prefs.h"
@ -132,6 +133,9 @@ bool InitAll(void)
// Init clipboard
ClipInit();
// Init ADB
ADBInit();
// Init audio
AudioInit();
@ -188,6 +192,9 @@ void ExitAll(void)
// Exit audio
AudioExit();
// Exit ADB
ADBExit();
// Exit clipboard
ClipExit();