- Fixed some improper preprocessor lines in autostart/autozend.cpp.

- Added XInput support. For the benefit of people compiling with MinGW,
  the CMakeLists.txt checks for xinput.h and disables it if it cannot
  be found. (And much to my surprise, I accidentally discovered that if you
  have the DirectX SDK installed, those headers actually do work with GCC,
  though they add a few extra warnings.)


SVN r1686 (trunk)
This commit is contained in:
Randy Heit 2009-06-28 03:09:17 +00:00
parent 43a71eba31
commit 49b95be4b2
11 changed files with 151 additions and 64 deletions

View File

@ -1,4 +1,12 @@
June 27, 2009 (Changes by Graf Zahl)
June 27, 2009
- Fixed some improper preprocessor lines in autostart/autozend.cpp.
- Added XInput support. For the benefit of people compiling with MinGW,
the CMakeLists.txt checks for xinput.h and disables it if it cannot
be found. (And much to my surprise, I accidentally discovered that if you
have the DirectX SDK installed, those headers actually do work with GCC,
though they add a few extra warnings.)
June 27, 2009 (Changes by Graf Zahl)
- Added Gez's submissions for A_M_Saw customization, area damage and
pitch for A_FireCustomMissile.

View File

@ -73,6 +73,16 @@ if( WIN32 )
else( NOT D3D_INCLUDE_DIR )
include_directories( ${D3D_INCLUDE_DIR} )
endif( NOT D3D_INCLUDE_DIR )
find_path( XINPUT_INCLUDE_DIR xinput.h
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include )
if( NOT XINPUT_INCLUDE_DIR )
message( SEND_ERROR "Could not find xinput.h. XInput will be disabled." )
add_definitions( -DNO_XINPUT )
else( NOT XINPUT_INCLUDE_DIR )
include_directories( ${XINPUT_INCLUDE_DIR} )
endif( NOT XINPUT_INCLUDE_DIR )
find_library( DX_ddraw_LIBRARY ddraw
PATHS ENV DXSDK_DIR
@ -402,6 +412,7 @@ if( WIN32 )
win32/i_keyboard.cpp
win32/i_mouse.cpp
win32/i_dijoy.cpp
win32/i_xinput.cpp
win32/i_main.cpp
win32/i_movie.cpp
win32/i_system.cpp

View File

@ -92,7 +92,7 @@ void *GRegHead __attribute__((section(GREG_SECTION))) = 0;
void *MRegHead __attribute__((section(MREG_SECTION))) = 0;
void *YRegHead __attribute__((section(YREG_SECTION))) = 0;
#elif
#else
#error Please fix autostart.cpp for your compiler

View File

@ -64,7 +64,7 @@ void *GRegTail __attribute__((section(GREG_SECTION))) = 0;
void *MRegTail __attribute__((section(MREG_SECTION))) = 0;
void *YRegTail __attribute__((section(YREG_SECTION))) = 0;
#elif
#else
#error Please fix autozend.cpp for your compiler

View File

@ -251,6 +251,14 @@ const char *KeyNames[NUM_KEYS] =
"axis3plus","axis3minus","axis4plus","axis4minus",
"axis5plus","axis5minus","axis6plus","axis6minus",
"axis7plus","axis7minus","axis8plus","axis8minus",
"lstickright","lstickleft","lstickdown","lstickup", // Gamepad axis-based buttons
"rstickright","rstickleft","rstickdown","rstickup",
"dpadup","dpaddown","dpadleft","dpadright", // Gamepad buttons
"pad_start","pad_back","lthumb","rthumb",
"lshoulder","rshoulder","ltrigger","rtrigger",
"pad_a", "pad_b", "pad_x", "pad_y"
};
static FString Bindings[NUM_KEYS];

View File

@ -188,7 +188,34 @@ enum ESkillLevels
#define KEY_JOYAXIS8MINUS 0x1AB
#define NUM_JOYAXISBUTTONS 8
#define NUM_KEYS 0x1AC
#define KEY_PAD_LTHUMB_RIGHT 0x1AC
#define KEY_PAD_LTHUMB_LEFT 0x1AD
#define KEY_PAD_LTHUMB_DOWN 0x1AE
#define KEY_PAD_LTHUMB_UP 0x1AF
#define KEY_PAD_RTHUMB_RIGHT 0x1B0
#define KEY_PAD_RTHUMB_LEFT 0x1B1
#define KEY_PAD_RTHUMB_DOWN 0x1B2
#define KEY_PAD_RTHUMB_UP 0x1B3
#define KEY_PAD_DPAD_UP 0x1B4
#define KEY_PAD_DPAD_DOWN 0x1B5
#define KEY_PAD_DPAD_LEFT 0x1B6
#define KEY_PAD_DPAD_RIGHT 0x1B7
#define KEY_PAD_START 0x1B8
#define KEY_PAD_BACK 0x1B9
#define KEY_PAD_LTHUMB 0x1BA
#define KEY_PAD_RTHUMB 0x1BB
#define KEY_PAD_LSHOULDER 0x1BC
#define KEY_PAD_RSHOULDER 0x1BD
#define KEY_PAD_LTRIGGER 0x1BE
#define KEY_PAD_RTRIGGER 0x1BF
#define KEY_PAD_A 0x1C0
#define KEY_PAD_B 0x1C1
#define KEY_PAD_X 0x1C2
#define KEY_PAD_Y 0x1C3
#define NUM_KEYS 0x1C4
enum EJoyAxis
{

View File

@ -1700,6 +1700,7 @@ void M_OptDrawer ()
if (item->type != screenres)
{
FString somestring;
const char *label;
if (item->type != discrete_joy)
{
@ -1713,7 +1714,8 @@ void M_OptDrawer ()
}
else
{
label = (*item->e.joyvalues)[item->a.joyselection]->GetName();
somestring = (*item->e.joyvalues)[item->a.joyselection]->GetName();
label = somestring;
}
}
width = SmallFont->StringWidth(label);

View File

@ -136,7 +136,7 @@ public:
FString GetIdentifier();
void SetDefaultConfig();
// IJoystick interface
// IJoystickConfig interface
FString GetName();
float GetSensitivity();
virtual void SetSensitivity(float scale);
@ -192,7 +192,6 @@ protected:
bool ReorderAxisPair(const GUID &x, const GUID &y, int pos);
HRESULT SetDataFormat();
bool SetConfigSection(bool create);
void GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
friend class FDInputJoystickManager;
};
@ -380,33 +379,17 @@ void FDInputJoystick::ProcessInput()
{
AxisInfo *info = &Axes[i];
LONG value = *(LONG *)(state + info->Ofs);
double deadzone = info->DeadZone;
double axisval;
BYTE buttonstate;
// Scale to [-1.0, 1.0]
axisval = (value - info->Min) * 2.0 / (info->Max - info->Min) - 1.0;
// Cancel out dead zone
if (fabs(axisval) < deadzone)
{
axisval = 0;
buttonstate = 0;
}
// Make the dead zone the new 0
else if (axisval < 0)
{
axisval = (axisval + deadzone) / (1.0 - deadzone);
buttonstate = 2; // button minus
}
else
{
axisval = (axisval - deadzone) / (1.0 - deadzone);
buttonstate = 1; // button plus
}
axisval = Joy_RemoveDeadZone(axisval, info->DeadZone, &buttonstate);
info->Value = float(axisval);
if (i < NUM_JOYAXISBUTTONS)
{
GenerateButtonEvents(info->ButtonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2);
Joy_GenerateButtonEvents(info->ButtonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2);
}
info->ButtonValue = buttonstate;
}
@ -441,36 +424,11 @@ void FDInputJoystick::ProcessInput()
pov = POVButtons[pov];
// Send events for POV "buttons" that have changed.
GenerateButtonEvents(info->Value, pov, 4, KEY_JOYPOV1_UP + i*4);
Joy_GenerateButtonEvents(info->Value, pov, 4, KEY_JOYPOV1_UP + i*4);
info->Value = pov;
}
}
//===========================================================================
//
// FDInputJoystick :: GenerateButtonEvents
//
//===========================================================================
void FDInputJoystick::GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base)
{
int changed = oldbuttons ^ newbuttons;
if (changed != 0)
{
event_t ev = { 0 };
int mask = 1;
for (int j = 0; j < 4; mask <<= 1, ++j)
{
if (changed & mask)
{
ev.data1 = base + j;
ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp;
D_PostEvent(&ev);
}
}
}
}
//===========================================================================
//
// FDInputJoystick :: AddAxes
@ -838,11 +796,12 @@ void FDInputJoystick::SetDefaultConfig()
{
Axes[i].DeadZone = DEFAULT_DEADZONE;
Axes[i].Multiplier = 1;
Axes[i].GameAxis = JOYAXIS_None;
}
// Triggers on a 360 controller have a much smaller deadzone.
if (Axes.Size() == 5 && Axes[4].Guid == GUID_ZAxis)
{
Axes[4].DeadZone = 30 / 32768.f;
Axes[4].DeadZone = 30 / 256.f;
}
// Two axes? Horizontal is yaw and vertical is forward.
if (Axes.Size() == 2)
@ -1094,7 +1053,7 @@ void FDInputJoystickManager :: AddAxes(float axes[NUM_JOYAXIS])
//===========================================================================
//
// FDInputJoystickManager :: GetJoysticks
// FDInputJoystickManager :: GetDevices
//
// Adds the IJoystick interfaces for each device we created to the sticks
// array.
@ -1150,12 +1109,16 @@ bool FDInputJoystickManager::WndProcHook(HWND hWnd, UINT message, WPARAM wParam,
BOOL CALLBACK FDInputJoystickManager::EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
TArray<Enumerator> *all = (TArray<Enumerator> *)pvRef;
Enumerator thisone;
// Do not add XInput devices if XInput was initialized.
if (JoyDevices[INPUT_XInput] == NULL || !IsXInputDevice(&lpddi->guidProduct))
{
TArray<Enumerator> *all = (TArray<Enumerator> *)pvRef;
Enumerator thisone;
thisone.Instance = lpddi->guidInstance;
thisone.Name = lpddi->tszInstanceName;
all->Push(thisone);
thisone.Instance = lpddi->guidInstance;
thisone.Name = lpddi->tszInstanceName;
all->Push(thisone);
}
return DIENUM_CONTINUE;
}
@ -1383,11 +1346,11 @@ FDInputJoystick *FDInputJoystickManager::EnumDevices()
//===========================================================================
//
// I_StartupJoystick
// I_StartupDirectInputJoystick
//
//===========================================================================
void I_StartupJoystick()
void I_StartupDirectInputJoystick()
{
FJoystickCollection *joys = new FDInputJoystickManager;
if (joys->GetDevice())
@ -1395,3 +1358,60 @@ void I_StartupJoystick()
JoyDevices[INPUT_DIJoy] = joys;
}
}
//===========================================================================
//
// Joy_RemoveDeadZone
//
//===========================================================================
double Joy_RemoveDeadZone(double axisval, double deadzone, BYTE *buttons)
{
// Cancel out deadzone.
if (fabs(axisval) < deadzone)
{
axisval = 0;
*buttons = 0;
}
// Make the dead zone the new 0.
else if (axisval < 0)
{
axisval = (axisval + deadzone) / (1.0 - deadzone);
*buttons = 2; // button minus
}
else
{
axisval = (axisval - deadzone) / (1.0 - deadzone);
*buttons = 1; // button plus
}
return axisval;
}
//===========================================================================
//
// Joy_GenerateButtonEvents
//
// Provided two bitmasks for a set of buttons, generates events to reflect
// any changes from the old to new set, where base is the key for bit 0,
// base+1 is the key for bit 1, etc.
//
//===========================================================================
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base)
{
int changed = oldbuttons ^ newbuttons;
if (changed != 0)
{
event_t ev = { 0 };
int mask = 1;
for (int j = 0; j < numbuttons; mask <<= 1, ++j)
{
if (changed & mask)
{
ev.data1 = base + j;
ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp;
D_PostEvent(&ev);
}
}
}
}

View File

@ -619,12 +619,15 @@ bool I_InitInput (void *hwnd)
Printf ("I_StartupMouse\n");
I_StartupMouse();
Printf ("I_StartupJoystick\n");
I_StartupJoystick();
Printf ("I_StartupKeyboard\n");
I_StartupKeyboard();
Printf ("I_StartupXInput\n");
I_StartupXInput();
Printf ("I_StartupDirectInputJoystick\n");
I_StartupDirectInputJoystick();
return TRUE;
}

View File

@ -147,7 +147,11 @@ extern FJoystickCollection *JoyDevices[NUM_JOYDEVICES];
void I_StartupMouse();
void I_CheckNativeMouse(bool prefer_native);
void I_StartupKeyboard();
void I_StartupJoystick();
void I_StartupXInput();
void I_StartupDirectInputJoystick();
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
double Joy_RemoveDeadZone(double axisval, double deadzone, BYTE *buttons);
// USB HID usage page numbers
#define HID_GENERIC_DESKTOP_PAGE 0x01

View File

@ -2004,6 +2004,10 @@
RelativePath=".\src\win32\I_system.h"
>
</File>
<File
RelativePath=".\src\win32\i_xinput.cpp"
>
</File>
<File
RelativePath=".\src\win32\icon1.ico"
>