electronstudio / raylib-python-cffi

Python CFFI bindings for Raylib
http://electronstudio.github.io/raylib-python-cffi
Eclipse Public License 2.0
142 stars 29 forks source link

Gamepad input doesn't work #51

Closed pkulev closed 2 years ago

pkulev commented 2 years ago

I'm using raylib-dynamic 3.7.0.post10 with hylang. Raylib recognizes attached gamepads on macos (m1) and windows, but all input fetching functions return no input. GetGamepadButtonPressed returns -1 all the time, GetGamepadAsixMovement returns 0 all the time and checking against concrete buttons returns False.

This is equivalent python code I used for testing (generated):

import pyray as pr
pr.set_config_flags(pr.FLAG_MSAA_4X_HINT)
pr.init_window(800, 600, 'Test gamepad')
pr.set_target_fps(60)
while not pr.window_should_close():
    pr.begin_drawing()
    pr.clear_background(pr.BLACK)
    if pr.is_gamepad_available(0):
        pr.draw_text(f'GP0: {pr.get_gamepad_name(0)}', 5, 5, 20, pr.RAYWHITE)
        pr.draw_text(f'Axis: {pr.get_gamepad_axis_count(0)}', 5, 30, 20, pr.RAYWHITE)
        pr.draw_text(f'Button: {pr.get_gamepad_button_pressed()}', 5, 55, 20, pr.RAYWHITE)
        _hy_anon_var_1 = pr.draw_text(
            f'Axis 0: {pr.get_gamepad_axis_movement(0, 0)}', 5, 85, 20, pr.RAYWHITE)
    else:
        _hy_anon_var_1 = None
    pr.end_drawing()
pr.close_window()

I used different gamepads, they all work in raylib example https://www.raylib.com/examples/core/loader.html?name=core_input_gamepad.

Also question, how to get gamepad name using GetGamepadName as string? It returns something too low level.

electronstudio commented 2 years ago

Does it work with the static library?

electronstudio commented 2 years ago

To get the name string:

pr.draw_text(f'GP0: {pr.ffi.string(pr.get_gamepad_name(0)).decode("utf-8")}', 5, 5, 20, pr.RAYWHITE)

possibly we should automate that conversion

electronstudio commented 2 years ago
  1. Please update to raylib-dynamic 4.0.0 that I just released. There may have been mismatch with header files before.
  2. For me, Xbox Elite pad is detected but no input received. However a PS4 pad works fine. That is the same in Raylib C and python raylib-dynamic 4.0. So if your pad isn't working, test it with Raylib C (not Raylib C WASM because that will use different APIs).
  3. If it's something that only happens in the dynamic version then that is why I put the big warning that weird things seem to happen with dynamic bindings.
pkulev commented 2 years ago

possibly we should automate that conversion

Yep, definitely should.

Does it work with the static library?

Yes, works. But why dynamic library has that "weird things to happen"? Dynamic libraries are everywhere...

I'll check 4.0.0 soon.

electronstudio commented 2 years ago

Yes, works. But why dynamic library has that "weird things to happen"? Dynamic libraries are everywhere...

Well Python CFFI recommends using static, so maybe not everywhere in Python CFFI world.

My best guess is that there is some problem such as the version of the DLL not matching the version of raylib.h and if this happened with the static version it would give you an error on compile, but because it's dynamic it runs but returns null, or corrupts memory or something else unexpected.

pkulev commented 2 years ago

static 3.7.0.post10 works on windows, but doesn't work on m1 macos the same way.

pkulev commented 2 years ago

Also tried 4.0.0 static, on both windows and macos gamepads are recognized, but no input. What's interesting: On windows I get

RAYLIB STATIC 4.0.0 LOADED
INFO: Initializing raylib **4.0**

On macos

RAYLIB STATIC 4.0.0 LOADED
INFO: Initializing raylib **3.7**
electronstudio commented 2 years ago

The reason for the version number mis-match is that you MacOS M1 pip is compiling the library using the system raylib, and you still have raylib 3.7 installed on the system. So install raylib 4.0 on system, and then re-install raylib-python-cffi so it compiles again.

electronstudio commented 2 years ago

I tested raylib-python-cffi 4.0.0 static and dynamic on Windows and it works for both my controllers. So I don't think the problem is raylib-python-cffi. Does the Raylib C gamepad example work on your Windows?

pkulev commented 2 years ago

Did some more tests.

Figuring now how to build those examples to try.

electronstudio commented 2 years ago

I think that error is because Music.looping is a bool ;(I.e. 1 byte) but MSVC compiler doesn’t properly support C99 bools and is treating it as an int (4 bytes). I will try to fix it.

electronstudio commented 2 years ago

The Music boolean error should be fixed now in 4.0.0.1 please test. Also string conversions should be automatic.

pkulev commented 2 years ago

It crashes on pr.get_gamepad_name(0) when I unplug gamepad:


  File "/Users/most/proj/tanki/.venv/lib/python3.9/site-packages/pyray/__init__.py", line 80, in func
    result = ffi.string(result).decode('utf-8')
RuntimeError: cannot use string() on <cdata 'char *' NULL>```
electronstudio commented 2 years ago

It’s returning a null pointer because the game pad doesn’t exist. Not sure what to do in that situation. I could put in a check for null and return “” instead. I suppose closest Python equivalent is to return None. But having to check if a function returned None is quite annoying for the user and error prone.

pkulev commented 2 years ago

For now empty string seems good enough. Functions that return const char*:

I've skipped those related to FS management and string manupulations.

electronstudio commented 2 years ago

Yeah that seems to be the least hassle for people to deal with.

BTW someone on Raylib Discord today reported their Xbox One gamepad doesnt work on MacOS, so I still think that's a Raylib issue.