Commits

Anonymous committed 3c9a13b

joystick module rewritten

Comments (0)

Files changed (9)

 access the CD inside that drive. All functions (except get_name())
 require the CD object to be initialized. This is done with the
 CD.init() function.
+<br>&nbsp;<br>
+Be sure to understand there is a difference between the cdrom module
+and the CD objects.
 
 <hr>
 
 checks for a cd in the drive</td></tr>
 
 
+<tr><td><a href=#get_id>get_id</a></td><td> -
+get device id number for drive</td></tr>
+
+
 <tr><td><a href=#get_init>get_init</a></td><td> -
 check if cd is initialized</td></tr>
 
 query name of cdrom drive</td></tr>
 
 
+<tr><td><a href=#get_numtracks>get_numtracks</a></td><td> -
+get number of tracks on cd</td></tr>
+
+
 <tr><td><a href=#get_paused>get_paused</a></td><td> -
 checks if the cd is currently paused</td></tr>
 
 check the start of an audio track</td></tr>
 
 
-<tr><td><a href=#get_tracks>get_tracks</a></td><td> -
-get number of tracks on cd</td></tr>
-
-
 <tr><td><a href=#init>init</a></td><td> -
 initialize a cdrom device for use</td></tr>
 
 Returns a true value if the cd drive is empty.
 </ul><br>&nbsp;<br>
 
+<a name=get_id><font size=+2><b>get_id
+</b></font><br><font size=+1><tt>
+CD.get_id() -> idnum
+</tt></font><ul>
+Returns the device id number for this cdrom drive. This is the
+same number used in the call to <a href=pygame_cdrom.html#CD>pygame.cdrom.CD()</a> to create this
+cd device. The CD object does not need to be initialized for this
+function to work.
+</ul><br>&nbsp;<br>
+
 <a name=get_init><font size=+2><b>get_init
 </b></font><br><font size=+1><tt>
 CD.get_init() -> bool
 is initialized.
 </ul><br>&nbsp;<br>
 
+<a name=get_numtracks><font size=+2><b>get_numtracks
+</b></font><br><font size=+1><tt>
+CD.get_numtracks() -> numtracks
+</tt></font><ul>
+Returns the number of available tracks on the CD. Note that not
+all of these tracks contain audio data. Use CD.get_audio() to check
+the track type before playing.
+</ul><br>&nbsp;<br>
+
 <a name=get_paused><font size=+2><b>get_paused
 </b></font><br><font size=+1><tt>
 CD.get_paused() -> bool
 on the cd.
 </ul><br>&nbsp;<br>
 
-<a name=get_tracks><font size=+2><b>get_tracks
-</b></font><br><font size=+1><tt>
-CD.get_tracks() -> numtracks
-</tt></font><ul>
-Returns the number of available tracks on the CD. Note that not
-all of these tracks contain audio data. Use CD.get_audio() to check
-the track type before playing.
-</ul><br>&nbsp;<br>
-
 <a name=init><font size=+2><b>init
 </b></font><br><font size=+1><tt>
 CD.init() -> None

docs/ref/Joystick.html

 </td></tr></table>
 <br>
 <h2 align=center>Joystick</h2>
-Thin object wrapper around the SDL joystick
-interface. Likely to be changed.
+The Joystick object represents a joystick device and allows you to
+access the controls on that joystick. All functions (except get_name()
+and get_id()) require the Joystick object to be initialized. This is done
+with the Joystick.init() function.
+<br>&nbsp;<br>
+Joystick control values are only updated during the calls to the event
+queue. Call pygame.event.pump() if you are not using the event queue for
+any input handling. Once a joystick object has been initialized, it will
+start to send joystick events to the input queue.
+<br>&nbsp;<br>
+Be sure to understand there is a difference between the joystick module
+and the Joystick objects.
 
 <hr>
 
 <table>
-<tr><td><a href=#get_axes>get_axes</a></td><td> -
-query number of axis</td></tr>
+<tr><td><a href=#get_axis>get_axis</a></td><td> -
+get the position of a joystick axis</td></tr>
 
 
-<tr><td><a href=#get_axis>get_axis</a></td><td> -
-query axis of a joystick</td></tr>
-
-
-<tr><td><a href=#get_balls>get_balls</a></td><td> -
-query number of balls</td></tr>
+<tr><td><a href=#get_ball>get_ball</a></td><td> -
+get the movement of a joystick trackball</td></tr>
 
 
 <tr><td><a href=#get_button>get_button</a></td><td> -
-query state of button</td></tr>
-
-
-<tr><td><a href=#get_buttons>get_buttons</a></td><td> -
-query number of buttons</td></tr>
+get the position of a joystick button</td></tr>
 
 
 <tr><td><a href=#get_hat>get_hat</a></td><td> -
-query position of hat</td></tr>
-
-
-<tr><td><a href=#get_hats>get_hats</a></td><td> -
-query number of hats</td></tr>
+get the position of a joystick hat</td></tr>
 
 
 <tr><td><a href=#get_id>get_id</a></td><td> -
-query id of joystick</td></tr>
+get device id number for joystick</td></tr>
+
+
+<tr><td><a href=#get_init>get_init</a></td><td> -
+check if joystick is initialized</td></tr>
+
+
+<tr><td><a href=#get_name>get_name</a></td><td> -
+query name of joystick drive</td></tr>
+
+
+<tr><td><a href=#get_numaxes>get_numaxes</a></td><td> -
+get number of axes on a joystick</td></tr>
+
+
+<tr><td><a href=#get_numballs>get_numballs</a></td><td> -
+get number of trackballs on a joystick</td></tr>
+
+
+<tr><td><a href=#get_numballs>get_numballs</a></td><td> -
+get number of hats on a joystick</td></tr>
+
+
+<tr><td><a href=#get_numbuttons>get_numbuttons</a></td><td> -
+get number of buttons on a joystick</td></tr>
+
+
+<tr><td><a href=#init>init</a></td><td> -
+initialize a joystick device for use</td></tr>
+
+
+<tr><td><a href=#quit>quit</a></td><td> -
+uninitialize a joystick device for use</td></tr>
 
 
 </table>
 
 <hr>
 
-<a name=get_axes><font size=+2><b>get_axes
+<a name=get_axis><font size=+2><b>get_axis
 </b></font><br><font size=+1><tt>
-Joystick.get_axes() -> count
+Joystick.get_axis(axis) -> float
 </tt></font><ul>
-Returns the number of axis on this Joystick
+Returns the current position of a joystick axis. The value
+will range from -1 to 1 with a value of 0 being centered. You
+may want to take into account some tolerance to handle jitter,
+and joystick drift may keep the joystick from centering at 0 or
+using the full range of position values.
 </ul><br>&nbsp;<br>
 
-<a name=get_axis><font size=+2><b>get_axis
+<a name=get_ball><font size=+2><b>get_ball
 </b></font><br><font size=+1><tt>
-Joystick.get_axis(axis) -> position
+Joystick.get_ball(button) -> x, y
 </tt></font><ul>
-Returns the current position of an axis control on
-the Joystick. Value is in the range -1.0 to 1.0.
-</ul><br>&nbsp;<br>
-
-<a name=get_balls><font size=+2><b>get_balls
-</b></font><br><font size=+1><tt>
-Joystick.get_balls() -> count
-</tt></font><ul>
-Returns number of trackballs on this Joystick
+Returns the relative movement of a joystick button. The
+value is a x, y pair holding the relative movement since the
+last call to <u>get_ball()</u>
 </ul><br>&nbsp;<br>
 
 <a name=get_button><font size=+2><b>get_button
 </b></font><br><font size=+1><tt>
 Joystick.get_button(button) -> bool
 </tt></font><ul>
-Returns true if the given Joystick button is being
-pressed.
-</ul><br>&nbsp;<br>
-
-<a name=get_buttons><font size=+2><b>get_buttons
-</b></font><br><font size=+1><tt>
-Joystick.get_buttons() -> count
-</tt></font><ul>
-Returns number of pushable buttons on this
-Joystick
+Returns the current state of a joystick button.
 </ul><br>&nbsp;<br>
 
 <a name=get_hat><font size=+2><b>get_hat
 </b></font><br><font size=+1><tt>
-Joystick.get_hat(pov_hat) -> state
+Joystick.get_hat(button) -> x, y
 </tt></font><ul>
-Returns the current position of a directional hat
-on the Joystick. Value in a position on the
-following compass. (think 1 is up, and goes around
-clockwise)
-8 1 2
-7 0 3
-6 5 4
-</ul><br>&nbsp;<br>
-
-<a name=get_hats><font size=+2><b>get_hats
-</b></font><br><font size=+1><tt>
-Joystick.get_hats() -> count
-</tt></font><ul>
-Returns number of directional hats on this
-Joystick
+Returns the current position of a position hat. The position
+is given as two values representing the X and Y position for the
+hat. (0, 0) means centered. A value of -1 means left/down a value
+of one means right/up
 </ul><br>&nbsp;<br>
 
 <a name=get_id><font size=+2><b>get_id
 </b></font><br><font size=+1><tt>
-Joystick.get_id() -> id
+Joystick.get_id() -> idnum
 </tt></font><ul>
-Returns the joystick id number for the Joystick
+Returns the device id number for this Joystick. This is the
+same number used in the call to <a href=pygame_joystick.html#Joystick>pygame.joystick.Joystick()</a> to create
+the object. The Joystick does not need to be initialized for this
+function to work.
+</ul><br>&nbsp;<br>
+
+<a name=get_init><font size=+2><b>get_init
+</b></font><br><font size=+1><tt>
+Joystick.get_init() -> bool
+</tt></font><ul>
+Returns a true value if the Joystick is initialized.
+</ul><br>&nbsp;<br>
+
+<a name=get_name><font size=+2><b>get_name
+</b></font><br><font size=+1><tt>
+Joystick.get_name(id) -> string
+</tt></font><ul>
+Returns the name of the Joystick device, given by the
+system. This function can be called before the Joystick
+is initialized.
+</ul><br>&nbsp;<br>
+
+<a name=get_numaxes><font size=+2><b>get_numaxes
+</b></font><br><font size=+1><tt>
+Joystick.get_numaxes() -> int
+</tt></font><ul>
+Returns the number of available axes on the Joystick.
+</ul><br>&nbsp;<br>
+
+<a name=get_numballs><font size=+2><b>get_numballs
+</b></font><br><font size=+1><tt>
+Joystick.get_numballs() -> int
+</tt></font><ul>
+Returns the number of available trackballs on the Joystick.
+</ul><br>&nbsp;<br>
+
+<a name=get_numballs><font size=+2><b>get_numballs
+</b></font><br><font size=+1><tt>
+Joystick.get_numballs() -> int
+</tt></font><ul>
+Returns the number of available directional hats on the Joystick.
+</ul><br>&nbsp;<br>
+
+<a name=get_numbuttons><font size=+2><b>get_numbuttons
+</b></font><br><font size=+1><tt>
+Joystick.get_numbuttons() -> int
+</tt></font><ul>
+Returns the number of available buttons on the Joystick.
+</ul><br>&nbsp;<br>
+
+<a name=init><font size=+2><b>init
+</b></font><br><font size=+1><tt>
+Joystick.init() -> None
+</tt></font><ul>
+In order to call most members in the Joystick object, the
+Joystick must be initialized. You can initialzie the Joystick object
+at anytime, and it is ok to initialize more than once.
+</ul><br>&nbsp;<br>
+
+<a name=quit><font size=+2><b>quit
+</b></font><br><font size=+1><tt>
+Joystick.quit() -> None
+</tt></font><ul>
+After you are completely finished with a joystick device, you
+can use this <a href=pygame.html#quit>quit()</a> function to free access to the drive.
+This will be cleaned up automatically when the joystick module is.
+uninitialized. It is safe to call this function on an uninitialized Joystick.
 </ul><br>&nbsp;<br>
 
 

docs/ref/pygame_cdrom.html

 This function needs a cdrom device number to work on. All
 cdrom drives on the system are enumerated for use as a CD
 object. To access most of the CD functions, you'll need to
-Init() the CD object. (note that the cdrom module will already
+Init() the CD. (note that the cdrom module will already
 be initialized). When multiple CD objects are created for the
 same CDROM device, the state and values for those CD objects
 will be shared.
 <br>&nbsp;<br>
-You can call the CD.get_name() function withouth initializing
-the CD object. This function returns the system name given to
-that CDROM drive.
+You can call the CD.get_name() and CD.get_id() functions
+without initializing the CD object.
+<br>&nbsp;<br>
+Be sure to understand the difference between the cdrom module
+and the CD objects.
 
 <hr>
 

docs/ref/pygame_joystick.html

 </td></tr></table>
 <br>
 <h2 align=center>pygame.joystick</h2>
-Thin wrapper around the SDL joystick interface.
-Likely to be changed.
+The joystick module provides a few functions to initialize
+the joystick subsystem and to manage the Joystick objects. These
+objects are created with the pygame.joystick.Joystick() function.
+This function needs a joystick device number to work on. All
+joystick devices on the system are enumerated for use as a Joystick
+object. To access most of the Joystick functions, you'll need to
+Init() the Joystick. (note that the joystick module will already
+be initialized). When multiple Joysticks objects are created for the
+same joystick device, the state and values for those Joystick objects
+will be shared.
+<br>&nbsp;<br>
+You can call the Joystick.get_name() and Joystick.get_id() functions
+without initializing the Joystick object.
+<br>&nbsp;<br>
+Joystick control values are only updated during the calls to the event
+queue. Call pygame.event.pump() if you are not using the event queue for
+any input handling. Once a joystick object has been initialized, it will
+start to send joystick events to the input queue.
+<br>&nbsp;<br>
+Be sure to understand the difference between the joystick module
+and the Joystick objects.
 
 <hr>
 
 <table>
+<tr><td><a href=#Joystick>Joystick</a></td><td> -
+create new joystick object</td></tr>
+
+
 <tr><td><a href=#get_count>get_count</a></td><td> -
-number of joysticks in system</td></tr>
+query number of joysticks on system</td></tr>
 
 
 <tr><td><a href=#get_init>get_init</a></td><td> -
 query initialization of joystick module</td></tr>
 
 
-<tr><td><a href=#get_name>get_name</a></td><td> -
-system name for joystick</td></tr>
-
-
 <tr><td><a href=#init>init</a></td><td> -
-initialize cdrom module</td></tr>
-
-
-<tr><td><a href=#is_opened>is_opened</a></td><td> -
-query opened joystick</td></tr>
-
-
-<tr><td><a href=#open>open</a></td><td> -
-return new joystick object</td></tr>
+initialize joystick module</td></tr>
 
 
 <tr><td><a href=#quit>quit</a></td><td> -
-uninitialize cdrom module</td></tr>
+uninitialize joystick module</td></tr>
 
 
 </table>
 
 <hr>
 
+<a name=Joystick><font size=+2><b>Joystick
+</b></font><br><font size=+1><tt>
+pygame.joystick.Joystick(id) -> Joystick
+</tt></font><ul>
+Creates a new joystick object for the given device id. The given id
+must be less than the value from <a href=#get_count>pygame.joystick.get_count()</a>.
+</ul><br>&nbsp;<br>
+
 <a name=get_count><font size=+2><b>get_count
 </b></font><br><font size=+1><tt>
 pygame.joystick.get_count() -> int
 </tt></font><ul>
-Returns the number of joysticks available on the
-system. Will be 0 if there are no joysticks.
+Returns the number of joysticks devices available on
+the system.
 </ul><br>&nbsp;<br>
 
 <a name=get_init><font size=+2><b>get_init
 </b></font><br><font size=+1><tt>
 pygame.joystick.get_init() -> bool
 </tt></font><ul>
-Returns true when the joystick module is
-initialized.
-</ul><br>&nbsp;<br>
-
-<a name=get_name><font size=+2><b>get_name
-</b></font><br><font size=+1><tt>
-pygame.joystick.get_name(id) -> string
-</tt></font><ul>
-Returns a readable name for the joystick device,
-given by the system.
+Returns true when the joystick module is initialized.
 </ul><br>&nbsp;<br>
 
 <a name=init><font size=+2><b>init
 Initialize the joystick module manually
 </ul><br>&nbsp;<br>
 
-<a name=is_opened><font size=+2><b>is_opened
-</b></font><br><font size=+1><tt>
-pygame.joystick.is_opened(id) -> bool
-</tt></font><ul>
-Returns true if the given joystick id has been
-previously opened.
-</ul><br>&nbsp;<br>
-
-<a name=open><font size=+2><b>open
-</b></font><br><font size=+1><tt>
-pygame.joystick.open(id) -> Joystick
-</tt></font><ul>
-Creates a new joystick object for the given
-joystick id. Once a joystick has been opened, it
-will start receiving joystick events on the event
-queue.
-</ul><br>&nbsp;<br>
-
 <a name=quit><font size=+2><b>quit
 </b></font><br><font size=+1><tt>
 pygame.joystick.quit() -> None
 import pygame.key
 import pygame.mouse
 import pygame.time
+import pygame.joystick
 #define PYGAMEAPI_CDROM_INTERNAL
 #include "pygame.h"
 
+
 #define CDROM_MAXDRIVES 32
 static SDL_CD* cdrom_drivedata[CDROM_MAXDRIVES] = {NULL};
 
 
-
 staticforward PyTypeObject PyCD_Type;
 static PyObject* PyCD_New(int id);
 #define PyCD_Check(x) ((x)->ob_type == &PyCD_Type)
 static void cdrom_autoquit()
 {
 	int loop;
-
 	for(loop = 0; loop < CDROM_MAXDRIVES; ++loop)
 	{
 		if(cdrom_drivedata[loop])
 }
 
 
-    /*DOC*/ static char doc_cd_get_tracks[] =
-    /*DOC*/    "CD.get_tracks() -> numtracks\n"
+    /*DOC*/ static char doc_cd_get_numtracks[] =
+    /*DOC*/    "CD.get_numtracks() -> numtracks\n"
     /*DOC*/    "get number of tracks on cd\n"
     /*DOC*/    "\n"
     /*DOC*/    "Returns the number of available tracks on the CD. Note that not\n"
     /*DOC*/    "the track type before playing.\n"
     /*DOC*/ ;
 
-static PyObject* cd_get_tracks(PyObject* self, PyObject* args)
+static PyObject* cd_get_numtracks(PyObject* self, PyObject* args)
 {
 	int cd_id = PyCD_AsID(self);
 	SDL_CD* cdrom = cdrom_drivedata[cd_id];
 	if(!cdrom)
 		return RAISE(PyExc_SDLError, "CD drive not initialized");
 
+	SDL_CDStatus(cdrom);
 	return PyInt_FromLong(cdrom->numtracks);
 }
 
 
+    /*DOC*/ static char doc_cd_get_id[] =
+    /*DOC*/    "CD.get_id() -> idnum\n"
+    /*DOC*/    "get device id number for drive\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Returns the device id number for this cdrom drive. This is the\n"
+    /*DOC*/    "same number used in the call to pygame.cdrom.CD() to create this\n"
+    /*DOC*/    "cd device. The CD object does not need to be initialized for this\n"
+    /*DOC*/    "function to work.\n"
+    /*DOC*/ ;
+
+static PyObject* cd_get_id(PyObject* self, PyObject* args)
+{
+	int cd_id = PyCD_AsID(self);
+
+	if(!PyArg_ParseTuple(args, ""))
+		return NULL;
+	return PyInt_FromLong(cd_id);
+}
+
+
     /*DOC*/ static char doc_cd_get_name[] =
     /*DOC*/    "CD.get_name(id) -> string\n"
     /*DOC*/    "query name of cdrom drive\n"
 	{ "get_busy", cd_get_busy, 1, doc_cd_get_busy },
 	{ "get_paused", cd_get_paused, 1, doc_cd_get_paused },
 	{ "get_current", cd_get_current, 1, doc_cd_get_current },
-	{ "get_tracks", cd_get_tracks, 1, doc_cd_get_tracks },
+	{ "get_numtracks", cd_get_numtracks, 1, doc_cd_get_numtracks },
+	{ "get_id", cd_get_id, 1, doc_cd_get_id },
 	{ "get_name", cd_get_name, 1, doc_cd_get_name },
 
 	{ "get_track_audio", cd_get_track_audio, 1, doc_cd_get_track_audio },
     /*DOC*/    "access the CD inside that drive. All functions (except get_name())\n"
     /*DOC*/    "require the CD object to be initialized. This is done with the\n"
     /*DOC*/    "CD.init() function.\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Be sure to understand there is a difference between the cdrom module\n"
+    /*DOC*/    "and the CD objects.\n"
     /*DOC*/ ;
 
 
     /*DOC*/    "This function needs a cdrom device number to work on. All\n"
     /*DOC*/    "cdrom drives on the system are enumerated for use as a CD\n"
     /*DOC*/    "object. To access most of the CD functions, you'll need to\n"
-    /*DOC*/    "Init() the CD object. (note that the cdrom module will already\n"
+    /*DOC*/    "Init() the CD. (note that the cdrom module will already\n"
     /*DOC*/    "be initialized). When multiple CD objects are created for the\n"
     /*DOC*/    "same CDROM device, the state and values for those CD objects\n"
     /*DOC*/    "will be shared.\n"
     /*DOC*/    "\n"
-    /*DOC*/    "You can call the CD.get_name() function withouth initializing\n"
-    /*DOC*/    "the CD object. This function returns the system name given to\n"
-    /*DOC*/    "that CDROM drive.\n"
+    /*DOC*/    "You can call the CD.get_name() and CD.get_id() functions\n"
+    /*DOC*/    "without initializing the CD object.\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Be sure to understand the difference between the cdrom module\n"
+    /*DOC*/    "and the CD objects.\n"
     /*DOC*/ ;
 
 
 static PyObject* dict_from_event(SDL_Event* event)
 {
 	PyObject* dict, *tuple, *obj;
+	int hx, hy;
 
 	if(!(dict = PyDict_New()))
 		return NULL;
 	case SDL_JOYHATMOTION:
 		PyDict_SetItemString(dict, "joy", PyInt_FromLong(event->jhat.which));
 		PyDict_SetItemString(dict, "hat", PyInt_FromLong(event->jhat.hat));
-		PyDict_SetItemString(dict, "value", PyInt_FromLong(event->jhat.value));
+		hx = hy = 0;
+		if(event->jhat.value&SDL_HAT_UP) hy = 1;
+		else if(event->jhat.value&SDL_HAT_DOWN) hy = -1;
+		if(event->jhat.value&SDL_HAT_LEFT) hx = 1;
+		else if(event->jhat.value&SDL_HAT_LEFT) hx = -1;
+		PyDict_SetItemString(dict, "value", Py_BuildValue("(ii)", hx, hy));
 		break;
 	case SDL_JOYBUTTONUP:
 	case SDL_JOYBUTTONDOWN:
 #include "pygame.h"
 
 
+#define JOYSTICK_MAXSTICKS 32
+static SDL_Joystick* joystick_stickdata[JOYSTICK_MAXSTICKS] = {NULL};
 
 
 staticforward PyTypeObject Joystick_Type;
-static PyObject* PyJoystick_New(SDL_Joystick*);
-#define PyJoystick_Check(x) ((x)->ob_type == &PyCD_Type)
+static PyObject* PyJoystick_New(int);
+#define PyJoystick_Check(x) ((x)->ob_type == &PyJoystick_Type)
 
 
 
 static void joy_autoquit()
 {
+	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_DISABLE);
+		SDL_JoystickEventState(SDL_ENABLE);
 		SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
 	}
 }
 		if(SDL_InitSubSystem(SDL_INIT_JOYSTICK))
 			return PyInt_FromLong(0);
 		SDL_JoystickEventState(SDL_ENABLE);
-		PyGame_RegisterQuit(cdrom_autoquit);
+		PyGame_RegisterQuit(joy_autoquit);
 	}
 	return PyInt_FromLong(1);
 }
 
 
-    /*DOC*/ static char doc_joy_quit[] =
+    /*DOC*/ static char doc_quit[] =
     /*DOC*/    "pygame.joystick.quit() -> None\n"
-    /*DOC*/    "uninitialize cdrom module\n"
+    /*DOC*/    "uninitialize joystick module\n"
     /*DOC*/    "\n"
     /*DOC*/    "Uninitialize the joystick module manually\n"
     /*DOC*/ ;
 
-static PyObject* joy_quit(PyObject* self, PyObject* arg)
+static PyObject* quit(PyObject* self, PyObject* arg)
 {
 	if(!PyArg_ParseTuple(arg, ""))
 		return NULL;
 	RETURN_NONE
 }
 
-    /*DOC*/ static char doc_joy_init[] =
+    /*DOC*/ static char doc_init[] =
     /*DOC*/    "pygame.joystick.init() -> None\n"
-    /*DOC*/    "initialize cdrom module\n"
+    /*DOC*/    "initialize joystick module\n"
     /*DOC*/    "\n"
     /*DOC*/    "Initialize the joystick module manually\n"
     /*DOC*/ ;
 
-static PyObject* joy_init(PyObject* self, PyObject* arg)
+static PyObject* init(PyObject* self, PyObject* arg)
 {
 	PyObject* result;
 	int istrue;
     /*DOC*/    "pygame.joystick.get_init() -> bool\n"
     /*DOC*/    "query initialization of joystick module\n"
     /*DOC*/    "\n"
-    /*DOC*/    "Returns true when the joystick module is\n"
-    /*DOC*/    "initialized.\n"
+    /*DOC*/    "Returns true when the joystick module is initialized.\n"
     /*DOC*/ ;
 
 static PyObject* get_init(PyObject* self, PyObject* arg)
 
 static void joy_dealloc(PyObject* self)
 {
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
-
-	if(SDL_WasInit(SDL_INIT_JOYSTICK)
-		SDL_JoystickClose(joy_ref->joy);
-
 	PyMem_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() -> id\n"
-    /*DOC*/    "query id of joystick\n"
+    /*DOC*/    "Joystick.get_id() -> idnum\n"
+    /*DOC*/    "get device id number for joystick\n"
     /*DOC*/    "\n"
-    /*DOC*/    "Returns the joystick id number for the Joystick\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)
 {
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
+	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(id) -> 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*/    "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;
 
-	return PyInt_FromLong(SDL_JoystickIndex(joy_ref->joy));
+	JOYSTICK_INIT_CHECK();
+	if(!joy)
+		return RAISE(PyExc_SDLError, "Joystick not initialized");
+
+	return PyInt_FromLong(SDL_JoystickNumAxes(joy));
 }
 
 
 
-    /*DOC*/ static char doc_joy_get_axes[] =
-    /*DOC*/    "Joystick.get_axes() -> count\n"
-    /*DOC*/    "query number of axis\n"
+    /*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 number of axis on this Joystick\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_axes(PyObject* self, PyObject* args)
+static PyObject* joy_get_axis(PyObject* self, PyObject* args)
 {
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
+	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;
 
-	return PyInt_FromLong(SDL_JoystickNumAxes(joy_ref->joy));
+	JOYSTICK_INIT_CHECK();
+	if(!joy)
+		return RAISE(PyExc_SDLError, "Joystick not initialized");
+
+	return PyInt_FromLong(SDL_JoystickNumButtons(joy));
 }
 
 
 
-    /*DOC*/ static char doc_joy_get_balls[] =
-    /*DOC*/    "Joystick.get_balls() -> count\n"
-    /*DOC*/    "query number of balls\n"
+    /*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 number of trackballs on this Joystick\n"
+    /*DOC*/    "Returns the current state of a joystick button.\n"
     /*DOC*/ ;
 
-static PyObject* joy_get_balls(PyObject* self, PyObject* args)
+static PyObject* joy_get_button(PyObject* self, PyObject* args)
 {
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
+	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;
 
-	return PyInt_FromLong(SDL_JoystickNumBalls(joy_ref->joy));
+	JOYSTICK_INIT_CHECK();
+	if(!joy)
+		return RAISE(PyExc_SDLError, "Joystick not initialized");
+
+	return PyInt_FromLong(SDL_JoystickNumBalls(joy));
 }
 
 
 
-    /*DOC*/ static char doc_joy_get_hats[] =
-    /*DOC*/    "Joystick.get_hats() -> count\n"
-    /*DOC*/    "query number of hats\n"
+    /*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 number of directional hats on this\n"
-    /*DOC*/    "Joystick\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_hats(PyObject* self, PyObject* args)
+static PyObject* joy_get_ball(PyObject* self, PyObject* args)
 {
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
+	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_numballs() -> 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;
 
-	return PyInt_FromLong(SDL_JoystickNumHats(joy_ref->joy));
+	JOYSTICK_INIT_CHECK();
+	if(!joy)
+		return RAISE(PyExc_SDLError, "Joystick not initialized");
+
+	return PyInt_FromLong(SDL_JoystickNumHats(joy));
 }
 
 
 
-    /*DOC*/ static char doc_joy_get_buttons[] =
-    /*DOC*/    "Joystick.get_buttons() -> count\n"
-    /*DOC*/    "query number of buttons\n"
+    /*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 number of pushable buttons on this\n"
-    /*DOC*/    "Joystick\n"
-    /*DOC*/ ;
-
-static PyObject* joy_get_buttons(PyObject* self, PyObject* args)
-{
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
-
-	if(!PyArg_ParseTuple(args, ""))
-		return NULL;
-
-	return PyInt_FromLong(SDL_JoystickNumButtons(joy_ref->joy));
-}
-
-
-
-    /*DOC*/ static char doc_joy_get_axis[] =
-    /*DOC*/    "Joystick.get_axis(axis) -> position\n"
-    /*DOC*/    "query axis of a joystick\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Returns the current position of an axis control on\n"
-    /*DOC*/    "the Joystick. Value is in the range -1.0 to 1.0.\n"
-    /*DOC*/ ;
-
-static PyObject* joy_get_axis(PyObject* self, PyObject* args)
-{
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
-	int axis;
-
-	if(!PyArg_ParseTuple(args, "i", &axis))
-		return NULL;
-
-	return PyFloat_FromDouble(SDL_JoystickGetAxis(joy_ref->joy, axis)/32767.0);
-}
-
-
-
-    /*DOC*/ static char doc_joy_get_hat[] =
-    /*DOC*/    "Joystick.get_hat(pov_hat) -> state\n"
-    /*DOC*/    "query position of hat\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Returns the current position of a directional hat\n"
-    /*DOC*/    "on the Joystick. Value in a position on the\n"
-    /*DOC*/    "following compass. (think 1 is up, and goes around\n"
-    /*DOC*/    "clockwise)\n"
-    /*DOC*/    "8 1 2\n"
-    /*DOC*/    "7 0 3\n"
-    /*DOC*/    "6 5 4\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)
 {
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
-	int hat;
+	int joy_id = PyJoystick_AsID(self);
+	SDL_Joystick* joy = joystick_stickdata[joy_id];
+	int index, px, py;
+	Uint8 value;
 
-	if(!PyArg_ParseTuple(args, "i", &hat))
+	if(!PyArg_ParseTuple(args, "i", &index))
 		return NULL;
 
-	return PyInt_FromLong(SDL_JoystickGetHat(joy_ref->joy, hat));
+	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);
 }
 
 
 
-    /*DOC*/ static char doc_joy_get_button[] =
-    /*DOC*/    "Joystick.get_button(button) -> bool\n"
-    /*DOC*/    "query state of button\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Returns true if the given Joystick button is being\n"
-    /*DOC*/    "pressed.\n"
-    /*DOC*/ ;
+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 },
 
-static PyObject* joy_get_button(PyObject* self, PyObject* args)
-{
-	PyJoystickObject* joy_ref = (PyJoystickObject*)self;
-	int button;
+	{ "get_id", joy_get_id, 1, doc_joy_get_id },
+	{ "get_name", joy_get_name, 1, doc_joy_get_name },
 
-	if(!PyArg_ParseTuple(args, "i", &button))
-		return NULL;
+	{ "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 },
 
-	return PyInt_FromLong(SDL_JoystickGetButton(joy_ref->joy, button));
-}
-
-
-
-/*joystick module funcs*/
-
-static PyObject* PyJoystick_New(SDL_Joystick* joy)
-{
-	PyJoystickObject* joyobj;
-
-	if(!joy)
-		return RAISE(PyExc_SDLError, SDL_GetError());
-
-	joyobj = PyObject_NEW(PyJoystickObject, &Joystick_Type);
-	if(!joyobj)
-		return NULL;
-
-	joyobj->joy = joy;
-
-	return (PyObject*)joyobj;
-}
-
-
-
-    /*DOC*/ static char doc_joy_open[] =
-    /*DOC*/    "pygame.joystick.open(id) -> Joystick\n"
-    /*DOC*/    "return new joystick object\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Creates a new joystick object for the given\n"
-    /*DOC*/    "joystick id. Once a joystick has been opened, it\n"
-    /*DOC*/    "will start receiving joystick events on the event\n"
-    /*DOC*/    "queue.\n"
-    /*DOC*/ ;
-
-static PyObject* joy_open(PyObject* self, PyObject* args)
-{
-	int id;
-
-	if(!PyArg_ParseTuple(args, "i", &id))
-		return NULL;
-
-	JOY_INIT_CHECK
-
-	return PyJoystick_New(SDL_JoystickOpen(id));
-}
-
-
-
-    /*DOC*/ static char doc_joy_get_count[] =
-    /*DOC*/    "pygame.joystick.get_count() -> int\n"
-    /*DOC*/    "number of joysticks in system\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Returns the number of joysticks available on the\n"
-    /*DOC*/    "system. Will be 0 if there are no joysticks.\n"
-    /*DOC*/ ;
-
-static PyObject* joy_get_count(PyObject* self, PyObject* args)
-{
-	if(!PyArg_ParseTuple(args, ""))
-		return NULL;
-
-	JOY_INIT_CHECK
-
-	return PyInt_FromLong(SDL_NumJoysticks());
-}
-
-
-
-    /*DOC*/ static char doc_joy_get_name[] =
-    /*DOC*/    "pygame.joystick.get_name(id) -> string\n"
-    /*DOC*/    "system name for joystick\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Returns a readable name for the joystick device,\n"
-    /*DOC*/    "given by the system.\n"
-    /*DOC*/ ;
-
-static PyObject* joy_get_name(PyObject* self, PyObject* args)
-{
-	int id;
-
-	if(!PyArg_ParseTuple(args, "i", &id))
-		return NULL;
-
-	JOY_INIT_CHECK
-
-	return PyString_FromString(SDL_JoystickName(id));
-}
-
-
-
-    /*DOC*/ static char doc_joy_is_opened[] =
-    /*DOC*/    "pygame.joystick.is_opened(id) -> bool\n"
-    /*DOC*/    "query opened joystick\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "Returns true if the given joystick id has been\n"
-    /*DOC*/    "previously opened.\n"
-    /*DOC*/ ;
-
-static PyObject* joy_is_opened(PyObject* self, PyObject* args)
-{
-	int id;
-	
-	if(!PyArg_ParseTuple(args, "i", &id))
-		return NULL;
-
-	JOY_INIT_CHECK
-
-	return PyInt_FromLong(SDL_JoystickOpened(id));
-}
-
-
-
-
-static PyMethodDef joy__builtins__[] =
-{
-	{ "get_id", joy_get_id, 1, joy_get_id },
-	{ "get_axes", joy_get_axes, 1, joy_get_axes },
-	{ "get_balls", joy_get_balls, 1, joy_get_balls },
-	{ "get_hats", joy_get_hats, 1, joy_get_hats },
-	{ "get_buttons", joy_get_buttons, 1, joy_get_buttons },
-	{ "get_axis", joy_get_axis, 1, joy_get_axis },
-	{ "get_hat", joy_get_hat, 1, joy_get_hat },
-	{ "get_button", joy_get_button, 1, joy_get_button },
 	{ NULL, NULL }
 };
 
 static PyObject* joy_getattr(PyObject* self, char* attrname)
 {
-	return Py_FindMethod(joy__builtins__, self, attrname);
-
-	PyErr_SetString(PyExc_NameError,	attrname);
-	return NULL;
+	return Py_FindMethod(joy_builtins, self, attrname);
 }
 
 
     /*DOC*/ static char doc_Joystick_MODULE[] =
-    /*DOC*/    "Thin object wrapper around the SDL joystick\n"
-    /*DOC*/    "interface. Likely to be changed.\n"
+    /*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 Joystick_Type =
+
+static PyTypeObject PyJoystick_Type =
 {
 	PyObject_HEAD_INIT(NULL)
 	0,
 	0,
 	joy_dealloc,
 	0,
-	joy_getattr
+	joy_getattr,
+	0,
+	0,
+	0,
+	0,
+	NULL,
+	0
 };
 
 
+
+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, joy_init_doc },
-	{ "init", joy_init, 1, joy_init_doc },
-	{ "quit", joy_quit, 1, joy_quit_doc },
-	{ "get_count", joy_get_count, 1, joy_get_count },
-	{ "get_name", joy_get_name, 1, joy_get_name },
-	{ "open", joy_open, 1, joy_open },
-	{ "is_opened", joy_is_opened, 1, joy_is_opened },
-	{ "update", joy_update, 1, joy_update },
-	{ "event_state", joy_event_state, 1, joy_event_state },
+	{ "__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*/    "Thin wrapper around the SDL joystick interface.\n"
-    /*DOC*/    "Likely to be changed.\n"
+    /*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 the difference between the joystick module\n"
+    /*DOC*/    "and the Joystick objects.\n"
     /*DOC*/ ;
 
-void initcdrom()
+void initjoystick()
 {
 	PyObject *module, *dict, *apiobj;
-	static void* c_api[PYGAMEAPI_CDROM_NUMSLOTS];
+	static void* c_api[PYGAMEAPI_JOYSTICK_NUMSLOTS];
 
-	PyType_Init(PyCD_Type);
+	PyType_Init(PyJoystick_Type);
 
 
     /* create the module */
 */
 
 	/** This header file includes all the definitions for the
-	 ** base pyGame extensions. This header only requires
+	 ** base pygame extensions. This header only requires
 	 ** SDL and Python includes. The reason for functions
 	 ** prototyped with #define's is to allow for maximum
 	 ** python portability. It also uses python as the
 	 ** own import_xxx() routine. You need to perform this import
 	 ** after you have initialized your own module, and before
 	 ** you call any routines from that module. Since every module
-	 ** in pyGame does this, there are plenty of examples.
+	 ** in pygame does this, there are plenty of examples.
 	 **
 	 ** The base module does include some useful conversion routines
 	 ** that you are free to use in your own extension.
 	 ** FIRSTSLOT and NUMSLOT constants up to date for each
 	 ** section. Also be sure not to overlap any of the slots.
 	 ** When you do make a mistake with this, it will result
-	 ** in a dereferenced NULL pointer that is easier to diagnose
+	 ** is a dereferenced NULL pointer that is easier to diagnose
 	 ** than it could be :]
 	 **/
 #include <Python.h>
 #define CDROM_INIT_CHECK() \
 	if(!SDL_WasInit(SDL_INIT_CDROM)) \
 		return RAISE(PyExc_SDLError, "cdrom system not initialized")
+#define JOYSTICK_INIT_CHECK() \
+	if(!SDL_WasInit(SDL_INIT_JOYSTICK)) \
+		return RAISE(PyExc_SDLError, "joystick system not initialized")
 
 
 
 
 
 
+
 /* CDROM */
 #define PYGAMEAPI_CDROM_FIRSTSLOT 30
 #define PYGAMEAPI_CDROM_NUMSLOTS 2
 #endif
 
 
+/* JOYSTICK */
+#define PYGAMEAPI_JOYSTICK_FIRSTSLOT 32
+#define PYGAMEAPI_JOYSTICK_NUMSLOTS 2
+typedef struct {
+	PyObject_HEAD
+	int id;
+} PyJoystickObject;
+#define PyJoystick_AsID(x) (((PyJoystickObject*)x)->id)
+#ifndef PYGAMEAPI_JOYSTICK_INTERNAL
+#define PyJoystick_Check(x) ((x)->ob_type == (PyTypeObject*)PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 0])
+#define PyJoystick_Type (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 0])
+#define PyJoystick_New (*(PyObject*(*)(int))PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 1])
+#define import_pygame_joystick() { \
+	PyObject *module = PyImport_ImportModule("pygame.joystick"); \
+	if (module != NULL) { \
+		PyObject *dict = PyModule_GetDict(module); \
+		PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY); \
+		if(PyCObject_Check(c_api)) {\
+			int i; void** localptr = (void*)PyCObject_AsVoidPtr(c_api); \
+			for(i = 0; i < PYGAMEAPI_JOYSTICK_NUMSLOTS; ++i) \
+				PyGAME_C_API[i + PYGAMEAPI_JOYSTICK_FIRSTSLOT] = localptr[i]; \
+} } }
+#endif
+
+
 
 /* DISPLAY */
 #define PYGAMEAPI_DISPLAY_FIRSTSLOT 35
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.