My GamePad360

I found something called PyPad360 v3.0 beta and I liked it but I thought I’d go ahead and tweak it a little. Also it depended on Panda unnecessarily. And it presumed I wanted to deal with inputs in a certain way. This version doesn’t need Panda3D to work. Only SDL2. I’ll describe below how I installed it.

(Also the name for this module is just becouse of a lack of imagination, rename it to whatevs if you like)

Maybe this isn’t the standard way of coding. Maybe some software engineer somewhere feels a disturbance in the force right now but here’s the code anyway:

import sys
import sdl2
import sdl2.ext

##Ignoring rumbling for now until I can figure out how that works

class MyPad360():
    def __init__(self):
        if sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_HAPTIC):
            raise RuntimeError(sdl2.SDL_GetError())
        
        self.BUTTONDOWN = sdl2.SDL_JOYBUTTONDOWN
        self.BUTTONUP = sdl2.SDL_JOYBUTTONUP
        self.AXISMOTION = sdl2.SDL_JOYAXISMOTION
        self.HATMOTION = sdl2.SDL_JOYHATMOTION
        
        if sys.platform == "win32" or sys.platform == "cygwin": # Mappings for Windows:
            self.BUTTON_ID = ["DPAD_UP", "DPAD_DOWN", "DPAD_LEFT", "DPAD_RIGHT", "START", "BACK", "LSTICK", "RSTICK", "LB", "RB", "A", "B", "X", "Y", "XBOX"]
            self.AXIS_ID = ["LSTICK_H", "LSTICK_V", "RSTICK_H", "RSTICK_V", "LT", "RT"]
        else: # Default mappings for Linux:
            self.BUTTON_ID = ["A", "B", "X", "Y", "LB", "RB", "BACK", "START", "XBOX", "LSTICK", "RSTICK", "DPAD_LEFT", "DPAD_RIGHT", "DPAD_UP", "DPAD_DOWN"]
            self.AXIS_ID = ["LSTICK_H", "LSTICK_V", "RSTICK_H", "RSTICK_V", "RT", "LT"]
        
    def setupMyPad360(self):
        count = sdl2.joystick.SDL_NumJoysticks()
        
        for i in range(count):
            joystick = sdl2.SDL_JoystickOpen(i)
        
        # Make sure init-events are ignored:
        for e in sdl2.ext.get_events():
            pass
    
    def getNumControllers(self):
        return sdl2.joystick.SDL_NumJoysticks()
    
    def events(self):
        # Return all unhandled events and deal with them in main program
        return sdl2.ext.get_events()

Here is an example program that uses an xbox controller and I’ve included a description inside on how to use it:

import MyPad360

mypad = MyPad360.MyPad360()
mypad.setupGamepads()

# This while-loop could be a task that repeats with a given frequency:
while True:
    for e in mypad.events():
        # XBox360 Controller-BUTTONS:
        # "e.type == mypad.BUTTONDOWN" tests if current event is a button press
        # "e.type == mypad.BUTTONUP" tests if current event is a button release
        # "e.jbutton.button" number ID for which button produced current event
        # "e.jbutton.which" tells you which controller is producing current button event
        
        # XBox360 Controller-STICKS and -TRIGGERS:
        # "e.type == mypad.AXISMOTION" tests if current event is a change with the sticks (VERY sensitive!)
        # "e.jaxis.axis" gives number ID for which stick caused current event and in which direction:
            # 0: left stick in left and right position
            # 1: left stick in back and forth position
            # 2: right stick in left and right position
            # 3: right stick in back and forth position
            # 4: left trigger
            # 5: right trigger
        # "e.jaxis.value" gives a value of position for which stick caused current event
            # Value ranges from -32767 to +32767 (left to right or forth to back for sticks), (released to pressed for triggers)
        # "e.jhat.which" tells you which controller is producing current stick event
        
        
        # Example code:
        if e.type == mypad.BUTTONDOWN:
            print "Pressed: ", mypad.BUTTON_ID[e.jbutton.button], "on controller!"
            
        elif e.type == mypad.BUTTONUP:
            print "Released: ", mypad.BUTTON_ID[e.jbutton.button], "on controller!"

I made a simple game with a little space ship as an experiment and it was quite easy to do with this as a reference.

Alright, to install SDL2 you need two things.
First: bitbucket.org/marcusva/py-sdl2/downloads
Download the latest version. Unpack and inside you will find a bunch of folders. Grab the folder “sdl2” and stick it in your Panda SDK directory: “Panda3D-1.8.1/python/Lib/site-packages”
Second: libsdl.org/download-2.0.php
Download the runtime library. I had to use the 32-bit but you could try out the 64-bit and see if that works.
Once downloaded, unzip SDL2.dll and put it somewhere where windows can find it with environment variable. I just shoved it in next to ppython.exe in “Panda3D-1.8.1/python” and it works fine.

Again, maybe this isn’t the best way to do things. I don’t know. Do what you want with this. Love ya! :smiley: