mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-11-25 09:44:02 +00:00
preliminary support for joystick POV-hats
This commit is contained in:
parent
53b027067a
commit
c80176d20a
8 changed files with 243 additions and 83 deletions
|
@ -867,7 +867,7 @@ void AquariaKeyConfig::onUpdate(float dt)
|
|||
}
|
||||
|
||||
if(!ac)
|
||||
for(int i = 0; i < MAX_JOYSTICK_AXIS; ++i)
|
||||
for(size_t i = 0; i < MAX_JOYSTICK_AXIS; ++i)
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(i);
|
||||
if(fabsf(ax) > JOY_AXIS_THRESHOLD)
|
||||
|
@ -878,6 +878,19 @@ void AquariaKeyConfig::onUpdate(float dt)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ac)
|
||||
for(size_t i = 0; i < MAX_JOYSTICK_HATS; ++i)
|
||||
{
|
||||
JoyHatDirection hd = j->getHat(i);
|
||||
if(hd != JOY_HAT_DIR_CENTERED)
|
||||
{
|
||||
ac = joyHatToActionButton(i, hd);
|
||||
while (j->getHat(i) != JOY_HAT_DIR_CENTERED)
|
||||
dsq->run(0.1f, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
clear = true;
|
||||
|
|
|
@ -4169,48 +4169,49 @@ void Avatar::startWallBurst(bool useCursor)
|
|||
}
|
||||
}
|
||||
|
||||
Vector Avatar::getKeyDir()
|
||||
bool Avatar::isActionAndGetDir(Vector& dir)
|
||||
{
|
||||
Vector dir;
|
||||
if (isActing(ACTION_SWIMLEFT, -1))
|
||||
dir += Vector(-1,0);
|
||||
if (isActing(ACTION_SWIMRIGHT, -1))
|
||||
dir += Vector(1,0);
|
||||
if (isActing(ACTION_SWIMUP, -1))
|
||||
dir += Vector(0,-1);
|
||||
if (isActing(ACTION_SWIMDOWN, -1))
|
||||
dir += Vector(0,1);
|
||||
bool dL = isActing(ACTION_SWIMLEFT, -1);
|
||||
bool dR = isActing(ACTION_SWIMRIGHT, -1);
|
||||
bool dU = isActing(ACTION_SWIMUP, -1);
|
||||
bool dD = isActing(ACTION_SWIMDOWN, -1);
|
||||
Vector a;
|
||||
if (dL)
|
||||
a += Vector(-1,0);
|
||||
if (dR)
|
||||
a += Vector(1,0);
|
||||
if (dU)
|
||||
a += Vector(0,-1);
|
||||
if (dD)
|
||||
a += Vector(0,1);
|
||||
|
||||
if (dir.x != 0 && dir.y != 0)
|
||||
dir/=2;
|
||||
if ((dL || dR) && (dU || dD))
|
||||
a *= 0.70710678f; // 1 / sqrt(2)
|
||||
|
||||
return dir;
|
||||
dir += a;
|
||||
return dL || dR || dU || dD;
|
||||
}
|
||||
|
||||
Vector Avatar::getFakeCursorPosition()
|
||||
{
|
||||
if (dsq->getInputMode() == INPUT_KEYBOARD)
|
||||
{
|
||||
return getKeyDir() * 350;
|
||||
}
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK)
|
||||
{
|
||||
float axisInput = 0;
|
||||
Joystick *j = 0;
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if( ((j = core->getJoystick(i))) )
|
||||
if(j->isEnabled())
|
||||
Vector dir;
|
||||
if(isActionAndGetDir(dir))
|
||||
return dir * 350;
|
||||
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled())
|
||||
{
|
||||
float axisInput = j->position.getLength2D();
|
||||
if(axisInput >= JOYSTICK_LOW_THRESHOLD)
|
||||
{
|
||||
axisInput = j->position.getLength2D();
|
||||
if(axisInput >= JOYSTICK_LOW_THRESHOLD)
|
||||
{
|
||||
const float axisMult = (maxMouse - minMouse) / (JOYSTICK_HIGH_THRESHOLD - JOYSTICK_LOW_THRESHOLD);
|
||||
const float distance = minMouse + ((axisInput - JOYSTICK_LOW_THRESHOLD) * axisMult);
|
||||
return (j->position * (distance / axisInput));
|
||||
}
|
||||
const float axisMult = (maxMouse - minMouse) / (JOYSTICK_HIGH_THRESHOLD - JOYSTICK_LOW_THRESHOLD);
|
||||
const float distance = minMouse + ((axisInput - JOYSTICK_LOW_THRESHOLD) * axisMult);
|
||||
return (j->position * (distance / axisInput));
|
||||
}
|
||||
}
|
||||
return Vector(0,0,0);
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
Vector Avatar::getVectorToCursorFromScreenCentre()
|
||||
|
|
|
@ -175,7 +175,7 @@ public:
|
|||
void clearTargets();
|
||||
bool singing;
|
||||
|
||||
Vector getKeyDir();
|
||||
bool isActionAndGetDir(Vector& dir);
|
||||
|
||||
void startBurstCommon();
|
||||
|
||||
|
|
|
@ -65,6 +65,34 @@ static std::string inputcode2string(int k)
|
|||
return os.str();
|
||||
}
|
||||
|
||||
if(k >= JOY_HAT_BEGIN && k < JOY_HAT_END)
|
||||
{
|
||||
if(k >= JOY_HAT_0_LEFT && k < JOY_HAT_END_LEFT)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "HL" << (k - JOY_HAT_0_LEFT);
|
||||
return os.str();
|
||||
}
|
||||
else if(k >= JOY_HAT_0_RIGHT && k < JOY_HAT_END_RIGHT)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "HR" << (k - JOY_HAT_0_RIGHT);
|
||||
return os.str();
|
||||
}
|
||||
else if(k >= JOY_HAT_0_UP && k < JOY_HAT_END_UP)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "HU" << (k - JOY_HAT_0_UP);
|
||||
return os.str();
|
||||
}
|
||||
else if(k >= JOY_HAT_0_DOWN && k < JOY_HAT_END_DOWN)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "HD" << (k - JOY_HAT_0_DOWN);
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
switch(k)
|
||||
{
|
||||
case MOUSE_BUTTON_LEFT:
|
||||
|
@ -134,15 +162,44 @@ std::string getInputCodeToUserString(unsigned int k, size_t joystickID)
|
|||
else if(k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
|
||||
pretty = jbtnname(joystickID, k - JOY_BUTTON_0);
|
||||
|
||||
std::string s;
|
||||
if(pretty && *pretty)
|
||||
{
|
||||
std::string s = pretty;
|
||||
s = pretty;
|
||||
if(tail)
|
||||
s += tail;
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string s = inputcode2string(k);
|
||||
if(k >= JOY_HAT_BEGIN && k < JOY_HAT_END)
|
||||
{
|
||||
if(k >= JOY_HAT_0_LEFT && k < JOY_HAT_END_LEFT)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "H" << (k - JOY_HAT_0_LEFT) << "<";
|
||||
return os.str();
|
||||
}
|
||||
else if(k >= JOY_HAT_0_RIGHT && k < JOY_HAT_END_RIGHT)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "H" << (k - JOY_HAT_0_RIGHT) << ">";
|
||||
return os.str();
|
||||
}
|
||||
else if(k >= JOY_HAT_0_UP && k < JOY_HAT_END_UP)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "H" << (k - JOY_HAT_0_UP) << "^";
|
||||
return os.str();
|
||||
}
|
||||
else if(k >= JOY_HAT_0_DOWN && k < JOY_HAT_END_DOWN)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "H" << (k - JOY_HAT_0_DOWN) << "v";
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
s = inputcode2string(k);
|
||||
return s.empty() ? stringbank.get(SB_BBGE_NO_KEY) : s;
|
||||
}
|
||||
|
||||
|
@ -190,6 +247,20 @@ int getStringToInputCode(const std::string& s)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else if(s.length() > 2 && s[0] == 'H') // joystick hat
|
||||
{
|
||||
JoyHatDirection hd;
|
||||
switch(s[1])
|
||||
{
|
||||
case 'L': hd = JOY_HAT_DIR_LEFT; break;
|
||||
case 'R': hd = JOY_HAT_DIR_RIGHT; break;
|
||||
case 'U': hd = JOY_HAT_DIR_UP; break;
|
||||
case 'D': hd = JOY_HAT_DIR_DOWN; break;
|
||||
default: return 0;
|
||||
}
|
||||
unsigned hatID = atoi(s.c_str() + 2);
|
||||
return joyHatToActionButton(hatID, hd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Maybe we're upgrading from an old config?
|
||||
|
|
|
@ -73,51 +73,78 @@ void ActionButtonStatus::_queryAllStatus()
|
|||
|
||||
bool ActionButtonStatus::_queryStatus(int k) const
|
||||
{
|
||||
bool keyState = false;
|
||||
if (k > 0 && k < KEY_MAXARRAY)
|
||||
return core->getKeyState(k);
|
||||
|
||||
if (k == MOUSE_BUTTON_LEFT)
|
||||
return core->mouse.buttons.left == DOWN;
|
||||
|
||||
if (k == MOUSE_BUTTON_RIGHT)
|
||||
return core->mouse.buttons.right == DOWN;
|
||||
|
||||
if (k == MOUSE_BUTTON_MIDDLE)
|
||||
return core->mouse.buttons.middle == DOWN;
|
||||
|
||||
if (k >= MOUSE_BUTTON_EXTRA_START && k < MOUSE_BUTTON_EXTRA_END)
|
||||
return core->mouse.buttons.extra[k - MOUSE_BUTTON_EXTRA_START];
|
||||
|
||||
// --- joystick from here ---
|
||||
|
||||
Joystick *j = core->getJoystick(joystickID);
|
||||
if(!j || !j->isEnabled())
|
||||
return false;
|
||||
|
||||
if (k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
|
||||
return j->getButton(k - JOY_BUTTON_0);
|
||||
|
||||
if (k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS)
|
||||
{
|
||||
keyState = core->getKeyState(k);
|
||||
}
|
||||
else if (k == MOUSE_BUTTON_LEFT)
|
||||
{
|
||||
keyState = core->mouse.buttons.left == DOWN;
|
||||
}
|
||||
else if (k == MOUSE_BUTTON_RIGHT)
|
||||
{
|
||||
keyState = core->mouse.buttons.right == DOWN;
|
||||
}
|
||||
else if (k == MOUSE_BUTTON_MIDDLE)
|
||||
{
|
||||
keyState = core->mouse.buttons.middle == DOWN;
|
||||
}
|
||||
else if (k >= MOUSE_BUTTON_EXTRA_START && k < MOUSE_BUTTON_EXTRA_END)
|
||||
{
|
||||
keyState = core->mouse.buttons.extra[k - MOUSE_BUTTON_EXTRA_START];
|
||||
}
|
||||
else if (k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
|
||||
{
|
||||
Joystick *j = core->getJoystick(joystickID);
|
||||
if(j && j->isEnabled())
|
||||
keyState = j->getButton(k - JOY_BUTTON_0);
|
||||
}
|
||||
else if (k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS)
|
||||
{
|
||||
Joystick *j = core->getJoystick(joystickID);
|
||||
if(j && j->isEnabled())
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_POS);
|
||||
keyState = ax > JOY_AXIS_THRESHOLD;
|
||||
}
|
||||
}
|
||||
else if (k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG)
|
||||
{
|
||||
Joystick *j = core->getJoystick(joystickID);
|
||||
if(j && j->isEnabled())
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_NEG);
|
||||
keyState = ax < -JOY_AXIS_THRESHOLD;
|
||||
}
|
||||
float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_POS);
|
||||
return ax > JOY_AXIS_THRESHOLD;
|
||||
}
|
||||
|
||||
return keyState;
|
||||
if (k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG)
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_NEG);
|
||||
return ax < -JOY_AXIS_THRESHOLD;
|
||||
}
|
||||
|
||||
if(k >= JOY_HAT_BEGIN && k < JOY_HAT_END)
|
||||
{
|
||||
if (k >= JOY_HAT_0_LEFT && k < JOY_HAT_END_LEFT)
|
||||
return j->getHat(k - JOY_HAT_0_LEFT);
|
||||
|
||||
if (k >= JOY_HAT_0_RIGHT && k < JOY_HAT_END_RIGHT)
|
||||
return j->getHat(k - JOY_HAT_0_RIGHT);
|
||||
|
||||
if (k >= JOY_HAT_0_UP && k < JOY_HAT_END_UP)
|
||||
return j->getHat(k - JOY_HAT_0_UP);
|
||||
|
||||
if (k >= JOY_HAT_0_DOWN && k < JOY_HAT_END_DOWN)
|
||||
return j->getHat(k - JOY_HAT_0_DOWN);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionButtonType joyHatToActionButton(unsigned hatID, JoyHatDirection dir)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
if(hatID < MAX_JOYSTICK_HATS)
|
||||
{
|
||||
if(dir & JOY_HAT_DIR_LEFT)
|
||||
ret = JOY_HAT_0_LEFT;
|
||||
else if(dir & JOY_HAT_DIR_RIGHT)
|
||||
ret = JOY_HAT_0_RIGHT;
|
||||
else if(dir & JOY_HAT_DIR_UP)
|
||||
ret = JOY_HAT_0_UP;
|
||||
else if(dir & JOY_HAT_DIR_DOWN)
|
||||
ret = JOY_HAT_0_DOWN;
|
||||
|
||||
if(ret)
|
||||
ret += hatID;
|
||||
}
|
||||
|
||||
return (ActionButtonType)ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,25 @@ enum ActionButtonType
|
|||
JOY_AXIS_0_NEG = JOY_AXIS_END_POS,
|
||||
JOY_AXIS_END_NEG = JOY_AXIS_0_NEG + MAX_JOYSTICK_AXIS,
|
||||
|
||||
ACTION_BUTTON_ENUM_SIZE = JOY_AXIS_END_NEG
|
||||
JOY_HAT_BEGIN = JOY_AXIS_END_NEG,
|
||||
JOY_HAT_0_LEFT = JOY_HAT_BEGIN,
|
||||
JOY_HAT_END_LEFT = JOY_HAT_0_LEFT + MAX_JOYSTICK_HATS,
|
||||
|
||||
JOY_HAT_0_RIGHT = JOY_HAT_END_LEFT,
|
||||
JOY_HAT_END_RIGHT = JOY_HAT_0_RIGHT + MAX_JOYSTICK_HATS,
|
||||
|
||||
JOY_HAT_0_UP = JOY_HAT_END_RIGHT,
|
||||
JOY_HAT_END_UP = JOY_HAT_0_UP + MAX_JOYSTICK_HATS,
|
||||
|
||||
JOY_HAT_0_DOWN = JOY_HAT_END_UP,
|
||||
JOY_HAT_END_DOWN = JOY_HAT_0_DOWN + MAX_JOYSTICK_HATS,
|
||||
JOY_HAT_END = JOY_HAT_END_DOWN,
|
||||
|
||||
ACTION_BUTTON_ENUM_SIZE = JOY_HAT_END
|
||||
};
|
||||
|
||||
ActionButtonType joyHatToActionButton(unsigned hatID, JoyHatDirection dir);
|
||||
|
||||
class ActionButtonStatus
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -334,11 +334,32 @@ unsigned Joystick::getNumHats() const
|
|||
return numHats;
|
||||
}
|
||||
|
||||
float Joystick::getAxisUncalibrated(int id) const
|
||||
float Joystick::getAxisUncalibrated(unsigned id) const
|
||||
{
|
||||
return id < MAX_JOYSTICK_AXIS ? axisRaw[id] : 0.0f;
|
||||
}
|
||||
|
||||
JoyHatDirection Joystick::getHat(unsigned id) const
|
||||
{
|
||||
unsigned dir = SDL_JoystickGetHat(sdl_joy, id);
|
||||
unsigned ret = JOY_HAT_DIR_CENTERED;
|
||||
switch(dir)
|
||||
{
|
||||
case SDL_HAT_UP: ret = JOY_HAT_DIR_UP; break;
|
||||
case SDL_HAT_DOWN: ret = JOY_HAT_DIR_DOWN; break;
|
||||
case SDL_HAT_LEFT: ret = JOY_HAT_DIR_LEFT; break;
|
||||
case SDL_HAT_RIGHT: ret = JOY_HAT_DIR_RIGHT; break;
|
||||
|
||||
case SDL_HAT_LEFTUP: ret = JOY_HAT_DIR_UP | JOY_HAT_DIR_LEFT; break;
|
||||
case SDL_HAT_RIGHTUP: ret = JOY_HAT_DIR_UP | JOY_HAT_DIR_RIGHT; break;
|
||||
case SDL_HAT_LEFTDOWN: ret = JOY_HAT_DIR_DOWN | JOY_HAT_DIR_LEFT; break;
|
||||
case SDL_HAT_RIGHTDOWN: ret = JOY_HAT_DIR_DOWN | JOY_HAT_DIR_RIGHT; break;
|
||||
|
||||
default: ;
|
||||
}
|
||||
return (JoyHatDirection)ret;
|
||||
}
|
||||
|
||||
const char *Joystick::getAxisName(unsigned axis) const
|
||||
{
|
||||
if(axis >= numJoyAxes)
|
||||
|
|
|
@ -15,6 +15,16 @@
|
|||
#define MAX_JOYSTICK_AXIS 32
|
||||
#define MAX_JOYSTICK_HATS 8
|
||||
|
||||
enum JoyHatDirection // bitmask
|
||||
{
|
||||
JOY_HAT_DIR_CENTERED = 0,
|
||||
JOY_HAT_DIR_UP = 1,
|
||||
JOY_HAT_DIR_DOWN = 2,
|
||||
JOY_HAT_DIR_LEFT = 4,
|
||||
JOY_HAT_DIR_RIGHT = 8
|
||||
};
|
||||
|
||||
|
||||
const static float JOY_AXIS_THRESHOLD = 0.6f;
|
||||
|
||||
class Joystick
|
||||
|
@ -38,7 +48,8 @@ public:
|
|||
void calibrate(Vector &vec, float dead);
|
||||
bool anyButton() const;
|
||||
bool getButton(size_t id) const { return !!(buttonBitmask & (1u << id)); }
|
||||
float getAxisUncalibrated(int id) const;
|
||||
float getAxisUncalibrated(unsigned id) const;
|
||||
JoyHatDirection getHat(unsigned id) const;
|
||||
unsigned getNumAxes() const;
|
||||
unsigned getNumButtons() const;
|
||||
unsigned getNumHats() const;
|
||||
|
|
Loading…
Reference in a new issue