Microsoft Corporation
June 24, 1996 (updated August 15, 1996)
The Microsoft® SideWinder™ 3D Pro joystick incorporates digital-optical technology for precision, speed, and reliability. Using the joystick is simple: it doesn't drift, it requires no calibration, and it offers more buttons, more axis control (four degrees of freedom), and faster poll time. In other words, it gives you more time to render cool graphics that enhance game play.
The SideWinder 3D Pro includes a minidriver to DirectInput™. To find out if a SideWinder 3D Pro is installed, you don't have to interpret the Registry settings; all you need to do is enumerate the currently selected joystick devices. The following console-application code fragment lists the OEM product name for all 16 joysticks:
#include <windows.h>
#include <mmsystem.h>
#include <regstr.h>
#include <stdio.h>
// Function prototypes:
MMRESULT joyGetOEMProductName(UINT id, LPTSTR pszName);
//
// --- Main Console application ---
// Enumerates JOYSTICKID 1 to 16, and displays the OEM product name for all 16
// Joysticks. Uses the routine joyGetOEMProductName.
//
void main(void)
{
TCHAR szNameDevice[256];
UINT i;
for (i=JOYSTICKID1; i< joyGetNumDevs(); i++)
{
printf("JOYSTICKID#%d : ", (i+1));
if (joyGetOEMProductName(i, (LPTSTR) &szNameDevice[0]) != ERROR_SUCCESS)
{
printf("None\n");
}
else
{
printf("%s\n", szNameDevice);
}
}
}
// ----------------------------------------------------------------------------
//
// Function: joyGetOEMProductName
// Parameters: UINT id - Joystick ID from JOYSTICKID1 to JOYSTICK16
// TCHAR * pszName - String storage for the OEM Product name
// for the selected Joystick device specified
// by the parameter "id"
//
// Returns: If Successful, pszName contains OEM product name for JOYSTICKID
// else Failure, returns MMRESULT error code, and pszName is cleared.
//
// Comments:
// JOYSTICKID1 to JOYSTICKID16 is zero-based, while the registry entries are
// 1-based. This routine expects the parameter "id" to be using JOYSTICKID1
// to JOYSTICKID16 which are defined in the multimedia header file mmsystem.h
// The following registry keys/values are defined in the header file
// regstr.h:
// REGSTR_PATH_JOYCONFIG
// REGSTR_PATH_JOYOEM
// REGSTR_VAL_JOYOEMNAME
//
// ----------------------------------------------------------------------------
}
MMRESULT joyGetOEMProductName(UINT id, TCHAR * pszName)
{
JOYCAPS JoyCaps;
TCHAR szKey[256];
TCHAR szValue[256];
UCHAR szOEMKey[256];
HKEY hKey;
DWORD dwcb;
LONG lr;
// Note: JOYSTICKID1-16 is zero-based; registry entries for VJOYD areis 1-based.
id++;
if (id > joyGetNumDevs() ) return JOYERR_NOCANDO;
// Open .. MediaResources\CurrentJoystickSettings
joyGetDevCaps((id-1), &JoyCaps, sizeof(JoyCaps));
sprintf(szKey,
"%s\\%s\\%s",
REGSTR_PATH_JOYCONFIG,
JoyCaps.szRegKey,
REGSTR_KEY_JOYCURR);
lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPTSTR) &szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lr != ERROR_SUCCESS) return JOYERR_NOCANDO;
// Get OEM Key name. If the query is unsuccessful, then Null the string and return
// an Error.
dwcb = sizeof(szOEMKey);
sprintf(szValue, "Joystick%d%s", id, REGSTR_VAL_JOYOEMNAME);
lr = RegQueryValueEx(hKey, szValue, 0, 0, (LPBYTE) &szOEMKey, (LPDWORD) &dwcb);
RegCloseKey(hKey);
if (lr != ERROR_SUCCESS)
{
*pszName = 0;
return JOYERR_NOCANDO;
}
// Open OEM Key from ...MediaProperties
sprintf(szKey, "%s\\%s", REGSTR_PATH_JOYOEM, szOEMKey);
lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lr != ERROR_SUCCESS) return JOYERR_NOCANDO;
// Get OEM Name
dwcb = sizeof(szValue);
lr = RegQueryValueEx( hKey,
REGSTR_VAL_JOYOEMNAME,
0, 0,
(LPBYTE) pszName,
(LPDWORD) &dwcb);
RegCloseKey(hKey);
if (lr != ERROR_SUCCESS)
return JOYERR_NOCANDO;
else
return JOYERR_NOERROR;
}
Tip Don't forget to link your code with Winmm.lib.
To determine if the SideWinder 3D Pro is currently selected, do a string compare of the OEM product name—which is obtained from the joyGetOEMProductName routine—with the string "SideWinder 3D Pro."
The SideWinder 3D Pro supports x and y axis rotation, throttle-slide control, an eight-way hat switch, and eight buttons. The JOYCAPS members listed below show the control capabilities.
SideWinder 3D Pro Control Capability
JOYCAPS Member | Control Capability |
jc.wXmin = 0 | Minimum x axis |
jc.wXmax = 65535 | Maximum x axis |
jc.wYmin = 0 | Minimum y axis |
jc.wYmax = 65535 | Maximum y axis |
jc.wZmin = 0 | Minimum throttle-slide control axis |
jc.wZmax = 65535 | Maximum throttle-slide control axis |
jc.wRmin = 0 | Minimum z rotation (rudder) axis |
jc.wRmax = 65535 | Maximum z rotation (rudder) axis |
jc.wNumButtons = 8 | Eight buttons available |
Polling a typical joystick can take anywhere from 1.2 to nearly 8 milliseconds (ms). That's way too slow for most game developers: they'd rather use that precious time for graphics rendering and play action.
Because the SideWinder 3D Pro uses digital overdrive technology, you can use a single poll call to get information about all four axes, eight buttons, and the status of the eight-way hat switch in an average of 800 microseconds! This makes it unnecessary to poll each button and axis separately. The following code module demonstrates how this API is used by getting the SideWinder 3D Pro data from DirectInput:
// Reminder: You need mmsystem.h and you must link with winmm.lib
#include <windows.h>
#include <mmsystem.h>
BOOL GetJoyData()
{
JoyInfoEx jix;
int nJoyID = JOYSTICKID1;
char szErr[256];
memset(&jix, 0x00, sizeof(JOYINFOEX)); // For good measure.
jix.dwSize = sizeof(JOYINFOEX);
// Note: With Midas, it takes no more time to return all
// information from the joystick than it does to just get only
// the button states or axis.
//
jix.dwFlags = JOY_RETURNALL;
strcpy(szErr,"");
// JjoyGetPoxEx will fill in the joyinfoex struct with all the
// joystick information.
//
switch(joyGetPosEx(nJoyID, &jix))
{
case JOYERR_NOERROR: // No problem.
break;
case MMSYSERR_NODRIVER:
strcpy(szErr,"The joystick driver is not present.");
return FALSE;
case MMSYSERR_INVALPARAM:
strcpy(szErr,"An invalid parameter was passed.");
return FALSE;
case MMSYSERR_BADDEVICEID:
strcpy(szErr,"The specified joystick identifier is invalid.");
return FALSE;
case JOYERR_UNPLUGGED:
strcpy(szErr,"Your joystick is unplugged.");
return FALSE;
default:
strcpy(szErr,"Unknown joystick error.");
return FALSE;
} // End of switch.
//
// This where you get the axis and buttons info.
// All axis are in the range 0 to 65535.
// jix.dwXpos - X position.
// jix.dwYPos - Y position.
// jix.dwZPos - Throttle slider control.
// jix.dwRpos - Z Rotation position.
//
// To see if button 1 is pressed:
// (jix.dwButtons & JOY_BUTTON1) ? PRESSED : NOT_PRESSED;
// likewise for the other buttons JOY_BUTTON2, JOY_BUTTON3 ...;
// JOY_BUTTON8
//
// Hat switch (POV) is in jix.dwPOV.
// The range is 0 to 35900 and the value is -1 if the
// hat switch is not pressed.
//
return TRUE;
} // GetJoyData()
You can use the SideWinder 3D Pro joystick in an MS-DOS® box under Windows® 95, but the SideWinder 3D Pro is optimized for Windows 95 games. If you run MS-DOS games under Windows 95, the minidriver will be giving you joystick data in digital overdrive mode, but the joystick data will only be for CH Flightstick Pro or ThrustMaster® emulation. You won't get the full benefit of digital overdrive, since MS-DOS games use analog.
When Digital Overdrive Is Used
Environment | Uses Digital Overdrive? |
Windows 95 DirectInput | Yes |
MS-DOS under Windows 95 | Yes |
MS-DOS | No; use CH/TM Analog emulation switch. |
What about calibration?
None is required; SideWinder 3D Pro is self-calibrating.
Can I write non-Windows 95 games (for example, MS-DOS native games) that take advantage of the digital overdrive mode?
No; digital overdrive mode requires DirectInput, which requires Windows 95.
If I need additional information, who do I talk to?
Send e-mail to swinddev@microsoft.com. Make sure you include your name and your company name with your question.