Game Development Community

Joystick/Gamepad support with cursor/mouse button control.

by Kent Butler · 07/30/2008 (7:22 am) · 6 comments

Download Code File

This resource came from a recent project rebuild. Though it was built in to the old code, I had no quick-easy way to just drop joystick support back into a clean TGE project. All of the information is out there on the forums, but some of it is old and some of it doesn't work so gleaning the good from the bad and getting it working was a minor chore initially. With a round-up of code changes from the older project, I essentially turned them into a resource so the problem doesn't come up again. After searching several different ways, I didn't find a complete drop-in solution on the site, so shared mine. The joystick/gamepad support stuff is pretty straight forward and comes from other posts and resources with some minor clean-ups.

The virtual mouse object is something that was made because putting the controller down to use the mouse really is a drag sometimes. I'm using it in projects by default and built it into the above mentioned controller rollup. The two were already all-but-resourced together, so I figured I'd share it too. It is documented reasonably well in the comments. If you want one feature but not the other, it is pretty easy to separate them; there are notes on this in the readme file.

The whole thing is tied together with an update to the optionsDlg gui that adds the gamepad controller and virtual mouse settings to the dialog. It also has a few little extras on the action map bindings screen such as a clear bindings button, restore system defaults, etc. This hasn't been used nearly as much as the actual code components (gamepad/vmouse) so there might be some special "features" - but so far nothing blaring has come up.

vMouse Notes: The virtual mouse hijacks joystick input events from the canvas whenever the cursor is active and converts bound joystick controls to mouse events. The vMouse object is a tickable simObject that sends mouseMove events through the advanceTime() function when the bound control has input(and the cursor is active). It will also convert bound gamepad button events to any mouse button or the following keyboard events: [Enter] [Tab] and [Esc].

It is implemented as part of the canvas and exposed to script through the canvas.getVMouse() console function. The vMouse.cs script assigns this object to the $VMOUSE variable which is used to control the object's settings.

There are obvious areas for improvement (POV controlled mouse movement, mouse pointer acceleration, etc.), but mostly everything seems pretty solid. If/when there are improvements, they will be posted here. This was initially a proof-of-concept. It works better than expected but still - use it at your own risk.

I'll try and keep up on comments - If anyone finds any bugs or has improvements, post them and I will try and update the resource (no promises).

#1
07/30/2008 (9:55 am)
This is going to make a long job much shorter! One question though: What exactly makes the joystick/gamepad code in this better than stock Torque's? I couldn't quite tell from the reading.
#2
07/30/2008 (12:40 pm)
Very interesting! I was looking for something like this, thanks for sharing!
Will test this in the weekend.
#3
08/03/2008 (11:45 am)
Nathan: The joystick code is pretty much Torque stock. There are just some quickie engine changes (to get the joystick and mouse working together without the yaw going all wacky) and script stuff. It's all already on the forums - this just is an easy way (?) to implement it. The virtual mouse is something I added, I didn't see a way to get the joystick to control the mouse cursor, so I wrote a quick hack - "better" is debatable.
#4
08/03/2008 (11:52 am)
Bugfix: Of course, already a bug popped up. It is in the ~/client/scripts/optionsDlg.cs file. The fix has been added to the .zip download (as of 8/3/08)

The bug's near the bottom in:
[b]function OptXAxisMenu::onSelect( %this, %id, %text )[/b]
and
[b]function OptYAxisMenu::onSelect( %this, %id, %text )[/b]

I named the $vmouse variables wrong (sloppy cut-paste).
if (%text $= "None")
      $VMOUSE.XAxisButton = NULL;
   else
      $VMOUSE.XAxisButton = %text;
should be
if (%text $= "None")
      $VMOUSE.XAxis  = NULL;
   else
      $VMOUSE.XAxis = %text;

Obviously ... that's in the Xaxis function, the same thing's gotta be done with the Yaxis too (or just use the download)
#5
09/11/2008 (5:17 pm)
I recently started working with Torque again, and was really happy to see something like this. With this code, I was able to get it working with a few changes. At first, the buttons worked, however, the mouse would not move. Turns out that it was polling for 2 joysticks. Joystick Port 0 would read correct values, but Joystick Port 1 would end up resetting mCurrentXRate and mCurrentYRate. So to work around this, I just added a check for
if(event->deviceType == JoystickDeviceType && cursorON && mVMouse != NULL )
to
if(event->deviceType == JoystickDeviceType && cursorON && mVMouse && (event->deviceInst == 0) != NULL )
Not sure if I added something in the engine or not, since I have not touched the code in quite some time. Hope that helps if anyone else runs into that problem
#6
02/06/2009 (6:48 am)
Thanks for this wonderful resource. I also have a problem. The cursor only move upwards and to the left. I think it's related with the setMousePosition BUG already described before in here -> http://www.garagegames.com/community/forums/viewthread/33222/1#comment_form

Did anyone faced this issue?

Thanks