py-sdl2 icon indicating copy to clipboard operation
py-sdl2 copied to clipboard

Mouse module issues

Open marcusva opened this issue 12 years ago • 3 comments

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

marcusva avatar Aug 16 '13 08:08 marcusva

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.

marcusva avatar Aug 16 '13 13:08 marcusva

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())

marcusva avatar Aug 16 '13 13:08 marcusva

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.

a-hurst avatar Sep 03 '22 16:09 a-hurst