View Full Version : TBDI - DirectInput Joystick module
Michael Hartlef
28-02-2007, 23:45
Hi folks,
I didn't know where to post it so feel free to move it. Here is the first directinput module for joystick support and a text file with the syntax of the 5 commands in it. Just 5, some will ask? Don't worry, I just got PowerBasic to do what I want.
I thought I needed a conversion of a C macro but no, I had false examples. After a look inside the MS SDK docu I found the bug and voila, now joystick behaves like a good boy. I would like you to test it temporary inside TopDown and let me know if it works or crashes. Before someone asks, copy the DLL inside the thinBasic lib folder.
After more tests are done and I added more stuff to it, I will ask Eros to include this module into the official distribution and hand it over to him.
Here is some code that has to be added to TopDown:
USES "TBDI"
'...
DIM But1 as integer
dim direturn as long
dim joyX as integer
dim joyY as integer
...
'Initialize DirectInput Joystick support
direturn = tbdi_init(0)
'...
'Check the state of both axxis and the button no.1
joyX = tbdi_joyX
joyY = tbdi_joyy
but1 = tbdi_joybutton(1)
'...
if GetAsyncKeyState(%VK_SPACE) or but1 then
'...
if GetAsyncKeyState(%VK_UP) or joyY < 0 then
'...
if GetAsyncKeyState(%VK_DOWN) or joyY> 0 then
'...
'Don't forget to release the joystick
tbdi_close
I think it is easy to use, or? I hope it works on your machines.
Cheers
Michael Hartlef
ErosOlmi
01-03-2007, 00:10
Mike,
I'm testing module. FIRST OF ALL: THANKSSSS!!
Now, I'm using a XBox 360 USB Controller. I've amended TopDown3D (see attached) and seems working fine.
I do not know if it is normal but when I move cursor left or right or top or bottom, it continue moving till the edge of limits even if I stop moving gamepad.
Maybe I'm making something wrong.
Michael Hartlef
01-03-2007, 00:16
Mmh, your code works fine here, I'm using a regular PC gamepad P880 from Saitek.
I will test it tommorow with my MS Sidewinder.
ErosOlmi
01-03-2007, 00:17
Mike, what is the meaning of parameter in TBDI_INIT(0) function?
Also consider you can add initialization and / or de-initialization in LoadLocalSymbols and UnLoadLocalSymbols function inside module.
When thinCore search for a requested script module, if found, LoadLocalSymbols is searched and executed.
When script ends, thinCore will take care to call UnLoadLocalSymbols from all currently open modules.
So maybe you can add code in UnLoadLocalSymbols to avoid users to call TBDI_CLOSE.
Just guessing.
Ciao
Eros
Petr Schreiber
01-03-2007, 00:18
:o
Mike,
this is perfect !
Logitech Wingman Precision works absolutely good with your module !
Great great great work !
Thanks,
Petr
ErosOlmi
01-03-2007, 00:20
So, maybe its my config. I will check.
Just a question. When I stop moving on gamepad tbdi_joyX or tbdi_joyY should return zero?
ErosOlmi
01-03-2007, 00:22
Forum syntax highlight will now recognize new TBDI keywords.
ErosOlmi
01-03-2007, 00:30
I found that X and Y returned by my gamepad is not zero but something different: sometimes positive, sometimes negative.
I've done a little test script and found it. Maybe only a calibration problem.
USES "TBDI"
uses "console"
DIM But1 as integer
dim direturn as long
dim joyX as integer
dim joyY as integer
'Initialize DirectInput Joystick support
direturn = tbdi_init(0)
while %TRUE
'Check the state of both axxis and the button no.1
joyX = tbdi_joyX
joyY = tbdi_joyy
but1 = tbdi_joybutton(1)
console_write "BUT1: " & But1
console_write " Y:" & joyY
console_write " X:" & joyX
console_writeline ""
wend
tbdi_close
Michael Hartlef
01-03-2007, 00:33
So, maybe its my config. I will check.
Just a question. When I stop moving on gamepad tbdi_joyX or tbdi_joyY should return zero?
Eros, Yes, it should. Maybe you can output the joyx and joyy values next to the score. It could be that your joystick needs a higher dead_zone. I will make it variable. IT could be that the default value is not high enough for you.
Btw. great suggestions about Init and close. I will do that. Init had the instance value as a parameter. When it was given 0, it is taken the DLL instance. But your solution is perfect.
Petr, thanks man. It caused me some gray hairs, but now it is working and is a good base for more stuff like force feedback.
Michael Hartlef
01-03-2007, 00:35
I found that X and Y returned by my gamepad is not zero but something different: sometimes positive, sometimes negative.
Yeah, that could be. Some joystick are not that good when it comes to hold constant values. Like I said, you would need a bigger dead_zone where it reports 0. Or the checks inside the gamelogic should be different. Not checking against 0.
Michael Hartlef
01-03-2007, 00:38
Can you switch the pad into DIGITAL mode? So use the 8 directional pad instead of the analog stick?
ErosOlmi
01-03-2007, 00:39
OK, definitely a gamepad config.
Always + or - values between 20/45 on both axis.
I will try to find another gamepad. Better, I will buy a new one in next days.
To solve my problem I will change to
if GetAsyncKeyState(%VK_UP) or joyY < -40 then
if GetAsyncKeyState(%VK_DOWN) or joyY > 40 then
'....
'....
Mike, THANKS FOR THE BIG PRESENT !
Michael Hartlef
01-03-2007, 00:42
Thank you too! It's great to see thinBasic envolve and be a part of it. It is another little step to complete thinBasic gaming abilities.
I will head to bed now, see you tommorow.
Wow lay down to take a nap and the game input device module is HERE, woo hoo. Thanks Mike!!
Thanks Eros for putting into a game file to play with.
Very happy to report works very well with my Logitech Extreme 3D joystick.
Mike, is there a routine that checks for the number of buttons on joysticks and gamepads?
I just used directx input functions before in programming and it seemed to handle everything well.
Mayb I ask what library you are using for input handling?
Michael Hartlef
01-03-2007, 07:39
I'm glad you found this a nice wake up surprise.
No, right now there are only these 5 little functions but I will add the suggested ones of course, if my coding abilities will let me do it.
I'm using PowerBasic to develop this module. With it I interface DirectInput from the MS DirectX SDK. I found some translated include files a basic example in the net.
The hard part was trying to get the joysticks report values between -1024 to 1024 bey default and not just raw data for the axxis from 0 to 65335. This was because the example I used was faulty plus the include files were also a little buggy. They used the wrong data types in some places.
So next step will be these little functions you mentioned plus functions to read all joysticks on a pad, sliders, POV. After this I will attack effects so you can have your pad rumbeling when your ship got hit. At the end I would like to able to support 2 joysticks at the same time, but I don't know right now how to do it.
It is definitly a great start and glad you will add all the support you can to it. I guess since thinBasic will always be on Windows Operating Systems going with DirectX is not an issue. I didn't know you could use part of an SDK for making your own dll modules. That is great to know.
I got another question for you, why were you concerned about dealing with 0 to 65335 as a range compared to the now -1024 to 1024, just curious?
Michael Hartlef
01-03-2007, 09:16
I found it more usefull, then saying the middle is 37thousandsomething. Plus I needed this functionality anyway to be able to control the deadzone of a joystick. You will get a function where you can set the range yourself.
The other solution for Joystick would be using the SDL lib, but then we would have to ship allways another dll with it. Plus effects are not available on it I think.
I see Mike, thanks. MY course that I ordered will show SDL, but I am not even to getting there yet to see what all it can do. They just mentioned it was great for making games. I will know more in a few months I guess once I make my way through.
Michael Hartlef
02-03-2007, 10:15
Last night I implemented allmost everything that I wanted. Onlyforce feedback is missing now. One problem I have is what Eros suggested, calling Init and Close from the attach and detach processes. thinbasic hangs up without any complain/message, etc. First I want to check it again before I call Eros for help. ;) After I did more documentation and write a sample script, I will release this version.
Michael Hartlef
03-03-2007, 12:42
Ok, I know where it hangs up now. In any example and the sdk docu, you have to acquiere the joystick before you use it. So I do that within the TBDI_Init function. It works. When I call this function from the DLL's attach process, it hangs at this part. The funny part is that when I don't acquiere the joystick, the joystick still works. Go figure ???
As I don't know if leaving it out will have bad sideeffects, I will stay with the external version of TBDI_Init and TBDI_Close for now. I think two extra commands won't make it that bad. When I have everything inside the module, I will give Eros the sources and let him have a try. Maybe I'm doing something wrong with the DLL's attach process. Regarding to TBDI_Close, when I put that inside the DETACH process of the DLL, it doesn't get called. Mmmh, maybe a bug inside thinbasic.
Tommorow night (my time) I will release this version. Tonight I find no time as we have friends over for dinner.
Petr Schreiber
03-03-2007, 12:49
Hi Mike,
I don't understand if TBDI_Close is your internal function or thinBASIC keyword.
I think for de-initialization part of thinBASIC module is dedicated function called UnLoadLocalSymbols.
It looks something like this in SDK template:
'----------------------------------------------------------------------------
FUNCTION UnLoadLocalSymbols ALIAS "UnLoadLocalSymbols" () EXPORT AS LONG
' This function is automatically called by thinCore whenever this DLL is unloaded.
' This function CAN be present but it is not necessary. If present, this function
' will be executed by thinBasic core when module will be released.
' Use this function to perform uninitialize process, if needed.
'----------------------------------------------------------------------------
'---
'Add here DeInitialization code if needed
'---
FUNCTION = 0&
END FUNCTION
I don't use LibMain at all. But maybe I get your problem wrong.
Anyway, have a nice day ( and dinner :) ),
Petr
Michael Hartlef
03-03-2007, 12:56
Dooo ::)
You are right. Instead of using the attach and detach processes, I could probably use the load and unload functions to initialize it. Thanks for the tip. If it still not works, then I bite into the table :D
Michael Hartlef
03-03-2007, 12:58
Double dooooo ::) Eros allready mentioned Petr's tip. Man, I am sooooo blind. 8) It is a wonder that I ever get things done. :-[
ErosOlmi
03-03-2007, 13:03
Hi Mike,
thanks a lot. Feel free to send me whatever you want me to check.
As Petr suggested, thinBasic do not handle LIBMAIN function. That function is handled automatically by the operating system.
thinBasic execute LoadLocalSymbols function at module calling and UnLoadLocalSymbols function when script stop execution.
Ciao
Eros
PS: you are too fast to post !!! :D
ErosOlmi
03-03-2007, 13:10
Using LIBMAIN can be too late or too early because thinCore is not aware of what is going on at that precise time.
That's why we introduced LoadLocalSymbols and UnLoadLocalSymbols. thinCore is responsible to call them exactly when needed. And at that time all global variables inside the script are already there.
Another reason is to hide internal module development to users trying to check internal functions. Only LoadLocalSymbols and UnLoadLocalSymbols are exported. This will keep thinBasic modules usable only by thinBasic interface because all is internal executed by code pointers to functions.
Ciao
Eros
Now, I'm using a XBox 360 USB Controller. I've amended TopDown3D (see attached) and seems working fine.
I do not know if it is normal but when I move cursor left or right or top or bottom, it continue moving till the edge of limits even if I stop moving gamepad.
Forgive the thread necromancy, but since this was never properly answered, I am answering it for any newcomers who may stumble on this issue.
Although I have not played with the DI commands, Mike's coding is always very solid and reliable.
The problem is DirectInput was not designed for the controller you are trying to use. NexGen (X360) controllers do not work properly under DirectInput. One example (from memory), is left and right buttons are handled as a single axis. Vibration usually does not work properly and there are many other issues which I can't remember.
As of 2005, you should be using XInput for all X360 controllers. XInput is compatible with XP SP1/DirectX 9 and above, so it should work with pretty much any system out there.
DirectInput can still be used for non-X360 controllers, but DirectInput was officially deprecated in 2011, and WM_INPUT should be able to handle most non-X360 controllers just fine.
Since 2011, Microsoft has strongly recommended that you do not use DirectInput for mouse or keyboard control. Microsoft now requires you to solely use WM_INPUT for keyboard and mouse. DirectInput never properly handled mouse and keyboard in all instances anyway, which is why Mark Sibly had to drop DirectInput in early versions of Blitz Plus and used WM_INPUT instead for keyboard/mouse input. DirectInput does not queue actions and was very problematic when using multiple windows.
Hopefully, this helps any newcomers who may encounter a problem and stumble on this thread when searching for a solution.
Michael Hartlef
21-09-2017, 10:07
Digged up from the grave :D
Guess if there is any need, I could look into integrating XInput.