mirror of
https://github.com/ctm/executor.git
synced 2024-11-16 05:05:22 +00:00
255 lines
5.8 KiB
C
255 lines
5.8 KiB
C
/* Copyright 1995 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_adb[] =
|
|
"$Id: adb.c 63 2004-12-24 18:19:43Z ctm $";
|
|
#endif
|
|
|
|
#include "rsys/common.h"
|
|
#include "EventMgr.h"
|
|
#include "OSEvent.h"
|
|
#include "ADB.h"
|
|
#include "rsys/adb.h"
|
|
#include "rsys/osevent.h"
|
|
#include "rsys/pstuff.h"
|
|
|
|
#include <stdarg.h>
|
|
/*
|
|
* NOTE: most of the code in adb.c was originally written solely to support
|
|
* apeiron (and potentially other games). Apeiron patches the mouse ADB
|
|
* service routines and makes a mental note of some of the data that it
|
|
* finds in there. Specifically it examines:
|
|
*
|
|
* a0@(1) bits 0-6 as a signed (bit 6 is sign bit) y delta of the mouse
|
|
* a0@(2) bits 0-6 as a signed (bit 6 is sign bit) x delta of the mouse
|
|
* a0@(1) bit 7 represents the current button state (0 = down)
|
|
* a0@(2) bit 7 must be set
|
|
*
|
|
* We are playing very fast and loose with ADB below, specifically trying to
|
|
* provide just enough information so Apeiron can detect mouse motion and
|
|
* mouse presses and releases. We realize that this code, especially
|
|
* adb_apeiron_hack and the front-end code that calls it, have many problems:
|
|
*
|
|
* We "support" the mouse, but not the keyboard
|
|
* We count on the installed driver not modifying the data
|
|
* We count on the installed driver not caring about other low-memory
|
|
* globals (i.e. we update them before the "driver" is called)
|
|
* The stub driver that we give them never does any work, so it can't
|
|
* be used to simulate mouse activity
|
|
* Probably tons more; the hack is so incomplete that it doesn't even
|
|
* make sense to think of all the ways it is incomplete
|
|
*/
|
|
|
|
PUBLIC void
|
|
ADBReInit (void)
|
|
{
|
|
warning_unimplemented (NULL_STRING);
|
|
}
|
|
|
|
PUBLIC OSErr
|
|
ADBOp (Ptr data, ProcPtr procp, Ptr buffer, INTEGER command)
|
|
{
|
|
warning_unimplemented (NULL_STRING);
|
|
return noErr;
|
|
}
|
|
|
|
PUBLIC INTEGER
|
|
CountADBs (void)
|
|
{
|
|
warning_unimplemented (NULL_STRING);
|
|
return 1;
|
|
}
|
|
|
|
enum { SPOOFED_MOUSE_ADDR = 3 };
|
|
|
|
PRIVATE Ptr adb_service_procp = 0; /* stored as though in lowglobal */
|
|
PRIVATE Ptr adb_data_ptr = (Ptr) 0x90ABCDEF;
|
|
|
|
PUBLIC void
|
|
C_adb_service_stub (void)
|
|
{
|
|
}
|
|
|
|
PUBLIC void
|
|
reset_adb_vector (void)
|
|
{
|
|
adb_service_procp = 0;
|
|
}
|
|
|
|
PUBLIC OSErr
|
|
GetIndADB (ADBDataBlock *adbp, INTEGER index)
|
|
{
|
|
OSErr retval;
|
|
|
|
warning_unimplemented (NULL_STRING);
|
|
if (index != 1)
|
|
retval = -1;
|
|
else
|
|
{
|
|
adbp->devType = CB (0); /* should check on Mac to see what mouse is */
|
|
adbp->origADBAddr = CB (SPOOFED_MOUSE_ADDR);
|
|
if (!adb_service_procp)
|
|
adb_service_procp = (Ptr) RM (P_adb_service_stub);
|
|
adbp->dbServiceRtPtr = adb_service_procp;
|
|
adbp->dbDataAreaAddr = RM (adb_data_ptr);
|
|
retval = SPOOFED_MOUSE_ADDR;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
PUBLIC OSErr
|
|
GetADBInfo (ADBDataBlock *adbp, INTEGER address)
|
|
{
|
|
OSErr retval;
|
|
|
|
warning_unimplemented (NULL_STRING);
|
|
if (address != SPOOFED_MOUSE_ADDR)
|
|
retval = -1;
|
|
else
|
|
retval = GetIndADB (adbp, 1);
|
|
return retval;
|
|
}
|
|
|
|
PUBLIC OSErr
|
|
SetADBInfo (ADBSetInfoBlock *adbp, INTEGER address)
|
|
{
|
|
OSErr retval;
|
|
|
|
warning_unimplemented (NULL_STRING);
|
|
if (address != SPOOFED_MOUSE_ADDR)
|
|
retval = -1;
|
|
else
|
|
{
|
|
adb_service_procp = adbp->siServiceRtPtr;
|
|
adb_data_ptr = MR (adbp->siDataAreaAddr);
|
|
retval = noErr;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE boolean_t
|
|
adb_vector_is_not_our_own (void)
|
|
{
|
|
boolean_t retval;
|
|
|
|
retval = adb_service_procp != 0 &&
|
|
adb_service_procp != (Ptr) RM (P_adb_service_stub);
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE void
|
|
call_patched_adb_vector (char *message)
|
|
{
|
|
unsigned long save_d0, save_a0;
|
|
|
|
save_d0 = EM_D0;
|
|
save_a0 = EM_A0;
|
|
EM_D0 = SPOOFED_MOUSE_ADDR << 4; /* based on Apeiron's code */
|
|
EM_A0 = (unsigned long) US_TO_SYN68K(message);
|
|
CALL_EMULATOR ((syn68k_addr_t) CL ((long) adb_service_procp));
|
|
EM_D0 = save_d0;
|
|
EM_A0 = save_a0;
|
|
}
|
|
|
|
static int
|
|
pin (int val, int min, int max)
|
|
{
|
|
int retval;
|
|
|
|
if (val < min)
|
|
retval = min;
|
|
else if (val > max)
|
|
retval = max;
|
|
else
|
|
retval = val;
|
|
return retval;
|
|
}
|
|
|
|
enum { LENGTH_OFFSET = 0, Y_OFFSET = 1, X_OFFSET = 2, MOUSE_OFFSET = 1 };
|
|
enum { BUTTON_UP_BIT = 0x80 };
|
|
|
|
/*
|
|
* if deltas_p is TRUE, dx and dy are supplied as arguments, otherwise they
|
|
* have to be computed as deltas off the last known MouseLocation. Eventually
|
|
* we should probably always have them be supplied as arguments since we
|
|
* should probably make our mouse handling more true to real life.
|
|
*/
|
|
|
|
PUBLIC void
|
|
adb_apeiron_hack (boolean_t deltas_p, ...)
|
|
{
|
|
static boolean_t been_here = FALSE;
|
|
static long old_x;
|
|
static long old_y;
|
|
long x, y;
|
|
boolean_t button_is_down;
|
|
char message[3];
|
|
|
|
x = CW (MouseLocation.h);
|
|
y = CW (MouseLocation.v);
|
|
button_is_down = !(ROMlib_mods & btnState);
|
|
|
|
/* begin code for PegLeg */
|
|
|
|
if (button_is_down)
|
|
MBState = 0;
|
|
else
|
|
MBState = 0xFF;
|
|
|
|
MTemp.h = MouseLocation.h;
|
|
MTemp.v = MouseLocation.v;
|
|
|
|
/* end code for PegLeg */
|
|
|
|
MouseLocation2 = MouseLocation;
|
|
|
|
if (!been_here)
|
|
{
|
|
old_x = x;
|
|
old_y = y;
|
|
been_here = TRUE;
|
|
}
|
|
if (adb_vector_is_not_our_own ())
|
|
{
|
|
int dx, dy;
|
|
|
|
if (deltas_p)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start (ap, deltas_p);
|
|
dx = va_arg (ap, int);
|
|
dy = va_arg (ap, int);
|
|
va_end (ap);
|
|
}
|
|
else
|
|
{
|
|
dx = x - old_x;
|
|
dy = y - old_y;
|
|
}
|
|
|
|
do
|
|
{
|
|
int this_dx, this_dy;
|
|
|
|
this_dx = pin (dx, -64, 63);
|
|
this_dy = pin (dy, -64, 63);
|
|
message[LENGTH_OFFSET] = sizeof (message) - 1;
|
|
message[X_OFFSET] = (this_dx) | 0x80; /* Apeiron expects the high */
|
|
message[Y_OFFSET] = (this_dy) | 0x80; /* bit to be set. */
|
|
if (button_is_down)
|
|
message[MOUSE_OFFSET] &= ~BUTTON_UP_BIT;
|
|
else
|
|
message[MOUSE_OFFSET] |= BUTTON_UP_BIT;
|
|
call_patched_adb_vector (message);
|
|
dx -= this_dx;
|
|
dy -= this_dy;
|
|
}
|
|
while (dx || dy);
|
|
}
|
|
old_x = x;
|
|
old_y = y;
|
|
}
|