Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Joysticks on a Mac, _DEVICEINPUT()
#1
Does anybody know if _DEVICE$ and _DEVICEINPUT() work on MacOS? I was just noodling around with a cheap joystick I got, but any reference to _DEVICEINPUT(3) causes an Illegal Function error. Also the stick doesn't show up as connected under _DEVICE$. I was using a few of Terry's (@TerryRitchie) joystick and device demo programs to get started.

This mashup below sorta works - it gets some input from the stick, but only when the stick is moved from the zero, zero position - when action is detected generically. Without using _DEVICEINPUT(3) I can't get actual live input. What's a guy to do?   Dodgy  Thanks.


Code: (Select All)
CONST JOYSTICK = 3 '        joystick controller id (may need to change to match your joystick id)

DIM DeviceCount AS INTEGER ' number of controller devices (used to activate)
DIM Threshold AS SINGLE '    amount of deflection needed to activate movement
DIM Xaxis AS SINGLE '        value of joystick x axis (horizontal)
DIM Yaxis AS SINGLE '        value of joystick y axis (vertical)
DIM x AS SINGLE '            x location of circle
DIM y AS SINGLE '            y location of circle
DIM Speed AS INTEGER '      axis speed multiplier

DeviceCount = _DEVICES '                                        activate controller statements
Threshold = .05 '                                              set axis threshold
Speed = 10 '                                                    set axis speed multiplier
x = 319 '                                                      center circle
y = 239
SCREEN _NEWIMAGE(640, 480, 32) '                                graphics screen
DO '                                                            begin controller loop
    _LIMIT 60 '                                                  60 frames per second
    CLS '                                                        clear screen
    LOCATE 2, 16 '                                              position cursor
    PRINT "Use joystick handle to move circle. Esc to exit." '  display instructions

    DeviceInput = _DEVICEINPUT '                                get any controller interaction
    IF DeviceInput THEN '                                        was a controller interacted with?
        WHILE _DEVICEINPUT(DeviceInput): WEND '                  yes, get the latest controller information

        'WHILE _DEVICEINPUT(JOYSTICK): WEND '      THIS CAUSES INSTANT CRASH  reference joystick 1 and get latest update
        Xaxis = _AXIS(1) '                                          get current horizontal value
        Yaxis = _AXIS(2) '                                          get current vertical value
        IF ABS(Xaxis) >= Threshold THEN x = x + Xaxis * Speed '      move circle horizontally if threshold met
        IF ABS(Yaxis) >= Threshold THEN y = y + Yaxis * Speed '      move circle vertically if threshold met
        IF x < 0 THEN x = x + 639 ELSE IF x > 639 THEN x = x - 639 ' keep horizontal movement on screen
        IF y < 0 THEN y = y + 479 ELSE IF y > 479 THEN y = y - 479 ' keep vertical movement on screen
        CIRCLE (x, y), 30 '                                          draw the circle
        _DISPLAY '                                                  update screen with changes
    END IF
LOOP UNTIL _KEYDOWN(27) '                                      leave when ESC pressed
SYSTEM '
Reply
#2
I'll can test with an XBox 360 controller during the weekend. Will let you know.
Reply
#3
Thanks, a740g!
Reply
#4
Quick update:

So, it seems that macOS does not support a wired Xbox 360 controller. Also, the PS4 and the Xbox One controllers are supported only when connected via BT.  Sad

https://support.apple.com/en-us/111099

I am still trying to figure out how to get my wired Xbox 360 controller to work.

There is this: https://github.com/360Controller/360Controller

But it has not been updated in ages and there is no support for Big Sur and above.
Reply
#5
Thanks, sounds like I need a PC for this assignment. Appreciate you taking a look!
Reply
#6
I'm continuing this thread, but discussing Steve's comments from this other thread from yesterday - https://qb64phoenix.com/forum/showthread.php?tid=3959 (posts #7 & #8) 

So @SMcNeill, the good news, I installed the "USB OverDrive" driver app for Mac you found (cost me $20!) and now my crappy little joystick is recognized by MacOS and QBPE, but, the bad news, when I run your joystick code nothing happens. However, good news, when I run the Terry R mashup prog I made, the joystick sorta, kinda works! BUT it only works by returning the stick back to the neutral position before another action is executed. I can move the circle around the screen by repeatedly bumping the stick, right, back, right, back, but it won't sample and move continuously. Maybe you've got an easy fix for this? I'll paste the code here with a couple comments added...

Undimming this line makes the prog no longer get stick input: While _DeviceInput(JOYSTICK): Wend

Code: (Select All)
Const JOYSTICK = 3 '            joystick controller id (may need to change to match your joystick id)

Dim DeviceCount As Integer '    number of controller devices (used to activate)
Dim Threshold As Single '      amount of deflection needed to activate movement
Dim Xaxis As Single '          value of joystick x axis (horizontal)
Dim Yaxis As Single '          value of joystick y axis (vertical)
Dim x As Single '              x location of circle
Dim y As Single '              y location of circle
Dim Speed As Integer '          axis speed multiplier

DeviceCount = _Devices '                activate controller statements
Threshold = .05 '  .05                  set axis threshold
Speed = 10 '                            set axis speed multiplier
x = 319 '                              center circle
y = 239
Screen _NewImage(640, 480, 32) '        graphics screen
Do '                                    begin controller loop
    _Limit 60 '                        60 frames per second
    Cls '                              clear screen
    Locate 2, 16 '                      position cursor
    Print "Use joystick handle to move circle. Esc to exit." ' display instructions

    DeviceInput = _DeviceInput '                get any controller interaction
    If DeviceInput Then '                      was a controller interacted with?
        'While _DeviceInput(DeviceInput): Wend '        yes, get the latest controller information  <<< this isn't needed <<<

        'While _DeviceInput(JOYSTICK): Wend '                                                        <<< this kills the joystick sampling <<<<<
        Xaxis = _Axis(1) '                    get current horizontal value
        Yaxis = _Axis(2) '                    get current vertical value

        If Abs(Xaxis) >= Threshold Then x = x + Xaxis * Speed '  move circle horizontally if threshold met
        If Abs(Yaxis) >= Threshold Then y = y + Yaxis * Speed '  move circle vertically if threshold met

        If x < 0 Then x = x + 639 Else If x > 639 Then x = x - 639 ' keep horizontal movement on screen
        If y < 0 Then y = y + 479 Else If y > 479 Then y = y - 479 ' keep vertical movement on screen
        Circle (x, y), 30 '                    draw the circle

        Print "X: "; Xaxis
        Print "Y: "; Yaxis
        Print "Devices: "; _Devices
        For i = 1 To _Devices
            Print Str$(i) + ") " + _Device$(i) + " Buttons:"; _LastButton(i); ",Axis:"; _LastAxis(i); ",Wheel:"; _LastWheel(i)
        Next
        _Display '                          update screen with changes
    End If
Loop Until _KeyDown(27) '                  leave when ESC pressed
System '
Reply
#7
Maybe this can help you: I completely avoid _deviceinput by using strig() and stick(); you can try the program I posted in the following thread : gamepad tester
It maps the controller and lets you test buttons and sticks. 
The program also uses _device, _device$(), _lastbutton(), _lastaxis(), and _lastwhell(). 
I run it on Linux on a Raspberry Pi 500. Tell me if it works on Mac.
Reply
#8
Merci, Herve! I’ll give your code a try as soon as I’m in front of my computer.  Smile
Reply
#9
You might have to make use of the cross platform project called hidapi. It allows you to communicate with HID devices on Windows, Mac, and Linux. I've used it before for testing a Nintendo Switch Pro controller on Windows and it worked great. You have to know more about the device you're working with, but it might be just what you need. The code below is from when I made that test program. Obviously, this code won't work on your computer, but it will at least give you an idea of how you would ultimately use the API headers on Mac:

Code: (Select All)
Option _Explicit
'$CONSOLE:ONLY
'_DEST _CONSOLE

Const MAX_STR = 255

Const LEFT_BUMPER = &H10
Const RIGHT_BUMPER = &H20
Const LEFT_TRIGGER = &H40
Const RIGHT_TRIGGER = &H80

Const X_BUTTON = &H8
Const A_BUTTON = &H2
Const B_BUTTON = &H1
Const Y_BUTTON = &H4

Const PLUS_BUTTON = &H2
Const MINUS_BUTTON = &H1

Const L_STICK_BTN = &H4
Const R_STICK_BTN = &H8

Const HOME_BUTTON = &H10
Const CAPTURE_BUTTON = &H20

Const NINTENDO_PRO_VID = &H0002057E
Const NINTENDO_PRO_PID = &H2009

Declare Dynamic Library "hidapi"
    Function hid_init% ()
    Function hid_open%& (ByVal vendor_id As _Unsigned Integer, ByVal product_id As _Unsigned Integer, ByVal serial_number As _Offset)
    Function hid_get_manufacturer_string% (ByVal device As _Offset, ByVal buffer As _Offset, ByVal maxlen As _Integer64)
    Function hid_get_product_string% (ByVal device As _Offset, ByVal buffer As _Offset, ByVal maxlen As _Integer64)
    Function hid_get_serial_number_string% (ByVal device As _Offset, ByVal buffer As _Offset, ByVal maxlen As _Integer64)
    Function hid_get_indexed_string% (ByVal device As _Offset, ByVal string_index As Integer, ByVal buffer As _Offset, ByVal maxlen As _Integer64)
    Function hid_write% (ByVal device As _Offset, ByVal datas As _Offset, ByVal length As _Integer64)
    Function hid_read% (ByVal device As _Offset, ByVal datas As _Offset, ByVal length As _Integer64)
    Sub hid_close (ByVal device As _Offset)
    Function hid_exit% ()
End Declare

Declare Dynamic Library "Kernel32"
    Function WideCharToMultiByte% (ByVal CodePage As _Unsigned Integer, ByVal dwFlags As Long, ByVal lpWideCharStr As _Offset, ByVal cchWideChar As Integer, ByVal lpMultiByteStr As _Offset, ByVal cbMultiByte As Integer, ByVal lpDefaultChar As _Offset, ByVal lpUsedDefaultChar As _Offset)
End Declare

If hid_init = 0 Then
    Dim res As Integer
    Dim handle As _Offset
    handle = hid_open(NINTENDO_PRO_VID, NINTENDO_PRO_PID, 0) 'Nintendo Switch Pro Controller
    'handle = hid_open(&H046D, &HC07E, 0) 'Logitech Gaming Mouse G402
    'handle = hid_open(&H0FD9, &H006A, 0)
    'handle = hid_open(&HB58E, &H9E84, 0)
    'handle = hid_open(&H046D, &HC21D, 0) 'Logitech F310 Gamepad
    If handle Then
        Dim buffer As String * MAX_STR
        Dim ansibuffer As String
        Dim buf(0 To 11) As _Unsigned _Byte
        buf(0) = &H3F
        res = hid_write(handle, _Offset(buf()), 12)
        'DIM x AS INTEGER
        Do
            Cls
            res = hid_read(handle, _Offset(buf()), 12)
            If res Then
                res = hid_get_manufacturer_string(handle, _Offset(buffer), MAX_STR)
                If res = 0 Then
                    ansibuffer = UnicodeToANSI(buffer)
                    Print "Manufacturer String : "; ansibuffer
                End If
                buffer = Space$(MAX_STR)
                res = hid_get_product_string(handle, _Offset(buffer), MAX_STR)
                If res = 0 Then
                    ansibuffer = UnicodeToANSI(buffer)
                    Print "Product String      : "; ansibuffer
                End If
                buffer = Space$(MAX_STR)
                res = hid_get_serial_number_string(handle, _Offset(buffer), MAX_STR)
                If res = 0 Then
                    ansibuffer = UnicodeToANSI(buffer)
                    Print "Serial Number String: "; ansibuffer
                End If
                buffer = Space$(MAX_STR)
                res = hid_get_indexed_string(handle, 1, _Offset(buffer), MAX_STR)
                If res = 0 Then
                    ansibuffer = UnicodeToANSI(buffer)
                    Print "Indexed String 1    : "; ansibuffer
                End If

                Print "Input report ID  :"; Hex$(buf(0))
                Print "Button status    :"; Hex$(buf(1)), Hex$(buf(2))
                Print "D-pad button      :"; Hex$(buf(3))
                Print "Left analog stick :"; "X"; buf(5), "Y"; map(buf(7), 255, 0, 0, 255)
                Print "Right analog stick:"; "X"; buf(9), "Y"; map(buf(11), 255, 0, 0, 255)
            End If
            _Display
        Loop Until InKey$ = Chr$(27)
        _AutoDisplay
    End If
    hid_close handle
End If
res = hid_exit
'SLEEP

Function UnicodeToANSI$ (buffer As String)
    Dim ansibuffer As String
    ansibuffer = Space$(Len(buffer) / 2)
    Dim a As Integer
    a = WideCharToMultiByte(437, 0, _Offset(buffer), Len(buffer), _Offset(ansibuffer), Len(ansibuffer), 0, 0)
    UnicodeToANSI = Mid$(ansibuffer, 1, InStr(ansibuffer, Chr$(0)) - 1)
End Function

Function map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
    map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
End Function
The noticing will continue
Reply
#10
@Herve, avoiding _DeviceInput seems to be important when using joysticks with QBPE on Macs. Your program works perfectly and is elegantly coded. Thanks for the insight. +1

Thanks, @SpriggsySpriggs, it turns out that good old Stick() and Strig() work just fine under MacOS once you have the USB OverDrive driver app installed. And it looks like somebody got married. Congrats!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Mac print #file crlf? BlameTroi 5 329 02-16-2026, 08:42 PM
Last Post: BlameTroi
  Mac debugger not connecting, a user error! BlameTroi 0 99 02-07-2026, 06:18 PM
Last Post: BlameTroi
  Mac current release sigabrt BlameTroi 3 220 02-05-2026, 02:26 PM
Last Post: a740g
  QB64pe 4.0 on Mac Troubles NakedApe 14 2,243 12-29-2024, 01:53 AM
Last Post: NakedApe
  Compiling for Mac-OS mdijkens 12 2,466 03-13-2024, 10:24 PM
Last Post: NakedApe

Forum Jump:


Users browsing this thread: 1 Guest(s)