Relative mouse motion interface for SNES and Subor mouse; this allows fullscreen mode to keep the mouse fixed in the centre of the screen, permitting infinite motion.
This commit is contained in:
parent
89a75e28fc
commit
b632b1d7a5
|
@ -894,10 +894,6 @@ GetMouseData (uint32 (&d)[3])
|
|||
int x, y;
|
||||
uint32 t;
|
||||
|
||||
// Don't get input when a movie is playing back
|
||||
if (FCEUMOV_Mode (MOVIEMODE_PLAY))
|
||||
return;
|
||||
|
||||
// retrieve the state of the mouse from SDL
|
||||
t = SDL_GetMouseState (&x, &y);
|
||||
#ifdef _GTK
|
||||
|
@ -934,6 +930,35 @@ GetMouseData (uint32 (&d)[3])
|
|||
// printf("mouse %d %d %d\n", d[0], d[1], d[2]);
|
||||
}
|
||||
|
||||
void GetMouseRelative (int32 (&d)[3])
|
||||
{
|
||||
// converts absolute mouse positions to relative ones for input devices that require this
|
||||
|
||||
// The windows version additionally in fullscreen will constantly return the mouse to center screen
|
||||
// after reading it, so that the user can endlessly keep moving the mouse.
|
||||
// The same should eventually be implemented here, but this version should minimally provide
|
||||
// the necessary relative input, piggybacking on the already implemented GetMouseData.
|
||||
|
||||
static int cx = -1;
|
||||
static int cy = -1;
|
||||
|
||||
uint32 md[3];
|
||||
GetMouseData (md);
|
||||
|
||||
if (cx < 0 || cy < 0)
|
||||
{
|
||||
cx = md[0];
|
||||
cy = md[1];
|
||||
}
|
||||
|
||||
int dx = md[0] - cx;
|
||||
int dy = md[1] - cy;
|
||||
|
||||
d[0] = dx;
|
||||
d[1] = dy;
|
||||
d[2] = md[2]; // buttons
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles outstanding SDL events.
|
||||
*/
|
||||
|
@ -1259,6 +1284,7 @@ UpdatePPadData (int w)
|
|||
}
|
||||
|
||||
static uint32 MouseData[3] = { 0, 0, 0 };
|
||||
static int32 MouseRelative[3] = { 0, 0, 0 };
|
||||
|
||||
static uint8 fkbkeys[0x48];
|
||||
|
||||
|
@ -1293,7 +1319,7 @@ void FCEUD_UpdateInput ()
|
|||
break;
|
||||
case SI_MOUSE:
|
||||
case SI_SNES_MOUSE:
|
||||
t |= 2;
|
||||
t |= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1338,9 +1364,17 @@ void FCEUD_UpdateInput ()
|
|||
UpdateGamepad ();
|
||||
}
|
||||
|
||||
if (t & 2)
|
||||
// Don't get input when a movie is playing back
|
||||
if (!FCEUMOV_Mode (MOVIEMODE_PLAY))
|
||||
{
|
||||
GetMouseData (MouseData);
|
||||
if (t & 2)
|
||||
{
|
||||
GetMouseData (MouseData);
|
||||
}
|
||||
if (t & 4)
|
||||
{
|
||||
GetMouseRelative (MouseRelative);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1405,7 +1439,7 @@ void InitInputInterface ()
|
|||
break;
|
||||
case SI_MOUSE:
|
||||
case SI_SNES_MOUSE:
|
||||
InputDPtr = MouseData;
|
||||
InputDPtr = MouseRelative;
|
||||
t |= 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ static void PresetExport(int preset);
|
|||
static void PresetImport(int preset);
|
||||
|
||||
static uint32 MouseData[3];
|
||||
static int32 MouseRelative[3];
|
||||
|
||||
//force the input types suggested by the game
|
||||
void ParseGIInput(FCEUGI *gi)
|
||||
|
@ -418,7 +419,9 @@ void UpdateRawInputAndHotkeys()
|
|||
|
||||
void FCEUD_UpdateInput()
|
||||
{
|
||||
bool joy=false,mouse=false;
|
||||
bool joy=false;
|
||||
bool mouse=false;
|
||||
bool mouse_relative=false;
|
||||
EMOVIEMODE FCEUMOVState = FCEUMOV_Mode();
|
||||
|
||||
UpdateRawInputAndHotkeys();
|
||||
|
@ -431,8 +434,8 @@ void FCEUD_UpdateInput()
|
|||
case SI_SNES:
|
||||
UpdateGamepad(true);
|
||||
break;
|
||||
case SI_MOUSE: mouse=true; break;
|
||||
case SI_SNES_MOUSE: mouse=true; break;
|
||||
case SI_MOUSE: mouse_relative=true; break;
|
||||
case SI_SNES_MOUSE: mouse_relative=true; break;
|
||||
case SI_ARKANOID: mouse=true; break;
|
||||
case SI_ZAPPER: mouse=true; break;
|
||||
case SI_POWERPADA:
|
||||
|
@ -466,9 +469,11 @@ void FCEUD_UpdateInput()
|
|||
if(joy)
|
||||
UpdateGamepad(false);
|
||||
|
||||
if(mouse)
|
||||
if(FCEUMOVState != MOVIEMODE_PLAY) //FatRatKnight: Moved this if out of the function
|
||||
GetMouseData(MouseData); //A more concise fix may be desired.
|
||||
if (FCEUMOVState != MOVIEMODE_PLAY) //FatRatKnight: Moved this if out of the function, a more concise fix may be desired.
|
||||
{
|
||||
if (mouse) GetMouseData(MouseData);
|
||||
if (mouse_relative) GetMouseRelative(MouseRelative);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,10 +523,10 @@ void InitInputPorts(bool fourscore)
|
|||
InputDPtr=MouseData;
|
||||
break;
|
||||
case SI_MOUSE:
|
||||
InputDPtr=MouseData;
|
||||
InputDPtr=MouseRelative;
|
||||
break;
|
||||
case SI_SNES_MOUSE:
|
||||
InputDPtr=MouseData;
|
||||
InputDPtr=MouseRelative;
|
||||
break;
|
||||
case SI_SNES:
|
||||
InputDPtr=snespad_return;
|
||||
|
|
|
@ -1200,6 +1200,46 @@ void GetMouseData(uint32 (&md)[3])
|
|||
md[2] = ((mouseb == MK_LBUTTON) ? 1 : 0) | (( mouseb == MK_RBUTTON ) ? 2 : 0);
|
||||
}
|
||||
|
||||
void GetMouseRelative(int32 (&md)[3])
|
||||
{
|
||||
static int cx = -1;
|
||||
static int cy = -1;
|
||||
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
|
||||
bool constrain = (fullscreen != 0) && (nofocus == 0);
|
||||
|
||||
if (constrain || cx < 0 || cy < 0)
|
||||
{
|
||||
RECT window;
|
||||
GetWindowRect(hAppWnd, &window);
|
||||
cx = (window.left + window.right) / 2;
|
||||
cy = (window.top + window.bottom) / 2;
|
||||
}
|
||||
|
||||
POINT cursor;
|
||||
if (GetCursorPos(&cursor))
|
||||
{
|
||||
dx = cursor.x - cx;
|
||||
dy = cursor.y - cy;
|
||||
|
||||
if (constrain)
|
||||
{
|
||||
SetCursorPos(cx,cy);
|
||||
}
|
||||
else
|
||||
{
|
||||
cx = cursor.x;
|
||||
cy = cursor.y;
|
||||
}
|
||||
}
|
||||
|
||||
md[0] = dx;
|
||||
md[1] = dy;
|
||||
md[2] = ((mouseb == MK_LBUTTON) ? 1 : 0) | (( mouseb == MK_RBUTTON ) ? 2 : 0);
|
||||
}
|
||||
|
||||
void DumpSubtitles(HWND hWnd)
|
||||
{
|
||||
const char filter[]="Subtitles files (*.srt)\0*.srt\0All Files (*.*)\0*.*\0\0";
|
||||
|
@ -2338,8 +2378,8 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|||
break;
|
||||
}
|
||||
|
||||
if(wParam==VK_F10)
|
||||
break; // 11.12.08 CH4 Disable F10 as System Key dammit
|
||||
if(wParam==VK_F10)
|
||||
break; // 11.12.08 CH4 Disable F10 as System Key dammit
|
||||
/*
|
||||
if(wParam == VK_RETURN)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ void LoadNewGamey(HWND hParent, const char *initialdir);
|
|||
int BrowseForFolder(HWND hParent, const char *htext, char *buf);
|
||||
void SetMainWindowStuff();
|
||||
void GetMouseData(uint32 (&md)[3]);
|
||||
void GetMouseRelative(int32 (&md)[3]);
|
||||
//void ChangeMenuItemText(int menuitem, string text);
|
||||
void UpdateMenuHotkeys();
|
||||
|
||||
|
|
|
@ -27,27 +27,28 @@
|
|||
|
||||
typedef struct {
|
||||
uint8 latch;
|
||||
int32 mx,my;
|
||||
int32 lmx,lmy;
|
||||
int32 dx,dy;
|
||||
uint32 mb;
|
||||
} MOUSE;
|
||||
|
||||
static MOUSE Mouse;
|
||||
|
||||
// since this game only picks up 1 mickey per frame,
|
||||
// allow a single delta to spread out over a few frames
|
||||
// to make it easier to move.
|
||||
const int INERTIA = 32;
|
||||
|
||||
static void StrobeMOUSE(int w)
|
||||
{
|
||||
Mouse.latch = Mouse.mb & 0x03;
|
||||
|
||||
int32 dx = Mouse.mx - Mouse.lmx;
|
||||
int32 dy = Mouse.my - Mouse.lmy;
|
||||
int32 dx = Mouse.dx;
|
||||
int32 dy = Mouse.dy;
|
||||
|
||||
Mouse.lmx = Mouse.mx;
|
||||
Mouse.lmy = Mouse.my;
|
||||
|
||||
if (dx > 0) Mouse.latch |= (0x2 << 2);
|
||||
else if (dx < 0) Mouse.latch |= (0x3 << 2);
|
||||
if (dy > 0) Mouse.latch |= (0x2 << 4);
|
||||
else if (dy < 0) Mouse.latch |= (0x3 << 4);
|
||||
if (dx > 0) { Mouse.latch |= (0x2 << 2); --Mouse.dx; }
|
||||
else if (dx < 0) { Mouse.latch |= (0x3 << 2); ++Mouse.dx; }
|
||||
if (dy > 0) { Mouse.latch |= (0x2 << 4); --Mouse.dy; }
|
||||
else if (dy < 0) { Mouse.latch |= (0x3 << 4); ++Mouse.dy; }
|
||||
|
||||
//FCEU_printf("Subor Mouse: %02X\n",Mouse.latch);
|
||||
}
|
||||
|
@ -62,9 +63,15 @@ static uint8 ReadMOUSE(int w)
|
|||
static void UpdateMOUSE(int w, void *data, int arg)
|
||||
{
|
||||
uint32 *ptr=(uint32*)data;
|
||||
Mouse.mx = ptr[0];
|
||||
Mouse.my = ptr[1];
|
||||
Mouse.dx += ptr[0]; ptr[0] = 0;
|
||||
Mouse.dy += ptr[1]; ptr[1] = 0;
|
||||
Mouse.mb = ptr[2];
|
||||
|
||||
if (Mouse.dx > INERTIA) Mouse.dx = INERTIA;
|
||||
else if (Mouse.dx < -INERTIA) Mouse.dx = -INERTIA;
|
||||
|
||||
if (Mouse.dy > INERTIA) Mouse.dy = INERTIA;
|
||||
else if (Mouse.dy < -INERTIA) Mouse.dy = -INERTIA;
|
||||
}
|
||||
|
||||
static INPUTC MOUSEC={ReadMOUSE,0,StrobeMOUSE,UpdateMOUSE,0,0};
|
||||
|
|
|
@ -26,9 +26,8 @@ typedef struct {
|
|||
bool strobe;
|
||||
uint32 latch; // latched data (read when strobe goes high to low)
|
||||
uint32 sensitivity; // reading while strobe is high cycles sensitivity 0,1,2
|
||||
int32 mx, my; // current screen location
|
||||
int32 lmx, lmy; // last latched location
|
||||
uint32 mb; // current buttons
|
||||
int32 dx, dy; // relative position to communicate
|
||||
int32 mb; // current buttons
|
||||
} SNES_MOUSE;
|
||||
|
||||
static SNES_MOUSE SNESMouse;
|
||||
|
@ -53,11 +52,10 @@ static void WriteSNESMouse(uint8 v)
|
|||
|
||||
if (SNESMouse.strobe && !strobing)
|
||||
{
|
||||
int dx = SNESMouse.mx - SNESMouse.lmx;
|
||||
int dy = SNESMouse.my - SNESMouse.lmy;
|
||||
|
||||
SNESMouse.lmx = SNESMouse.mx;
|
||||
SNESMouse.lmy = SNESMouse.my;
|
||||
int dx = SNESMouse.dx;
|
||||
int dy = SNESMouse.dy;
|
||||
SNESMouse.dx = 0;
|
||||
SNESMouse.dy = 0;
|
||||
|
||||
// convert to sign and magnitude
|
||||
bool sx = (dx < 0);
|
||||
|
@ -91,9 +89,10 @@ static void WriteSNESMouse(uint8 v)
|
|||
|
||||
static void UpdateSNESMouse(int w, void *data, int arg)
|
||||
{
|
||||
uint32 *ptr=(uint32*)data;
|
||||
SNESMouse.mx = ptr[0]; // screen position
|
||||
SNESMouse.my = ptr[1];
|
||||
int32 *ptr=(int32*)data;
|
||||
|
||||
SNESMouse.dx += ptr[0]; ptr[0] = 0;
|
||||
SNESMouse.dy += ptr[1]; ptr[1] = 0;
|
||||
SNESMouse.mb = ptr[2] & 3; // bit 0 = left button, bit 1 = right button
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue