1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 09:44:02 +00:00
Aquaria/BBGE/ActionInput.cpp
2020-07-07 22:30:25 +02:00

332 lines
7.5 KiB
C++

/*
Copyright (C) 2007, 2010 - Bit-Blot
This file is part of Aquaria.
Aquaria is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "ActionInput.h"
#include "ActionMapper.h"
#include "Core.h"
#include "SDL.h"
#include "GameKeyNames.h"
#include "StringBank.h"
static std::string inputcode2string(int k)
{
if(k <= 0)
return std::string();
if(k < KEY_MAXARRAY)
{
// Returns KEY_* or NULL
const std::string& str = getKeyNameFromInputCode(k);
if(str.length())
return str;
// fallback
std::ostringstream os;
os << "K:" << k;
return os.str();
}
if(k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
{
std::ostringstream os;
os << "JB:" << (k - JOY_BUTTON_0);
return os.str();
}
if(k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS)
{
std::ostringstream os;
os << "AX:+" << (k - JOY_AXIS_0_POS);
return os.str();
}
if(k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG)
{
std::ostringstream os;
os << "AX:-" << (k - JOY_AXIS_0_NEG);
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:
return "LMB";
case MOUSE_BUTTON_RIGHT:
return "RMB";
case MOUSE_BUTTON_MIDDLE:
return "MMB";
default:
if(k >= MOUSE_BUTTON_EXTRA_START && k < MOUSE_BUTTON_EXTRA_START+mouseExtraButtons)
{
std::ostringstream os;
os << "MB:" << (k - MOUSE_BUTTON_LEFT);
return os.str();
}
}
return std::string();
}
static const char *jaxisname(int joystickID, int axis)
{
Joystick *j = core->getJoystick(joystickID);
return j ? j->getAxisName(axis) : NULL;
}
static const char *jbtnname(int joystickID, int btn)
{
Joystick *j = core->getJoystick(joystickID);
return j ? j->getButtonName(btn) : NULL;
}
std::string getInputCodeToString(int k)
{
std::string s = inputcode2string(k);
return s.empty() ? "0" : s;
}
std::string getInputCodeToUserString(unsigned int k, size_t joystickID)
{
const char *pretty = NULL, *tail = NULL;
// Special case keyboard input:
// Return key name for current keyboard layout!
// It's just confusing to see Y instead of Z with a german keyboard layout...
if(k && k < KEY_MAXARRAY)
{
#ifdef BBGE_BUILD_SDL2
pretty = SDL_GetScancodeName((SDL_Scancode)k);
const SDL_Keycode kcode = SDL_GetKeyFromScancode((SDL_Scancode)k);
if(kcode != SDLK_UNKNOWN)
pretty = SDL_GetKeyName(kcode);
#else
pretty = SDL_GetKeyName((SDLKey)k);
#endif
}
if(k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS)
{
pretty = jaxisname(joystickID, k - JOY_AXIS_0_POS);
tail = "(+)";
}
else if(k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG)
{
pretty = jaxisname(joystickID, k - JOY_AXIS_0_NEG);
tail = "(-)";
}
else if(k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
pretty = jbtnname(joystickID, k - JOY_BUTTON_0);
std::string s;
if(pretty && *pretty)
{
s = pretty;
if(tail)
s += tail;
return s;
}
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;
}
static int checkInp(const char *s, int category, int limit, StringBankIndexBBGE errid)
{
const int k = atoi(s);
if(!k)
return 0;
if(k < limit)
return k + category;
std::ostringstream os;
os << stringbank.get(errid) << k;
errorLog(os.str());
return 0;
}
int getStringToInputCode(const std::string& s)
{
int k = 0;
if(s == "LMB")
k = MOUSE_BUTTON_LEFT;
else if(s == "RMB")
k = MOUSE_BUTTON_RIGHT;
else if(s == "MMB")
k = MOUSE_BUTTON_MIDDLE;
else if(!strncmp(s.c_str(), "K:", 2))
k = checkInp(s.c_str() + 2, 0, KEY_MAXARRAY, SB_BBGE_INVALID_KEY_ID);
else if(!strncmp(s.c_str(), "JB:", 3))
k = checkInp(s.c_str() + 3, JOY_BUTTON_0, JOY_BUTTON_END, SB_BBGE_INVALID_JOY_BTN);
else if(!strncmp(s.c_str(), "MB:", 3))
k = checkInp(s.c_str() + 3, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_EXTRA_END, SB_BBGE_INVALID_MOUSE_BTN);
else if(s.length() > 4 && !strncmp(s.c_str(), "AX:", 3))
{
switch(s[3])
{
case '+':
k = checkInp(s.c_str() + 4, JOY_AXIS_0_POS, JOY_AXIS_END_POS, SB_BBGE_INVALID_JOY_AXIS_POS);
break;
case '-':
k = checkInp(s.c_str() + 4, JOY_AXIS_0_NEG, JOY_AXIS_END_NEG, SB_BBGE_INVALID_JOY_AXIS_NEG);
break;
default:
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?
// This handles KEY_* and some old mouse/joystick names.
k = getInputCodeFromKeyName(s.c_str());
}
// Non-configurable keys
if(k == KEY_ESCAPE)
return 0;
if(k < ACTION_BUTTON_ENUM_SIZE)
return k;
std::ostringstream os;
os << "ActionButton out of range: [" << s << "] = " << k;
errorLog(os.str());
return 0;
}
ActionInput::ActionInput()
{
for (int i = 0; i < INP_COMBINED_SIZE; i++)
data.all[i] = 0;
}
std::string ActionInput::toString() const
{
std::ostringstream os;
for (int i = 0; i < INP_MSESIZE; i++)
{
os << getInputCodeToString(data.single.mse[i]) << " ";
}
for (int i = 0; i < INP_KEYSIZE; i++)
{
os << getInputCodeToString(data.single.key[i]) << " ";
}
for (int i = 0; i < INP_JOYSIZE; i++)
{
os << getInputCodeToString(data.single.joy[i]) << " ";
}
return os.str();
}
void ActionInput::fromString(const std::string &read)
{
std::istringstream is(read);
std::string str;
for (int i = 0; i < INP_MSESIZE; i++)
{
is >> str;
data.single.mse[i] = getStringToInputCode(str);
}
for (int i = 0; i < INP_KEYSIZE; i++)
{
is >> str;
data.single.key[i] = getStringToInputCode(str);
}
for (int i = 0; i < INP_JOYSIZE; i++)
{
is >> str;
data.single.joy[i] = getStringToInputCode(str);
}
}