diff --git a/Output/OpenTK.Compatibility.dll b/Output/OpenTK.Compatibility.dll index d6d8149e..46bbbf70 100644 Binary files a/Output/OpenTK.Compatibility.dll and b/Output/OpenTK.Compatibility.dll differ diff --git a/Output/OpenTK.GLControl.dll b/Output/OpenTK.GLControl.dll index e31628d5..8fad65c9 100644 Binary files a/Output/OpenTK.GLControl.dll and b/Output/OpenTK.GLControl.dll differ diff --git a/Output/OpenTK.dll b/Output/OpenTK.dll index afff0dd1..e792eef0 100644 Binary files a/Output/OpenTK.dll and b/Output/OpenTK.dll differ diff --git a/Vocaluxe/Base/CController.cs b/Vocaluxe/Base/CController.cs index 604b17c0..773bac5d 100644 --- a/Vocaluxe/Base/CController.cs +++ b/Vocaluxe/Base/CController.cs @@ -37,6 +37,7 @@ namespace Vocaluxe.Base _MousePool = new List(); _AddController(new CWiiMote()); + _AddController(new CGamePad()); _AddController(CVocaluxeServer.Controller); } diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 261dd4f5..04f41743 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -23,6 +23,7 @@ using System; using System.Drawing; using System.IO; using System.Windows.Forms; +using OpenTK.Graphics.OpenGL; using Vocaluxe.Base; using VocaluxeLib; using VocaluxeLib.Draw; @@ -71,8 +72,8 @@ namespace Vocaluxe.Lib.Draw GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texWidth, texHeight, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)OpenTK.Graphics.TextureWrapMode.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)OpenTK.Graphics.TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); @@ -334,7 +335,7 @@ namespace Vocaluxe.Lib.Draw GL.Enable(EnableCap.Blend); GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - GL.Begin(BeginMode.Quads); + GL.Begin(PrimitiveType.Quads); GL.MatrixMode(MatrixMode.Color); GL.PushMatrix(); if (Math.Abs(rect.Rotation) > 0.001) @@ -385,7 +386,7 @@ namespace Vocaluxe.Lib.Draw GL.Translate(-0.5f, -0.5f, 0); } - GL.Begin(BeginMode.Quads); + GL.Begin(PrimitiveType.Quads); GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset); @@ -470,7 +471,7 @@ namespace Vocaluxe.Lib.Draw GL.Translate(-0.5f, -0.5f, 0); } - GL.Begin(BeginMode.Quads); + GL.Begin(PrimitiveType.Quads); GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); GL.TexCoord2(dc.Tx1, dc.Ty1); diff --git a/Vocaluxe/Lib/Input/CGamePad.cs b/Vocaluxe/Lib/Input/CGamePad.cs new file mode 100644 index 00000000..4e0ecca4 --- /dev/null +++ b/Vocaluxe/Lib/Input/CGamePad.cs @@ -0,0 +1,222 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.Diagnostics.PerformanceData; +using System.Drawing; +using System.Threading; +using System.Windows.Forms; +using OpenTK.Input; +using Vocaluxe.Base; +using VocaluxeLib; + +namespace Vocaluxe.Lib.Input +{ + class CGamePad : CControllerFramework + { + private int _GamePadIndex; + private const float _LimitFactor = 1.0f; + + private GamePadState _OldButtonStates; + + private bool _Connected + { + get { return _GamePadIndex != -1; } + } + + private Thread _HandlerThread; + private AutoResetEvent _EvTerminate; + private Object _Sync; + private bool _Active; + private CRumbleTimer _RumbleTimer; + + public override string GetName() + { + return "GamePad"; + } + + public override bool Init() + { + if (!base.Init()) + return false; + + _Sync = new Object(); + _RumbleTimer = new CRumbleTimer(); + + _HandlerThread = new Thread(_MainLoop) {Name = "GamePad", Priority = ThreadPriority.BelowNormal}; + _EvTerminate = new AutoResetEvent(false); + + _OldButtonStates = new GamePadState(); + return true; + } + + public override void Close() + { + _Active = false; + if (_HandlerThread != null) + { + //Join before freeing stuff + //This also ensures, that no other thread is created till the current one is terminated + _EvTerminate.Set(); + _HandlerThread.Join(); + _HandlerThread = null; + _EvTerminate.Dispose(); + _EvTerminate = null; + } + base.Close(); + } + + public override void Connect() + { + if (_Active || _HandlerThread == null) + return; + _Active = true; + _HandlerThread.Start(); + } + + public override void Disconnect() + { + Close(); + } + + public override bool IsConnected() + { + return _Connected; + } + + public override void SetRumble(float duration) + { + lock (_Sync) + { + _RumbleTimer.Set(duration); + } + } + + private void _MainLoop() + { + + while (_Active) + { + Thread.Sleep(5); + + if (!_Connected) + { + if (!_DoConnect()) + _EvTerminate.WaitOne(1000); + } + else + { + bool startRumble; + bool stopRumble; + lock (_Sync) + { + startRumble = _RumbleTimer.ShouldStart; + stopRumble = _RumbleTimer.ShouldStop; + } + + if (startRumble) + GamePad.SetVibration(_GamePadIndex, 1.0f, 1.0f); + else if (stopRumble) + GamePad.SetVibration(_GamePadIndex, 0.0f, 0.0f); + + _HandleButtons(GamePad.GetState(_GamePadIndex)); + } + } + + GamePad.SetVibration(_GamePadIndex, 0.0f, 0.0f); + + _GamePadIndex = -1; + } + + private void _HandleButtons(GamePadState buttonStates) + { + bool lb = (buttonStates.Buttons.LeftShoulder == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.LeftShoulder == OpenTK.Input.ButtonState.Released); + bool rb = (buttonStates.Buttons.RightShoulder == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.RightShoulder == OpenTK.Input.ButtonState.Released); + lb |= (buttonStates.Buttons.RightStick == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.RightStick == OpenTK.Input.ButtonState.Released); + + + var key = Keys.None; + + if (buttonStates.DPad.IsDown && !_OldButtonStates.DPad.IsDown) + key = Keys.Down; + else if (buttonStates.DPad.IsUp && !_OldButtonStates.DPad.IsUp) + key = Keys.Up; + else if (buttonStates.DPad.IsLeft && !_OldButtonStates.DPad.IsLeft) + key = Keys.Left; + else if (buttonStates.DPad.IsRight && !_OldButtonStates.DPad.IsRight) + key = Keys.Right; + else if (buttonStates.Buttons.Start == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.Start == OpenTK.Input.ButtonState.Released) + key = Keys.Space; + else if (buttonStates.Buttons.A == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.A == OpenTK.Input.ButtonState.Released) + key = Keys.Enter; + else if (buttonStates.Buttons.X == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.X == OpenTK.Input.ButtonState.Released) + key = Keys.Escape; + else if (buttonStates.Buttons.Back == OpenTK.Input.ButtonState.Pressed && _OldButtonStates.Buttons.Back == OpenTK.Input.ButtonState.Released) + key = Keys.Back; + else if (buttonStates.Triggers.Left >= 0.8 && _OldButtonStates.Triggers.Left < 0.8) + key = Keys.PageUp; + else if (buttonStates.Triggers.Right >= 0.8 && _OldButtonStates.Triggers.Right < 0.8) + key = Keys.PageDown; + + if (key != Keys.None) + AddKeyEvent(new SKeyEvent(ESender.Gamepad, false, false, false, false, char.MinValue, key)); + + if (Math.Abs(buttonStates.ThumbSticks.Right.X - _OldButtonStates.ThumbSticks.Right.X) > 0.01 + || Math.Abs(buttonStates.ThumbSticks.Right.Y - _OldButtonStates.ThumbSticks.Right.Y) > 0.01 + || lb || rb) + { + var x = Math.Min(CSettings.RenderW, Math.Max(0, (int)(CSettings.RenderW * (buttonStates.ThumbSticks.Right.X / 2.0 * _LimitFactor + 0.5f)))); + var y = Math.Min(CSettings.RenderH, Math.Max(0, (int)(CSettings.RenderH * (buttonStates.ThumbSticks.Right.Y / 2.0 * _LimitFactor * (-1) + 0.5f)))); + + AddMouseEvent(new SMouseEvent(ESender.Gamepad, EModifier.None, x, y, lb, false, rb, 0, false, false, false, false)); + } + + _OldButtonStates = buttonStates; + } + + private bool _DoConnect() + { + _GamePadIndex = -1; + for (int i = 0; i < 4; i++) + { + if (GamePad.GetCapabilities(i).IsConnected) + { + _GamePadIndex = i; + break; + } + } + + + GamePad.SetVibration(_GamePadIndex, 1.0f, 1.0f); + Thread.Sleep(125); + GamePad.SetVibration(_GamePadIndex, 0.0f, 0.0f); + Thread.Sleep(125); + GamePad.SetVibration(_GamePadIndex, 1.0f, 1.0f); + Thread.Sleep(125); + GamePad.SetVibration(_GamePadIndex, 0.0f, 0.0f); + Thread.Sleep(125); + GamePad.SetVibration(_GamePadIndex, 1.0f, 1.0f); + Thread.Sleep(125); + GamePad.SetVibration(_GamePadIndex, 0.0f, 0.0f); + + + return _GamePadIndex != -1; + } + + + } +} \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index c684ab1e..1f2fcad1 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -236,6 +236,7 @@ + diff --git a/VocaluxeLib/Enums.cs b/VocaluxeLib/Enums.cs index 5de35d34..82746f4e 100644 --- a/VocaluxeLib/Enums.cs +++ b/VocaluxeLib/Enums.cs @@ -56,7 +56,8 @@ namespace VocaluxeLib { Mouse, Keyboard, - WiiMote + WiiMote, + Gamepad } #endregion Inputs