SDL2 Joystick issues
Hello. I need help regarding my post from StackOverflow.
https://stackoverflow.com/questions/78100724/inconsitent-detection-of-joystick-button-input-using-sdl-in-c-sharp-with-the-use
Summary: Code is not working properly when 2 or more joysticks are connected. Only one joystick connected and it works well.
Stack Overflow
Inconsitent detection of joystick button input using SDL in C# with...
So I made a code that will detect joystick button input in a TPL where all joysticks' inputs are detected simultaneously. Good thing is that if there's only one joystick connected, it works consist...
174 Replies
This part should be in the main method
the first while loop is to keep the game running
main method?
on every frame, you handle ur input, a character's physics, rendering, etc...
yeah the
static void Main(string[] args)
one
for now your game is a console game, it only handles input,
the while (SDL.SDL_PollEvent(out e) != 0)
loops on every key just got pressed/unpressedhow about the product ID?
because i do need it
so that i can make sure that it's actually following the right joystick
you could say it acts like
but SDL was made in C, C has no foreach afaik
do you get what i mean?
now lets say you pressed X on one of the 8 joysticks
the while loop here will only loop once, and the
e
has the data of the key pressed
are you following?still a bit confused because i used to have everything thrown at me and think it'd work
that's your problem, you should exactly understand everything ur writing
dont assume it will automatically work
let's say this is my main for now
and then i'll have to add the things from the other file that has the namespace
SDLCSharp
wait why are you closing the joysticks?
this is pretty much just displaying the joysticks that i have that are connected
you haven't answered my question
u are opening the joystick on every frame, you dont need that
once is enough
well, im opening multiple joysticks
yeah thats good, then you close them
I never used GetProduct tho
yeah that's the product ID of the joystick
it's important for my project
the IntPtr from JoystickOpen is enough for me
anyway
i remove the closing of joysticks, okay...
what's next, adding the while loop for checking the state of joysticks buttons
no need to use dictionary, just use List<Joystick>
I'll just keep it that way
if ull keep it that way how are you gonna access their instances?
you have a class called
Joystick1
, why even store the info of joystick in a dictionary if you can just store it in a list of Joystick1
this is my original code.
List<int> productIDs = new List<int> { 12345, 12346, 12347 };
arent the joystick product ids 0, 1, 2 and so on?no, they're number indices
12345, 12346, 12347 are just for display
the product IDs that i have are for, not public
yeah but do u know what this code does?
yeah, if the productID of a joystick matches the one in the productIDs, it will be added to the Dictionary
Otherwise, it won't be added
so wait, u know the productId from the start?
alright fair enough ig
anyway please delete this
Dictionary<int, Tuple<int, int>> joystickInfo = new Dictionary<int, Tuple<int, int>>();
classes are a thing,
store the data of each joystick in each instance of Joystick1
let the class's constructor take the values and store them into its fields
There is a better way and cleaner way than using Dictionary in your case
also you dont need to make many classes for your joysticksokay
because you can make many instances out of a single class
so i made a class Joystick
that's good, what's next...
show me ur class
great but u could change
private int getProductIDs;
to private int _productId;
alright
in C# its recommended to name private fields like that
to begin with an underscore
i see
ok now you can put the Handle method
in the Joystick class, right?
yeah
Well, this happened
ops
hm
you missed something
break;
what does SDL_JoystickGetButton
return?
int?nint
on joystick and int
on buttonthen you know what to do
use
int
not bool
if its 0 it indicates the button index isnt pressed, 1 if it isnow ill go back to main and try your while loop
good but do u understand this error?
i did
ok
i fixed it
ok now but GetButton doesnt take a product id
yeah
it takes
i
insteadNo
really?
yeah
it needs the value that JoyStickOpen returns
for the first parameter
which is
i
No
unless i misunderstood
SDL2/SDL_JoystickGetButton
The Simple Directmedia Layer Wiki
it requires an instance of
SDL_Joystick
which SDL_JoystickOpen
returns
but its IntPtr in your case because that's how C# see's every pointer from C/C++ like thatso i have to change it
?
ofcourse
it wants the value that SDL_JoystickOpen returns
well, im trying to find what can be a replacement for
IntPtr
nowwhy would you?
nint
is alias for IntPtr
btw
so, same thingoh
yeah i came from C++ but i saw C# fitting better for my project
so i got confused
anyways, now i have to get joystick in as well for Joystick too, right?
no you need to figure out how to pass the value of
IntPtr joystick
into your class
because you need that value
does this not work?
it should, if you have the correct parameters in your constructor
how's this?
looks perfect
alright, now onto complex part
yeah i would put Console.WriteLine under int pressed
to print the info of the joystick and the pressed button
you have a big problem tho
in ur main method
hm
i think i need to get like, specific buttons
No
like, 0, 1, 2, 3, etc.
not now
well, did you test? what did you find so far?
i did test
i have 2 joysticks
it seems to only detect the first one instead of both
i dont think the 2nd joystick was detected
yes
because
ur
while(!quit`)
is in the for loop
which means i will never be 1 or more
the for loop will always be stuck in the first loopmhm
the while loop should be outside of the for loop
i removed it and it does work
cool
now onto the more complex part
i need to know which is which now
like, i have different names from these joysticks that i have
and the buttons too
i need to know which pressed button came from any of my joysticks
u have i, and productid of each joystick
u could differentiate with their values
should i also add
e.jbutton.which
too?i never heard of that
because it does display both, but it feels like the other button is getting triggered because this joystick of mine has 2 buttons
SDL does not have
which
that in jbutton
did u mean e.jbutton.button
?hm
let's say i have this joystick that has 2 buttons and it's on and off from a single switch.
up is on, down is off
what do u mean?
and i have another joystick that has 3 buttons from a single switch, if it's at 1, 1 is on, 2 and 3 is off.
wait
realize that
so im pushing buttons from 8
but once i do that, 9 does trigger too
a button event is only called once when u press, it doesnt constantly call it while ur holding a button
what are u censoring 😅
actual product ID of my joysticks
gotta hide em
button 8, button 9?
no
ic
joystick 8 and joystick 9
:bigthonk:
show ur joystick class
and ur main
show ur main too
oh wait
like i said
yeah i know why
the SDL_Event doesnt know what joystick button u pressed
yeah
it just knows the button index that is pressed
i mean, that's another thing
wrap ur console.write line in an if condition of
pressed
if (pressed == 1)
the other thing is that if i press something from 8, since joystick 9 has also a pressed button too, it displays both
do that, and it should work
do the if condition
the reason for ur bug was
then here
yeah
it should be like, i pressed a button from a specific joystick, then it should display which button did i press and which joystick did it come from.
thats SDL_JoystickGetButton's job
it detects if the pressed button is coming from that specific joystick
yeah
question is, which button was pressed
that's what im trying to find
its stored in
e.jbutton.button
okay
that works now
but what about where it's only detecting a specific joystick regardless of another joystick having a pressed button too.
for example, im only pressing 8 here but 9 shows up as well because it has a button down too.
i only want to get from 8.
huh, show ur joystick class again
is this an old image?
it doesnt match ur code
ill show again
im only pressing joystick 6 here,
but 8 shows up
although im not doing anything with it
:bigthonk:
it does have a pressed button (there's no other way around it with my physical joystick)
can u print the value of
_joystick
i mean, if it's not possible, i guess that's fine
it's random numbers
i know, show them
those are addresses, like the ones you see in C/C++
and ur only pressing buttons from only 1 joystick?
yep
It doesn't make sense tbh
hm
i think i can just leave it at that
as long as it stays there, it's fine
atleast im not touching it
maybe ur other joystick is lagging?
no
or its very sensitive
just that it always has one button down
just think of switches
a lightswitch
it's pretty much on the firmware that's it's like this
All i can think of is that ur joystick is very sensitive
actually
it's just the firmware's built like this
so it's all fine
If you say so
anyways,
on to more complex part:
im thinking of doing something like this
you could start with creating a method called OnPressed(int button);
it also has to be on a specific joystick, as it shows there
well you have ur productId
OnPressed has to be those
{ Console.Write("\nSouth"); }
stuff, right?
something like that
alright
thanks for your big help
np
@R another thing, is there a way to make sure that im getting all the button state from a joystick?
because from this code, it only shows when im pressing a button but it's not getting all button states
button state as in if its pressed or not?
yep
let's say, i have a joystick that has a lot of buttons
some of them are pressed and some of them are not
yea
well u have
SDL_JoystickGetButton
it gets the state of a button
loop on all of the buttonsin my current code, how do you do that?
use a for loop?
oh right
@R now the issue here idk how would i get that
i
or do i just write 0-26 here?wdym how u would get that i
hm
oh wait
this is wrong
i was trying to get all button states
i decided to write 0-26.
rather than getting the i
?
okay
let me try to clear something up
this is kind of what i did:
@R
does this work fine?
ofcourse not, u never used
i
well, this is like
im using specific buttons only
then loop on those specific buttons
it did somehow work but i have a bad feeling that
SDL.SDL_JoystickGetButton(_joystick, 0);
will be also detected by other joysticksit shouldnt
hm
let me try to put it on the test.
+ now the variable
button
is useless here since you never used ityep
which would make the method's purpose pointless
hm
yeah
i got back to that old error
2+ joysticks just don't work
but
i learned something here
feels like i have to make a custom event-driven system in my program
so that i can try reducing cpu usage
use Thread.Sleep
Games that render 60 frames per sec, they just divide 1000 / 60, which is 16.66666666667 ms
Note that Thread.Sleep is not precise
it is far off from precise
What would you recommend?
Timers? Either roll your own high resolution timer or use a library
If you need exact or close to 60 fps
well i use Thread.Sleep with 16.66667 ms minus the amount of ms that passed since the previous frame
@ajcdev sorry, turns out it does, lol
no idea how i missed it