Mesen-X/GUI.NET/CursorManager.cs

192 lines
4.9 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
namespace Mesen.GUI
{
public class CursorManager
{
private static bool _cursorHidden = false;
private static Point _lastPosition;
private static Timer _tmrHideMouse = new Timer();
private static Timer _tmrCheckMouseMove = new Timer();
private static bool _mouseCaptured = false;
static CursorManager()
{
_tmrHideMouse.Interval = 3000;
_tmrHideMouse.Tick += tmrHideMouse_Tick;
_tmrCheckMouseMove.Interval = 500;
_tmrCheckMouseMove.Tick += tmrCheckMouseMove_Tick;
_tmrCheckMouseMove.Start();
}
public static void StopTimers()
{
_tmrCheckMouseMove.Stop();
_tmrHideMouse.Stop();
}
private static void tmrCheckMouseMove_Tick(object sender, EventArgs e)
{
//Rarely the cursor becomes hidden despite leaving the window or moving
//Have not been able to find a reliable way to reproduce it yet
//This is a patch to prevent that bug from having any negative impact
if(!_mouseCaptured && _lastPosition != Cursor.Position) {
_lastPosition = Cursor.Position;
bool running = InteropEmu.IsRunning() && !InteropEmu.IsPaused();
if(running && ConfigManager.Config.InputInfo.HideMousePointerForZapper && CursorManager.IsLightGun) {
//Keep mouse hidden when using zapper if option to hide mouse is enabled
return;
}
ShowMouse();
}
}
private static void tmrHideMouse_Tick(object sender, EventArgs e)
{
if(InteropEmu.IsRunning() && !InteropEmu.IsPaused()) {
HideMouse();
_tmrHideMouse.Stop();
} else {
ShowMouse();
_tmrHideMouse.Stop();
}
}
private static void ShowMouse()
{
if(_cursorHidden) {
Cursor.Show();
_cursorHidden = false;
}
}
private static void HideMouse()
{
if(!_cursorHidden) {
Cursor.Hide();
_cursorHidden = true;
}
}
private static bool IsLightGun
{
get { return InteropEmu.HasZapper() || (InteropEmu.GetConsoleType() == ConsoleType.Famicom && InteropEmu.GetExpansionDevice() == InteropEmu.ExpansionPortDevice.BandaiHyperShot); }
}
public static bool NeedMouseIcon
{
get { return CursorManager.IsLightGun || (InteropEmu.GetConsoleType() == ConsoleType.Famicom && InteropEmu.GetExpansionDevice() == InteropEmu.ExpansionPortDevice.OekaKidsTablet); }
}
public static void OnMouseMove(Control ctrl)
{
if(_mouseCaptured && AllowMouseCapture) {
HideMouse();
_tmrHideMouse.Stop();
Form frm = Application.OpenForms[0];
Point centerPos = frm.PointToScreen(new Point(frm.Width / 2, frm.Height / 2));
Point diff = new Point(Cursor.Position.X - centerPos.X, Cursor.Position.Y - centerPos.Y);
if(diff.X != 0 || diff.Y != 0) {
InteropEmu.SetMouseMovement((Int16)diff.X, (Int16)diff.Y);
Cursor.Position = centerPos;
}
} else {
_mouseCaptured = false;
if(!InteropEmu.IsRunning() || InteropEmu.IsPaused()) {
ShowMouse();
} else if(ConfigManager.Config.InputInfo.HideMousePointerForZapper && CursorManager.IsLightGun) {
//Keep mouse hidden when using zapper if option to hide mouse is enabled
HideMouse();
return;
}
_tmrHideMouse.Stop();
if(!CursorManager.NeedMouseIcon) {
//Only hide mouse if no zapper (otherwise this could be pretty annoying)
ctrl.Cursor = Cursors.Default;
if(InteropEmu.IsRunning() && !InteropEmu.IsPaused()) {
_tmrHideMouse.Start();
}
}
}
}
public static void OnMouseLeave()
{
_tmrHideMouse.Stop();
ShowMouse();
}
public static bool AllowMouseCapture
{
get
{
if(!InteropEmu.IsRunning()) {
return false;
}
if(InteropEmu.IsPaused()) {
return false;
}
if(InteropEmu.CheckFlag(EmulationFlags.InBackground)) {
return false;
}
if(InteropEmu.GetConsoleType() == ConsoleType.Famicom) {
switch(InteropEmu.GetExpansionDevice()) {
case InteropEmu.ExpansionPortDevice.ArkanoidController:
case InteropEmu.ExpansionPortDevice.HoriTrack:
return true;
}
}
for(int i = 0; i < 4; i++) {
switch(InteropEmu.GetControllerType(i)) {
case InteropEmu.ControllerType.ArkanoidController:
case InteropEmu.ControllerType.SnesMouse:
case InteropEmu.ControllerType.SuborMouse:
return true;
}
}
return false;
}
}
public static void ReleaseMouse()
{
_mouseCaptured = false;
ShowMouse();
}
public static void CaptureMouse()
{
if(AllowMouseCapture) {
if(!_mouseCaptured) {
InteropEmu.DisplayMessage("Input", ResourceHelper.GetMessage("MouseModeEnabled"));
}
_mouseCaptured = true;
HideMouse();
Form frm = Application.OpenForms[0];
Point centerPos = frm.PointToScreen(new Point(frm.Width / 2, frm.Height / 2));
Cursor.Position = centerPos;
}
}
}
}