dinput linux joystick update

Robert Reif reif at earthlink.net
Tue Aug 31 10:58:44 CDT 2004


Adds default data formats for c_dfDIJoystick and c_dfDIJoystick2.
Adds object properties for more than one object.
Adds error checks for acquired.
Default to using c_dfDIJoystick2 data format.
Tries to use user supplied data formats (only works if same as one of 
the defaults).
Code cleanup, error checking and tracing added.
Added support for up to 8 axis.

DXSDK joystick sample program now works the same as on windows.
Joystick in Need For Speed III works now.

To Do:
Handle non standard data formats.
Deadzone and saturation not implemented.
-------------- next part --------------
diff -u -N wine.cvs/dlls/dinput/data_formats.c wine/dlls/dinput/data_formats.c
--- wine.cvs/dlls/dinput/data_formats.c	1969-12-31 19:00:00.000000000 -0500
+++ wine/dlls/dinput/data_formats.c	2004-08-30 16:49:39.000000000 -0400
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2004 Robert Reif
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* TODO:
+ * add keyboard and mouse
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "dinput.h"
+
+#define numObjects(x) (sizeof(x) / sizeof(x[0])) 
+
+DIOBJECTDATAFORMAT dfDIJoystick[] = { 
+  { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+};
+
+const DIDATAFORMAT c_dfDIJoystick = { 
+    sizeof(DIDATAFORMAT),
+    sizeof(DIOBJECTDATAFORMAT),
+    DIDF_ABSAXIS,
+    sizeof(DIJOYSTATE2),
+    numObjects(dfDIJoystick),
+    dfDIJoystick
+}; 
+
+DIOBJECTDATAFORMAT dfDIJoystick2[] = { 
+  { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+  { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, 
+}; 
+
+const DIDATAFORMAT c_dfDIJoystick2 = { 
+    sizeof(DIDATAFORMAT),
+    sizeof(DIOBJECTDATAFORMAT),
+    DIDF_ABSAXIS,
+    sizeof(DIJOYSTATE2),
+    numObjects(dfDIJoystick2),
+    dfDIJoystick2
+}; 
diff -u -N wine.cvs/dlls/dinput/device.c wine/dlls/dinput/device.c
--- wine.cvs/dlls/dinput/device.c	2004-07-28 07:27:01.000000000 -0400
+++ wine/dlls/dinput/device.c	2004-08-31 09:02:15.000000000 -0400
@@ -108,7 +108,7 @@
     }
 }
 
-void _dump_DIPROPHEADER(DIPROPHEADER *diph) {
+void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) {
     if (TRACE_ON(dinput)) {
 	DPRINTF("  - dwObj = 0x%08lx\n", diph->dwObj);
 	DPRINTF("  - dwHow = %s\n",
diff -u -N wine.cvs/dlls/dinput/device_private.h wine/dlls/dinput/device_private.h
--- wine.cvs/dlls/dinput/device_private.h	2004-08-15 15:23:06.000000000 -0400
+++ wine/dlls/dinput/device_private.h	2004-08-31 09:02:48.000000000 -0400
@@ -88,7 +88,7 @@
 /* Various debug tools */
 extern void _dump_cooperativelevel_DI(DWORD dwFlags) ;
 extern void _dump_EnumObjects_flags(DWORD dwFlags) ;
-extern void _dump_DIPROPHEADER(DIPROPHEADER *diph) ;
+extern void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) ;
 extern void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) ;
 extern void _dump_OBJECTINSTANCEW(DIDEVICEOBJECTINSTANCEW *ddoi) ;
 extern void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) ;
diff -u -N wine.cvs/dlls/dinput/joystick_linux.c wine/dlls/dinput/joystick_linux.c
--- wine.cvs/dlls/dinput/joystick_linux.c	2004-08-31 11:35:31.000000000 -0400
+++ wine/dlls/dinput/joystick_linux.c	2004-08-31 11:32:00.000000000 -0400
@@ -66,6 +66,13 @@
 #define WINE_JOYSTICK_AXIS_BASE   0
 #define WINE_JOYSTICK_BUTTON_BASE 8
 
+typedef struct {
+    LONG lMin;
+    LONG lMax;
+    LONG lDeadZone;
+    LONG lSaturation;
+} ObjProps;
+
 typedef struct JoystickImpl JoystickImpl;
 static IDirectInputDevice8AVtbl JoystickAvt;
 static IDirectInputDevice8WVtbl JoystickWvt;
@@ -81,11 +88,12 @@
 	/* joystick private */
 	int				joyfd;
 	LPDIDATAFORMAT			df;
+	ObjProps			*props;
         HANDLE				hEvent;
-	LONG				lMin,lMax,deadzone;
         LPDIDEVICEOBJECTDATA 		data_queue;
         int				queue_head, queue_tail, queue_len;
 	DIJOYSTATE2			js;
+	BOOL				acquired;
 };
 
 static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
@@ -163,18 +171,58 @@
 
 static JoystickImpl *alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput)
 {
-  JoystickImpl* newDevice;
+    DWORD i;
+    JoystickImpl* newDevice;
+
+    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
+    if (newDevice == 0)
+        return 0;
+
+    newDevice->lpVtbl = jvt;
+    newDevice->ref = 1;
+    newDevice->joyfd = -1;
+    newDevice->dinput = dinput;
+    newDevice->acquired = FALSE;
+    CopyMemory(&(newDevice->guid),rguid,sizeof(*rguid));
+
+    /* copy default data format */
+    newDevice->df = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwSize);
+    if (newDevice->df == 0) {
+        HeapFree(GetProcessHeap(), 0, newDevice);
+        return 0;
+    }
+    CopyMemory(newDevice->df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
+
+    /* copy default objects */
+    newDevice->df->rgodf = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*c_dfDIJoystick2.dwObjSize);
+    if (newDevice->df->rgodf == 0) {
+        HeapFree(GetProcessHeap(), 0, newDevice->df);
+        HeapFree(GetProcessHeap(), 0, newDevice);
+        return 0;
+    }
+    CopyMemory(newDevice->df->rgodf,c_dfDIJoystick2.rgodf,c_dfDIJoystick2.dwNumObjs*c_dfDIJoystick2.dwObjSize);
+
+    /* create default properties */
+    newDevice->props = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*sizeof(ObjProps));
+    if (newDevice->props == 0) {
+        HeapFree(GetProcessHeap(), 0, newDevice->df->rgodf);
+        HeapFree(GetProcessHeap(), 0, newDevice->df);
+        HeapFree(GetProcessHeap(), 0, newDevice);
+        return 0;
+    }
+
+    /* initialize default properties */
+    for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
+        newDevice->props[i].lMin = 0;
+	newDevice->props[i].lMax = 0xffff;
+        newDevice->props[i].lDeadZone = 1000;
+        newDevice->props[i].lSaturation = 0;
+    }
 
-  newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
-  newDevice->lpVtbl = jvt;
-  newDevice->ref = 1;
-  newDevice->joyfd = -1;
-  newDevice->lMin = -32768;
-  newDevice->lMax = +32767;
-  newDevice->dinput = dinput;
-  memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
+    if (TRACE_ON(dinput))
+        _dump_DIDATAFORMAT(newDevice->df);
 
-  return newDevice;
+    return newDevice;
 }
 
 static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
@@ -187,13 +235,22 @@
 	IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
 	IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
       *pdev=(IDirectInputDeviceA*) alloc_device(rguid, &JoystickAvt, dinput);
+      if (*pdev == 0) {
+        WARN("out of memory\n");
+        return DIERR_OUTOFMEMORY;
+      }
 
       TRACE("Creating a Joystick device (%p)\n", *pdev);
       return DI_OK;
-    } else
+    } else {
+      WARN("no interface\n");
+      *pdev = 0;
       return DIERR_NOINTERFACE;
+    }
   }
 
+  WARN("invalid device GUID\n");
+  *pdev = 0;
   return DIERR_DEVICENOTREG;
 }
 
@@ -207,13 +264,22 @@
 	IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
 	IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
       *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &JoystickWvt, dinput);
+      if (*pdev == 0) {
+        WARN("out of memory\n");
+        return DIERR_OUTOFMEMORY;
+      }
 
       TRACE("Creating a Joystick device (%p)\n", *pdev);
       return DI_OK;
-    } else
+    } else {
+      WARN("no interface\n");
+      *pdev = 0;
       return DIERR_NOINTERFACE;
+    }
   }
 
+  WARN("invalid device GUID\n");
+  *pdev = 0;
   return DIERR_DEVICENOTREG;
 }
 
@@ -233,21 +299,25 @@
  */
 static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
 {
-	ICOM_THIS(JoystickImpl,iface);
-
-	This->ref--;
-	if (This->ref)
-		return This->ref;
+    ICOM_THIS(JoystickImpl,iface);
 
-	/* Free the data queue */
-	if (This->data_queue != NULL)
-	  HeapFree(GetProcessHeap(),0,This->data_queue);
+    This->ref--;
+    if (This->ref)
+        return This->ref;
+
+    /* Free the data queue */
+    if (This->data_queue != NULL)
+        HeapFree(GetProcessHeap(),0,This->data_queue);
+
+    /* Free the DataFormat */
+    HeapFree(GetProcessHeap(), 0, This->df->rgodf);
+    HeapFree(GetProcessHeap(), 0, This->df);
 
-	/* Free the DataFormat */
-	HeapFree(GetProcessHeap(), 0, This->df);
+    /* Free the properties */
+    HeapFree(GetProcessHeap(), 0, This->props);
 
-	HeapFree(GetProcessHeap(),0,This);
-	return 0;
+    HeapFree(GetProcessHeap(),0,This);
+    return 0;
 }
 
 /******************************************************************************
@@ -255,22 +325,64 @@
   *   the device driver sends back with GetDeviceState.
   */
 static HRESULT WINAPI JoystickAImpl_SetDataFormat(
-	LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
-)
+    LPDIRECTINPUTDEVICE8A iface,
+    LPCDIDATAFORMAT df)
 {
-  ICOM_THIS(JoystickImpl,iface);
-
-  TRACE("(this=%p,%p)\n",This,df);
-
-  _dump_DIDATAFORMAT(df);
-
-  /* Store the new data format */
-  This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
-  memcpy(This->df, df, df->dwSize);
-  This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
-  memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
+    ICOM_THIS(JoystickImpl,iface);
+    int i;
+    LPDIDATAFORMAT new_df;
+    LPDIOBJECTDATAFORMAT new_rgodf;
+    ObjProps * new_props;
+
+    TRACE("(%p,%p)\n",This,df);
+
+    if (This->acquired == TRUE) {
+        WARN("acquired\n");
+        return DIERR_ACQUIRED;
+    }
+
+    if (TRACE_ON(dinput))
+        _dump_DIDATAFORMAT(df);
+
+    /* Store the new data format */
+    new_df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
+    if (new_df == 0) {
+        WARN("out of memory\n");
+        return DIERR_OUTOFMEMORY;
+    }
+
+    new_rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
+    if (new_rgodf == 0) {
+        WARN("out of memory\n");
+        HeapFree(GetProcessHeap(),0,new_df);
+        return DIERR_OUTOFMEMORY;
+    }
+
+    new_props = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*sizeof(ObjProps));
+    if (This->props == 0) {
+        WARN("out of memory\n");
+        HeapFree(GetProcessHeap(),0,new_rgodf);
+        HeapFree(GetProcessHeap(),0,new_df);
+        return DIERR_OUTOFMEMORY;
+    }
+
+    HeapFree(GetProcessHeap(),0,This->df);
+    HeapFree(GetProcessHeap(),0,This->df->rgodf);
+    HeapFree(GetProcessHeap(),0,This->props);
+
+    This->df = new_df;
+    CopyMemory(This->df, df, df->dwSize);
+    This->df->rgodf = new_rgodf;
+    CopyMemory(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
+    This->props = new_props;
+    for (i = 0; i < df->dwNumObjs; i++) {
+        This->props[i].lMin = 0;
+	This->props[i].lMax = 0xffff;
+        This->props[i].lDeadZone = 1000;
+        This->props[i].lSaturation = 0;
+    }
 
-  return 0;
+    return DI_OK;
 }
 
 /******************************************************************************
@@ -286,7 +398,8 @@
     This->joyfd=open(JOYDEV,O_RDONLY);
     if (This->joyfd==-1)
     	return DIERR_NOTFOUND;
-    return 0;
+    This->acquired = TRUE;
+    return DI_OK;
 }
 
 /******************************************************************************
@@ -300,21 +413,40 @@
     if (This->joyfd!=-1) {
   	close(This->joyfd);
 	This->joyfd = -1;
+        This->acquired = FALSE;
 	return DI_OK;
     }
-    else 
-    	return DI_NOEFFECT;
+
+    This->acquired = FALSE;
+    return DI_NOEFFECT;
 }
 
-#define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
+LONG map_axis(JoystickImpl * This, short val, short index)
+{
+    double	fval = val;
+    double	fmin = This->props[index].lMin;
+    double	fmax = This->props[index].lMax;
+    double	fret;
+
+    fret = (((fval + 32767.0) * (fmax - fmin)) / (32767.0*2.0)) + fmin;
+
+    if (fret >= 0.0)
+        fret += 0.5;
+    else
+        fret -= 0.5;
+
+    return fret;
+}
 
 static void joy_polldev(JoystickImpl *This) {
     struct timeval tv;
     fd_set	readfds;
     struct	js_event jse;
 
-    if (This->joyfd==-1)
+    if (This->joyfd==-1) {
+        WARN("device not open\n");
 	return;
+    }
     while (1) {
 	memset(&tv,0,sizeof(tv));
 	FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
@@ -324,7 +456,8 @@
 	if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
 	    return;
 	}
-	TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value);
+	TRACE("js_event: type 0x%x, number %d, value %d\n",
+              jse.type,jse.number,jse.value);
 	if (jse.type & JS_EVENT_BUTTON) {
 	    GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,(This->dinput->evsequence)++);
 	    This->js.rgbButtons[jse.number] = jse.value?0x80:0x00;
@@ -333,18 +466,38 @@
 	    switch (jse.number) {
 	    case 0:
 		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
-		This->js.lX = map_axis(jse.value);
+		This->js.lX = map_axis(This, jse.value, jse.number);
 		break;
 	    case 1:
 		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
-		This->js.lY = map_axis(jse.value);
+		This->js.lY = map_axis(This, jse.value, jse.number);
 		break;
 	    case 2:
 		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
-		This->js.lZ = map_axis(jse.value);
+		This->js.lZ = map_axis(This, jse.value, jse.number);
+		break;
+	    case 3:
+		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
+		This->js.lRx = map_axis(This, jse.value, jse.number);
+		break;
+	    case 4:
+		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
+		This->js.lRy = map_axis(This, jse.value, jse.number);
+		break;
+	    case 5:
+		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
+		This->js.lRz = map_axis(This, jse.value, jse.number);
+		break;
+	    case 6:
+		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
+		This->js.rglSlider[0] = map_axis(This, jse.value, jse.number);
+		break;
+	    case 7:
+		GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++);
+		This->js.rglSlider[1] = map_axis(This, jse.value, jse.number);
 		break;
 	    default:
-		FIXME("more than 3 axes (%d) not handled!\n",jse.number);
+		FIXME("more than 8 axes (%d) not handled!\n",jse.number);
 		break;
 	    }
 	}
@@ -356,12 +509,15 @@
   *
   */
 static HRESULT WINAPI JoystickAImpl_GetDeviceState(
-	LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
-) {
+    LPDIRECTINPUTDEVICE8A iface,
+    DWORD len,
+    LPVOID ptr)
+{
     ICOM_THIS(JoystickImpl,iface);
 
+    TRACE("(%p,0x%08lx,%p)\n",This,len,ptr);
+
     joy_polldev(This);
-    TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
     if ((len != sizeof(DIJOYSTATE)) && (len != sizeof(DIJOYSTATE2))) {
     	FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
 	return E_FAIL;
@@ -369,7 +525,7 @@
     memcpy(ptr,&(This->js),len);
     This->queue_head = 0;
     This->queue_tail = 0;
-    return 0;
+    return DI_OK;
 }
 
 /******************************************************************************
@@ -392,50 +548,104 @@
   if (dod == NULL) {
   } else {
   }
-  return 0;
+  return DI_OK;
+}
+
+int find_property(JoystickImpl * This, LPCDIPROPHEADER ph)
+{
+    int i;
+    if (ph->dwHow == DIPH_BYOFFSET) {
+        for (i = 0; i < This->df->dwNumObjs; i++) {
+            if (This->df->rgodf[i].dwOfs == ph->dwObj) {
+                return i;
+            }
+        }
+    } else if (ph->dwHow == DIPH_BYID) {
+        int axis = 0;
+        int button = 0;
+        for (i = 0; i < This->df->dwNumObjs; i++) {
+            DWORD type = 0;
+            if (DIDFT_GETTYPE(This->df->rgodf[i].dwType) & DIDFT_AXIS) {
+                axis++;  
+                type = DIDFT_GETTYPE(This->df->rgodf[i].dwType) | 
+                    DIDFT_MAKEINSTANCE(axis << WINE_JOYSTICK_AXIS_BASE); 
+                TRACE("type = 0x%08lx\n", type);
+            }
+            if (DIDFT_GETTYPE(This->df->rgodf[i].dwType) & DIDFT_BUTTON) {
+                button++;  
+                type = DIDFT_GETTYPE(This->df->rgodf[i].dwType) |
+                    DIDFT_MAKEINSTANCE(button << WINE_JOYSTICK_BUTTON_BASE); 
+                TRACE("type = 0x%08lx\n", type);
+            }
+            if (type == ph->dwObj) {
+                return i;
+            }
+        }
+    }
+
+    return -1;
 }
 
 /******************************************************************************
   *     SetProperty : change input device properties
   */
-static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
-					    REFGUID rguid,
-					    LPCDIPROPHEADER ph)
+static HRESULT WINAPI JoystickAImpl_SetProperty(
+    LPDIRECTINPUTDEVICE8A iface,
+    REFGUID rguid,
+    LPCDIPROPHEADER ph)
 {
-  ICOM_THIS(JoystickImpl,iface);
+    ICOM_THIS(JoystickImpl,iface);
 
-  FIXME("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
-  FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
+    TRACE("(%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
 
-  if (!HIWORD(rguid)) {
-    switch ((DWORD)rguid) {
-    case (DWORD) DIPROP_BUFFERSIZE: {
-      LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
-
-      FIXME("buffersize = %ld\n",pd->dwData);
-      break;
-    }
-    case (DWORD)DIPROP_RANGE: {
-      LPCDIPROPRANGE	pr = (LPCDIPROPRANGE)ph;
-
-      FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
-      This->lMin = pr->lMin;
-      This->lMax = pr->lMax;
-      break;
-    }
-    case (DWORD)DIPROP_DEADZONE: {
-      LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
-
-      FIXME("deadzone(%ld)\n",pd->dwData);
-      This->deadzone = pd->dwData;
-      break;
-    }
-    default:
-      FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
-      break;
+    if (TRACE_ON(dinput))
+        _dump_DIPROPHEADER(ph);
+
+    if (!HIWORD(rguid)) {
+        switch ((DWORD)rguid) {
+        case (DWORD) DIPROP_BUFFERSIZE: {
+            LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
+            FIXME("buffersize = %ld\n",pd->dwData);
+            break;
+        }
+        case (DWORD)DIPROP_RANGE: {
+            LPCDIPROPRANGE	pr = (LPCDIPROPRANGE)ph;
+            int obj = find_property(This, ph);
+            TRACE("proprange(%ld,%ld) obj=%d\n",pr->lMin,pr->lMax,obj);
+            if (obj >= 0) {
+                This->props[obj].lMin = pr->lMin;
+                This->props[obj].lMax = pr->lMax;
+                return DI_OK;
+            }       
+            break;
+        }
+        case (DWORD)DIPROP_DEADZONE: {
+            LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
+            int obj = find_property(This, ph);
+            TRACE("deadzone(%ld) obj=%d\n",pd->dwData,obj);
+            if (obj >= 0) {
+                This->props[obj].lDeadZone  = pd->dwData;
+                return DI_OK;
+            }
+            break;
+        }
+        case (DWORD)DIPROP_SATURATION: {
+            LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
+            int obj = find_property(This, ph);
+            TRACE("saturation(%ld) obj=%d\n",pd->dwData,obj);
+            if (obj >= 0) {
+                This->props[obj].lSaturation = pd->dwData;
+                return DI_OK;
+            }
+            break;
+        }
+        default:
+            FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
+            break;
+        }
     }
-  }
-  return 0;
+
+    return DI_OK;
 }
 
 /******************************************************************************
@@ -451,6 +661,29 @@
     return DI_OK;
 }
 
+static void _dump_DIDEVCAPS(LPDIDEVCAPS lpDIDevCaps)
+{
+    TRACE("dwSize: %ld\n", lpDIDevCaps->dwSize);
+    TRACE("dwFlags: %08lx\n",lpDIDevCaps->dwFlags);
+    TRACE("dwDevType: %08lx %s\n", lpDIDevCaps->dwDevType,
+          lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
+          lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
+          lpDIDevCaps->dwDevType == DIDEVTYPE_MOUSE ? "DIDEVTYPE_MOUSE" :
+          lpDIDevCaps->dwDevType == DIDEVTYPE_KEYBOARD ? "DIDEVTYPE_KEYBOARD" :
+          lpDIDevCaps->dwDevType == DIDEVTYPE_JOYSTICK ? "DIDEVTYPE_JOYSTICK" :
+          lpDIDevCaps->dwDevType == DIDEVTYPE_HID ? "DIDEVTYPE_HID" : "UNKNOWN");
+    TRACE("dwAxes: %ld\n",lpDIDevCaps->dwAxes);
+    TRACE("dwButtons: %ld\n",lpDIDevCaps->dwButtons);
+    TRACE("dwPOVs: %ld\n",lpDIDevCaps->dwPOVs);
+    if (lpDIDevCaps->dwSize > sizeof(DIDEVCAPS_DX3)) {
+        TRACE("dwFFSamplePeriod: %ld\n",lpDIDevCaps->dwFFSamplePeriod);
+        TRACE("dwFFMinTimeResolution: %ld\n",lpDIDevCaps->dwFFMinTimeResolution);
+        TRACE("dwFirmwareRevision: %ld\n",lpDIDevCaps->dwFirmwareRevision);
+        TRACE("dwHardwareRevision: %ld\n",lpDIDevCaps->dwHardwareRevision);
+        TRACE("dwFFDriverVersion: %ld\n",lpDIDevCaps->dwFFDriverVersion);
+    }
+}
+
 static HRESULT WINAPI JoystickAImpl_GetCapabilities(
 	LPDIRECTINPUTDEVICE8A iface,
 	LPDIDEVCAPS lpDIDevCaps)
@@ -460,6 +693,7 @@
     int		xfd = This->joyfd;
 
     TRACE("%p->(%p)\n",iface,lpDIDevCaps);
+
     if (xfd==-1)
     	xfd = open(JOYDEV,O_RDONLY);
     lpDIDevCaps->dwFlags	= DIDC_ATTACHED;
@@ -476,11 +710,24 @@
 #endif
     if (xfd!=This->joyfd)
     	close(xfd);
+    if (lpDIDevCaps->dwSize > sizeof(DIDEVCAPS_DX3)) {
+        lpDIDevCaps->dwFFSamplePeriod = 0;
+        lpDIDevCaps->dwFFMinTimeResolution = 0;
+        lpDIDevCaps->dwFirmwareRevision = 0;
+        lpDIDevCaps->dwHardwareRevision = 0;
+        lpDIDevCaps->dwFFDriverVersion = 0;
+    }
+
+    if (TRACE_ON(dinput))
+        _dump_DIDEVCAPS(lpDIDevCaps);
+
     return DI_OK;
 }
-static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE8A iface) {
+
+static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE8A iface)
+{
     ICOM_THIS(JoystickImpl,iface);
-    TRACE("(),stub!\n");
+    TRACE("()\n");
 
     joy_polldev(This);
     return DI_OK;
@@ -533,11 +780,31 @@
 	ddoi.guidType = GUID_ZAxis;
 	ddoi.dwOfs = DIJOFS_Z;
 	break;
+      case 3:
+	ddoi.guidType = GUID_RxAxis;
+	ddoi.dwOfs = DIJOFS_RX;
+	break;
+      case 4:
+	ddoi.guidType = GUID_RyAxis;
+	ddoi.dwOfs = DIJOFS_RY;
+	break;
+      case 5:
+	ddoi.guidType = GUID_RzAxis;
+	ddoi.dwOfs = DIJOFS_RZ;
+	break;
+      case 6:
+	ddoi.guidType = GUID_Slider;
+	ddoi.dwOfs = DIJOFS_SLIDER(0);
+	break;
+      case 7:
+	ddoi.guidType = GUID_Slider;
+	ddoi.dwOfs = DIJOFS_SLIDER(1);
+	break;
       default:
 	ddoi.guidType = GUID_Unknown;
 	ddoi.dwOfs = DIJOFS_Z + (i - 2) * sizeof(LONG);
       }
-      ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << i) << WINE_JOYSTICK_AXIS_BASE) | DIDFT_ABSAXIS;
+      ddoi.dwType = DIDFT_MAKEINSTANCE((i + 1) << WINE_JOYSTICK_AXIS_BASE) | DIDFT_AXIS;
       sprintf(ddoi.tszName, "%d-Axis", i);
       _dump_OBJECTINSTANCEA(&ddoi);
       if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
@@ -558,7 +825,7 @@
 
     for (i = 0; i < buttons; i++) {
       ddoi.dwOfs = DIJOFS_BUTTON(i);
-      ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << i) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+      ddoi.dwType = DIDFT_MAKEINSTANCE((i + 1) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_BUTTON;
       sprintf(ddoi.tszName, "%d-Button", i);
       _dump_OBJECTINSTANCEA(&ddoi);
       if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
@@ -593,51 +860,138 @@
 /******************************************************************************
   *     GetProperty : get input device properties
   */
-static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
-						REFGUID rguid,
-						LPDIPROPHEADER pdiph)
+static HRESULT WINAPI JoystickAImpl_GetProperty(
+    LPDIRECTINPUTDEVICE8A iface,
+    REFGUID rguid,
+    LPDIPROPHEADER pdiph)
 {
-  ICOM_THIS(JoystickImpl,iface);
-
-  TRACE("(this=%p,%s,%p): stub!\n",
-	iface, debugstr_guid(rguid), pdiph);
+    ICOM_THIS(JoystickImpl,iface);
 
-  if (TRACE_ON(dinput))
-    _dump_DIPROPHEADER(pdiph);
+    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph);
 
-  if (!HIWORD(rguid)) {
-    switch ((DWORD)rguid) {
-    case (DWORD) DIPROP_BUFFERSIZE: {
-      LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
-
-      TRACE(" return buffersize = %d\n",This->queue_len);
-      pd->dwData = This->queue_len;
-      break;
-    }
-
-    case (DWORD) DIPROP_RANGE: {
-      LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
-
-      if ((pdiph->dwHow == DIPH_BYID) &&
-	  (pdiph->dwObj & DIDFT_ABSAXIS)) {
-	/* The app is querying the current range of the axis : return the lMin and lMax values */
-	pr->lMin = This->lMin;
-	pr->lMax = This->lMax;
-      }
+    if (TRACE_ON(dinput))
+        _dump_DIPROPHEADER(pdiph);
 
-      break;
+    if (!HIWORD(rguid)) {
+        switch ((DWORD)rguid) {
+        case (DWORD) DIPROP_BUFFERSIZE: {
+            LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
+            TRACE(" return buffersize = %d\n",This->queue_len);
+            pd->dwData = This->queue_len;
+            break;
+        }
+        case (DWORD) DIPROP_RANGE: {
+            LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
+            int obj = find_property(This, pdiph);
+            /* The app is querying the current range of the axis 
+             * return the lMin and lMax values */
+            if (obj >= 0) {
+                pr->lMin = This->props[obj].lMin;
+                pr->lMax = This->props[obj].lMax;
+                TRACE("range(%ld, %ld) obj=%d\n", pr->lMin, pr->lMax, obj);
+                return DI_OK;
+            }
+            break;
+        }
+        case (DWORD) DIPROP_DEADZONE: {
+            LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
+            int obj = find_property(This, pdiph);
+            if (obj >= 0) {
+                pd->dwData = This->props[obj].lDeadZone;
+                TRACE("deadzone(%ld) obj=%d\n", pd->dwData, obj);
+                return DI_OK;
+            }
+            break;
+        }
+        case (DWORD) DIPROP_SATURATION: {
+            LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
+            int obj = find_property(This, pdiph);
+            if (obj >= 0) {
+                pd->dwData = This->props[obj].lSaturation;
+                TRACE("saturation(%ld) obj=%d\n", pd->dwData, obj);
+                return DI_OK;
+            }
+            break;
+        }
+        default:
+            FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
+            break;
+        }
     }
 
+    return DI_OK;
+}
+
+/******************************************************************************
+  *     GetObjectInfo : get object info
+  */
+HRESULT WINAPI JoystickAImpl_GetObjectInfo(
+        LPDIRECTINPUTDEVICE8A iface,
+        LPDIDEVICEOBJECTINSTANCEA pdidoi,
+        DWORD dwObj,
+        DWORD dwHow)
+{
+    ICOM_THIS(JoystickImpl,iface);
+    DIDEVICEOBJECTINSTANCEA didoiA;
+    int i;
+
+    TRACE("(%p,%p,%ld,0x%08lx(%s))\n",
+          iface, pdidoi, dwObj, dwHow,
+          dwHow == DIPH_BYOFFSET ? "DIPH_BYOFFSET" :
+          dwHow == DIPH_BYID ? "DIPH_BYID" :
+          dwHow == DIPH_BYUSAGE ? "DIPH_BYUSAGE" :
+          "UNKNOWN");
+
+    if (pdidoi == NULL) {
+        WARN("invalid parameter: pdidoi = NULL\n");
+        return DIERR_INVALIDPARAM;
+    }
+
+    if ((pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEA)) &&
+        (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3A))) {
+        WARN("invalid parameter: pdidoi->dwSize = %ld != %d or %d\n",
+             pdidoi->dwSize, sizeof(DIDEVICEOBJECTINSTANCEA),
+             sizeof(DIDEVICEOBJECTINSTANCE_DX3A));
+        return DIERR_INVALIDPARAM;
+    }
+
+    ZeroMemory(&didoiA, sizeof(didoiA));
+    didoiA.dwSize = pdidoi->dwSize;
+
+    switch (dwHow) {
+    case DIPH_BYOFFSET:
+        for (i = 0; i < This->df->dwNumObjs; i++) {
+            if (This->df->rgodf[i].dwOfs == dwObj) {
+                if (This->df->rgodf[i].pguid)
+                    didoiA.guidType = *This->df->rgodf[i].pguid;
+                else
+                    didoiA.guidType = GUID_NULL;
+                didoiA.dwOfs = dwObj;
+                didoiA.dwType = This->df->rgodf[i].dwType;
+                didoiA.dwFlags = This->df->rgodf[i].dwFlags;
+                strcpy(didoiA.tszName, "?????"); 
+                CopyMemory(pdidoi, &didoiA, pdidoi->dwSize);
+                return DI_OK;
+            }
+        }
+        break;
+    case DIPH_BYID:
+        FIXME("dwHow = DIPH_BYID not implemented\n");
+        break;
+    case DIPH_BYUSAGE:
+        FIXME("dwHow = DIPH_BYUSAGE not implemented\n");
+        break;
     default:
-      FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
-      break;
+        WARN("invalid parameter: dwHow = %08lx\n", dwHow);
+        return DIERR_INVALIDPARAM;
     }
-  }
 
+    CopyMemory(pdidoi, &didoiA, pdidoi->dwSize);
 
-  return DI_OK;
+    return DI_OK;
 }
 
+
 static IDirectInputDevice8AVtbl JoystickAvt =
 {
 	IDirectInputDevice2AImpl_QueryInterface,
@@ -654,7 +1008,7 @@
 	JoystickAImpl_SetDataFormat,
 	JoystickAImpl_SetEventNotification,
 	IDirectInputDevice2AImpl_SetCooperativeLevel,
-	IDirectInputDevice2AImpl_GetObjectInfo,
+	JoystickAImpl_GetObjectInfo,
 	IDirectInputDevice2AImpl_GetDeviceInfo,
 	IDirectInputDevice2AImpl_RunControlPanel,
 	IDirectInputDevice2AImpl_Initialize,
diff -u -N wine.cvs/dlls/dinput/Makefile.in wine/dlls/dinput/Makefile.in
--- wine.cvs/dlls/dinput/Makefile.in	2004-07-28 07:27:01.000000000 -0400
+++ wine/dlls/dinput/Makefile.in	2004-08-30 16:43:51.000000000 -0400
@@ -7,6 +7,7 @@
 EXTRALIBS = -ldxguid -luuid
 
 C_SRCS = \
+	data_formats.c \
 	device.c \
 	dinput_main.c \
 	joystick_linux.c \


More information about the wine-patches mailing list