1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-05-12 12:03:56 +00:00

preliminary support for joystick POV-hats

This commit is contained in:
fgenesis 2020-07-07 22:30:25 +02:00
parent 53b027067a
commit c80176d20a
8 changed files with 243 additions and 83 deletions

View file

@ -867,7 +867,7 @@ void AquariaKeyConfig::onUpdate(float dt)
} }
if(!ac) 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); float ax = j->getAxisUncalibrated(i);
if(fabsf(ax) > JOY_AXIS_THRESHOLD) if(fabsf(ax) > JOY_AXIS_THRESHOLD)
@ -878,6 +878,19 @@ void AquariaKeyConfig::onUpdate(float dt)
break; 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 else
clear = true; clear = true;

View file

@ -4169,48 +4169,49 @@ void Avatar::startWallBurst(bool useCursor)
} }
} }
Vector Avatar::getKeyDir() bool Avatar::isActionAndGetDir(Vector& dir)
{ {
Vector dir; bool dL = isActing(ACTION_SWIMLEFT, -1);
if (isActing(ACTION_SWIMLEFT, -1)) bool dR = isActing(ACTION_SWIMRIGHT, -1);
dir += Vector(-1,0); bool dU = isActing(ACTION_SWIMUP, -1);
if (isActing(ACTION_SWIMRIGHT, -1)) bool dD = isActing(ACTION_SWIMDOWN, -1);
dir += Vector(1,0); Vector a;
if (isActing(ACTION_SWIMUP, -1)) if (dL)
dir += Vector(0,-1); a += Vector(-1,0);
if (isActing(ACTION_SWIMDOWN, -1)) if (dR)
dir += Vector(0,1); a += Vector(1,0);
if (dU)
a += Vector(0,-1);
if (dD)
a += Vector(0,1);
if (dir.x != 0 && dir.y != 0) if ((dL || dR) && (dU || dD))
dir/=2; a *= 0.70710678f; // 1 / sqrt(2)
return dir; dir += a;
return dL || dR || dU || dD;
} }
Vector Avatar::getFakeCursorPosition() Vector Avatar::getFakeCursorPosition()
{ {
if (dsq->getInputMode() == INPUT_KEYBOARD) Vector dir;
{ if(isActionAndGetDir(dir))
return getKeyDir() * 350; return dir * 350;
}
if (dsq->getInputMode() == INPUT_JOYSTICK) for(size_t i = 0; i < core->getNumJoysticks(); ++i)
{ if(Joystick *j = core->getJoystick(i))
float axisInput = 0; if(j->isEnabled())
Joystick *j = 0; {
for(size_t i = 0; i < core->getNumJoysticks(); ++i) float axisInput = j->position.getLength2D();
if( ((j = core->getJoystick(i))) ) if(axisInput >= JOYSTICK_LOW_THRESHOLD)
if(j->isEnabled())
{ {
axisInput = j->position.getLength2D(); const float axisMult = (maxMouse - minMouse) / (JOYSTICK_HIGH_THRESHOLD - JOYSTICK_LOW_THRESHOLD);
if(axisInput >= 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() Vector Avatar::getVectorToCursorFromScreenCentre()

View file

@ -175,7 +175,7 @@ public:
void clearTargets(); void clearTargets();
bool singing; bool singing;
Vector getKeyDir(); bool isActionAndGetDir(Vector& dir);
void startBurstCommon(); void startBurstCommon();

View file

@ -65,6 +65,34 @@ static std::string inputcode2string(int k)
return os.str(); 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) switch(k)
{ {
case MOUSE_BUTTON_LEFT: 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) else if(k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
pretty = jbtnname(joystickID, k - JOY_BUTTON_0); pretty = jbtnname(joystickID, k - JOY_BUTTON_0);
std::string s;
if(pretty && *pretty) if(pretty && *pretty)
{ {
std::string s = pretty; s = pretty;
if(tail) if(tail)
s += tail; s += tail;
return s; 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; return s.empty() ? stringbank.get(SB_BBGE_NO_KEY) : s;
} }
@ -190,6 +247,20 @@ int getStringToInputCode(const std::string& s)
return 0; 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 else
{ {
// Maybe we're upgrading from an old config? // Maybe we're upgrading from an old config?

View file

@ -73,51 +73,78 @@ void ActionButtonStatus::_queryAllStatus()
bool ActionButtonStatus::_queryStatus(int k) const bool ActionButtonStatus::_queryStatus(int k) const
{ {
bool keyState = false;
if (k > 0 && k < KEY_MAXARRAY) 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); float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_POS);
} return ax > JOY_AXIS_THRESHOLD;
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;
}
} }
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;
}

View file

@ -26,9 +26,25 @@ enum ActionButtonType
JOY_AXIS_0_NEG = JOY_AXIS_END_POS, JOY_AXIS_0_NEG = JOY_AXIS_END_POS,
JOY_AXIS_END_NEG = JOY_AXIS_0_NEG + MAX_JOYSTICK_AXIS, 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 class ActionButtonStatus
{ {
public: public:

View file

@ -334,11 +334,32 @@ unsigned Joystick::getNumHats() const
return numHats; return numHats;
} }
float Joystick::getAxisUncalibrated(int id) const float Joystick::getAxisUncalibrated(unsigned id) const
{ {
return id < MAX_JOYSTICK_AXIS ? axisRaw[id] : 0.0f; 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 const char *Joystick::getAxisName(unsigned axis) const
{ {
if(axis >= numJoyAxes) if(axis >= numJoyAxes)

View file

@ -15,6 +15,16 @@
#define MAX_JOYSTICK_AXIS 32 #define MAX_JOYSTICK_AXIS 32
#define MAX_JOYSTICK_HATS 8 #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; const static float JOY_AXIS_THRESHOLD = 0.6f;
class Joystick class Joystick
@ -38,7 +48,8 @@ public:
void calibrate(Vector &vec, float dead); void calibrate(Vector &vec, float dead);
bool anyButton() const; bool anyButton() const;
bool getButton(size_t id) const { return !!(buttonBitmask & (1u << id)); } 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 getNumAxes() const;
unsigned getNumButtons() const; unsigned getNumButtons() const;
unsigned getNumHats() const; unsigned getNumHats() const;