- Joystick axes can be configured in the menu again. TODO: Config saving

and loading, XInput, allow axes to be used as buttons (for the Xbox
  controller's trigger buttons), allow the joystick to move through the
  menus, and my PS2 adapter which has no Vista x64 drivers.
  * I'm sure SDL is broken again. Don't bother reporting it, because I already know.

SVN r1680 (trunk)
This commit is contained in:
Randy Heit 2009-06-26 02:45:05 +00:00
parent 6d1cee3398
commit 590eb5cb76
8 changed files with 549 additions and 166 deletions

View file

@ -1,4 +1,10 @@
June 22, 2009
June 25, 2009
- Joystick axes can be configured in the menu again. TODO: Config saving
and loading, XInput, allow axes to be used as buttons (for the Xbox
controller's trigger buttons), allow the joystick to move through the
menus, and my PS2 adapter which has no Vista x64 drivers.
June 22, 2009
- Changed the definition of SBarInfoCoordinate to use bitfields to pack its
members into 32 bits so that it can be stored in a plain old int without
any transformations. The transformation coord -> int -> coord was

View file

@ -584,7 +584,7 @@ void G_BuildTiccmd (ticcmd_t *cmd)
// Remap some axes depending on button state.
if (Button_Strafe.bDown || (Button_Mlook.bDown && lookstrafe))
{
joyaxes[JOYAXIS_Side] = -joyaxes[JOYAXIS_Yaw];
joyaxes[JOYAXIS_Side] = joyaxes[JOYAXIS_Yaw];
joyaxes[JOYAXIS_Yaw] = 0;
}
if (Button_Mlook.bDown)
@ -604,7 +604,7 @@ void G_BuildTiccmd (ticcmd_t *cmd)
LocalKeyboardTurner = true;
}
side += int(MAXPLMOVE * joyaxes[JOYAXIS_Side]);
side -= int(MAXPLMOVE * joyaxes[JOYAXIS_Side]);
forward += int(joyaxes[JOYAXIS_Forward] * MAXPLMOVE);
fly += int(joyaxes[JOYAXIS_Up] * 2048);

View file

@ -92,7 +92,7 @@ enum
////////////////////////////////////////////////////////////////////////////////
SBarInfoCoordinate::SBarInfoCoordinate(int coord, bool relCenter) :
value(coord), relCenter(relCenter)
relCenter(relCenter), value(coord)
{
}

View file

@ -101,7 +101,7 @@ typedef enum {
discretes,
cdiscrete,
ediscrete,
discrete_guid,
discrete_joy,
control,
screenres,
bitflag,
@ -112,9 +112,13 @@ typedef enum {
colorpicker,
intslider,
palettegrid,
joy_sens,
joy_slider,
joy_map,
joy_inverter,
} itemtype;
struct GUIDName;
struct IJoystickConfig;
struct menuitem_t
{
@ -127,6 +131,7 @@ struct menuitem_t
FColorCVar *colorcvar;
int selmode;
float fval;
int joyselection;
} a;
union {
float min; /* aka numvalues aka invflag */
@ -152,13 +157,14 @@ struct menuitem_t
struct value_t *values;
struct valuestring_t *valuestrings;
struct valueenum_t *enumvalues;
GUIDName *guidvalues;
TArray<IJoystickConfig *> *joyvalues;
char *command;
void (*cfunc)(FBaseCVar *cvar, float newval);
void (*mfunc)(void);
void (*lfunc)(int);
int highlight;
int flagmask;
int joyslidernum;
} e;
};

View file

@ -3,7 +3,7 @@
** New options menu code
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** Copyright 1998-2009 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -289,7 +289,10 @@ menu_t MouseMenu =
*
*=======================================*/
#define SELECTED_JOYSTICK (Joysticks[JoystickItems[1].a.joyselection])
EXTERN_CVAR (Bool, use_joystick)
void UpdateJoystickMenu();
#if 0
EXTERN_CVAR (Float, joy_speedmultiplier)
EXTERN_CVAR (Int, joy_xaxis)
@ -318,12 +321,12 @@ EXTERN_CVAR (GUID, joy_guid)
static value_t JoyAxisMapNames[6] =
{
{ 0.0, "None" },
{ 1.0, "Turning" },
{ 2.0, "Looking Up/Down" },
{ 3.0, "Moving Forward" },
{ 4.0, "Strafing" },
{ 5.0, "Moving Up/Down" }
{ (float)JOYAXIS_None, "None" },
{ (float)JOYAXIS_Yaw, "Turning" },
{ (float)JOYAXIS_Pitch, "Looking Up/Down" },
{ (float)JOYAXIS_Forward, "Moving Forward" },
{ (float)JOYAXIS_Side, "Strafing" },
{ (float)JOYAXIS_Up, "Moving Up/Down" }
};
static value_t Inversion[2] =
@ -332,55 +335,13 @@ static value_t Inversion[2] =
{ 1.0, "Inverted" }
};
static menuitem_t JoystickItems[] =
{
#if 0
{ discrete, "Enable joystick", {&use_joystick}, {2.0}, {0.0}, {0.0}, {YesNo} },
{ discrete_guid,"Active joystick", {&joy_guid}, {0.0}, {0.0}, {0.0}, {NULL} },
{ slider, "Overall sensitivity", {&joy_speedmultiplier}, {0.9f}, {2.0}, {0.2f}, {NULL} },
#endif
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ whitetext,"Axis Assignments", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
static TArray<IJoystickConfig *> Joysticks;
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
};
static TArray<menuitem_t> JoystickItems;
menu_t JoystickMenu =
{
"JOYSTICK OPTIONS",
0,
countof(JoystickItems),
0,
JoystickItems,
};
@ -1633,19 +1594,6 @@ int M_FindCurVal (float cur, valuestring_t *values, int numvals)
return v;
}
#if 0
int M_FindCurGUID (const GUID &guid, GUIDName *values, int numvals)
{
int v;
for (v = 0; v < numvals; v++)
if (memcmp (&values[v].ID, &guid, sizeof(GUID)) == 0)
break;
return v;
}
#endif
const char *M_FindCurVal(const char *cur, valueenum_t *values, int numvals)
{
for (int v = 0; v < numvals; ++v)
@ -1753,7 +1701,23 @@ void M_OptDrawer ()
if (item->type != screenres)
{
width = SmallFont->StringWidth (item->label);
const char *label;
if (item->type != discrete_joy)
{
label = item->label;
}
else
{
if (item->e.joyvalues->Size() == 0)
{
label = "No devices connected";
}
else
{
label = (*item->e.joyvalues)[item->a.joyselection]->GetName();
}
}
width = SmallFont->StringWidth(label);
switch (item->type)
{
case more:
@ -1769,6 +1733,13 @@ void M_OptDrawer ()
color = item->type != rightmore ? CR_GREEN : MoreColor;
break;
case discrete_joy:
x = 160 - width / 2;
// Move cursor to the left of this item.
indent = x - 14;
color = ValueColor;
break;
case redtext:
x = 160 - width / 2;
color = LabelColor;
@ -1802,7 +1773,7 @@ void M_OptDrawer ()
? CR_YELLOW : LabelColor;
break;
}
screen->DrawText (SmallFont, color, x, y, item->label, DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
screen->DrawText (SmallFont, color, x, y, label, DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
switch (item->type)
{
@ -1846,11 +1817,19 @@ void M_OptDrawer ()
case discrete:
case cdiscrete:
case inverter:
case joy_map:
{
int v, vals;
overlay = 0;
value = item->a.cvar->GetGenericRep (CVAR_Float);
if (item->type == joy_map)
{
value.Float = (float)SELECTED_JOYSTICK->GetAxisMap(item->a.joyselection);
}
else
{
value = item->a.cvar->GetGenericRep (CVAR_Float);
}
if (item->type == inverter)
{
value.Float = (value.Float < 0.f);
@ -1902,34 +1881,37 @@ void M_OptDrawer ()
}
break;
#if 0
case discrete_guid:
{
int v, vals;
vals = (int)item->b.numvalues;
v = M_FindCurGUID (*(item->a.guidcvar), item->e.guidvalues, vals);
if (v == vals)
{
UCVarValue val = item->a.guidcvar->GetGenericRep (CVAR_String);
screen->DrawText (SmallFont, ValueColor, indent + 14, y, val.String, DTA_Clean, true, TAG_DONE);
}
else
{
screen->DrawText (SmallFont, ValueColor, indent + 14, y, item->e.guidvalues[v].Name,
DTA_Clean, true, TAG_DONE);
}
}
break;
#endif
case nochoice:
screen->DrawText (SmallFont, CR_GOLD, indent + 14, y,
(item->e.values[(int)item->b.min]).name, DTA_Clean, true, TAG_DONE);
break;
case joy_sens:
value.Float = SELECTED_JOYSTICK->GetSensitivity();
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float);
break;
case joy_slider:
if (item->e.joyslidernum == 0)
{
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
}
else
{
assert(item->e.joyslidernum == 1);
value.Float = SELECTED_JOYSTICK->GetAxisDeadZone(item->a.joyselection);
}
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float));
break;
case joy_inverter:
assert(item->e.joyslidernum == 0);
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
screen->DrawText(SmallFont, ValueColor, indent + 14, y,
(value.Float < 0) ? "Yes" : "No",
DTA_Clean, true, TAG_DONE);
break;
case slider:
value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float);
@ -2356,6 +2338,47 @@ void M_OptResponder (event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case joy_sens:
value.Float = SELECTED_JOYSTICK->GetSensitivity() - item->d.step;
if (value.Float < item->b.min)
value.Float = item->b.min;
SELECTED_JOYSTICK->SetSensitivity(value.Float);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case joy_slider:
if (item->e.joyslidernum == 0)
{
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
}
else
{
assert(item->e.joyslidernum == 1);
value.Float = SELECTED_JOYSTICK->GetAxisDeadZone(item->a.joyselection);
}
if (value.Float >= 0)
{
value.Float -= item->d.step;
if (value.Float < item->b.min)
value.Float = item->b.min;
}
else
{
value.Float += item->d.step;
if (value.Float < -item->c.max)
value.Float = -item->c.max;
}
if (item->e.joyslidernum == 0)
{
SELECTED_JOYSTICK->SetAxisScale(item->a.joyselection, value.Float);
}
else
{
SELECTED_JOYSTICK->SetAxisDeadZone(item->a.joyselection, value.Float);
}
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case palettegrid:
SelColorIndex = (SelColorIndex - 1) & 15;
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
@ -2364,12 +2387,20 @@ void M_OptResponder (event_t *ev)
case discretes:
case discrete:
case cdiscrete:
case joy_map:
{
int cur;
int numvals;
numvals = (int)item->b.min;
value = item->a.cvar->GetGenericRep (CVAR_Float);
if (item->type == joy_map)
{
value.Float = (float)SELECTED_JOYSTICK->GetAxisMap(item->a.joyselection);
}
else
{
value = item->a.cvar->GetGenericRep (CVAR_Float);
}
if (item->type != discretes)
{
cur = M_FindCurVal (value.Float, item->e.values, numvals);
@ -2382,7 +2413,14 @@ void M_OptResponder (event_t *ev)
cur = numvals - 1;
value.Float = item->type != discretes ? item->e.values[cur].value : item->e.valuestrings[cur].value;
item->a.cvar->SetGenericRep (value, CVAR_Float);
if (item->type == joy_map)
{
SELECTED_JOYSTICK->SetAxisMap(item->a.joyselection, (EJoyAxis)(int)value.Float);
}
else
{
item->a.cvar->SetGenericRep (value, CVAR_Float);
}
// Hack hack. Rebuild list of resolutions
if (item->e.values == Depths)
@ -2417,22 +2455,14 @@ void M_OptResponder (event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
#if 0
case discrete_guid:
case discrete_joy:
if (--item->a.joyselection < 0)
{
int cur;
int numvals;
numvals = (int)item->b.numvalues;
cur = M_FindCurGUID (*(item->a.guidcvar), item->e.guidvalues, numvals);
if (--cur < 0)
cur = numvals - 1;
*(item->a.guidcvar) = item->e.guidvalues[cur].ID;
item->a.joyselection = item->e.joyvalues->Size() - 1;
}
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
UpdateJoystickMenu();
S_Sound(CHAN_VOICE|CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
#endif
case inverter:
value = item->a.cvar->GetGenericRep (CVAR_Float);
@ -2441,6 +2471,13 @@ void M_OptResponder (event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case joy_inverter:
assert(item->e.joyslidernum == 0);
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
SELECTED_JOYSTICK->SetAxisScale(item->a.joyselection, -value.Float);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case screenres:
{
int col;
@ -2507,6 +2544,47 @@ void M_OptResponder (event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case joy_sens:
value.Float = SELECTED_JOYSTICK->GetSensitivity() + item->d.step;
if (value.Float > item->c.max)
value.Float = item->c.max;
SELECTED_JOYSTICK->SetSensitivity(value.Float);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case joy_slider:
if (item->e.joyslidernum == 0)
{
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
}
else
{
assert(item->e.joyslidernum == 1);
value.Float = SELECTED_JOYSTICK->GetAxisDeadZone(item->a.joyselection);
}
if (value.Float >= 0)
{
value.Float += item->d.step;
if (value.Float > item->c.max)
value.Float = item->c.max;
}
else
{
value.Float -= item->d.step;
if (value.Float > item->b.min)
value.Float = -item->b.min;
}
if (item->e.joyslidernum == 0)
{
SELECTED_JOYSTICK->SetAxisScale(item->a.joyselection, value.Float);
}
else
{
SELECTED_JOYSTICK->SetAxisDeadZone(item->a.joyselection, value.Float);
}
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case palettegrid:
SelColorIndex = (SelColorIndex + 1) & 15;
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
@ -2515,12 +2593,20 @@ void M_OptResponder (event_t *ev)
case discretes:
case discrete:
case cdiscrete:
case joy_map:
{
int cur;
int numvals;
numvals = (int)item->b.min;
value = item->a.cvar->GetGenericRep (CVAR_Float);
if (item->type == joy_map)
{
value.Float = (float)SELECTED_JOYSTICK->GetAxisMap(item->a.joyselection);
}
else
{
value = item->a.cvar->GetGenericRep (CVAR_Float);
}
if (item->type != discretes)
{
cur = M_FindCurVal (value.Float, item->e.values, numvals);
@ -2533,7 +2619,14 @@ void M_OptResponder (event_t *ev)
cur = 0;
value.Float = item->type != discretes ? item->e.values[cur].value : item->e.valuestrings[cur].value;
item->a.cvar->SetGenericRep (value, CVAR_Float);
if (item->type == joy_map)
{
SELECTED_JOYSTICK->SetAxisMap(item->a.joyselection, (EJoyAxis)(int)value.Float);
}
else
{
item->a.cvar->SetGenericRep (value, CVAR_Float);
}
// Hack hack. Rebuild list of resolutions
if (item->e.values == Depths)
@ -2568,22 +2661,14 @@ void M_OptResponder (event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
#if 0
case discrete_guid:
case discrete_joy:
if ((unsigned)++item->a.joyselection >= item->e.joyvalues->Size())
{
int cur;
int numvals;
numvals = (int)item->b.numvalues;
cur = M_FindCurGUID (*(item->a.guidcvar), item->e.guidvalues, numvals);
if (++cur >= numvals)
cur = 0;
*(item->a.guidcvar) = item->e.guidvalues[cur].ID;
item->a.joyselection = 0;
}
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
UpdateJoystickMenu();
S_Sound(CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
#endif
case inverter:
value = item->a.cvar->GetGenericRep (CVAR_Float);
@ -2592,6 +2677,13 @@ void M_OptResponder (event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case joy_inverter:
assert(item->e.joyslidernum == 0);
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
SELECTED_JOYSTICK->SetAxisScale(item->a.joyselection, -value.Float);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case screenres:
{
int col;
@ -2743,6 +2835,13 @@ void M_OptResponder (event_t *ev)
item->a.cvar->SetGenericRep (value, CVAR_Float);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
else if (item->type == joy_inverter)
{
assert(item->e.joyslidernum == 0);
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
SELECTED_JOYSTICK->SetAxisScale(item->a.joyselection, -value.Float);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
else if (item->type == screenres)
{
}
@ -2995,34 +3094,96 @@ CCMD (menu_mouse)
void UpdateJoystickMenu ()
{
#if 0
static FIntCVar * const cvars[8] =
{
&joy_xaxis, &joy_yaxis, &joy_zaxis,
&joy_xrot, &joy_yrot, &joy_zrot,
&joy_slider, &joy_dial
};
static FFloatCVar * const cvars2[5] =
{
&joy_yawspeed, &joy_pitchspeed, &joy_forwardspeed,
&joy_sidespeed, &joy_upspeed
};
static FFloatCVar * const cvars3[8] =
{
&joy_xthreshold, &joy_ythreshold, &joy_zthreshold,
&joy_xrotthreshold, &joy_yrotthreshold, &joy_zrotthreshold,
&joy_sliderthreshold, &joy_dialthreshold
};
int i;
menuitem_t item = { whitetext };
int itemnum;
IJoystickConfig *joy;
int i, line;
if (JoystickNames.Size() == 0)
if (JoystickItems.Size() > 1)
{
JoystickItems[0].type = redtext;
JoystickItems[0].label = "No joysticks connected";
line = 1;
itemnum = JoystickItems[1].a.joyselection;
}
else
{
itemnum = 0;
}
JoystickItems.Clear();
I_GetJoysticks(Joysticks);
if (Joysticks.Size() == 0)
{
item.type = redtext;
item.label = "No joysticks connected";
JoystickItems.Push(item);
}
else
{
item.type = discrete;
item.label = "Enable joystick";
item.a.cvar = &use_joystick;
item.b.numvalues = 2;
item.e.values = YesNo;
JoystickItems.Push(item);
item.type = discrete_joy;
item.label = "Change settings for";
item.a.joyselection = itemnum;
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.label = "Axis Configuration";
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";
@ -3093,17 +3254,17 @@ void UpdateJoystickMenu ()
}
}
}
JoystickMenu.numitems = line;
if (JoystickMenu.lastOn >= line)
#endif
JoystickMenu.items = &JoystickItems[0];
JoystickMenu.numitems = JoystickItems.Size();
if (JoystickMenu.lastOn >= JoystickMenu.numitems)
{
JoystickMenu.lastOn = line - 1;
JoystickMenu.lastOn = JoystickMenu.numitems - 1;
}
if (screen != NULL)
{
CalcIndent (&JoystickMenu);
CalcIndent(&JoystickMenu);
}
#endif
}
static void JoystickOptions ()

View file

@ -120,7 +120,7 @@ public:
// TYPES -------------------------------------------------------------------
class FDInputJoystick : public FInputDevice
class FDInputJoystick : public FInputDevice, IJoystickConfig
{
public:
FDInputJoystick(const GUID *instance, FString &name);
@ -134,6 +134,21 @@ public:
FString GetIdentifier();
void SetDefaultConfig();
// IJoystick interface
FString GetName();
float GetSensitivity();
virtual void SetSensitivity(float scale);
int GetNumAxes();
float GetAxisDeadZone(int axis);
EJoyAxis GetAxisMap(int axis);
const char *GetAxisName(int axis);
float GetAxisScale(int axis);
void SetAxisDeadZone(int axis, float deadzone);
void SetAxisMap(int axis, EJoyAxis gameaxis);
void SetAxisScale(int axis, float scale);
protected:
struct AxisInfo
{
@ -188,6 +203,7 @@ public:
void ProcessInput();
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
void AddAxes(float axes[NUM_JOYAXIS]);
void GetDevices(TArray<IJoystickConfig *> &sticks);
protected:
struct Enumerator
@ -447,7 +463,7 @@ void FDInputJoystick::AddAxes(float axes[NUM_JOYAXIS])
axisval = (axisval - deadzone) / (1.0 - deadzone);
}
// Add to the game axis.
axes[Axes[i].GameAxis] += float(axisval * mul * Axes[i].Multiplier);
axes[Axes[i].GameAxis] -= float(axisval * mul * Axes[i].Multiplier);
}
}
@ -803,23 +819,23 @@ void FDInputJoystick::SetDefaultConfig()
// Two axes? Horizontal is yaw and vertical is forward.
if (Axes.Size() == 2)
{
Axes[0].GameAxis = JOYAXIS_Yaw; Axes[0].Multiplier = -1;
Axes[0].GameAxis = JOYAXIS_Yaw;
Axes[1].GameAxis = JOYAXIS_Forward;
}
// Three axes? First two are movement, third is yaw.
else if (Axes.Size() >= 3)
{
Axes[0].GameAxis = JOYAXIS_Side;
Axes[1].GameAxis = JOYAXIS_Forward; Axes[1].Multiplier = -1;
Axes[2].GameAxis = JOYAXIS_Yaw; Axes[2].Multiplier = -1;
Axes[1].GameAxis = JOYAXIS_Forward;
Axes[2].GameAxis = JOYAXIS_Yaw;
// Four axes? First two are movement, last two are looking around.
if (Axes.Size() >= 4)
{
Axes[3].GameAxis = JOYAXIS_Pitch; Axes[3].Multiplier = -0.75f;
Axes[3].GameAxis = JOYAXIS_Pitch; Axes[3].Multiplier = 0.75f;
// Five axes? Use the fifth one for moving up and down.
if (Axes.Size() >= 5)
{
Axes[4].GameAxis = JOYAXIS_Up; Axes[4].Multiplier = -1;
Axes[4].GameAxis = JOYAXIS_Up;
}
}
}
@ -827,6 +843,152 @@ void FDInputJoystick::SetDefaultConfig()
// the user might want to use it.
}
//===========================================================================
//
// FDInputJoystick :: GetName
//
//===========================================================================
FString FDInputJoystick::GetName()
{
return Name;
}
//===========================================================================
//
// FDInputJoystick :: GetSensitivity
//
//===========================================================================
float FDInputJoystick::GetSensitivity()
{
return Multiplier;
}
//===========================================================================
//
// FDInputJoystick :: SetSensitivity
//
//===========================================================================
void FDInputJoystick::SetSensitivity(float scale)
{
Multiplier = scale;
}
//===========================================================================
//
// FDInputJoystick :: GetNumAxes
//
//===========================================================================
int FDInputJoystick::GetNumAxes()
{
return (int)Axes.Size();
}
//===========================================================================
//
// FDInputJoystick :: GetAxisDeadZone
//
//===========================================================================
float FDInputJoystick::GetAxisDeadZone(int axis)
{
if (unsigned(axis) >= Axes.Size())
{
return 0;
}
return Axes[axis].DeadZone;
}
//===========================================================================
//
// FDInputJoystick :: GetAxisMap
//
//===========================================================================
EJoyAxis FDInputJoystick::GetAxisMap(int axis)
{
if (unsigned(axis) >= Axes.Size())
{
return JOYAXIS_None;
}
return Axes[axis].GameAxis;
}
//===========================================================================
//
// FDInputJoystick :: GetAxisName
//
//===========================================================================
const char *FDInputJoystick::GetAxisName(int axis)
{
if (unsigned(axis) < Axes.Size())
{
return Axes[axis].Name;
}
return "Invalid";
}
//===========================================================================
//
// FDInputJoystick :: GetAxisScale
//
//===========================================================================
float FDInputJoystick::GetAxisScale(int axis)
{
if (unsigned(axis) >= Axes.Size())
{
return 0;
}
return Axes[axis].Multiplier;
}
//===========================================================================
//
// FDInputJoystick :: SetAxisDeadZone
//
//===========================================================================
void FDInputJoystick::SetAxisDeadZone(int axis, float deadzone)
{
if (unsigned(axis) < Axes.Size())
{
Axes[axis].DeadZone = clamp(deadzone, 0.f, 1.f);
}
}
//===========================================================================
//
// FDInputJoystick :: SetAxisMap
//
//===========================================================================
void FDInputJoystick::SetAxisMap(int axis, EJoyAxis gameaxis)
{
if (unsigned(axis) < Axes.Size())
{
Axes[axis].GameAxis = (unsigned(gameaxis) < NUM_JOYAXIS) ? gameaxis : JOYAXIS_None;
}
}
//===========================================================================
//
// FDInputJoystick :: SetAxisScale
//
//===========================================================================
void FDInputJoystick::SetAxisScale(int axis, float scale)
{
if (unsigned(axis) < Axes.Size())
{
Axes[axis].Multiplier = scale;
}
}
//===========================================================================
//
// FDInputJoystickManager - Constructor
@ -902,6 +1064,23 @@ void FDInputJoystickManager :: AddAxes(float axes[NUM_JOYAXIS])
}
}
//===========================================================================
//
// FDInputJoystickManager :: GetJoysticks
//
// Adds the IJoystick interfaces for each device we created to the sticks
// array.
//
//===========================================================================
void FDInputJoystickManager::GetDevices(TArray<IJoystickConfig *> &sticks)
{
for (unsigned i = 0; i < Devices.Size(); ++i)
{
sticks.Push(Devices[i]);
}
}
//===========================================================================
//
// FDInputJoystickManager :: WndProcHook
@ -1161,7 +1340,7 @@ void FDInputJoystickManager::EnumDevices()
// Append numbers.
for (k = i - 1; k < j; ++k)
{
controllers[k].Name.AppendFormat(" %d", k - i - 2);
controllers[k].Name.AppendFormat(" #%d", k - i + 2);
}
}
}

View file

@ -744,6 +744,18 @@ void I_GetAxes(float axes[NUM_JOYAXIS])
}
}
void I_GetJoysticks(TArray<IJoystickConfig *> &sticks)
{
sticks.Clear();
for (int i = 0; i < NUM_JOYDEVICES; ++i)
{
if (JoyDevices[i] != NULL)
{
JoyDevices[i]->GetDevices(sticks);
}
}
}
void I_PutInClipboard (const char *str)
{
if (str == NULL || !OpenClipboard (Window))

View file

@ -43,7 +43,25 @@ void I_PutInClipboard (const char *str);
FString I_GetFromClipboard (bool windows_has_no_selection_clipboard);
void I_GetEvent();
struct NOVTABLE IJoystickConfig
{
virtual FString GetName() = 0;
virtual float GetSensitivity() = 0;
virtual void SetSensitivity(float scale) = 0;
virtual int GetNumAxes() = 0;
virtual float GetAxisDeadZone(int axis) = 0;
virtual EJoyAxis GetAxisMap(int axis) = 0;
virtual const char *GetAxisName(int axis) = 0;
virtual float GetAxisScale(int axis) = 0;
virtual void SetAxisDeadZone(int axis, float zone) = 0;
virtual void SetAxisMap(int axis, EJoyAxis gameaxis) = 0;
virtual void SetAxisScale(int axis, float scale) = 0;
};
void I_GetAxes(float axes[NUM_JOYAXIS]);
void I_GetJoysticks(TArray<IJoystickConfig *> &sticks);
#ifdef USE_WINDOWS_DWORD
// Don't make these definitions available to the main body of the source code.
@ -109,10 +127,11 @@ protected:
void PostKeyEvent(int keynum, INTBOOL down, bool foreground);
};
class FJoystickCollection : public FInputDevice
class NOVTABLE FJoystickCollection : public FInputDevice
{
public:
virtual void AddAxes(float axes[NUM_JOYAXIS]) = 0;
virtual void GetDevices(TArray<IJoystickConfig *> &sticks) = 0;
};
enum