Pages

Wednesday, March 13, 2013

[TUT] Script + XBox 360 controller


One of the frequently asked feature is the possibility of use xbox 360 controller with the script, i will show two ways of obtaining xbox control key presses.


First of all i wanna say thanks to pedro2555 for providing info about SlimDX, say thanks to Andrew for providing info about XNA, thanks to MOrdecki for info about the key values for native calls and thanks to "Soyeldiablo" for giving tip about analogue sticks :)

Download the sample project here, let's use this project as the base for this tutorial.


  • Basic native methods (recommended)
IS_USING_CONTROLLER: Will return true when you press one button or move an analogue stick in the control, if you move mouse or press an key in keyboard it will return false again.
IS_BUTTON_PRESSED: Here we use two params: first one is the controller number, second is the number of the key in the controller, if the key is down this will return true.
GET_POSITION_OF_ANALOGUE_STICKS: Return in the params the X and Y of the analogue sticks.

This is the list of all key values for controller:
BUTTON_BACK = 13
BUTTON_START = 12
BUTTON_X = 14
BUTTON_Y = 15
BUTTON_A = 16
BUTTON_B =17
BUTTON_DPAD_UP = 8
BUTTON_DPAD_DOWN = 9
BUTTON_DPAD_LEFT = 10
BUTTON_DPAD_RIGHT = 11
BUTTON_TRIGGER_LEFT = 5,
BUTTON_TRIGGER_RIGHT =7
BUTTON_BUMPER_LEFT = 4
BUTTON_BUMPER_RIGHT = 6
BUTTON_STICK_LEFT = 18
BUTTON_STICK_RIGHT = 19

Example of GET_POSITION_OF_ANALOGUE_STICKS use:


As you can see we need this objects of class Pointer (GTA.Native.Pointer) to be used as parameter in the Native function call, the first param of the native method is the controller number.

Also we need to initialize this pointers indicating their types, if we mismatch the type the pointer will receive nil as result, so be careful with the type, for this native call the correct type is Int32:
LeftStick_X = New GTA.Native.Pointer(GetType(Int32))
The values go from -127 to 127, idle its 0.

I wrote a small class that you can use to handle all the methods


  • Microsoft XNA DLL
With Microsoft XNA we can have access to xbox controller and detect when user press an button, what we need? First let's download the Microsoft XNA Framework Redistributable 4.0 and install it. After installing we need to find the DLL that must go with the script, if you use the windows file search you will find the dll in this folder probably:


Copy this file to the GTAIV.exe folder, when you release your script you need to release this dll too, and tell to the user that it must be placed in GTAIV.exe folder.

Now in our project let's add an reference to this dll file:


We will need an global object of Microsoft.Xna.Framework.Input.GamePadState:


And in the tick event we need to check for updates doing the follow:


If you put an simple message in the keyDown event you will see that none of the control buttons trigger this event, so to check if an button of the control is pressed we need to do this in the tick:


Check if the control is connected and then check for each key that we need to know if its pressed, in this case i showed an message indicating if button A is pressed. We also can check the triggers pressed, the difference here is that we have an float value that goes from 0 to 1 and from 0 to -1:


the same can be done with Thumb sticks specifying if we are looking for X or Y value:


Easy right? Yes, that is, the problem is when you need to use the button press like an hotkey, we need to create an global object of type int64 (or maybe int32) to store the last PacketNumber of the control, each time that we press an button this PacketNumber is increased, so in the tick we check if the last Packet number is different from the actual one and then we consider it an button press event:

and in the tick:


this PacketNumber will change each time that we press an button and when we release too or when we change the Thumb or Trigger position.

The most interesting way is create boolean variable for each button and float variables for each Thumb and Trigger that we plan to use in the script:


and uses an method to check this buttons states:


I'm not sure if we need to send only the XNA dll with the script or the entire packet (Microsoft XNA Framework Redistributable 4.0), in my tests just the dll was enough.

Download this script here


  • SlimDX DLL
Other tool that we can use to make this checks is the SlimDX, you can download it here, download the version for .Net 4.0 that is used by the ScriptHook. After installing we need to find the dll like we did with the XNA, if you use the windows file search you probably will find it here:


Like XNA dll, we need to copy this dll to the GTAIV.exe folder and add as reference in the project.

The object that will do the checks is the following:


Now what changes is how we get the PacketNumber and how we detect what key is pressed:



Download the script here



If you don't have an XBox 360 controller you can simulate one using an simple gamepad, the result its not very precise but it helps, to do this you can use this software:

You will need to download the main files and the application, put then inside the GTAIV.exe folder and run the application to configure the buttons of your gamepad to behave like an XBox 360 controller ;)