Hammer Bro.
Hammer Bro.

Reputation: 985

PySDL2 and SDL_GetKeyboardState

I'm trying to learn SDL via PySDL2 (currently version 0.7.0; source / documentation). It provides a ctypes Python wrapper to (I assume) all of SDL's normal functions, and it provides a few more Pythonic functions via its sdl2.ext package to handle the nitty-gritty and return results in Python types. For example, sdl2.ext.get_events() will call sdl2.SDL_PumpEvents(), then peep at all the events on the queue and return them as a Python list.

However, I cannot tell if such a convenience function exists for SDL_GetKeyboardState(). The official SDL Wiki documentation for the function defines it as:

const Uint8* SDL_GetKeyboardState(int* numkeys)

where numkeys may be null (otherwise it will receive the length of the returned array) and the returned Uint8* is a pointer to an array of key states, indexed by SDL_Scancode values, which will hold 1 if the key is down or 0 if it is up.

PySDL2 does provide a direct call to SDL_GetKeyboardState via sdl2.keyboard.SDL_GetKeyboardState(numkeys), but that returns a ctypes value that is not immediately useful.

So my question is, is there some more Pythonic function for getting the current SDL keyboard state via PySDL2? If there is, what is it and how should it be used? If there's not, should one be submitted?

For reference, I think I figured out how to achieve this functionality myself, but it was a rough baptism in ctypes so I might have mangled something:

import ctypes
import sdl2


KEYBOARD_ARRAY_TYPE = ctypes.c_uint8 * sdl2.SDL_NUM_SCANCODES


def get_keyboard_state():
    """ Returns a pointer to the current SDL keyboard state,
    which is updated on SDL_PumpEvents. """
    raw_keystate = sdl2.keyboard.SDL_GetKeyboardState(None)
    pointer = ctypes.cast(raw_keystate, ctypes.POINTER(KEYBOARD_ARRAY_TYPE))
    return pointer.contents

Upvotes: 0

Views: 1753

Answers (2)

zebus
zebus

Reputation: 11

There is a simpler solution that does not require importing ctypes:

keystatus = sdl2.SDL_GetKeyboardState(None)
if keystatus[sdl2.SDL_SCANCODE_W]:
    print("the w key was pressed")

Upvotes: 1

Eryk Sun
Eryk Sun

Reputation: 34270

Here's a modification that uses numkeys instead of the constant SDL_NUM_SCANCODES:

import ctypes
import sdl2

def get_keyboard_state():
    """ Returns a list with the current SDL keyboard state,
    which is updated on SDL_PumpEvents. """
    numkeys = ctypes.c_int()
    keystate = sdl2.keyboard.SDL_GetKeyboardState(ctypes.byref(numkeys))
    ptr_t = ctypes.POINTER(ctypes.c_uint8 * numkeys.value)        
    return ctypes.cast(keystate, ptr_t)[0]

Upvotes: 2

Related Questions