Пример #1
0
		public static void Initialize()
		{
			if (dinput == null)
				dinput = new DirectInput();

			Devices = new List<GamePad>();

			foreach (DeviceInstance device in dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
			{
				Console.WriteLine("joydevice: {0} `{1}`", device.InstanceGuid, device.ProductName);

				if (device.ProductName.Contains("XBOX 360"))
					continue; // Don't input XBOX 360 controllers into here; we'll process them via XInput (there are limitations in some trigger axes when xbox pads go over xinput)

				var joystick = new Joystick(dinput, device.InstanceGuid);
				joystick.SetCooperativeLevel(GlobalWin.MainForm.Handle, CooperativeLevel.Background | CooperativeLevel.Nonexclusive);
				foreach (DeviceObjectInstance deviceObject in joystick.GetObjects())
				{
					if ((deviceObject.ObjectType & ObjectDeviceType.Axis) != 0)
						joystick.GetObjectPropertiesById((int)deviceObject.ObjectType).SetRange(-1000, 1000);
				}
				joystick.Acquire();

				GamePad p = new GamePad(device.InstanceName, device.InstanceGuid, joystick);
				Devices.Add(p);
			}
		}
Пример #2
0
        private void UpdateThreadProc()
        {
            while (true)
            {
                var keyEvents = OSTailoredCode.IsUnixHost
                                        ? OTK_Keyboard.Update()
                                        : KeyInput.Update().Concat(IPCKeyInput.Update());
                if (OSTailoredCode.IsUnixHost)
                {
                    OTK_GamePad.UpdateAll();
                }
                else
                {
                    GamePad.UpdateAll();
                    GamePad360.UpdateAll();
                }

                //this block is going to massively modify data structures that the binding method uses, so we have to lock it all
                lock (this)
                {
                    _newEvents.Clear();

                    //analyze keys
                    foreach (var ke in keyEvents)
                    {
                        HandleButton(ke.Key.ToString(), ke.Pressed, InputFocus.Keyboard);
                    }

                    lock (_floatValues)
                    {
                        //FloatValues.Clear();

                        // analyze OpenTK xinput (or is it libinput?)
                        foreach (var pad in OTK_GamePad.EnumerateDevices())
                        {
                            foreach (var but in pad.buttonObjects)
                            {
                                HandleButton(pad.InputNamePrefix + but.ButtonName, but.ButtonAction(), InputFocus.Pad);
                            }
                            foreach (var sv in pad.GetFloats())
                            {
                                var n = $"{pad.InputNamePrefix}{sv.Item1} Axis";
                                var f = sv.Item2;
                                if (_trackDeltas)
                                {
                                    _floatDeltas[n] += Math.Abs(f - _floatValues[n]);
                                }
                                _floatValues[n] = f;
                            }
                        }

                        // analyze xinput
                        foreach (var pad in GamePad360.EnumerateDevices())
                        {
                            string xName = $"X{pad.PlayerNumber} ";
                            for (int b = 0; b < pad.NumButtons; b++)
                            {
                                HandleButton(xName + pad.ButtonName(b), pad.Pressed(b), InputFocus.Pad);
                            }
                            foreach (var sv in pad.GetFloats())
                            {
                                string n = xName + sv.Item1;
                                float  f = sv.Item2;
                                if (_trackDeltas)
                                {
                                    _floatDeltas[n] += Math.Abs(f - _floatValues[n]);
                                }
                                _floatValues[n] = f;
                            }
                        }

                        // analyze joysticks
                        foreach (var pad in GamePad.EnumerateDevices())
                        {
                            string jName = $"J{pad.PlayerNumber} ";
                            for (int b = 0; b < pad.NumButtons; b++)
                            {
                                HandleButton(jName + pad.ButtonName(b), pad.Pressed(b), InputFocus.Pad);
                            }
                            foreach (var sv in pad.GetFloats())
                            {
                                string n = jName + sv.Item1;
                                float  f = sv.Item2;
                                //if (n == "J5 RotationZ")
                                //	System.Diagnostics.Debugger.Break();
                                if (_trackDeltas)
                                {
                                    _floatDeltas[n] += Math.Abs(f - _floatValues[n]);
                                }
                                _floatValues[n] = f;
                            }
                        }

                        // analyze moose
                        // other sorts of mouse api (raw input) could easily be added as a separate listing under a different class
                        if (_wantingMouseFocus.Contains(Form.ActiveForm))
                        {
                            var mousePos = Control.MousePosition;
                            if (_trackDeltas)
                            {
                                // these are relative to screen coordinates, but that's not terribly important
                                _floatDeltas["WMouse X"] += Math.Abs(mousePos.X - _floatValues["WMouse X"]) * 50;
                                _floatDeltas["WMouse Y"] += Math.Abs(mousePos.Y - _floatValues["WMouse Y"]) * 50;
                            }
                            // coordinate translation happens later
                            _floatValues["WMouse X"] = mousePos.X;
                            _floatValues["WMouse Y"] = mousePos.Y;

                            var mouseBtns = Control.MouseButtons;
                            HandleButton("WMouse L", (mouseBtns & MouseButtons.Left) != 0, InputFocus.Mouse);
                            HandleButton("WMouse C", (mouseBtns & MouseButtons.Middle) != 0, InputFocus.Mouse);
                            HandleButton("WMouse R", (mouseBtns & MouseButtons.Right) != 0, InputFocus.Mouse);
                            HandleButton("WMouse 1", (mouseBtns & MouseButtons.XButton1) != 0, InputFocus.Mouse);
                            HandleButton("WMouse 2", (mouseBtns & MouseButtons.XButton2) != 0, InputFocus.Mouse);
                        }
                        else
                        {
                            // don't do this: for now, it will interfere with the virtualpad. don't do something similar for the mouse position either
                            // unpress all buttons
                            //HandleButton("WMouse L", false);
                            //HandleButton("WMouse C", false);
                            //HandleButton("WMouse R", false);
                            //HandleButton("WMouse 1", false);
                            //HandleButton("WMouse 2", false);
                        }
                    }

                    if (_newEvents.Count != 0)
                    {
                        //WHAT!? WE SHOULD NOT BE SO NAIVELY TOUCHING MAINFORM FROM THE INPUTTHREAD. ITS BUSY RUNNING.
                        AllowInput allowInput = GlobalWin.MainForm.AllowInput(false);

                        foreach (var ie in _newEvents)
                        {
                            //events are swallowed in some cases:
                            if (ie.LogicalButton.Alt && ShouldSwallow(GlobalWin.MainForm.AllowInput(true), ie))
                            {
                                continue;
                            }
                            if (ie.EventType == InputEventType.Press && ShouldSwallow(allowInput, ie))
                            {
                                continue;
                            }

                            EnqueueEvent(ie);
                        }
                    }

                    _ignoreEventsNextPoll = false;
                }                 //lock(this)

                //arbitrary selection of polling frequency:
                Thread.Sleep(10);
            }
        }
Пример #3
0
        static void SubMain(string[] args)
        {
            // this check has to be done VERY early.  i stepped through a debug build with wrong .dll versions purposely used,
            // and there was a TypeLoadException before the first line of SubMain was reached (some static ColorType init?)
            // zero 25-dec-2012 - only do for public builds. its annoying during development
            if (!VersionInfo.DeveloperBuild)
            {
                var thisversion = typeof(Program).Assembly.GetName().Version;
                var utilversion = Assembly.LoadWithPartialName("Bizhawk.Client.Common").GetName().Version;
                var emulversion = Assembly.LoadWithPartialName("Bizhawk.Emulation.Cores").GetName().Version;

                if (thisversion != utilversion || thisversion != emulversion)
                {
                    MessageBox.Show("Conflicting revisions found!  Don't mix .dll versions!");
                    return;
                }
            }

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            string iniPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini");

            Global.Config = ConfigService.Load <Config>(iniPath);
            Global.Config.ResolveDefaults();
            HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler();

#if WINDOWS
            try { GlobalWin.DSound = SoundEnumeration.Create(); }
            catch
            {
                MessageBox.Show("Couldn't initialize DirectSound! Things may go poorly for you. Try changing your sound driver to 41khz instead of 48khz in mmsys.cpl.", "Initialization Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif

            //create IGL context.
            //at some point in the future, we may need to select from several drivers
            GlobalWin.GL        = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK();
            GlobalWin.GLManager = new GLManager();
            GlobalWin.CR_GL     = GlobalWin.GLManager.GetContextForIGL(GlobalWin.GL);

            //WHY do we have to do this? some intel graphics drivers (ig7icd64.dll 10.18.10.3304 on an unknown chip on win8.1) are calling SetDllDirectory() for the process, which ruins stuff.
            //The relevant initialization happened just before in "create IGL context".
            //It isn't clear whether we need the earlier SetDllDirectory(), but I think we do.
            //note: this is pasted instead of being put in a static method due to this initialization code being sensitive to things like that, and not wanting to cause it to break
            //pasting should be safe (not affecting the jit order of things)
            string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
            SetDllDirectory(dllDir);

            try
            {
#if WINDOWS
                if (Global.Config.SingleInstanceMode)
                {
                    try
                    {
                        new SingleInstanceController(args).Run(args);
                    }
                    catch (ObjectDisposedException)
                    {
                        /*Eat it, MainForm disposed itself and Run attempts to dispose of itself.  Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error*/
                    }
                }
                else
                {
#endif
                using (var mf = new MainForm(args))
                {
                    var title = mf.Text;
                    mf.Show();
                    mf.Text = title;
                    try
                    {
                        mf.ProgramRunLoop();
                    }
                    catch (Exception e)
                    {
#if WINDOWS
                        if (!VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive)
                        {
                            var result = MessageBox.Show(
                                "EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may succeed)",
                                "Fatal error: " + e.GetType().Name,
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Exclamation
                                );
                            if (result == DialogResult.Yes)
                            {
                                Global.MovieSession.Movie.Save();
                            }
                        }
#endif
                        throw;
                    }
                }
#if WINDOWS
            }
#endif
            }
            catch (Exception e)
            {
                string message = e.ToString();
                if (e.InnerException != null)
                {
                    message += "\n\nInner Exception:\n\n" + e.InnerException;
                }

                message += "\n\nStackTrace:\n" + e.StackTrace;
                MessageBox.Show(message);
            }
#if WINDOWS
            finally
            {
                if (GlobalWin.DSound != null && GlobalWin.DSound.Disposed == false)
                {
                    GlobalWin.DSound.Dispose();
                }
                GlobalWin.GL.Dispose();
                GamePad.CloseAll();
            }
#endif
        }
Пример #4
0
        static int SubMain(string[] args)
        {
            // this check has to be done VERY early.  i stepped through a debug build with wrong .dll versions purposely used,
            // and there was a TypeLoadException before the first line of SubMain was reached (some static ColorType init?)
            // zero 25-dec-2012 - only do for public builds. its annoying during development
            if (!VersionInfo.DeveloperBuild)
            {
                var thisversion = typeof(Program).Assembly.GetName().Version;
                var utilversion = Assembly.Load(new AssemblyName("Bizhawk.Client.Common")).GetName().Version;
                var emulversion = Assembly.Load(new AssemblyName("Bizhawk.Emulation.Cores")).GetName().Version;

                if (thisversion != utilversion || thisversion != emulversion)
                {
                    MessageBox.Show("Conflicting revisions found!  Don't mix .dll versions!");
                    return(-1);
                }
            }

            BizHawk.Common.TempFileCleaner.Start();


            HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler();

            string iniPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini");

            Global.Config = ConfigService.Load <Config>(iniPath);
            Global.Config.ResolveDefaults();
            BizHawk.Client.Common.StringLogUtil.DefaultToDisk = Global.Config.MoviesOnDisk;
            BizHawk.Client.Common.StringLogUtil.DefaultToAWE  = Global.Config.MoviesInAWE;

            //super hacky! this needs to be done first. still not worth the trouble to make this system fully proper
            for (int i = 0; i < args.Length; i++)
            {
                var arg = args[i].ToLower();
                if (arg.StartsWith("--gdi"))
                {
                    Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
                }
            }

            //create IGL context. we do this whether or not the user has selected OpenGL, so that we can run opengl-based emulator cores
            GlobalWin.IGL_GL = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(2, 0, false);

            //setup the GL context manager, needed for coping with multiple opengl cores vs opengl display method
            GLManager.CreateInstance(GlobalWin.IGL_GL);
            GlobalWin.GLManager = GLManager.Instance;
            GlobalWin.CR_GL     = GlobalWin.GLManager.GetContextForIGL(GlobalWin.GL);

            //now create the "GL" context for the display method. we can reuse the IGL_TK context if opengl display method is chosen
REDO_DISPMETHOD:
            if (Global.Config.DispMethod == Config.EDispMethod.GdiPlus)
            {
                GlobalWin.GL = new Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus();
            }
            else if (Global.Config.DispMethod == Config.EDispMethod.SlimDX9)
            {
                try
                {
                    GlobalWin.GL = new Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9();
                }
                catch (Exception ex)
                {
                    var e2 = new Exception("Initialization of Direct3d 9 Display Method failed; falling back to GDI+", ex);
                    new ExceptionBox(e2).ShowDialog();
                    //fallback
                    Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
                    goto REDO_DISPMETHOD;
                }
            }
            else
            {
                GlobalWin.GL = GlobalWin.IGL_GL;
                //check the opengl version and dont even try to boot this crap up if its too old
                int version = GlobalWin.IGL_GL.Version;
                if (version < 200)
                {
                    //fallback
                    Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
                    goto REDO_DISPMETHOD;
                }
            }

            //try creating a GUI Renderer. If that doesn't succeed. we fallback
            //TODO - need a factory for the GUI Renderer, I hate pasting this code
            try
            {
                BizHawk.Bizware.BizwareGL.IGuiRenderer Renderer;
                if (GlobalWin.GL is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)
                {
                    Renderer = new BizHawk.Bizware.BizwareGL.GuiRenderer(GlobalWin.GL);
                }
                else if (GlobalWin.GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
                {
                    Renderer = new BizHawk.Bizware.BizwareGL.GuiRenderer(GlobalWin.GL);
                }
                else
                {
                    Renderer = new BizHawk.Bizware.BizwareGL.Drivers.GdiPlus.GDIPlusGuiRenderer((BizHawk.Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus)GlobalWin.GL);
                }
            }
            catch (Exception ex)
            {
                var e2 = new Exception("Initialization of Display Method failed; falling back to GDI+", ex);
                new ExceptionBox(e2).ShowDialog();
                //fallback
                Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
                goto REDO_DISPMETHOD;
            }

            //WHY do we have to do this? some intel graphics drivers (ig7icd64.dll 10.18.10.3304 on an unknown chip on win8.1) are calling SetDllDirectory() for the process, which ruins stuff.
            //The relevant initialization happened just before in "create IGL context".
            //It isn't clear whether we need the earlier SetDllDirectory(), but I think we do.
            //note: this is pasted instead of being put in a static method due to this initialization code being sensitive to things like that, and not wanting to cause it to break
            //pasting should be safe (not affecting the jit order of things)
            string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");

            SetDllDirectory(dllDir);

            if (System.Diagnostics.Debugger.IsAttached)
            {             // Let the debugger handle errors
#if WINDOWS
                if (Global.Config.SingleInstanceMode)
                {
                    try
                    {
                        new SingleInstanceController(args).Run(args);
                    }
                    catch (ObjectDisposedException)
                    {
                        /*Eat it, MainForm disposed itself and Run attempts to dispose of itself.  Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error*/
                    }
                }
                else
#endif
                {
                    using (var mf = new MainForm(args))
                    {
                        var title = mf.Text;
                        mf.Show();
                        mf.Text = title;

                        GlobalWin.ExitCode = mf.ProgramRunLoop();
                    }
                }
            }
            else
            {             // Display error message windows
                try
                {
#if WINDOWS
                    if (Global.Config.SingleInstanceMode)
                    {
                        try
                        {
                            new SingleInstanceController(args).Run(args);
                        }
                        catch (ObjectDisposedException)
                        {
                            /*Eat it, MainForm disposed itself and Run attempts to dispose of itself.  Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error*/
                        }
                    }
                    else
#endif
                    {
                        using (var mf = new MainForm(args))
                        {
                            var title = mf.Text;
                            mf.Show();
                            mf.Text = title;

                            if (System.Diagnostics.Debugger.IsAttached)
                            {
                                GlobalWin.ExitCode = mf.ProgramRunLoop();
                            }
                            else
                            {
                                try
                                {
                                    GlobalWin.ExitCode = mf.ProgramRunLoop();
                                }
                                catch (Exception e)
                                {
#if WINDOWS
                                    if (!VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive)
                                    {
                                        var result = MessageBox.Show(
                                            "EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)",
                                            "Fatal error: " + e.GetType().Name,
                                            MessageBoxButtons.YesNo,
                                            MessageBoxIcon.Exclamation
                                            );
                                        if (result == DialogResult.Yes)
                                        {
                                            Global.MovieSession.Movie.Save();
                                        }
                                    }
#endif
                                    throw;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    new ExceptionBox(e).ShowDialog();
                }
#if WINDOWS
                finally
                {
                    if (GlobalWin.Sound != null)
                    {
                        GlobalWin.Sound.Dispose();
                        GlobalWin.Sound = null;
                    }
                    GlobalWin.GL.Dispose();
                    GamePad.CloseAll();
                }
#endif
            }

            //cleanup:
            //cleanup IGL stuff so we can get better refcounts when exiting process, for debugging
            //DOESNT WORK FOR SOME REASON
            //GlobalWin.IGL_GL = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK();
            //GLManager.Instance.Dispose();
            //if (GlobalWin.IGL_GL != GlobalWin.GL)
            //  GlobalWin.GL.Dispose();
            //((IDisposable)GlobalWin.IGL_GL).Dispose();

            //return 0 assuming things have gone well, non-zero values could be used as error codes or for scripting purposes
            return(GlobalWin.ExitCode);
        }         //SubMain