1
0
Fork 0
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:
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)
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;

View file

@ -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()

View file

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

View file

@ -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?

View file

@ -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;
}

View file

@ -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:

View file

@ -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)

View file

@ -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;