/*
pygame - Python Game Library
Copyright (C) 2000-2001 Pete Shinners
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Pete Shinners
pete@shinners.org
*/
#define PYGAMEAPI_JOYSTICK_INTERNAL
#include "pygame.h"
#define JOYSTICK_MAXSTICKS 32
static SDL_Joystick* joystick_stickdata[JOYSTICK_MAXSTICKS] = {NULL};
staticforward PyTypeObject PyJoystick_Type;
static PyObject* PyJoystick_New(int);
#define PyJoystick_Check(x) ((x)->ob_type == &PyJoystick_Type)
static void joy_autoquit(void)
{
int loop;
for(loop = 0; loop < JOYSTICK_MAXSTICKS; ++loop)
{
if(joystick_stickdata[loop])
{
SDL_JoystickClose(joystick_stickdata[loop]);
joystick_stickdata[loop] = NULL;
}
}
if(SDL_WasInit(SDL_INIT_JOYSTICK))
{
SDL_JoystickEventState(SDL_ENABLE);
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
}
static PyObject* joy_autoinit(PyObject* self, PyObject* arg)
{
if(!PyArg_ParseTuple(arg, ""))
return NULL;
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
{
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK))
return PyInt_FromLong(0);
SDL_JoystickEventState(SDL_ENABLE);
PyGame_RegisterQuit(joy_autoquit);
}
return PyInt_FromLong(1);
}
/*DOC*/ static char doc_quit[] =
/*DOC*/ "pygame.joystick.quit() -> None\n"
/*DOC*/ "uninitialize joystick module\n"
/*DOC*/ "\n"
/*DOC*/ "Uninitialize the joystick module manually\n"
/*DOC*/ ;
static PyObject* quit(PyObject* self, PyObject* arg)
{
if(!PyArg_ParseTuple(arg, ""))
return NULL;
joy_autoquit();
RETURN_NONE
}
/*DOC*/ static char doc_init[] =
/*DOC*/ "pygame.joystick.init() -> None\n"
/*DOC*/ "initialize joystick module\n"
/*DOC*/ "\n"
/*DOC*/ "Initialize the joystick module manually\n"
/*DOC*/ ;
static PyObject* init(PyObject* self, PyObject* arg)
{
PyObject* result;
int istrue;
if(!PyArg_ParseTuple(arg, ""))
return NULL;
result = joy_autoinit(self, arg);
istrue = PyObject_IsTrue(result);
Py_DECREF(result);
if(!istrue)
return RAISE(PyExc_SDLError, SDL_GetError());
RETURN_NONE
}
/*DOC*/ static char doc_get_init[] =
/*DOC*/ "pygame.joystick.get_init() -> bool\n"
/*DOC*/ "query initialization of joystick module\n"
/*DOC*/ "\n"
/*DOC*/ "Returns true when the joystick module is initialized.\n"
/*DOC*/ ;
static PyObject* get_init(PyObject* self, PyObject* arg)
{
if(!PyArg_ParseTuple(arg, ""))
return NULL;
return PyInt_FromLong(SDL_WasInit(SDL_INIT_JOYSTICK)!=0);
}
/*joystick object funcs*/
static void joy_dealloc(PyObject* self)
{
PyObject_DEL(self);
}
/*DOC*/ static char doc_Joystick[] =
/*DOC*/ "pygame.joystick.Joystick(id) -> Joystick\n"
/*DOC*/ "create new joystick object\n"
/*DOC*/ "\n"
/*DOC*/ "Creates a new joystick object for the given device id. The given id\n"
/*DOC*/ "must be less than the value from pygame.joystick.get_count().\n"
/*DOC*/ ;
static PyObject* Joystick(PyObject* self, PyObject* args)
{
int id;
if(!PyArg_ParseTuple(args, "i", &id))
return NULL;
JOYSTICK_INIT_CHECK();
return PyJoystick_New(id);
}
/*DOC*/ static char doc_get_count[] =
/*DOC*/ "pygame.joystick.get_count() -> int\n"
/*DOC*/ "query number of joysticks on system\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the number of joysticks devices available on\n"
/*DOC*/ "the system.\n"
/*DOC*/ ;
static PyObject* get_count(PyObject* self, PyObject* args)
{
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
return PyInt_FromLong(SDL_NumJoysticks());
}
/*DOC*/ static char doc_joy_init[] =
/*DOC*/ "Joystick.init() -> None\n"
/*DOC*/ "initialize a joystick device for use\n"
/*DOC*/ "\n"
/*DOC*/ "In order to call most members in the Joystick object, the\n"
/*DOC*/ "Joystick must be initialized. You can initialzie the Joystick object\n"
/*DOC*/ "at anytime, and it is ok to initialize more than once.\n"
/*DOC*/ ;
static PyObject* joy_init(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joystick_stickdata[joy_id])
{
joystick_stickdata[joy_id] = SDL_JoystickOpen(joy_id);
if(!joystick_stickdata[joy_id])
return RAISE(PyExc_SDLError, SDL_GetError());
}
RETURN_NONE
}
/*DOC*/ static char doc_joy_quit[] =
/*DOC*/ "Joystick.quit() -> None\n"
/*DOC*/ "uninitialize a joystick device for use\n"
/*DOC*/ "\n"
/*DOC*/ "After you are completely finished with a joystick device, you\n"
/*DOC*/ "can use this quit() function to free access to the drive.\n"
/*DOC*/ "This will be cleaned up automatically when the joystick module is.\n"
/*DOC*/ "uninitialized. It is safe to call this function on an uninitialized Joystick.\n"
/*DOC*/ ;
static PyObject* joy_quit(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
if(joystick_stickdata[joy_id])
{
SDL_JoystickClose(joystick_stickdata[joy_id]);
joystick_stickdata[joy_id] = NULL;
}
RETURN_NONE
}
/*DOC*/ static char doc_joy_get_init[] =
/*DOC*/ "Joystick.get_init() -> bool\n"
/*DOC*/ "check if joystick is initialized\n"
/*DOC*/ "\n"
/*DOC*/ "Returns a true value if the Joystick is initialized.\n"
/*DOC*/ ;
static PyObject* joy_get_init(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
if(!PyArg_ParseTuple(args, ""))
return NULL;
return PyInt_FromLong(joystick_stickdata[joy_id] != NULL);
}
/*DOC*/ static char doc_joy_get_id[] =
/*DOC*/ "Joystick.get_id() -> idnum\n"
/*DOC*/ "get device id number for joystick\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the device id number for this Joystick. This is the\n"
/*DOC*/ "same number used in the call to pygame.joystick.Joystick() to create\n"
/*DOC*/ "the object. The Joystick does not need to be initialized for this\n"
/*DOC*/ "function to work.\n"
/*DOC*/ ;
static PyObject* joy_get_id(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
if(!PyArg_ParseTuple(args, ""))
return NULL;
return PyInt_FromLong(joy_id);
}
/*DOC*/ static char doc_joy_get_name[] =
/*DOC*/ "Joystick.get_name() -> string\n"
/*DOC*/ "query name of joystick drive\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the name of the Joystick device, given by the\n"
/*DOC*/ "system. This function can be called before the Joystick\n"
/*DOC*/ "object is initialized.\n"
/*DOC*/ ;
static PyObject* joy_get_name(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
return PyString_FromString(SDL_JoystickName(joy_id));
}
/*DOC*/ static char doc_joy_get_numaxes[] =
/*DOC*/ "Joystick.get_numaxes() -> int\n"
/*DOC*/ "get number of axes on a joystick\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the number of available axes on the Joystick.\n"
/*DOC*/ ;
static PyObject* joy_get_numaxes(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
return PyInt_FromLong(SDL_JoystickNumAxes(joy));
}
/*DOC*/ static char doc_joy_get_axis[] =
/*DOC*/ "Joystick.get_axis(axis) -> float\n"
/*DOC*/ "get the position of a joystick axis\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the current position of a joystick axis. The value\n"
/*DOC*/ "will range from -1 to 1 with a value of 0 being centered. You\n"
/*DOC*/ "may want to take into account some tolerance to handle jitter,\n"
/*DOC*/ "and joystick drift may keep the joystick from centering at 0 or\n"
/*DOC*/ "using the full range of position values.\n"
/*DOC*/ ;
static PyObject* joy_get_axis(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
int axis, value;
if(!PyArg_ParseTuple(args, "i", &axis))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
if(axis < 0 || axis >= SDL_JoystickNumAxes(joy))
return RAISE(PyExc_SDLError, "Invalid joystick axis");
value = SDL_JoystickGetAxis(joy, axis);
return PyFloat_FromDouble(value / 32768.0);
}
/*DOC*/ static char doc_joy_get_numbuttons[] =
/*DOC*/ "Joystick.get_numbuttons() -> int\n"
/*DOC*/ "get number of buttons on a joystick\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the number of available buttons on the Joystick.\n"
/*DOC*/ ;
static PyObject* joy_get_numbuttons(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
return PyInt_FromLong(SDL_JoystickNumButtons(joy));
}
/*DOC*/ static char doc_joy_get_button[] =
/*DOC*/ "Joystick.get_button(button) -> bool\n"
/*DOC*/ "get the position of a joystick button\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the current state of a joystick button.\n"
/*DOC*/ ;
static PyObject* joy_get_button(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
int index, value;
if(!PyArg_ParseTuple(args, "i", &index))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
if(index < 0 || index >= SDL_JoystickNumButtons(joy))
return RAISE(PyExc_SDLError, "Invalid joystick button");
value = SDL_JoystickGetButton(joy, index);
return PyInt_FromLong(value);
}
/*DOC*/ static char doc_joy_get_numballs[] =
/*DOC*/ "Joystick.get_numballs() -> int\n"
/*DOC*/ "get number of trackballs on a joystick\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the number of available trackballs on the Joystick.\n"
/*DOC*/ ;
static PyObject* joy_get_numballs(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
return PyInt_FromLong(SDL_JoystickNumBalls(joy));
}
/*DOC*/ static char doc_joy_get_ball[] =
/*DOC*/ "Joystick.get_ball(button) -> x, y\n"
/*DOC*/ "get the movement of a joystick trackball\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the relative movement of a joystick button. The\n"
/*DOC*/ "value is a x, y pair holding the relative movement since the\n"
/*DOC*/ "last call to get_ball()\n"
/*DOC*/ ;
static PyObject* joy_get_ball(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
int index, dx, dy;
if(!PyArg_ParseTuple(args, "i", &index))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
if(index < 0 || index >= SDL_JoystickNumBalls(joy))
return RAISE(PyExc_SDLError, "Invalid joystick trackball");
SDL_JoystickGetBall(joy, index, &dx, &dy);
return Py_BuildValue("(ii)", dx, dy);
}
/*DOC*/ static char doc_joy_get_numhats[] =
/*DOC*/ "Joystick.get_numhats() -> int\n"
/*DOC*/ "get number of hats on a joystick\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the number of available directional hats on the Joystick.\n"
/*DOC*/ ;
static PyObject* joy_get_numhats(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
if(!PyArg_ParseTuple(args, ""))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
return PyInt_FromLong(SDL_JoystickNumHats(joy));
}
/*DOC*/ static char doc_joy_get_hat[] =
/*DOC*/ "Joystick.get_hat(button) -> x, y\n"
/*DOC*/ "get the position of a joystick hat\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the current position of a position hat. The position\n"
/*DOC*/ "is given as two values representing the X and Y position for the\n"
/*DOC*/ "hat. (0, 0) means centered. A value of -1 means left/down a value\n"
/*DOC*/ "of one means right/up\n"
/*DOC*/ ;
static PyObject* joy_get_hat(PyObject* self, PyObject* args)
{
int joy_id = PyJoystick_AsID(self);
SDL_Joystick* joy = joystick_stickdata[joy_id];
int index, px, py;
Uint8 value;
if(!PyArg_ParseTuple(args, "i", &index))
return NULL;
JOYSTICK_INIT_CHECK();
if(!joy)
return RAISE(PyExc_SDLError, "Joystick not initialized");
if(index < 0 || index >= SDL_JoystickNumHats(joy))
return RAISE(PyExc_SDLError, "Invalid joystick hat");
px = py = 0;
value = SDL_JoystickGetHat(joy, index);
if(value&SDL_HAT_UP) py = 1;
else if(value&SDL_HAT_DOWN) py = -1;
if(value&SDL_HAT_RIGHT) px = 1;
else if(value&SDL_HAT_LEFT) px = -1;
return Py_BuildValue("(ii)", px, py);
}
static PyMethodDef joy_builtins[] =
{
{ "init", joy_init, 1, doc_joy_init },
{ "quit", joy_quit, 1, doc_joy_quit },
{ "get_init", joy_get_init, 1, doc_joy_get_init },
{ "get_id", joy_get_id, 1, doc_joy_get_id },
{ "get_name", joy_get_name, 1, doc_joy_get_name },
{ "get_numaxes", joy_get_numaxes, 1, doc_joy_get_numaxes },
{ "get_axis", joy_get_axis, 1, doc_joy_get_axis },
{ "get_numbuttons", joy_get_numbuttons, 1, doc_joy_get_numbuttons },
{ "get_button", joy_get_button, 1, doc_joy_get_button },
{ "get_numballs", joy_get_numballs, 1, doc_joy_get_numballs },
{ "get_ball", joy_get_ball, 1, doc_joy_get_ball },
{ "get_numhats", joy_get_numhats, 1, doc_joy_get_numhats },
{ "get_hat", joy_get_hat, 1, doc_joy_get_hat },
{ NULL, NULL }
};
static PyObject* joy_getattr(PyObject* self, char* attrname)
{
return Py_FindMethod(joy_builtins, self, attrname);
}
/*DOC*/ static char doc_Joystick_MODULE[] =
/*DOC*/ "The Joystick object represents a joystick device and allows you to\n"
/*DOC*/ "access the controls on that joystick. All functions (except get_name()\n"
/*DOC*/ "and get_id()) require the Joystick object to be initialized. This is done\n"
/*DOC*/ "with the Joystick.init() function.\n"
/*DOC*/ "\n"
/*DOC*/ "Joystick control values are only updated during the calls to the event\n"
/*DOC*/ "queue. Call pygame.event.pump() if you are not using the event queue for\n"
/*DOC*/ "any input handling. Once a joystick object has been initialized, it will\n"
/*DOC*/ "start to send joystick events to the input queue.\n"
/*DOC*/ "\n"
/*DOC*/ "Be sure to understand there is a difference between the joystick module\n"
/*DOC*/ "and the Joystick objects.\n"
/*DOC*/ ;
static PyTypeObject PyJoystick_Type =
{
PyObject_HEAD_INIT(NULL)
0,
"Joystick",
sizeof(PyJoystickObject),
0,
joy_dealloc,
0,
joy_getattr,
0,
0,
0,
0,
NULL,
0,
(hashfunc)NULL,
(ternaryfunc)NULL,
(reprfunc)NULL,
0L,0L,0L,0L,
doc_Joystick_MODULE /* Documentation string */
};
static PyObject* PyJoystick_New(int id)
{
PyJoystickObject* joy;
if(id < 0 || id >= JOYSTICK_MAXSTICKS || id >= SDL_NumJoysticks())
return RAISE(PyExc_SDLError, "Invalid joystick device number");
joy = PyObject_NEW(PyJoystickObject, &PyJoystick_Type);
if(!joy) return NULL;
joy->id = id;
return (PyObject*)joy;
}
static PyMethodDef joystick_builtins[] =
{
{ "__PYGAMEinit__", joy_autoinit, 1, doc_joy_init },
{ "init", init, 1, doc_init },
{ "quit", quit, 1, doc_quit },
{ "get_init", get_init, 1, doc_get_init },
{ "get_count", get_count, 1, doc_get_count },
{ "Joystick", Joystick, 1, doc_Joystick },
{ NULL, NULL }
};
/*DOC*/ static char doc_pygame_joystick_MODULE[] =
/*DOC*/ "The joystick module provides a few functions to initialize\n"
/*DOC*/ "the joystick subsystem and to manage the Joystick objects. These\n"
/*DOC*/ "objects are created with the pygame.joystick.Joystick() function.\n"
/*DOC*/ "This function needs a joystick device number to work on. All\n"
/*DOC*/ "joystick devices on the system are enumerated for use as a Joystick\n"
/*DOC*/ "object. To access most of the Joystick functions, you'll need to\n"
/*DOC*/ "init() the Joystick. (note that the joystick module will already\n"
/*DOC*/ "be initialized). When multiple Joysticks objects are created for the\n"
/*DOC*/ "same joystick device, the state and values for those Joystick objects\n"
/*DOC*/ "will be shared.\n"
/*DOC*/ "\n"
/*DOC*/ "You can call the Joystick.get_name() and Joystick.get_id() functions\n"
/*DOC*/ "without initializing the Joystick object.\n"
/*DOC*/ "\n"
/*DOC*/ "Joystick control values are only updated during the calls to the event\n"
/*DOC*/ "queue. Call pygame.event.pump() if you are not using the event queue for\n"
/*DOC*/ "any input handling. Once a joystick object has been initialized, it will\n"
/*DOC*/ "start to send joystick events to the input queue.\n"
/*DOC*/ "\n"
/*DOC*/ "Be sure to understand there is a difference between the joystick module\n"
/*DOC*/ "and the Joystick objects.\n"
/*DOC*/ ;
PYGAME_EXPORT
void initjoystick(void)
{
PyObject *module, *dict, *apiobj;
static void* c_api[PYGAMEAPI_JOYSTICK_NUMSLOTS];
PyType_Init(PyJoystick_Type);
/* create the module */
module = Py_InitModule3("joystick", joystick_builtins, doc_pygame_joystick_MODULE);
dict = PyModule_GetDict(module);
PyDict_SetItemString(dict, "JoystickType", (PyObject *)&PyJoystick_Type);
/* export the c api */
c_api[0] = &PyJoystick_Type;
c_api[1] = PyJoystick_New;
apiobj = PyCObject_FromVoidPtr(c_api, NULL);
PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
Py_DECREF(apiobj);
/*imported needed apis*/
import_pygame_base();
}
syntax highlighted by Code2HTML, v. 0.9.1