Enhanced Joystick support
Monkey Targets Forums/Desktop/Enhanced Joystick support
| ||
Featuring - 16 simultaneous joysticks - 128 buttons per joystick - 8 axes per joystick - POV hat (Including the XBox 360 controller DPad) GLFW/Windows only at this stage, but maybe not too hard to hack for other platforms and targets. Apologies about the hacky mess, it's the first C I've written in a decade. Call EJoyInit() during OnCreate() and EJoyUpdate() during OnUpdate() Joystick.Cpp #pragma comment(lib, "winmm.lib") float axisarray[8]; unsigned char buttonarray[128]; int EJoyConnected(int index){ return glfwGetJoystickParam( GLFW_JOYSTICK_1 + index, GLFW_PRESENT ); } int EJoyAxes(int index){ return glfwGetJoystickParam( GLFW_JOYSTICK_1 + index, GLFW_AXES ); } int EJoyButtons(int index){ return glfwGetJoystickParam( GLFW_JOYSTICK_1 + index, GLFW_BUTTONS ); } void EJoyAxisStates(int index,int axes){ glfwGetJoystickPos( GLFW_JOYSTICK_1 + index, axisarray, axes); return; } void EJoyButtonStates(int index,int buttons){ glfwGetJoystickButtons( GLFW_JOYSTICK_1 + index, buttonarray, buttons ); return; } float EJoyAxisState(int axis){ return axisarray[axis]; } int EJoyButtonState(int button){ return buttonarray[button]; } //Based on code from https://github.com/fatty/glfw/blob/f84990bffd20d5663de1889c60ef4bf334e76fb7/src/win32_joystick.c int EJoyHatState(int index){ JOYCAPS jc; JOYINFOEX ji; joyGetDevCaps(index, &jc, sizeof(JOYCAPS)); // Get joystick state ji.dwSize = sizeof(JOYINFOEX); ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV; joyGetPosEx(index, &ji); const int hats = (jc.wCaps & JOYCAPS_HASPOV) ? 1 : 0; if (hats > 0 ) { if(ji.dwPOV>36000) return -1; return ji.dwPOV / 100; } return -1; } Joystick.Monkey Import mojo Import "joystick.cpp" Extern Function EJoyConnected:Int(index) = "EJoyConnected" Function EJoyButtons:Int(index) = "EJoyButtons" Function EJoyAxes:Int(index) = "EJoyAxes" Function EJoyButtonStates:Int(index, buttons) = "EJoyButtonStates" Function EJoyAxisStates:Int(index, axes) = "EJoyAxisStates" Function EJoyButtonState:Int(button) = "EJoyButtonState" Function EJoyAxisState:Float(axis) = "EJoyAxisState" Function EJoyHatState:Int(index) = "EJoyHatState" Public Const DeadZone:Float = 0.1 Class Joystick Global State:= New Joystick[16] Field Connected:Bool = False Field Axes:Float[] Field Buttons:Int[] Field Hat:int End Function EJoyAxis:Float(index, axis) If (index >= EJoyCount) Return 0 If (Joystick.State[index].Axes.Length <= axis) Return 0 Return Joystick.State[index].Axes[axis] End Function EJoyHat:Float(index) If (index >= EJoyCount) Return 0 Return Joystick.State[index].Hat End Function EJoyX:Float(index) Return EJoyAxis(index, 0) End Function EJoyY:Float(index) Return EJoyAxis(index, 1) End Function EJoyZ:Float(index) Return EJoyAxis(index, 2) End Function EJoyHit(index, button) If (index >= EJoyCount) Return 0 If (button >= Joystick.State[index].Buttons.Length) Return 0 If Joystick.State[index].Buttons[button] = 1 Return 1 Return 0 End Function EJoyDown(index, button) If (index >= EJoyCount) Return 0 If (button >= Joystick.State[index].Buttons.Length) Return 0 If Joystick.State[index].Buttons[button] > 0 Return 1 Return 0 End Function EJoyInit() EJoyCount = 0 For Local a = 0 To 15 Joystick.State[a] = New Joystick() If (EJoyConnected(a)) Joystick.State[a].Connected = True Joystick.State[a].Axes = New float[EJoyAxes(a)] Joystick.State[a].Buttons = New int[EJoyButtons(a)] Print "Axes" + EJoyAxes(a) Print "Buttons" + EJoyButtons(a) EJoyCount += 1 EndIf Next End Function EJoyUpdate() For Local a = 0 To 15 If (Joystick.State[a].Connected = True) EJoyAxisStates(a, Joystick.State[a].Axes.Length) EJoyButtonStates(a, Joystick.State[a].Buttons.Length) Joystick.State[a].Hat = EJoyHatState(a) For Local b = 0 To Joystick.State[a].Axes.Length - 1 Joystick.State[a].Axes[b] = Min(Max(EJoyAxisState(b), -1.0), 1.0) If (Abs(Joystick.State[a].Axes[b]) < DeadZone) Joystick.State[a].Axes[b] = 0 EndIf Next For Local b = 0 To Joystick.State[a].Buttons.Length - 1 Select Joystick.State[a].Buttons[b] Case 0 If EJoyButtonState(b) = 1 Then Joystick.State[a].Buttons[b] = 1 EndIf Case 1 Joystick.State[a].Buttons[b] = 2 Case 2 If EJoyButtonState(b) = 0 Then Joystick.State[a].Buttons[b] = 0 End Next EndIf Next End Global EJoyCount |
| ||
This is great! I will not be using the module (as joystick support has improved quite a lot in Monkey lately) but there are a few ideas I will definitely borrow from you (like reading additional axes and getting info on the joystick). They will make nice additions to the handful of GLFW-specific enhancements I already have in my engine (checking if a joystick is connected was one of them) Thanks :) |
| ||
Awesome work. Mark and his team should have a look at it if this is really good. |