py-sdl2
py-sdl2 copied to clipboard
Mouse module issues
Originally reported by: sp4ztique (Bitbucket: sp4ztique, GitHub: sp4ztique)
The mouse related functions i.e. SDL_GetMouseState(), aren't well documented for python, as in C they involve getting the mouse position via x and y pointers passed to the function, rather than just returning a tuple or using a class. I've had a lot of trouble getting this function to work, as I'm trying to use the mouse for unit movement, similar to diablo or RTS games, but even when I try and create pointers with ctypes, this function doesn't want to work. If I pass x and y as None, I can get it to return the mouse button states, but I can't seem to get the right ctypes pointer.
I'd really rather use this library than the dead pygame, but if I can't get the mouse co-ordinates I'm going to be forced to switch to pygame.
Also, sorry for posting this here, if you have somewhere you'd rather questions sent I'll happily switch to that platform.
- Bitbucket: https://bitbucket.org/marcusva/py-sdl2/issue/10
Original comment by Marcus von Appen (Bitbucket: marcusva, GitHub: marcusva):
Todo: add a small primer about how to use the most important ctypes features with the sdl2 API.
Original comment by Marcus von Appen (Bitbucket: marcusva, GitHub: marcusva):
Providing a documentation for how to use all wrapped SDL2 API parts would mean duplicating the SDL2 documentation and adjusting some parts for Python's ctypes interface, which would be (mainly) a waste of time.
I'll add a small primer about how to deal with in/out values and pointers to the py-sdl2 documentation, though, to make it easier for newcomers.
As a rule of thumb (use with care, exceptions ahead), you can stick to the following:
- if the argument to the function is a pointer, into which a value has to be written, use ctypes.byref() with the matching value type.
- if the argument to the function is a pointer, which won't be modified, you can use ctypes.POINTER or, if the argument is a struct pointer, use the argument directly in most cases.
Find below a small example for SDL_GetMouseState.
#!python
"""Simple example for using sdl2 directly."""
import os
import sys
import ctypes
from sdl2 import *
def run():
SDL_Init(SDL_INIT_VIDEO)
window = SDL_CreateWindow(b"Hello World",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
592, 460, SDL_WINDOW_SHOWN)
fname = os.path.join(os.path.dirname(os.path.abspath(__file__)),
"resources", "hello.bmp")
image = SDL_LoadBMP(fname.encode("utf-8"))
windowsurface = SDL_GetWindowSurface(window)
SDL_BlitSurface(image, None, windowsurface, None)
SDL_UpdateWindowSurface(window)
SDL_FreeSurface(image)
running = True
event = SDL_Event()
ct_x = ctypes.c_int(0)
ct_y = ctypes.c_int(0)
while running:
while SDL_PollEvent(ctypes.byref(event)) != 0:
if event.type == SDL_QUIT:
running = False
break
SDL_Delay(200)
# Get the mouse state
buttons = SDL_GetMouseState(ctypes.byref(ct_x), ctypes.byref(ct_y))
print("Mouse is at: (%d, %d)" % (ct_x.value, ct_y.value))
button_state = [0, 0, 0, 0, 0]
# (left, right, middle, x1, x2)
if buttons & SDL_BUTTON_LMASK:
button_state[0] = 1
if buttons & SDL_BUTTON_RMASK:
button_state[1] = 1
if buttons & SDL_BUTTON_MMASK:
button_state[2] = 1
if buttons & SDL_BUTTON_X1MASK:
button_state[3] = 1
if buttons & SDL_BUTTON_X2MASK:
button_state[4] = 1
print("Buttons pressed: %s" % button_state)
SDL_DestroyWindow(window)
SDL_Quit()
return 0
if __name__ == "__main__":
sys.exit(run())
Since working with SDL2's mouse module is pretty unpleasant in Python, sdl2.ext would benefit a lot from having a simple sdl2.ext.mouse API. This would support getting/setting mouse position, showing/hiding the cursor, retrieving the button state, and (potentially) a function or two for checking for/handling mouse events in the SDL2 event queue.