mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 06:41:41 +00:00
- Split the joystick menu into two parts: A top level with general options
and a list of all attached controllers, and a second level for configuring an individual controller. - Fixed: Pressing Up at the top of a menu with more lines than fit on screen would find an incorrect bottom position if the menu had a custom top height. - Added the cvars joy_dinput, joy_ps2raw, and joy_xinput to enable/disable specific game controller input systems independant of each other. - Device change broadcasts are now sent to the Doom event queue, so device scanning can be handled in one common place. - Added a fast version of IsXInputDevice that uses the Raw Input device list, because querying WMI for this information is painfully slow. - Added support for compiling with FMOD Ex 4.26+ and running the game with an older DLL. This combination will now produce sound. SVN r1717 (trunk)
This commit is contained in:
parent
8e5b7373b8
commit
f74f6a1659
15 changed files with 628 additions and 374 deletions
|
@ -1,4 +1,19 @@
|
||||||
July 13, 2009 (Changes by Graf Zahl)
|
July 14, 2009
|
||||||
|
- Split the joystick menu into two parts: A top level with general options
|
||||||
|
and a list of all attached controllers, and a second level for configuring
|
||||||
|
an individual controller.
|
||||||
|
- Fixed: Pressing Up at the top of a menu with more lines than fit on screen
|
||||||
|
would find an incorrect bottom position if the menu had a custom top height.
|
||||||
|
- Added the cvars joy_dinput, joy_ps2raw, and joy_xinput to enable/disable
|
||||||
|
specific game controller input systems independant of each other.
|
||||||
|
- Device change broadcasts are now sent to the Doom event queue, so
|
||||||
|
device scanning can be handled in one common place.
|
||||||
|
- Added a fast version of IsXInputDevice that uses the Raw Input device
|
||||||
|
list, because querying WMI for this information is painfully slow.
|
||||||
|
- Added support for compiling with FMOD Ex 4.26+ and running the game
|
||||||
|
with an older DLL. This combination will now produce sound.
|
||||||
|
|
||||||
|
July 13, 2009 (Changes by Graf Zahl)
|
||||||
- added submission for raising master/children/siblings.
|
- added submission for raising master/children/siblings.
|
||||||
- added submission for no decals on wall option.
|
- added submission for no decals on wall option.
|
||||||
- removed some useless code from SpawnMissile function.
|
- removed some useless code from SpawnMissile function.
|
||||||
|
|
|
@ -38,7 +38,8 @@ enum EGenericEvent
|
||||||
EV_KeyDown, // data1: scan code, data2: Qwerty ASCII code
|
EV_KeyDown, // data1: scan code, data2: Qwerty ASCII code
|
||||||
EV_KeyUp, // same
|
EV_KeyUp, // same
|
||||||
EV_Mouse, // x, y: mouse movement deltas
|
EV_Mouse, // x, y: mouse movement deltas
|
||||||
EV_GUI_Event // subtype specifies actual event
|
EV_GUI_Event, // subtype specifies actual event
|
||||||
|
EV_DeviceChange,// a device has been connected or removed
|
||||||
};
|
};
|
||||||
|
|
||||||
// Event structure.
|
// Event structure.
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "compatibility.h"
|
#include "compatibility.h"
|
||||||
|
#include "m_joy.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, hud_althud)
|
EXTERN_CVAR(Bool, hud_althud)
|
||||||
void DrawHUD();
|
void DrawHUD();
|
||||||
|
@ -240,6 +241,8 @@ void D_ProcessEvents (void)
|
||||||
for (; eventtail != eventhead ; eventtail = (eventtail+1)&(MAXEVENTS-1))
|
for (; eventtail != eventhead ; eventtail = (eventtail+1)&(MAXEVENTS-1))
|
||||||
{
|
{
|
||||||
ev = &events[eventtail];
|
ev = &events[eventtail];
|
||||||
|
if (ev->type == EV_DeviceChange)
|
||||||
|
UpdateJoystickMenu(I_UpdateDeviceList());
|
||||||
if (C_Responder (ev))
|
if (C_Responder (ev))
|
||||||
continue; // console ate the event
|
continue; // console ate the event
|
||||||
if (M_Responder (ev))
|
if (M_Responder (ev))
|
||||||
|
@ -260,6 +263,11 @@ void D_ProcessEvents (void)
|
||||||
|
|
||||||
void D_PostEvent (const event_t *ev)
|
void D_PostEvent (const event_t *ev)
|
||||||
{
|
{
|
||||||
|
// Do not post duplicate consecutive EV_DeviceChange events.
|
||||||
|
if (ev->type == EV_DeviceChange && events[eventhead].type == EV_DeviceChange)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
events[eventhead] = *ev;
|
events[eventhead] = *ev;
|
||||||
if (ev->type == EV_Mouse && !testpolymost && !paused && menuactive == MENU_Off &&
|
if (ev->type == EV_Mouse && !testpolymost && !paused && menuactive == MENU_Off &&
|
||||||
ConsoleState != c_down && ConsoleState != c_falling)
|
ConsoleState != c_down && ConsoleState != c_falling)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "m_joy.h"
|
#include "m_joy.h"
|
||||||
#include "gameconfigfile.h"
|
#include "gameconfigfile.h"
|
||||||
|
#include "d_event.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -15,6 +16,23 @@
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, joy_ps2raw)
|
||||||
|
EXTERN_CVAR(Bool, joy_dinput)
|
||||||
|
EXTERN_CVAR(Bool, joy_xinput)
|
||||||
|
|
||||||
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
joy_ps2raw.Callback();
|
||||||
|
joy_dinput.Callback();
|
||||||
|
joy_xinput.Callback();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
// CODE --------------------------------------------------------------------
|
// CODE --------------------------------------------------------------------
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -142,3 +160,80 @@ void M_SaveJoystickConfig(IJoystickConfig *joy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, const int *keys)
|
||||||
|
{
|
||||||
|
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 = keys[j];
|
||||||
|
ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp;
|
||||||
|
D_PostEvent(&ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
|
||||||
enum EJoyAxis
|
enum EJoyAxis
|
||||||
{
|
{
|
||||||
|
@ -43,11 +44,18 @@ struct NOVTABLE IJoystickConfig
|
||||||
virtual FString GetIdentifier() = 0;
|
virtual FString GetIdentifier() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, use_joystick);
|
||||||
|
|
||||||
bool M_LoadJoystickConfig(IJoystickConfig *joy);
|
bool M_LoadJoystickConfig(IJoystickConfig *joy);
|
||||||
void M_SaveJoystickConfig(IJoystickConfig *joy);
|
void M_SaveJoystickConfig(IJoystickConfig *joy);
|
||||||
|
|
||||||
|
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
|
||||||
|
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, const int *keys);
|
||||||
|
double Joy_RemoveDeadZone(double axisval, double deadzone, BYTE *buttons);
|
||||||
|
|
||||||
// These ought to be provided by a system-specific i_input.cpp.
|
// These ought to be provided by a system-specific i_input.cpp.
|
||||||
void I_GetAxes(float axes[NUM_JOYAXIS]);
|
void I_GetAxes(float axes[NUM_JOYAXIS]);
|
||||||
void I_GetJoysticks(TArray<IJoystickConfig *> &sticks);
|
void I_GetJoysticks(TArray<IJoystickConfig *> &sticks);
|
||||||
|
IJoystickConfig *I_UpdateDeviceList();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -94,6 +94,7 @@ typedef enum {
|
||||||
rightmore,
|
rightmore,
|
||||||
safemore,
|
safemore,
|
||||||
rsafemore,
|
rsafemore,
|
||||||
|
joymore,
|
||||||
slider,
|
slider,
|
||||||
absslider,
|
absslider,
|
||||||
inverter,
|
inverter,
|
||||||
|
@ -101,7 +102,6 @@ typedef enum {
|
||||||
discretes,
|
discretes,
|
||||||
cdiscrete,
|
cdiscrete,
|
||||||
ediscrete,
|
ediscrete,
|
||||||
discrete_joy,
|
|
||||||
control,
|
control,
|
||||||
screenres,
|
screenres,
|
||||||
bitflag,
|
bitflag,
|
||||||
|
@ -158,7 +158,6 @@ struct menuitem_t
|
||||||
struct value_t *values;
|
struct value_t *values;
|
||||||
struct valuestring_t *valuestrings;
|
struct valuestring_t *valuestrings;
|
||||||
struct valueenum_t *enumvalues;
|
struct valueenum_t *enumvalues;
|
||||||
TArray<IJoystickConfig *> *joyvalues;
|
|
||||||
char *command;
|
char *command;
|
||||||
void (*cfunc)(FBaseCVar *cvar, float newval);
|
void (*cfunc)(FBaseCVar *cvar, float newval);
|
||||||
void (*mfunc)(void);
|
void (*mfunc)(void);
|
||||||
|
|
|
@ -290,34 +290,26 @@ menu_t MouseMenu =
|
||||||
*
|
*
|
||||||
*=======================================*/
|
*=======================================*/
|
||||||
|
|
||||||
#define SELECTED_JOYSTICK (Joysticks[JoystickItems[1].a.joyselection])
|
EXTERN_CVAR(Bool, use_joystick)
|
||||||
EXTERN_CVAR (Bool, use_joystick)
|
EXTERN_CVAR(Bool, joy_ps2raw)
|
||||||
|
EXTERN_CVAR(Bool, joy_dinput)
|
||||||
|
EXTERN_CVAR(Bool, joy_xinput)
|
||||||
|
|
||||||
#if 0
|
static TArray<IJoystickConfig *> Joysticks;
|
||||||
EXTERN_CVAR (Float, joy_speedmultiplier)
|
static TArray<menuitem_t> JoystickItems;
|
||||||
EXTERN_CVAR (Int, joy_xaxis)
|
|
||||||
EXTERN_CVAR (Int, joy_yaxis)
|
menu_t JoystickMenu =
|
||||||
EXTERN_CVAR (Int, joy_zaxis)
|
{
|
||||||
EXTERN_CVAR (Int, joy_xrot)
|
"CONTROLLER OPTIONS",
|
||||||
EXTERN_CVAR (Int, joy_yrot)
|
};
|
||||||
EXTERN_CVAR (Int, joy_zrot)
|
|
||||||
EXTERN_CVAR (Int, joy_slider)
|
/*=======================================
|
||||||
EXTERN_CVAR (Int, joy_dial)
|
*
|
||||||
EXTERN_CVAR (Float, joy_xthreshold)
|
* Joystick Config Menu
|
||||||
EXTERN_CVAR (Float, joy_ythreshold)
|
*
|
||||||
EXTERN_CVAR (Float, joy_zthreshold)
|
*=======================================*/
|
||||||
EXTERN_CVAR (Float, joy_xrotthreshold)
|
|
||||||
EXTERN_CVAR (Float, joy_yrotthreshold)
|
IJoystickConfig *SELECTED_JOYSTICK;
|
||||||
EXTERN_CVAR (Float, joy_zrotthreshold)
|
|
||||||
EXTERN_CVAR (Float, joy_sliderthreshold)
|
|
||||||
EXTERN_CVAR (Float, joy_dialthreshold)
|
|
||||||
EXTERN_CVAR (Float, joy_yawspeed)
|
|
||||||
EXTERN_CVAR (Float, joy_pitchspeed)
|
|
||||||
EXTERN_CVAR (Float, joy_forwardspeed)
|
|
||||||
EXTERN_CVAR (Float, joy_sidespeed)
|
|
||||||
EXTERN_CVAR (Float, joy_upspeed)
|
|
||||||
EXTERN_CVAR (GUID, joy_guid)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static value_t JoyAxisMapNames[6] =
|
static value_t JoyAxisMapNames[6] =
|
||||||
{
|
{
|
||||||
|
@ -335,13 +327,11 @@ static value_t Inversion[2] =
|
||||||
{ 1.0, "Inverted" }
|
{ 1.0, "Inverted" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static TArray<IJoystickConfig *> Joysticks;
|
static TArray<menuitem_t> JoystickConfigItems;
|
||||||
|
|
||||||
static TArray<menuitem_t> JoystickItems;
|
menu_t JoystickConfigMenu =
|
||||||
|
|
||||||
menu_t JoystickMenu =
|
|
||||||
{
|
{
|
||||||
"JOYSTICK OPTIONS",
|
"CONFIGURE CONTROLLER",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1519,7 +1509,7 @@ static void CalcIndent (menu_t *menu)
|
||||||
{
|
{
|
||||||
item = menu->items + i;
|
item = menu->items + i;
|
||||||
if (item->type != whitetext && item->type != redtext && item->type != screenres &&
|
if (item->type != whitetext && item->type != redtext && item->type != screenres &&
|
||||||
(item->type != discrete || !item->c.discretecenter))
|
item->type != joymore && (item->type != discrete || !item->c.discretecenter))
|
||||||
{
|
{
|
||||||
thiswidth = SmallFont->StringWidth (item->label);
|
thiswidth = SmallFont->StringWidth (item->label);
|
||||||
if (thiswidth > widest)
|
if (thiswidth > widest)
|
||||||
|
@ -1694,6 +1684,10 @@ void M_OptDrawer ()
|
||||||
{
|
{
|
||||||
indent = 160;
|
indent = 160;
|
||||||
}
|
}
|
||||||
|
else if (item->type == joymore)
|
||||||
|
{
|
||||||
|
indent = 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indent = CurrentMenu->indent;
|
indent = CurrentMenu->indent;
|
||||||
|
@ -1703,19 +1697,19 @@ void M_OptDrawer ()
|
||||||
{
|
{
|
||||||
FString somestring;
|
FString somestring;
|
||||||
const char *label;
|
const char *label;
|
||||||
if (item->type != discrete_joy)
|
if (item->type != joymore)
|
||||||
{
|
{
|
||||||
label = item->label;
|
label = item->label;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (item->e.joyvalues->Size() == 0)
|
if (Joysticks.Size() == 0)
|
||||||
{
|
{
|
||||||
label = "No devices connected";
|
label = "No devices connected";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
somestring = (*item->e.joyvalues)[item->a.joyselection]->GetName();
|
somestring = Joysticks[item->a.joyselection]->GetName();
|
||||||
label = somestring;
|
label = somestring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1728,6 +1722,11 @@ void M_OptDrawer ()
|
||||||
color = MoreColor;
|
color = MoreColor;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case joymore:
|
||||||
|
x = 20;
|
||||||
|
color = MoreColor;
|
||||||
|
break;
|
||||||
|
|
||||||
case numberedmore:
|
case numberedmore:
|
||||||
case rsafemore:
|
case rsafemore:
|
||||||
case rightmore:
|
case rightmore:
|
||||||
|
@ -1735,13 +1734,6 @@ void M_OptDrawer ()
|
||||||
color = item->type != rightmore ? CR_GREEN : MoreColor;
|
color = item->type != rightmore ? CR_GREEN : MoreColor;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case discrete_joy:
|
|
||||||
x = 160 - width / 2;
|
|
||||||
// Move cursor to the left of this item.
|
|
||||||
indent = x - 14;
|
|
||||||
color = ValueColor;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case redtext:
|
case redtext:
|
||||||
x = 160 - width / 2;
|
x = 160 - width / 2;
|
||||||
color = LabelColor;
|
color = LabelColor;
|
||||||
|
@ -2222,7 +2214,11 @@ void M_OptResponder (event_t *ev)
|
||||||
int maxitems, rowheight;
|
int maxitems, rowheight;
|
||||||
|
|
||||||
// Figure out how many lines of text fit on the menu
|
// Figure out how many lines of text fit on the menu
|
||||||
if (BigFont && CurrentMenu->texttitle)
|
if (CurrentMenu->y != 0)
|
||||||
|
{
|
||||||
|
maxitems = CurrentMenu->y;
|
||||||
|
}
|
||||||
|
else if (BigFont && CurrentMenu->texttitle)
|
||||||
{
|
{
|
||||||
maxitems = 15 + BigFont->GetHeight ();
|
maxitems = 15 + BigFont->GetHeight ();
|
||||||
}
|
}
|
||||||
|
@ -2457,15 +2453,6 @@ void M_OptResponder (event_t *ev)
|
||||||
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
|
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case discrete_joy:
|
|
||||||
if (--item->a.joyselection < 0)
|
|
||||||
{
|
|
||||||
item->a.joyselection = item->e.joyvalues->Size() - 1;
|
|
||||||
}
|
|
||||||
UpdateJoystickMenu(NULL);
|
|
||||||
S_Sound(CHAN_VOICE|CHAN_UI, "menu/change", 1, ATTN_NONE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case inverter:
|
case inverter:
|
||||||
value = item->a.cvar->GetGenericRep (CVAR_Float);
|
value = item->a.cvar->GetGenericRep (CVAR_Float);
|
||||||
value.Float = -value.Float;
|
value.Float = -value.Float;
|
||||||
|
@ -2663,15 +2650,6 @@ void M_OptResponder (event_t *ev)
|
||||||
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
|
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case discrete_joy:
|
|
||||||
if ((unsigned)++item->a.joyselection >= item->e.joyvalues->Size())
|
|
||||||
{
|
|
||||||
item->a.joyselection = 0;
|
|
||||||
}
|
|
||||||
UpdateJoystickMenu(NULL);
|
|
||||||
S_Sound(CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case inverter:
|
case inverter:
|
||||||
value = item->a.cvar->GetGenericRep (CVAR_Float);
|
value = item->a.cvar->GetGenericRep (CVAR_Float);
|
||||||
value.Float = -value.Float;
|
value.Float = -value.Float;
|
||||||
|
@ -2775,6 +2753,7 @@ void M_OptResponder (event_t *ev)
|
||||||
item->type == numberedmore ||
|
item->type == numberedmore ||
|
||||||
item->type == rightmore ||
|
item->type == rightmore ||
|
||||||
item->type == rsafemore ||
|
item->type == rsafemore ||
|
||||||
|
item->type == joymore ||
|
||||||
item->type == safemore)
|
item->type == safemore)
|
||||||
&& item->e.mfunc)
|
&& item->e.mfunc)
|
||||||
{
|
{
|
||||||
|
@ -3094,21 +3073,114 @@ CCMD (menu_mouse)
|
||||||
MouseOptions ();
|
MouseOptions ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DrawJoystickConfigMenuHeader()
|
||||||
|
{
|
||||||
|
FString joyname = SELECTED_JOYSTICK->GetName();
|
||||||
|
screen->DrawText(BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
|
||||||
|
160-BigFont->StringWidth(CurrentMenu->texttitle)/2, 5,
|
||||||
|
CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE);
|
||||||
|
screen->DrawText(SmallFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
|
||||||
|
160-SmallFont->StringWidth(joyname)/2, 8 + BigFont->GetHeight(),
|
||||||
|
joyname, DTA_Clean, true, TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateJoystickConfigMenu(IJoystickConfig *joy)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
menuitem_t item = { whitetext };
|
||||||
|
|
||||||
|
JoystickConfigItems.Clear();
|
||||||
|
if (joy == NULL)
|
||||||
|
{
|
||||||
|
item.type = redtext;
|
||||||
|
item.label = "Invalid controller specified for menu";
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SELECTED_JOYSTICK = joy;
|
||||||
|
|
||||||
|
item.type = joy_sens;
|
||||||
|
item.label = "Overall sensitivity";
|
||||||
|
item.b.min = 0.5f;
|
||||||
|
item.c.max = 2.f;
|
||||||
|
item.d.step = 0.2f;
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
item.type = redtext;
|
||||||
|
item.label = " ";
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
item.type = whitetext;
|
||||||
|
if (joy->GetNumAxes() > 0)
|
||||||
|
{
|
||||||
|
item.label = "Axis Configuration";
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
for (i = 0; i < joy->GetNumAxes(); ++i)
|
||||||
|
{
|
||||||
|
item.type = redtext;
|
||||||
|
item.label = " ";
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
item.type = joy_map;
|
||||||
|
item.label = joy->GetAxisName(i);
|
||||||
|
item.a.joyselection = i;
|
||||||
|
item.b.numvalues = countof(JoyAxisMapNames);
|
||||||
|
item.e.values = JoyAxisMapNames;
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
item.type = joy_slider;
|
||||||
|
item.label = "Sensitivity";
|
||||||
|
item.b.min = 0;
|
||||||
|
item.c.max = 4;
|
||||||
|
item.d.step = 0.2f;
|
||||||
|
item.e.joyslidernum = 0;
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
item.type = joy_inverter;
|
||||||
|
item.label = "Invert";
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
|
||||||
|
item.type = joy_slider;
|
||||||
|
item.label = "Dead Zone";
|
||||||
|
item.b.position = 1;
|
||||||
|
item.c.max = 0.9f;
|
||||||
|
item.d.step = 0.05f;
|
||||||
|
item.e.joyslidernum = 1;
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.label = "No configurable axes";
|
||||||
|
JoystickConfigItems.Push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JoystickConfigMenu.items = &JoystickConfigItems[0];
|
||||||
|
JoystickConfigMenu.numitems = JoystickConfigItems.Size();
|
||||||
|
JoystickConfigMenu.lastOn = 0;
|
||||||
|
JoystickConfigMenu.scrollpos = 0;
|
||||||
|
JoystickConfigMenu.y = 25 + BigFont->GetHeight();
|
||||||
|
JoystickConfigMenu.PreDraw = DrawJoystickConfigMenuHeader;
|
||||||
|
if (screen != NULL)
|
||||||
|
{
|
||||||
|
CalcIndent(&JoystickConfigMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StartJoystickConfigMenu()
|
||||||
|
{
|
||||||
|
UpdateJoystickConfigMenu(Joysticks[JoystickItems[JoystickMenu.lastOn].a.joyselection]);
|
||||||
|
M_SwitchMenu(&JoystickConfigMenu);
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateJoystickMenu(IJoystickConfig *selected)
|
void UpdateJoystickMenu(IJoystickConfig *selected)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
menuitem_t item = { whitetext };
|
menuitem_t item = { whitetext };
|
||||||
int itemnum;
|
int itemnum = -1;
|
||||||
IJoystickConfig *joy;
|
|
||||||
|
|
||||||
if (JoystickItems.Size() > 1)
|
|
||||||
{
|
|
||||||
itemnum = JoystickItems[1].a.joyselection;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
itemnum = 0;
|
|
||||||
}
|
|
||||||
JoystickItems.Clear();
|
JoystickItems.Clear();
|
||||||
I_GetJoysticks(Joysticks);
|
I_GetJoysticks(Joysticks);
|
||||||
if ((unsigned)itemnum >= Joysticks.Size())
|
if ((unsigned)itemnum >= Joysticks.Size())
|
||||||
|
@ -3126,162 +3198,95 @@ void UpdateJoystickMenu(IJoystickConfig *selected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
item.type = discrete;
|
||||||
|
item.label = "Enable controller support";
|
||||||
|
item.a.cvar = &use_joystick;
|
||||||
|
item.b.numvalues = 2;
|
||||||
|
item.e.values = YesNo;
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
item.label = "Enable DirectInput controllers";
|
||||||
|
item.a.cvar = &joy_dinput;
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
|
item.label = "Enable XInput controllers";
|
||||||
|
item.a.cvar = &joy_xinput;
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
|
item.label = "Enable raw PlayStation 2 adapters";
|
||||||
|
item.a.cvar = &joy_ps2raw;
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
item.type = redtext;
|
||||||
|
item.label = " ";
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
if (Joysticks.Size() == 0)
|
if (Joysticks.Size() == 0)
|
||||||
{
|
{
|
||||||
item.type = redtext;
|
item.type = redtext;
|
||||||
item.label = "No joysticks connected";
|
item.label = "No controllers detected";
|
||||||
JoystickItems.Push(item);
|
JoystickItems.Push(item);
|
||||||
|
if (!use_joystick)
|
||||||
|
{
|
||||||
|
item.type = whitetext;
|
||||||
|
item.label = "Controller support must be";
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
|
item.label = "enabled to detect any";
|
||||||
|
JoystickItems.Push(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item.type = discrete;
|
item.label = "Configure controllers:";
|
||||||
item.label = "Enable joystick";
|
|
||||||
item.a.cvar = &use_joystick;
|
|
||||||
item.b.numvalues = 2;
|
|
||||||
item.e.values = YesNo;
|
|
||||||
JoystickItems.Push(item);
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
item.type = discrete_joy;
|
item.type = joymore;
|
||||||
item.label = "Change settings for";
|
item.e.mfunc = StartJoystickConfigMenu;
|
||||||
item.a.joyselection = itemnum;
|
for (int i = 0; i < (int)Joysticks.Size(); ++i)
|
||||||
item.e.joyvalues = &Joysticks;
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
item.type = joy_sens;
|
|
||||||
item.label = "Overall sensitivity";
|
|
||||||
item.b.min = 0.5f;
|
|
||||||
item.c.max = 2.f;
|
|
||||||
item.d.step = 0.2f;
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
item.type = redtext;
|
|
||||||
item.label = " ";
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
joy = Joysticks[itemnum];
|
|
||||||
if (joy->GetNumAxes() > 0)
|
|
||||||
{
|
{
|
||||||
item.type = whitetext;
|
item.a.joyselection = i;
|
||||||
item.label = "Axis Configuration";
|
if (i == itemnum)
|
||||||
|
{
|
||||||
|
JoystickMenu.lastOn = JoystickItems.Size();
|
||||||
|
}
|
||||||
JoystickItems.Push(item);
|
JoystickItems.Push(item);
|
||||||
|
|
||||||
for (i = 0; i < joy->GetNumAxes(); ++i)
|
|
||||||
{
|
|
||||||
item.type = redtext;
|
|
||||||
item.label = " ";
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
item.type = joy_map;
|
|
||||||
item.label = joy->GetAxisName(i);
|
|
||||||
item.a.joyselection = i;
|
|
||||||
item.b.numvalues = countof(JoyAxisMapNames);
|
|
||||||
item.e.values = JoyAxisMapNames;
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
item.type = joy_slider;
|
|
||||||
item.label = "Sensitivity";
|
|
||||||
item.b.min = 0;
|
|
||||||
item.c.max = 4;
|
|
||||||
item.d.step = 0.2f;
|
|
||||||
item.e.joyslidernum = 0;
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
item.type = joy_inverter;
|
|
||||||
item.label = "Invert";
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
|
|
||||||
item.type = joy_slider;
|
|
||||||
item.label = "Dead Zone";
|
|
||||||
item.b.position = 1;
|
|
||||||
item.c.max = 0.9f;
|
|
||||||
item.d.step = 0.05f;
|
|
||||||
item.e.joyslidernum = 1;
|
|
||||||
JoystickItems.Push(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
JoystickItems[0].type = discrete;
|
|
||||||
JoystickItems[0].label = "Enable joystick";
|
|
||||||
|
|
||||||
JoystickItems[1].b.numvalues = float(JoystickNames.Size());
|
|
||||||
JoystickItems[1].e.guidvalues = &JoystickNames[0];
|
|
||||||
|
|
||||||
line = 5;
|
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
if (JoyAxisNames[i] != NULL)
|
|
||||||
{
|
|
||||||
JoystickItems[line].label = JoyAxisNames[i];
|
|
||||||
JoystickItems[line].type = discrete;
|
|
||||||
JoystickItems[line].a.intcvar = cvars[i];
|
|
||||||
JoystickItems[line].b.numvalues = 6.f;
|
|
||||||
JoystickItems[line].d.graycheck = NULL;
|
|
||||||
JoystickItems[line].e.values = JoyAxisMapNames;
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JoystickItems[line].type = redtext;
|
|
||||||
JoystickItems[line].label = " ";
|
|
||||||
line++;
|
|
||||||
|
|
||||||
JoystickItems[line].type = whitetext;
|
|
||||||
JoystickItems[line].label = "Axis Sensitivity";
|
|
||||||
line++;
|
|
||||||
|
|
||||||
for (i = 0; i < 5; ++i)
|
|
||||||
{
|
|
||||||
JoystickItems[line].type = absslider;
|
|
||||||
JoystickItems[line].label = JoyAxisMapNames[i+1].name;
|
|
||||||
JoystickItems[line].a.cvar = cvars2[i];
|
|
||||||
JoystickItems[line].b.min = 0.0;
|
|
||||||
JoystickItems[line].c.max = 4.0;
|
|
||||||
JoystickItems[line].d.step = 0.2f;
|
|
||||||
line++;
|
|
||||||
|
|
||||||
JoystickItems[line].type = inverter;
|
|
||||||
JoystickItems[line].label = JoyAxisMapNames[i+1].name;
|
|
||||||
JoystickItems[line].a.cvar = cvars2[i];
|
|
||||||
JoystickItems[line].e.values = Inversion;
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
|
|
||||||
JoystickItems[line].type = redtext;
|
|
||||||
JoystickItems[line].label = " ";
|
|
||||||
line++;
|
|
||||||
|
|
||||||
JoystickItems[line].type = whitetext;
|
|
||||||
JoystickItems[line].label = "Axis Dead Zones";
|
|
||||||
line++;
|
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
if (JoyAxisNames[i] != NULL)
|
|
||||||
{
|
|
||||||
JoystickItems[line].label = JoyAxisNames[i];
|
|
||||||
JoystickItems[line].type = slider;
|
|
||||||
JoystickItems[line].a.cvar = cvars3[i];
|
|
||||||
JoystickItems[line].b.min = 0.0;
|
|
||||||
JoystickItems[line].c.max = 0.9f;
|
|
||||||
JoystickItems[line].d.step = 0.05f;
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
JoystickMenu.items = &JoystickItems[0];
|
JoystickMenu.items = &JoystickItems[0];
|
||||||
JoystickMenu.numitems = JoystickItems.Size();
|
JoystickMenu.numitems = JoystickItems.Size();
|
||||||
if (JoystickMenu.lastOn >= JoystickMenu.numitems)
|
if (JoystickMenu.lastOn >= JoystickMenu.numitems)
|
||||||
{
|
{
|
||||||
JoystickMenu.lastOn = JoystickMenu.numitems - 1;
|
JoystickMenu.lastOn = JoystickMenu.numitems - 1;
|
||||||
}
|
}
|
||||||
|
if (CurrentMenu == &JoystickMenu && CurrentItem >= JoystickMenu.numitems)
|
||||||
|
{
|
||||||
|
CurrentItem = JoystickMenu.lastOn;
|
||||||
|
}
|
||||||
if (screen != NULL)
|
if (screen != NULL)
|
||||||
{
|
{
|
||||||
CalcIndent(&JoystickMenu);
|
CalcIndent(&JoystickMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the joystick config menu is open, close it if the device it's
|
||||||
|
// open for is gone.
|
||||||
|
for (i = 0; (unsigned)i < Joysticks.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (Joysticks[i] == SELECTED_JOYSTICK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == Joysticks.Size())
|
||||||
|
{
|
||||||
|
SELECTED_JOYSTICK = NULL;
|
||||||
|
if (CurrentMenu == &JoystickConfigMenu)
|
||||||
|
{
|
||||||
|
M_PopMenuStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JoystickOptions ()
|
static void JoystickOptions ()
|
||||||
|
|
|
@ -474,3 +474,8 @@ void I_GetAxes(float axes[NUM_JOYAXIS])
|
||||||
axes[i] = 0;
|
axes[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IJoystickConfig *I_UpdateDeviceList()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -1179,6 +1179,8 @@ void FMODSoundRenderer::PrintStatus()
|
||||||
unsigned int bufferlength;
|
unsigned int bufferlength;
|
||||||
int numbuffers;
|
int numbuffers;
|
||||||
|
|
||||||
|
Printf ("Loaded FMOD version: "TEXTCOLOR_GREEN"%x.%02x.%02x\n", ActiveFMODVersion >> 16,
|
||||||
|
(ActiveFMODVersion >> 8) & 255, ActiveFMODVersion & 255);
|
||||||
if (FMOD_OK == Sys->getOutput(&output))
|
if (FMOD_OK == Sys->getOutput(&output))
|
||||||
{
|
{
|
||||||
Printf ("Output type: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(OutputNames, output));
|
Printf ("Output type: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(OutputNames, output));
|
||||||
|
@ -1361,11 +1363,12 @@ SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int
|
||||||
FMODStreamCapsule *capsule;
|
FMODStreamCapsule *capsule;
|
||||||
FMOD::Sound *sound;
|
FMOD::Sound *sound;
|
||||||
FMOD_RESULT result;
|
FMOD_RESULT result;
|
||||||
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
|
FMOD_CREATESOUNDEXINFO exinfo;
|
||||||
FMOD_MODE mode;
|
FMOD_MODE mode;
|
||||||
int sample_shift;
|
int sample_shift;
|
||||||
int channel_shift;
|
int channel_shift;
|
||||||
|
|
||||||
|
InitCreateSoundExInfo(&exinfo);
|
||||||
capsule = new FMODStreamCapsule (userdata, callback, this);
|
capsule = new FMODStreamCapsule (userdata, callback, this);
|
||||||
|
|
||||||
mode = FMOD_2D | FMOD_OPENUSER | FMOD_LOOP_NORMAL | FMOD_SOFTWARE | FMOD_CREATESTREAM | FMOD_OPENONLY;
|
mode = FMOD_2D | FMOD_OPENUSER | FMOD_LOOP_NORMAL | FMOD_SOFTWARE | FMOD_CREATESTREAM | FMOD_OPENONLY;
|
||||||
|
@ -1434,11 +1437,12 @@ SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int
|
||||||
SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int flags, int offset, int length)
|
SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int flags, int offset, int length)
|
||||||
{
|
{
|
||||||
FMOD_MODE mode;
|
FMOD_MODE mode;
|
||||||
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
|
FMOD_CREATESOUNDEXINFO exinfo;
|
||||||
FMOD::Sound *stream;
|
FMOD::Sound *stream;
|
||||||
FMOD_RESULT result;
|
FMOD_RESULT result;
|
||||||
bool url;
|
bool url;
|
||||||
|
|
||||||
|
InitCreateSoundExInfo(&exinfo);
|
||||||
mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM;
|
mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM;
|
||||||
if (flags & SoundStream::Loop)
|
if (flags & SoundStream::Loop)
|
||||||
{
|
{
|
||||||
|
@ -2129,11 +2133,12 @@ void FMODSoundRenderer::UpdateSounds()
|
||||||
|
|
||||||
SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits)
|
SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits)
|
||||||
{
|
{
|
||||||
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
|
FMOD_CREATESOUNDEXINFO exinfo;
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
|
|
||||||
if (length == 0) return retval;
|
if (length == 0) return retval;
|
||||||
|
|
||||||
|
InitCreateSoundExInfo(&exinfo);
|
||||||
exinfo.length = length;
|
exinfo.length = length;
|
||||||
exinfo.numchannels = channels;
|
exinfo.numchannels = channels;
|
||||||
exinfo.defaultfrequency = frequency;
|
exinfo.defaultfrequency = frequency;
|
||||||
|
@ -2184,11 +2189,12 @@ SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequ
|
||||||
|
|
||||||
SoundHandle FMODSoundRenderer::LoadSound(BYTE *sfxdata, int length)
|
SoundHandle FMODSoundRenderer::LoadSound(BYTE *sfxdata, int length)
|
||||||
{
|
{
|
||||||
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
|
FMOD_CREATESOUNDEXINFO exinfo;
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
|
|
||||||
if (length == 0) return retval;
|
if (length == 0) return retval;
|
||||||
|
|
||||||
|
InitCreateSoundExInfo(&exinfo);
|
||||||
exinfo.length = length;
|
exinfo.length = length;
|
||||||
|
|
||||||
const FMOD_MODE samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE;
|
const FMOD_MODE samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE;
|
||||||
|
@ -2623,7 +2629,7 @@ void FMODSoundRenderer::DrawSpectrum(float *spectrumarray, int x, int y, int wid
|
||||||
|
|
||||||
short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizebytes, ECodecType type)
|
short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizebytes, ECodecType type)
|
||||||
{
|
{
|
||||||
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
|
FMOD_CREATESOUNDEXINFO exinfo;
|
||||||
FMOD::Sound *sound;
|
FMOD::Sound *sound;
|
||||||
FMOD_SOUND_FORMAT format;
|
FMOD_SOUND_FORMAT format;
|
||||||
int channels;
|
int channels;
|
||||||
|
@ -2631,6 +2637,7 @@ short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizeby
|
||||||
FMOD_RESULT result;
|
FMOD_RESULT result;
|
||||||
short *outbuf;
|
short *outbuf;
|
||||||
|
|
||||||
|
InitCreateSoundExInfo(&exinfo);
|
||||||
if (type == CODEC_Vorbis)
|
if (type == CODEC_Vorbis)
|
||||||
{
|
{
|
||||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS;
|
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS;
|
||||||
|
@ -2667,3 +2674,28 @@ short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizeby
|
||||||
}
|
}
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FMODSoundRenderer :: InitCreateSoundExInfo
|
||||||
|
//
|
||||||
|
// Allow for compiling with 4.26 APIs while still running with older DLLs.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FMODSoundRenderer::InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const
|
||||||
|
{
|
||||||
|
#if FMOD_VERSION >= 0x42600
|
||||||
|
if (ActiveFMODVersion < 0x42600)
|
||||||
|
{
|
||||||
|
// This parameter was added for 4.26.00, and trying to pass it to older
|
||||||
|
// DLLs will fail.
|
||||||
|
exinfo->cbsize = myoffsetof(FMOD_CREATESOUNDEXINFO, ignoresetfilesystem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
exinfo->cbsize = sizeof(exinfo);
|
||||||
|
}
|
||||||
|
memset((BYTE *)exinfo + sizeof(exinfo->cbsize), 0, exinfo->cbsize - sizeof(exinfo->cbsize));
|
||||||
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ private:
|
||||||
FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, bool areasound, FMOD_MODE oldmode) const;
|
FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, bool areasound, FMOD_MODE oldmode) const;
|
||||||
|
|
||||||
bool ReconnectSFXReverbUnit();
|
bool ReconnectSFXReverbUnit();
|
||||||
|
void InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const;
|
||||||
|
|
||||||
bool Init ();
|
bool Init ();
|
||||||
void Shutdown ();
|
void Shutdown ();
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <wbemidl.h>
|
#include <wbemidl.h>
|
||||||
#endif
|
#endif
|
||||||
#include <oleauto.h>
|
#include <oleauto.h>
|
||||||
#include <dbt.h>
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#define USE_WINDOWS_DWORD
|
#define USE_WINDOWS_DWORD
|
||||||
|
@ -28,6 +27,7 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
|
#include "rawinput.h"
|
||||||
|
|
||||||
// WBEMIDL BITS -- because w32api doesn't have this, either -----------------
|
// WBEMIDL BITS -- because w32api doesn't have this, either -----------------
|
||||||
|
|
||||||
|
@ -208,9 +208,9 @@ public:
|
||||||
|
|
||||||
bool GetDevice();
|
bool GetDevice();
|
||||||
void ProcessInput();
|
void ProcessInput();
|
||||||
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
|
|
||||||
void AddAxes(float axes[NUM_JOYAXIS]);
|
void AddAxes(float axes[NUM_JOYAXIS]);
|
||||||
void GetDevices(TArray<IJoystickConfig *> &sticks);
|
void GetDevices(TArray<IJoystickConfig *> &sticks);
|
||||||
|
IJoystickConfig *Rescan();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Enumerator
|
struct Enumerator
|
||||||
|
@ -225,6 +225,8 @@ protected:
|
||||||
static BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
|
static BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
|
||||||
static int STACK_ARGS NameSort(const void *a, const void *b);
|
static int STACK_ARGS NameSort(const void *a, const void *b);
|
||||||
static bool IsXInputDevice(const GUID *guid);
|
static bool IsXInputDevice(const GUID *guid);
|
||||||
|
static bool IsXInputDeviceFast(const GUID *guid);
|
||||||
|
static bool IsXInputDeviceSlow(const GUID *guid);
|
||||||
};
|
};
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
@ -245,8 +247,12 @@ extern HWND Window;
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
CVAR (Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR(Bool, joy_dinput, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||||
FJoystickCollection *JoyDevices[NUM_JOYDEVICES];
|
{
|
||||||
|
I_StartupDirectInputJoystick();
|
||||||
|
event_t ev = { EV_DeviceChange };
|
||||||
|
D_PostEvent(&ev);
|
||||||
|
}
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
|
@ -981,7 +987,7 @@ FDInputJoystickManager::~FDInputJoystickManager()
|
||||||
|
|
||||||
bool FDInputJoystickManager::GetDevice()
|
bool FDInputJoystickManager::GetDevice()
|
||||||
{
|
{
|
||||||
if (g_pdi == NULL || !use_joystick || Args->CheckParm("-nojoy"))
|
if (g_pdi == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1041,37 +1047,6 @@ void FDInputJoystickManager::GetDevices(TArray<IJoystickConfig *> &sticks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// FDInputJoystickManager :: WndProcHook
|
|
||||||
//
|
|
||||||
// Listen for device change broadcasts and rescan the attached devices
|
|
||||||
// when they are received.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool FDInputJoystickManager::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
|
||||||
{
|
|
||||||
if (message != WM_DEVICECHANGE)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef _DEBUG
|
|
||||||
char out[64];
|
|
||||||
mysnprintf(out, countof(out), "WM_DEVICECHANGE wParam=%d\n", wParam);
|
|
||||||
OutputDebugString(out);
|
|
||||||
#endif
|
|
||||||
if ((wParam != DBT_DEVNODES_CHANGED &&
|
|
||||||
wParam != DBT_DEVICEARRIVAL &&
|
|
||||||
wParam != DBT_CONFIGCHANGED))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
UpdateJoystickMenu(EnumDevices());
|
|
||||||
// Return false so that other devices can handle this too if they want.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FDInputJoystickManager :: EnumCallback STATIC
|
// FDInputJoystickManager :: EnumCallback STATIC
|
||||||
|
@ -1101,16 +1076,46 @@ BOOL CALLBACK FDInputJoystickManager::EnumCallback(LPCDIDEVICEINSTANCE lpddi, LP
|
||||||
//
|
//
|
||||||
// FDInputJoystickManager :: IsXInputDevice STATIC
|
// FDInputJoystickManager :: IsXInputDevice STATIC
|
||||||
//
|
//
|
||||||
// Pretty much copied straight from the article "XInput and DirectInput".
|
// Does the DirectInput product GUID correspond to an XInput controller?
|
||||||
//
|
|
||||||
// Enum each PNP device using WMI and check each device ID to see if it
|
// If the product's device ID contains contains "IG_"
|
||||||
// contains "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an
|
// (ex. "VID_045E&PID_028E&IG_00"), then it is an XInput device.
|
||||||
// XInput device. Unfortunately this information can not be found by just
|
// Unfortunately this information can not be found by just using DirectInput.
|
||||||
// using DirectInput.
|
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
bool FDInputJoystickManager::IsXInputDevice(const GUID *guid)
|
bool FDInputJoystickManager::IsXInputDevice(const GUID *guid)
|
||||||
|
{
|
||||||
|
if (MyGetRawInputDeviceList == NULL || MyGetRawInputDeviceInfoA == NULL)
|
||||||
|
{
|
||||||
|
return IsXInputDeviceSlow(guid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return IsXInputDeviceFast(guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FDInputJoystickManager :: IsXInputDeviceSlow STATIC
|
||||||
|
//
|
||||||
|
// Pretty much copied straight from the article "XInput and DirectInput".
|
||||||
|
//
|
||||||
|
// Enum each PNP device using WMI and check each device ID. This is
|
||||||
|
// Microsoft's reference implementation, but it is damn slow. After
|
||||||
|
// a hardware change, connecting to the WMI server can take nearly three
|
||||||
|
// seconds, and creating the instance enumerator consistantly takes longer
|
||||||
|
// than 0.25 seconds.
|
||||||
|
//
|
||||||
|
// The XInput DLL can apparently be hacked fairly simply to work with
|
||||||
|
// Windows 2000, and since Raw Input wasn't introduced until XP, I think
|
||||||
|
// that's reason enough to keep this version around, despite it being
|
||||||
|
// so horrendously slow.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool FDInputJoystickManager::IsXInputDeviceSlow(const GUID *guid)
|
||||||
{
|
{
|
||||||
IWbemLocator *wbemlocator = NULL;
|
IWbemLocator *wbemlocator = NULL;
|
||||||
IEnumWbemClassObject *enumdevices = NULL;
|
IEnumWbemClassObject *enumdevices = NULL;
|
||||||
|
@ -1201,6 +1206,71 @@ cleanup:
|
||||||
return isxinput;
|
return isxinput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FDInputJoystickManager :: IsXInputDeviceFast STATIC
|
||||||
|
//
|
||||||
|
// The theory of operation is the same as for IsXInputDeviceSlow, except that
|
||||||
|
// we use the Raw Input device list to find the device ID instead of WMI.
|
||||||
|
// This generally takes ~0.02 ms on my machine, though it occasionally spikes
|
||||||
|
// at over 1 ms. Either way, it is a huge order of magnitude faster than WMI.
|
||||||
|
// (around 10,000 times faster, in fact!)
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool FDInputJoystickManager::IsXInputDeviceFast(const GUID *guid)
|
||||||
|
{
|
||||||
|
UINT nDevices, numDevices;
|
||||||
|
RAWINPUTDEVICELIST *devices;
|
||||||
|
UINT i;
|
||||||
|
bool isxinput = false;
|
||||||
|
|
||||||
|
if (MyGetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((devices = (RAWINPUTDEVICELIST *)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices)) == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((numDevices = MyGetRawInputDeviceList(devices, &nDevices, sizeof(RAWINPUTDEVICELIST))) == (UINT)-1)
|
||||||
|
{
|
||||||
|
free(devices);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < numDevices; ++i)
|
||||||
|
{
|
||||||
|
// I am making the assumption here that all possible XInput devices
|
||||||
|
// will report themselves as generic HID devices and not as keyboards
|
||||||
|
// or mice.
|
||||||
|
if (devices[i].dwType == RIM_TYPEHID)
|
||||||
|
{
|
||||||
|
RID_DEVICE_INFO rdi;
|
||||||
|
UINT cbSize;
|
||||||
|
|
||||||
|
cbSize = rdi.cbSize = sizeof(rdi);
|
||||||
|
if (MyGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) >= 0)
|
||||||
|
{
|
||||||
|
if(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == guid->Data1)
|
||||||
|
{
|
||||||
|
char name[256];
|
||||||
|
UINT namelen = countof(name);
|
||||||
|
UINT reslen;
|
||||||
|
|
||||||
|
reslen = MyGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, name, &namelen);
|
||||||
|
if (reslen != (UINT)-1)
|
||||||
|
{
|
||||||
|
isxinput = (strstr(name, "IG_") != NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(devices);
|
||||||
|
return isxinput;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FDInputJoystickManager :: NameSort STATIC
|
// FDInputJoystickManager :: NameSort STATIC
|
||||||
|
@ -1319,6 +1389,21 @@ FDInputJoystick *FDInputJoystickManager::EnumDevices()
|
||||||
return newone;
|
return newone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FDInputJoystickManager :: Rescan
|
||||||
|
//
|
||||||
|
// Used by the joy_ps2raw and joy_xinput callbacks to rescan the
|
||||||
|
// DirectInput devices, since their presence or absence can affect the
|
||||||
|
// results of the scan.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
IJoystickConfig *FDInputJoystickManager::Rescan()
|
||||||
|
{
|
||||||
|
return EnumDevices();
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// I_StartupDirectInputJoystick
|
// I_StartupDirectInputJoystick
|
||||||
|
@ -1327,85 +1412,24 @@ FDInputJoystick *FDInputJoystickManager::EnumDevices()
|
||||||
|
|
||||||
void I_StartupDirectInputJoystick()
|
void I_StartupDirectInputJoystick()
|
||||||
{
|
{
|
||||||
FJoystickCollection *joys = new FDInputJoystickManager;
|
if (!joy_dinput || !use_joystick || Args->CheckParm("-nojoy"))
|
||||||
if (joys->GetDevice())
|
|
||||||
{
|
{
|
||||||
JoyDevices[INPUT_DIJoy] = joys;
|
if (JoyDevices[INPUT_DIJoy] != NULL)
|
||||||
}
|
{
|
||||||
}
|
delete JoyDevices[INPUT_DIJoy];
|
||||||
|
JoyDevices[INPUT_DIJoy] = NULL;
|
||||||
//===========================================================================
|
UpdateJoystickMenu(NULL);
|
||||||
//
|
}
|
||||||
// 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
|
else
|
||||||
{
|
{
|
||||||
axisval = (axisval - deadzone) / (1.0 - deadzone);
|
if (JoyDevices[INPUT_DIJoy] == NULL)
|
||||||
*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)
|
FJoystickCollection *joys = new FDInputJoystickManager;
|
||||||
|
if (joys->GetDevice())
|
||||||
{
|
{
|
||||||
ev.data1 = base + j;
|
JoyDevices[INPUT_DIJoy] = joys;
|
||||||
ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp;
|
|
||||||
D_PostEvent(&ev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, const int *keys)
|
|
||||||
{
|
|
||||||
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 = keys[j];
|
|
||||||
ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp;
|
|
||||||
D_PostEvent(&ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -47,6 +47,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
#include <dbt.h>
|
||||||
#include <dinput.h>
|
#include <dinput.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
|
@ -118,7 +119,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void FindRawInputFunctions();
|
static void FindRawInputFunctions();
|
||||||
BOOL DI_InitJoy (void);
|
FJoystickCollection *JoyDevices[NUM_JOYDEVICES];
|
||||||
|
|
||||||
|
|
||||||
extern HINSTANCE g_hInst;
|
extern HINSTANCE g_hInst;
|
||||||
extern DWORD SessionID;
|
extern DWORD SessionID;
|
||||||
|
@ -551,6 +553,16 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_ERASEBKGND:
|
case WM_ERASEBKGND:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case WM_DEVICECHANGE:
|
||||||
|
if (wParam == DBT_DEVNODES_CHANGED ||
|
||||||
|
wParam == DBT_DEVICEARRIVAL ||
|
||||||
|
wParam == DBT_CONFIGCHANGED)
|
||||||
|
{
|
||||||
|
event_t ev = { EV_DeviceChange };
|
||||||
|
D_PostEvent(&ev);
|
||||||
|
}
|
||||||
|
return DefWindowProc (hWnd, message, wParam, lParam);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc (hWnd, message, wParam, lParam);
|
return DefWindowProc (hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
@ -765,6 +777,24 @@ void I_GetJoysticks(TArray<IJoystickConfig *> &sticks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a new controller was added, returns a pointer to it.
|
||||||
|
IJoystickConfig *I_UpdateDeviceList()
|
||||||
|
{
|
||||||
|
IJoystickConfig *newone = NULL;
|
||||||
|
for (int i = 0; i < NUM_JOYDEVICES; ++i)
|
||||||
|
{
|
||||||
|
if (JoyDevices[i] != NULL)
|
||||||
|
{
|
||||||
|
IJoystickConfig *thisnewone = JoyDevices[i]->Rescan();
|
||||||
|
if (newone == NULL)
|
||||||
|
{
|
||||||
|
newone = thisnewone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newone;
|
||||||
|
}
|
||||||
|
|
||||||
void I_PutInClipboard (const char *str)
|
void I_PutInClipboard (const char *str)
|
||||||
{
|
{
|
||||||
if (str == NULL || !OpenClipboard (Window))
|
if (str == NULL || !OpenClipboard (Window))
|
||||||
|
|
|
@ -115,6 +115,7 @@ class NOVTABLE FJoystickCollection : public FInputDevice
|
||||||
public:
|
public:
|
||||||
virtual void AddAxes(float axes[NUM_JOYAXIS]) = 0;
|
virtual void AddAxes(float axes[NUM_JOYAXIS]) = 0;
|
||||||
virtual void GetDevices(TArray<IJoystickConfig *> &sticks) = 0;
|
virtual void GetDevices(TArray<IJoystickConfig *> &sticks) = 0;
|
||||||
|
virtual IJoystickConfig *Rescan() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -135,10 +136,6 @@ void I_StartupDirectInputJoystick();
|
||||||
void I_StartupRawPS2();
|
void I_StartupRawPS2();
|
||||||
bool I_IsPS2Adapter(DWORD vidpid);
|
bool I_IsPS2Adapter(DWORD vidpid);
|
||||||
|
|
||||||
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
|
|
||||||
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, const int *keys);
|
|
||||||
double Joy_RemoveDeadZone(double axisval, double deadzone, BYTE *buttons);
|
|
||||||
|
|
||||||
// USB HID usage page numbers
|
// USB HID usage page numbers
|
||||||
#define HID_GENERIC_DESKTOP_PAGE 0x01
|
#define HID_GENERIC_DESKTOP_PAGE 0x01
|
||||||
#define HID_SIMULATION_CONTROLS_PAGE 0x02
|
#define HID_SIMULATION_CONTROLS_PAGE 0x02
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <dbt.h>
|
|
||||||
|
|
||||||
#define USE_WINDOWS_DWORD
|
#define USE_WINDOWS_DWORD
|
||||||
#include "i_input.h"
|
#include "i_input.h"
|
||||||
|
@ -150,12 +149,11 @@ public:
|
||||||
|
|
||||||
bool GetDevice();
|
bool GetDevice();
|
||||||
bool ProcessRawInput(RAWINPUT *raw, int code);
|
bool ProcessRawInput(RAWINPUT *raw, int code);
|
||||||
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
|
|
||||||
void AddAxes(float axes[NUM_JOYAXIS]);
|
void AddAxes(float axes[NUM_JOYAXIS]);
|
||||||
void GetDevices(TArray<IJoystickConfig *> &sticks);
|
void GetDevices(TArray<IJoystickConfig *> &sticks);
|
||||||
|
IJoystickConfig *Rescan();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HMODULE XInputDLL;
|
|
||||||
TArray<FRawPS2Controller *> Devices;
|
TArray<FRawPS2Controller *> Devices;
|
||||||
bool Registered;
|
bool Registered;
|
||||||
|
|
||||||
|
@ -200,6 +198,13 @@ extern HWND Window;
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Bool, joy_ps2raw, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||||
|
{
|
||||||
|
I_StartupRawPS2();
|
||||||
|
event_t ev = { EV_DeviceChange };
|
||||||
|
D_PostEvent(&ev);
|
||||||
|
}
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
static const int ButtonKeys[16] =
|
static const int ButtonKeys[16] =
|
||||||
|
@ -938,37 +943,6 @@ void FRawPS2Manager::GetDevices(TArray<IJoystickConfig *> &sticks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// FRawPS2Manager :: WndProcHook
|
|
||||||
//
|
|
||||||
// Listen for device change broadcasts and rescan the attached devices
|
|
||||||
// when they are received.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool FRawPS2Manager::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
|
||||||
{
|
|
||||||
if (message != WM_DEVICECHANGE)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef _DEBUG
|
|
||||||
char out[64];
|
|
||||||
mysnprintf(out, countof(out), "WM_DEVICECHANGE wParam=%d\n", wParam);
|
|
||||||
OutputDebugString(out);
|
|
||||||
#endif
|
|
||||||
if ((wParam != DBT_DEVNODES_CHANGED &&
|
|
||||||
wParam != DBT_DEVICEARRIVAL &&
|
|
||||||
wParam != DBT_CONFIGCHANGED))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
UpdateJoystickMenu(EnumDevices());
|
|
||||||
// Return false so that other devices can handle this too if they want.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FRawPS2Manager :: ProcessRawInput
|
// FRawPS2Manager :: ProcessRawInput
|
||||||
|
@ -994,6 +968,17 @@ bool FRawPS2Manager::ProcessRawInput(RAWINPUT *raw, int code)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FRawPS2Manager :: Rescan
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
IJoystickConfig *FRawPS2Manager::Rescan()
|
||||||
|
{
|
||||||
|
return EnumDevices();
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FRawPS2Manager :: EnumDevices
|
// FRawPS2Manager :: EnumDevices
|
||||||
|
@ -1292,10 +1277,25 @@ void FRawPS2Manager::DoRegister()
|
||||||
|
|
||||||
void I_StartupRawPS2()
|
void I_StartupRawPS2()
|
||||||
{
|
{
|
||||||
FJoystickCollection *joys = new FRawPS2Manager;
|
if (!joy_ps2raw || !use_joystick || Args->CheckParm("-nojoy"))
|
||||||
if (joys->GetDevice())
|
|
||||||
{
|
{
|
||||||
JoyDevices[INPUT_RawPS2] = joys;
|
if (JoyDevices[INPUT_RawPS2] != NULL)
|
||||||
|
{
|
||||||
|
delete JoyDevices[INPUT_RawPS2];
|
||||||
|
JoyDevices[INPUT_RawPS2] = NULL;
|
||||||
|
UpdateJoystickMenu(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (JoyDevices[INPUT_RawPS2] == NULL)
|
||||||
|
{
|
||||||
|
FJoystickCollection *joys = new FRawPS2Manager;
|
||||||
|
if (joys->GetDevice())
|
||||||
|
{
|
||||||
|
JoyDevices[INPUT_RawPS2] = joys;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,7 @@ public:
|
||||||
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
|
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
|
||||||
void AddAxes(float axes[NUM_JOYAXIS]);
|
void AddAxes(float axes[NUM_JOYAXIS]);
|
||||||
void GetDevices(TArray<IJoystickConfig *> &sticks);
|
void GetDevices(TArray<IJoystickConfig *> &sticks);
|
||||||
|
IJoystickConfig *Rescan();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HMODULE XInputDLL;
|
HMODULE XInputDLL;
|
||||||
|
@ -136,6 +137,13 @@ protected:
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Bool, joy_xinput, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||||
|
{
|
||||||
|
I_StartupXInput();
|
||||||
|
event_t ev = { EV_DeviceChange };
|
||||||
|
D_PostEvent(&ev);
|
||||||
|
}
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
static XInputGetStateType InputGetState;
|
static XInputGetStateType InputGetState;
|
||||||
|
@ -734,6 +742,17 @@ bool FXInputManager::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FXInputManager :: Rescan
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
IJoystickConfig *FXInputManager::Rescan()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// I_StartupXInput
|
// I_StartupXInput
|
||||||
|
@ -742,10 +761,25 @@ bool FXInputManager::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM
|
||||||
|
|
||||||
void I_StartupXInput()
|
void I_StartupXInput()
|
||||||
{
|
{
|
||||||
FJoystickCollection *joys = new FXInputManager;
|
if (!joy_xinput || !use_joystick || Args->CheckParm("-nojoy"))
|
||||||
if (joys->GetDevice())
|
|
||||||
{
|
{
|
||||||
JoyDevices[INPUT_XInput] = joys;
|
if (JoyDevices[INPUT_XInput] != NULL)
|
||||||
|
{
|
||||||
|
delete JoyDevices[INPUT_XInput];
|
||||||
|
JoyDevices[INPUT_XInput] = NULL;
|
||||||
|
UpdateJoystickMenu(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (JoyDevices[INPUT_XInput] == NULL)
|
||||||
|
{
|
||||||
|
FJoystickCollection *joys = new FXInputManager;
|
||||||
|
if (joys->GetDevice())
|
||||||
|
{
|
||||||
|
JoyDevices[INPUT_XInput] = joys;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue