C
C#•3mo ago
jcaishere

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
TheRanger
TheRanger•3mo ago
This part should be in the main method
while (!quit) // beginning of a frame
{
SDL.SDL_Event e;
while (SDL.SDL_PollEvent(out e) != 0)
{
foreach(var joystick in joysticks)
{
joystick.Handle(e);
}
}
// end of a frame
}
while (!quit) // beginning of a frame
{
SDL.SDL_Event e;
while (SDL.SDL_PollEvent(out e) != 0)
{
foreach(var joystick in joysticks)
{
joystick.Handle(e);
}
}
// end of a frame
}
the first while loop is to keep the game running
jcaishere
jcaishere•3mo ago
main method?
TheRanger
TheRanger•3mo ago
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/unpressed
jcaishere
jcaishere•3mo ago
how about the product ID? because i do need it so that i can make sure that it's actually following the right joystick
TheRanger
TheRanger•3mo ago
you could say it acts like
foreach(var e in sdl_keyevents)
{
}
foreach(var e in sdl_keyevents)
{
}
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?
jcaishere
jcaishere•3mo ago
still a bit confused because i used to have everything thrown at me and think it'd work
TheRanger
TheRanger•3mo ago
that's your problem, you should exactly understand everything ur writing dont assume it will automatically work
jcaishere
jcaishere•3mo ago
using System;
using SDL2;
using System.Threading.Tasks;
using SDLCSharp;
using System.Collections.Concurrent;
using static SDL2.SDL;

class Program
{
static void Main(string[] args)
{
SDL.SDL_Init(SDL.SDL_INIT_JOYSTICK);
Dictionary<int, Tuple<int, int>> joystickInfo = new Dictionary<int, Tuple<int, int>>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);
int instanceID = SDL.SDL_JoystickInstanceID(joystick);

joystickInfo[getProductIDs] = Tuple.Create(i, instanceID);

SDL.SDL_JoystickClose(joystick);
}
}

Console.WriteLine("Connected Joysticks:");
foreach (var entry in joystickInfo)
{
int productID = entry.Key;
int joystickIndex = entry.Value.Item1;
int instanceID = entry.Value.Item2;
Console.WriteLine($"Product ID: {productID}, Joystick Index: {joystickIndex}, Instance ID: {instanceID}");
}


}

}
using System;
using SDL2;
using System.Threading.Tasks;
using SDLCSharp;
using System.Collections.Concurrent;
using static SDL2.SDL;

class Program
{
static void Main(string[] args)
{
SDL.SDL_Init(SDL.SDL_INIT_JOYSTICK);
Dictionary<int, Tuple<int, int>> joystickInfo = new Dictionary<int, Tuple<int, int>>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);
int instanceID = SDL.SDL_JoystickInstanceID(joystick);

joystickInfo[getProductIDs] = Tuple.Create(i, instanceID);

SDL.SDL_JoystickClose(joystick);
}
}

Console.WriteLine("Connected Joysticks:");
foreach (var entry in joystickInfo)
{
int productID = entry.Key;
int joystickIndex = entry.Value.Item1;
int instanceID = entry.Value.Item2;
Console.WriteLine($"Product ID: {productID}, Joystick Index: {joystickIndex}, Instance ID: {instanceID}");
}


}

}
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
TheRanger
TheRanger•3mo ago
wait why are you closing the joysticks?
jcaishere
jcaishere•3mo ago
this is pretty much just displaying the joysticks that i have that are connected
TheRanger
TheRanger•3mo ago
you haven't answered my question u are opening the joystick on every frame, you dont need that once is enough
jcaishere
jcaishere•3mo ago
well, im opening multiple joysticks
TheRanger
TheRanger•3mo ago
yeah thats good, then you close them I never used GetProduct tho
jcaishere
jcaishere•3mo ago
yeah that's the product ID of the joystick it's important for my project
TheRanger
TheRanger•3mo ago
the IntPtr from JoystickOpen is enough for me anyway
jcaishere
jcaishere•3mo ago
i remove the closing of joysticks, okay... what's next, adding the while loop for checking the state of joysticks buttons
TheRanger
TheRanger•3mo ago
no need to use dictionary, just use List<Joystick>
jcaishere
jcaishere•3mo ago
I'll just keep it that way
TheRanger
TheRanger•3mo ago
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
jcaishere
jcaishere•3mo ago
List<int> productIDs = new List<int> { 12345, 12346, 12347 };
Dictionary<int, Tuple<int, int>> joystickInfo = new Dictionary<int, Tuple<int, int>>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);
int instanceID = SDL.SDL_JoystickInstanceID(joystick);

if (productIDs.Contains(getProductIDs))
{
joystickInfo[getProductIDs] = Tuple.Create(i, instanceID);
}

}
}

Console.WriteLine("Connected Joysticks:");
foreach (var entry in joystickInfo)
{
int productID = entry.Key;
int joystickIndex = entry.Value.Item1;
int instanceID = entry.Value.Item2;
Console.WriteLine($"Product ID: {productID}, Joystick Index: {joystickIndex}, Instance ID: {instanceID}");
}
List<int> productIDs = new List<int> { 12345, 12346, 12347 };
Dictionary<int, Tuple<int, int>> joystickInfo = new Dictionary<int, Tuple<int, int>>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);
int instanceID = SDL.SDL_JoystickInstanceID(joystick);

if (productIDs.Contains(getProductIDs))
{
joystickInfo[getProductIDs] = Tuple.Create(i, instanceID);
}

}
}

Console.WriteLine("Connected Joysticks:");
foreach (var entry in joystickInfo)
{
int productID = entry.Key;
int joystickIndex = entry.Value.Item1;
int instanceID = entry.Value.Item2;
Console.WriteLine($"Product ID: {productID}, Joystick Index: {joystickIndex}, Instance ID: {instanceID}");
}
this is my original code.
TheRanger
TheRanger•3mo ago
List<int> productIDs = new List<int> { 12345, 12346, 12347 }; arent the joystick product ids 0, 1, 2 and so on?
jcaishere
jcaishere•3mo ago
no, they're number indices 12345, 12346, 12347 are just for display the product IDs that i have are for, not public
TheRanger
TheRanger•3mo ago
yeah but do u know what this code does?
if (productIDs.Contains(getProductIDs))
{
joystickInfo[getProductIDs] = Tuple.Create(i, instanceID);
}
if (productIDs.Contains(getProductIDs))
{
joystickInfo[getProductIDs] = Tuple.Create(i, instanceID);
}
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
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
List<int> productIDs = new List<int> { 12345, 12346, 12347 };
List<Joystick> joysticks = new List<Joystick>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);
int instanceID = SDL.SDL_JoystickInstanceID(joystick);

if (productIDs.Contains(getProductIDs))
{
joysticks.Add(new Joystick(i, getProductIDs, instanceId));
}

}
}
List<int> productIDs = new List<int> { 12345, 12346, 12347 };
List<Joystick> joysticks = new List<Joystick>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);
int instanceID = SDL.SDL_JoystickInstanceID(joystick);

if (productIDs.Contains(getProductIDs))
{
joysticks.Add(new Joystick(i, getProductIDs, instanceId));
}

}
}
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 joysticks
jcaishere
jcaishere•3mo ago
okay
TheRanger
TheRanger•3mo ago
because you can make many instances out of a single class
jcaishere
jcaishere•3mo ago
so i made a class Joystick that's good, what's next...
TheRanger
TheRanger•3mo ago
show me ur class
jcaishere
jcaishere•3mo ago
internal class Joystick
{
private int i;
private int getProductIDs;

public Joystick(int i, int getProductIDs)
{
this.i = i;
this.getProductIDs = getProductIDs;
}
}
internal class Joystick
{
private int i;
private int getProductIDs;

public Joystick(int i, int getProductIDs)
{
this.i = i;
this.getProductIDs = getProductIDs;
}
}
TheRanger
TheRanger•3mo ago
great but u could change private int getProductIDs; to private int _productId;
jcaishere
jcaishere•3mo ago
alright
TheRanger
TheRanger•3mo ago
in C# its recommended to name private fields like that to begin with an underscore
jcaishere
jcaishere•3mo ago
i see
TheRanger
TheRanger•3mo ago
ok now you can put the Handle method
jcaishere
jcaishere•3mo ago
in the Joystick class, right?
TheRanger
TheRanger•3mo ago
yeah
jcaishere
jcaishere•3mo ago
Well, this happened
No description
TheRanger
TheRanger•3mo ago
ops
public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
bool pressed = SDL.SDL_JoystickGetButton(_yourJoystickId, e.jbutton.button);
break;
}
}
public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
bool pressed = SDL.SDL_JoystickGetButton(_yourJoystickId, e.jbutton.button);
break;
}
}
jcaishere
jcaishere•3mo ago
No description
jcaishere
jcaishere•3mo ago
hm
TheRanger
TheRanger•3mo ago
you missed something break; what does SDL_JoystickGetButton return? int?
jcaishere
jcaishere•3mo ago
nint on joystick and int on button
TheRanger
TheRanger•3mo ago
then you know what to do use int not bool if its 0 it indicates the button index isnt pressed, 1 if it is
jcaishere
jcaishere•3mo ago
now ill go back to main and try your while loop
TheRanger
TheRanger•3mo ago
good but do u understand this error?
jcaishere
jcaishere•3mo ago
i did
TheRanger
TheRanger•3mo ago
ok
jcaishere
jcaishere•3mo ago
i fixed it
TheRanger
TheRanger•3mo ago
ok now but GetButton doesnt take a product id
jcaishere
jcaishere•3mo ago
yeah it takes i instead
TheRanger
TheRanger•3mo ago
No
jcaishere
jcaishere•3mo ago
really?
TheRanger
TheRanger•3mo ago
yeah it needs the value that JoyStickOpen returns for the first parameter
jcaishere
jcaishere•3mo ago
which is i
TheRanger
TheRanger•3mo ago
No
jcaishere
jcaishere•3mo ago
unless i misunderstood
TheRanger
TheRanger•3mo ago
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 that
jcaishere
jcaishere•3mo ago
so i have to change it ?
TheRanger
TheRanger•3mo ago
ofcourse it wants the value that SDL_JoystickOpen returns
jcaishere
jcaishere•3mo ago
well, im trying to find what can be a replacement for IntPtr now
TheRanger
TheRanger•3mo ago
why would you? nint is alias for IntPtr btw so, same thing
jcaishere
jcaishere•3mo ago
oh 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?
TheRanger
TheRanger•3mo ago
no you need to figure out how to pass the value of IntPtr joystick into your class because you need that value
jcaishere
jcaishere•3mo ago
joysticks.Add(new Joystick(i, getProductIDs, joystick));
joysticks.Add(new Joystick(i, getProductIDs, joystick));
does this not work?
TheRanger
TheRanger•3mo ago
it should, if you have the correct parameters in your constructor
jcaishere
jcaishere•3mo ago
using SDL2;
using static SDL2.SDL;

internal class Joystick
{
private int i;
private int _productId;
private nint _joystick;

public Joystick(int i, int _productId, nint _joystick)
{
this.i = i;
this._productId = _productId;
this._joystick = _joystick;
}

public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button);
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
}
}
using SDL2;
using static SDL2.SDL;

internal class Joystick
{
private int i;
private int _productId;
private nint _joystick;

public Joystick(int i, int _productId, nint _joystick)
{
this.i = i;
this._productId = _productId;
this._joystick = _joystick;
}

public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button);
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
}
}
how's this?
TheRanger
TheRanger•3mo ago
looks perfect
jcaishere
jcaishere•3mo ago
alright, now onto complex part
TheRanger
TheRanger•3mo ago
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
jcaishere
jcaishere•3mo ago
hm i think i need to get like, specific buttons
TheRanger
TheRanger•3mo ago
No
jcaishere
jcaishere•3mo ago
like, 0, 1, 2, 3, etc.
TheRanger
TheRanger•3mo ago
not now well, did you test? what did you find so far?
jcaishere
jcaishere•3mo ago
i did test i have 2 joysticks it seems to only detect the first one instead of both
TheRanger
TheRanger•3mo ago
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 loop
jcaishere
jcaishere•3mo ago
mhm
TheRanger
TheRanger•3mo ago
the while loop should be outside of the for loop
jcaishere
jcaishere•3mo ago
i removed it and it does work
TheRanger
TheRanger•3mo ago
cool
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
u have i, and productid of each joystick u could differentiate with their values
jcaishere
jcaishere•3mo ago
should i also add e.jbutton.which too?
TheRanger
TheRanger•3mo ago
i never heard of that
jcaishere
jcaishere•3mo ago
because it does display both, but it feels like the other button is getting triggered because this joystick of mine has 2 buttons
TheRanger
TheRanger•3mo ago
SDL does not have which that in jbutton did u mean e.jbutton.button ?
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
what do u mean?
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
realize that
jcaishere
jcaishere•3mo ago
No description
jcaishere
jcaishere•3mo ago
so im pushing buttons from 8 but once i do that, 9 does trigger too
TheRanger
TheRanger•3mo ago
a button event is only called once when u press, it doesnt constantly call it while ur holding a button what are u censoring 😅
jcaishere
jcaishere•3mo ago
actual product ID of my joysticks gotta hide em
TheRanger
TheRanger•3mo ago
button 8, button 9?
jcaishere
jcaishere•3mo ago
no
TheRanger
TheRanger•3mo ago
ic
jcaishere
jcaishere•3mo ago
joystick 8 and joystick 9
TheRanger
TheRanger•3mo ago
:bigthonk: show ur joystick class and ur main
jcaishere
jcaishere•3mo ago
using SDL2;
using static SDL2.SDL;

internal class Joystick
{
private int i;
private int _productId;
private nint _joystick;

public Joystick(int i, int _productId, nint _joystick)
{
this.i = i;
this._productId = _productId;
this._joystick = _joystick;
}

public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button);
Console.WriteLine($"Joystick {_productId} is pressed!");
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
}
}
using SDL2;
using static SDL2.SDL;

internal class Joystick
{
private int i;
private int _productId;
private nint _joystick;

public Joystick(int i, int _productId, nint _joystick)
{
this.i = i;
this._productId = _productId;
this._joystick = _joystick;
}

public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button);
Console.WriteLine($"Joystick {_productId} is pressed!");
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
}
}
TheRanger
TheRanger•3mo ago
show ur main too oh wait like i said
jcaishere
jcaishere•3mo ago
using System;
using SDL2;
using static SDL2.SDL;

class Program
{
static void Main(string[] args)
{
SDL.SDL_Init(SDL.SDL_INIT_JOYSTICK);

List<int> productIDs = new List<int> { /*hidden for reasons*/ };
List<Joystick> joysticks = new List<Joystick>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);

if (productIDs.Contains(getProductIDs))
{
joysticks.Add(new Joystick(i, getProductIDs, joystick));
}

}
}

bool quit = false;

while (!quit)
{
SDL.SDL_Event e;
while (SDL.SDL_PollEvent(out e) != 0)
{
foreach (var joy in joysticks)
{
joy.Handle(e);
}
}
}
}
}
using System;
using SDL2;
using static SDL2.SDL;

class Program
{
static void Main(string[] args)
{
SDL.SDL_Init(SDL.SDL_INIT_JOYSTICK);

List<int> productIDs = new List<int> { /*hidden for reasons*/ };
List<Joystick> joysticks = new List<Joystick>();

int numJoysticks = SDL.SDL_NumJoysticks();
for (int i = 0; i < numJoysticks; ++i)
{
IntPtr joystick = SDL.SDL_JoystickOpen(i);
if (joystick != IntPtr.Zero)
{
int getProductIDs = SDL.SDL_JoystickGetProduct(joystick);

if (productIDs.Contains(getProductIDs))
{
joysticks.Add(new Joystick(i, getProductIDs, joystick));
}

}
}

bool quit = false;

while (!quit)
{
SDL.SDL_Event e;
while (SDL.SDL_PollEvent(out e) != 0)
{
foreach (var joy in joysticks)
{
joy.Handle(e);
}
}
}
}
}
TheRanger
TheRanger•3mo ago
yeah i know why the SDL_Event doesnt know what joystick button u pressed
jcaishere
jcaishere•3mo ago
yeah
TheRanger
TheRanger•3mo ago
it just knows the button index that is pressed
jcaishere
jcaishere•3mo ago
i mean, that's another thing
TheRanger
TheRanger•3mo ago
wrap ur console.write line in an if condition of pressed if (pressed == 1)
jcaishere
jcaishere•3mo ago
the other thing is that if i press something from 8, since joystick 9 has also a pressed button too, it displays both
TheRanger
TheRanger•3mo ago
do that, and it should work do the if condition the reason for ur bug was
while (SDL.SDL_PollEvent(out e) != 0)
{
// oh look, a button was pressed
foreach (var joy in joysticks) // let every joystick handle e
{
joy.Handle(e);
}
}
while (SDL.SDL_PollEvent(out e) != 0)
{
// oh look, a button was pressed
foreach (var joy in joysticks) // let every joystick handle e
{
joy.Handle(e);
}
}
then here
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN: // its a joystick button
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button); // returns true for joystick 8, but false for joystick 9
Console.WriteLine($"Joystick {_productId} is pressed!"); //doesnt matter, a joystick button is pressed, ill just call this
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN: // its a joystick button
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button); // returns true for joystick 8, but false for joystick 9
Console.WriteLine($"Joystick {_productId} is pressed!"); //doesnt matter, a joystick button is pressed, ill just call this
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
jcaishere
jcaishere•3mo ago
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.
TheRanger
TheRanger•3mo ago
thats SDL_JoystickGetButton's job it detects if the pressed button is coming from that specific joystick
jcaishere
jcaishere•3mo ago
yeah question is, which button was pressed that's what im trying to find
TheRanger
TheRanger•3mo ago
its stored in e.jbutton.button
jcaishere
jcaishere•3mo ago
okay that works now but what about where it's only detecting a specific joystick regardless of another joystick having a pressed button too.
jcaishere
jcaishere•3mo ago
for example, im only pressing 8 here but 9 shows up as well because it has a button down too.
No description
jcaishere
jcaishere•3mo ago
i only want to get from 8.
TheRanger
TheRanger•3mo ago
huh, show ur joystick class again
jcaishere
jcaishere•3mo ago
using SDL2;
using static SDL2.SDL;

internal class Joystick
{
private int i;
private int _productId;
private nint _joystick;

public Joystick(int i, int _productId, nint _joystick)
{
this.i = i;
this._productId = _productId;
this._joystick = _joystick;
}

public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button);
if (pressed == 1)
{
Console.WriteLine($"Joystick {_productId} button {e.jbutton.button} is pressed!");
}
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
}
}
using SDL2;
using static SDL2.SDL;

internal class Joystick
{
private int i;
private int _productId;
private nint _joystick;

public Joystick(int i, int _productId, nint _joystick)
{
this.i = i;
this._productId = _productId;
this._joystick = _joystick;
}

public void Handle(SDL_Event e)
{
switch (e.type)
{
case SDL.SDL_EventType.SDL_JOYBUTTONDOWN:
int pressed = SDL.SDL_JoystickGetButton(_joystick, e.jbutton.button);
if (pressed == 1)
{
Console.WriteLine($"Joystick {_productId} button {e.jbutton.button} is pressed!");
}
break;
case SDL.SDL_EventType.SDL_JOYAXISMOTION:
int motion = SDL.SDL_JoystickGetAxis(_joystick, e.jaxis.axis);
break;
default:
break;
}
}
}
TheRanger
TheRanger•3mo ago
is this an old image? it doesnt match ur code
jcaishere
jcaishere•3mo ago
ill show again
jcaishere
jcaishere•3mo ago
No description
jcaishere
jcaishere•3mo ago
im only pressing joystick 6 here, but 8 shows up although im not doing anything with it
TheRanger
TheRanger•3mo ago
:bigthonk:
jcaishere
jcaishere•3mo ago
it does have a pressed button (there's no other way around it with my physical joystick)
TheRanger
TheRanger•3mo ago
can u print the value of _joystick
jcaishere
jcaishere•3mo ago
i mean, if it's not possible, i guess that's fine it's random numbers
TheRanger
TheRanger•3mo ago
i know, show them those are addresses, like the ones you see in C/C++
jcaishere
jcaishere•3mo ago
No description
TheRanger
TheRanger•3mo ago
and ur only pressing buttons from only 1 joystick?
jcaishere
jcaishere•3mo ago
yep
TheRanger
TheRanger•3mo ago
It doesn't make sense tbh
jcaishere
jcaishere•3mo ago
hm i think i can just leave it at that as long as it stays there, it's fine atleast im not touching it
TheRanger
TheRanger•3mo ago
maybe ur other joystick is lagging?
jcaishere
jcaishere•3mo ago
no
TheRanger
TheRanger•3mo ago
or its very sensitive
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
All i can think of is that ur joystick is very sensitive
jcaishere
jcaishere•3mo ago
actually it's just the firmware's built like this so it's all fine
TheRanger
TheRanger•3mo ago
If you say so
jcaishere
jcaishere•3mo ago
anyways, on to more complex part:
byte button0 = SDL.SDL_JoystickGetButton(joy1, 0);
byte button1 = SDL.SDL_JoystickGetButton(joy1, 1);
byte button2 = SDL.SDL_JoystickGetButton(joy1, 2);
byte button3 = SDL.SDL_JoystickGetButton(joy1, 3);

if (button0 == 1) { Console.Write("\nOff"); }

if (button1 == 1) { Console.Write("\nLeft"); }

if (button2 == 1) { Console.Write("\nCenter"); }

if (button3 == 1) { Console.Write("\nRight"); }
byte button0 = SDL.SDL_JoystickGetButton(joy1, 0);
byte button1 = SDL.SDL_JoystickGetButton(joy1, 1);
byte button2 = SDL.SDL_JoystickGetButton(joy1, 2);
byte button3 = SDL.SDL_JoystickGetButton(joy1, 3);

if (button0 == 1) { Console.Write("\nOff"); }

if (button1 == 1) { Console.Write("\nLeft"); }

if (button2 == 1) { Console.Write("\nCenter"); }

if (button3 == 1) { Console.Write("\nRight"); }
byte button4 = SDL.SDL_JoystickGetButton(joy2, 4);
byte button5 = SDL.SDL_JoystickGetButton(joy2, 5);
byte button6 = SDL.SDL_JoystickGetButton(joy2, 6);
byte button7 = SDL.SDL_JoystickGetButton(joy2, 7);

if (button4 == 1) { Console.Write("\nSouth"); }

if (button5 == 1) { Console.Write("\nWest"); }

if (button6 == 1) { Console.Write("\nNorth"); }

if (button7 == 1) { Console.Write("\nEast"); }
byte button4 = SDL.SDL_JoystickGetButton(joy2, 4);
byte button5 = SDL.SDL_JoystickGetButton(joy2, 5);
byte button6 = SDL.SDL_JoystickGetButton(joy2, 6);
byte button7 = SDL.SDL_JoystickGetButton(joy2, 7);

if (button4 == 1) { Console.Write("\nSouth"); }

if (button5 == 1) { Console.Write("\nWest"); }

if (button6 == 1) { Console.Write("\nNorth"); }

if (button7 == 1) { Console.Write("\nEast"); }
im thinking of doing something like this
TheRanger
TheRanger•3mo ago
you could start with creating a method called OnPressed(int button);
jcaishere
jcaishere•3mo ago
it also has to be on a specific joystick, as it shows there
TheRanger
TheRanger•3mo ago
if (pressed == 1)
{
OnPressed(e.jbutton.button);
Console.WriteLine($"Joystick {_productId} button {e.jbutton.button} is pressed!");
}
if (pressed == 1)
{
OnPressed(e.jbutton.button);
Console.WriteLine($"Joystick {_productId} button {e.jbutton.button} is pressed!");
}
well you have ur productId
jcaishere
jcaishere•3mo ago
OnPressed has to be those { Console.Write("\nSouth"); } stuff, right?
TheRanger
TheRanger•3mo ago
void OnPressed(int button)
{
if (_productId = 1111)
{
if (button == 0) { Console.Write("\nOff"); }
if (button == 1) { Console.Write("\nLeft"); }
if (button == 2) { Console.Write("\nCenter"); }
if (button == 3) { Console.Write("\nRight"); }
}
else if (_productId == 2222)
{
if (button == 5) { Console.Write("\nSouth"); }
if (button == 6) { Console.Write("\nWest"); }
if (button == 7) { Console.Write("\nNorth"); }
if (button == 8) { Console.Write("\nEast"); }
}
void OnPressed(int button)
{
if (_productId = 1111)
{
if (button == 0) { Console.Write("\nOff"); }
if (button == 1) { Console.Write("\nLeft"); }
if (button == 2) { Console.Write("\nCenter"); }
if (button == 3) { Console.Write("\nRight"); }
}
else if (_productId == 2222)
{
if (button == 5) { Console.Write("\nSouth"); }
if (button == 6) { Console.Write("\nWest"); }
if (button == 7) { Console.Write("\nNorth"); }
if (button == 8) { Console.Write("\nEast"); }
}
something like that
jcaishere
jcaishere•3mo ago
alright thanks for your big help
TheRanger
TheRanger•3mo ago
np
jcaishere
jcaishere•3mo ago
@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
TheRanger
TheRanger•3mo ago
button state as in if its pressed or not?
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
yea well u have SDL_JoystickGetButton it gets the state of a button loop on all of the buttons
jcaishere
jcaishere•3mo ago
in my current code, how do you do that?
TheRanger
TheRanger•3mo ago
use a for loop?
jcaishere
jcaishere•3mo ago
oh right
void OnPressed(int button)
{
if (_productId = 1111)
{
for (int i = 0; i < 27; i++)
{
int pressed = SDL.SDL_JoystickGetButton(_joystick, i);
}
}
else if (_productId == 2222)
{
if (button == 5) { Console.Write("\nSouth"); }
if (button == 6) { Console.Write("\nWest"); }
if (button == 7) { Console.Write("\nNorth"); }
if (button == 8) { Console.Write("\nEast"); }
}
}
void OnPressed(int button)
{
if (_productId = 1111)
{
for (int i = 0; i < 27; i++)
{
int pressed = SDL.SDL_JoystickGetButton(_joystick, i);
}
}
else if (_productId == 2222)
{
if (button == 5) { Console.Write("\nSouth"); }
if (button == 6) { Console.Write("\nWest"); }
if (button == 7) { Console.Write("\nNorth"); }
if (button == 8) { Console.Write("\nEast"); }
}
}
@R now the issue here idk how would i get that i or do i just write 0-26 here?
TheRanger
TheRanger•3mo ago
wdym how u would get that i
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
?
jcaishere
jcaishere•3mo ago
okay let me try to clear something up this is kind of what i did:
void OnPressed(int button)
{
if (_productId = 1111)
{
for (int i = 0; i < 27; i++)
{
byte button0 = SDL.SDL_JoystickGetButton(_joystick, 0);
byte button1 = SDL.SDL_JoystickGetButton(_joystick, 1);
byte button2 = SDL.SDL_JoystickGetButton(_joystick, 2);
byte button3 = SDL.SDL_JoystickGetButton(_joystick, 3);

if (button0 == 1) { Console.Write("\nOff"); }
if (button1 == 1) { Console.Write("\nLeft"); }
if (button2 == 1) { Console.Write("\nCenter"); }
if (button3 == 1) { Console.Write("\nRight"); }

}
}

}
void OnPressed(int button)
{
if (_productId = 1111)
{
for (int i = 0; i < 27; i++)
{
byte button0 = SDL.SDL_JoystickGetButton(_joystick, 0);
byte button1 = SDL.SDL_JoystickGetButton(_joystick, 1);
byte button2 = SDL.SDL_JoystickGetButton(_joystick, 2);
byte button3 = SDL.SDL_JoystickGetButton(_joystick, 3);

if (button0 == 1) { Console.Write("\nOff"); }
if (button1 == 1) { Console.Write("\nLeft"); }
if (button2 == 1) { Console.Write("\nCenter"); }
if (button3 == 1) { Console.Write("\nRight"); }

}
}

}
@R does this work fine?
TheRanger
TheRanger•3mo ago
ofcourse not, u never used i
jcaishere
jcaishere•3mo ago
well, this is like im using specific buttons only
TheRanger
TheRanger•3mo ago
then loop on those specific buttons
jcaishere
jcaishere•3mo ago
it did somehow work but i have a bad feeling that SDL.SDL_JoystickGetButton(_joystick, 0); will be also detected by other joysticks
TheRanger
TheRanger•3mo ago
it shouldnt
jcaishere
jcaishere•3mo ago
hm let me try to put it on the test.
TheRanger
TheRanger•3mo ago
+ now the variable button is useless here since you never used it
jcaishere
jcaishere•3mo ago
yep
TheRanger
TheRanger•3mo ago
which would make the method's purpose pointless
jcaishere
jcaishere•3mo ago
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
TheRanger
TheRanger•3mo ago
use Thread.Sleep Games that render 60 frames per sec, they just divide 1000 / 60, which is 16.66666666667 ms
Buddy
Buddy•3mo ago
Note that Thread.Sleep is not precise it is far off from precise
TheRanger
TheRanger•3mo ago
What would you recommend?
Buddy
Buddy•3mo ago
Timers? Either roll your own high resolution timer or use a library If you need exact or close to 60 fps
TheRanger
TheRanger•3mo ago
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