diff --git a/trunk/src/drivers/sdl/input.cpp b/trunk/src/drivers/sdl/input.cpp index 2a89a789..3cf13b3c 100644 --- a/trunk/src/drivers/sdl/input.cpp +++ b/trunk/src/drivers/sdl/input.cpp @@ -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; } diff --git a/trunk/src/drivers/win/input.cpp b/trunk/src/drivers/win/input.cpp index 58143ae0..3e93e7a4 100644 --- a/trunk/src/drivers/win/input.cpp +++ b/trunk/src/drivers/win/input.cpp @@ -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; diff --git a/trunk/src/drivers/win/window.cpp b/trunk/src/drivers/win/window.cpp index 126d54e5..5fc4583b 100644 --- a/trunk/src/drivers/win/window.cpp +++ b/trunk/src/drivers/win/window.cpp @@ -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) { diff --git a/trunk/src/drivers/win/window.h b/trunk/src/drivers/win/window.h index d0f145c8..66284072 100644 --- a/trunk/src/drivers/win/window.h +++ b/trunk/src/drivers/win/window.h @@ -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(); diff --git a/trunk/src/input/mouse.cpp b/trunk/src/input/mouse.cpp index 17adf69c..19768252 100644 --- a/trunk/src/input/mouse.cpp +++ b/trunk/src/input/mouse.cpp @@ -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}; diff --git a/trunk/src/input/snesmouse.cpp b/trunk/src/input/snesmouse.cpp index 4d13781e..782a45a7 100644 --- a/trunk/src/input/snesmouse.cpp +++ b/trunk/src/input/snesmouse.cpp @@ -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 }