1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-05-09 18:43:48 +00:00

Getting closer to mutliple inputs actually working

Split logic and state from ActionMapper into another class,
of which one exists per input set.
This commit is contained in:
fgenesis 2016-07-17 22:25:24 +02:00
parent dcf09343b5
commit c943759ce1
16 changed files with 309 additions and 186 deletions

View file

@ -223,8 +223,6 @@ DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir)
for (int i = 0; i < 16; i++)
firstElementOnLayer[i] = 0;
pActionSets = &user.control.actionSets;
}
DSQ::~DSQ()
@ -4597,4 +4595,29 @@ void DSQ::fixupJoysticks()
ActionSet& as = user.control.actionSets[i];
as.updateJoystick();
}
// HACK: why here? kinda dirty, but the joystick ID needs to be propagated
importActionButtons();
}
void DSQ::initActionButtons()
{
clearActionButtons();
for(size_t i = 0; i < user.control.actionSets.size(); ++i)
actionStatus.push_back(new ActionButtonStatus);
importActionButtons();
}
void DSQ::importActionButtons()
{
assert(user.control.actionSets.size() == actionStatus.size());
for(size_t i = 0; i < actionStatus.size(); ++i)
{
const ActionSet& as = user.control.actionSets[i];
ActionButtonStatus *abs = actionStatus[i];
abs->import(as);
}
}

View file

@ -557,6 +557,10 @@ protected:
void fixupJoysticks();
virtual void onJoystickAdded(int deviceID);
virtual void onJoystickRemoved(int instanceID);
public:
void initActionButtons();
void importActionButtons();
};
extern DSQ *dsq;

View file

@ -2528,6 +2528,11 @@ float Game::getHalfTimer(float mod)
void Game::action(int id, int state, int source)
{
{
std::ostringstream os;
os << "Game:action " << id << ", " << state << ", " << source;
debugLog(os.str());
}
for (int i = 0; i < paths.size(); i++)
{
if (paths[i]->catchActions)

View file

@ -49,6 +49,7 @@ extern "C"
#include "Beam.h"
#include "Hair.h"
#include "Spore.h"
#include "Shader.h"
#include "../BBGE/MathFunctions.h"
@ -4972,7 +4973,7 @@ luaFunc(isLeftMouse)
{
int source = lua_tointeger(L, 1) - 1;
bool isDown = (source < 0 && core->mouse.buttons.left)
|| (dsq->game->avatar && dsq->game->avatar->pollAction(ACTION_PRIMARY, source));
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_PRIMARY, source));
luaReturnBool(isDown);
}
@ -4980,7 +4981,7 @@ luaFunc(isRightMouse)
{
int source = lua_tointeger(L, 1) - 1;
bool isDown = (source < 0 && core->mouse.buttons.right)
|| (dsq->game->avatar && dsq->game->avatar->pollAction(ACTION_SECONDARY, source));
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_SECONDARY, source));
luaReturnBool(isDown);
}

View file

@ -598,6 +598,8 @@ void UserSettings::apply()
as.updateJoystick();
}
dsq->initActionButtons();
core->debugLogActive = system.debugLogOn;
if (dsq->game)

View file

@ -23,10 +23,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <string>
#define INP_MSESIZE 1
#define INP_KEYSIZE 2
#define INP_JOYSIZE 1
enum ActionInputSize
{
INP_MSESIZE = 1,
INP_KEYSIZE = 2,
INP_JOYSIZE = 1,
INP_COMBINED_SIZE = INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE
};
std::string getInputCodeToString(int k);
std::string getInputCodeToUserString(int k, int joystickID);
@ -39,9 +42,16 @@ public:
std::string name;
int mse[INP_MSESIZE];
int key[INP_KEYSIZE];
int joy[INP_JOYSIZE];
union
{
struct
{
int mse[INP_MSESIZE];
int key[INP_KEYSIZE];
int joy[INP_JOYSIZE];
};
int all[INP_COMBINED_SIZE];
};
inline bool hasMouse(int actionID) const { return _has(mse, actionID); }
inline bool hasKey(int actionID) const { return _has(key, actionID); }

View file

@ -24,6 +24,7 @@ ActionMapper::ActionMapper()
cleared = false;
inputEnabled = true;
inUpdate = false;
//memset(keyStatus, 0, sizeof(keyStatus));
}
ActionMapper::~ActionMapper()
@ -50,7 +51,7 @@ bool ActionMapper::isActing(int actionID, int source)
ActionData& ad = *i;
if(ad.id == actionID)
for (ButtonList::iterator ii = ad.buttonList.begin(); ii != ad.buttonList.end(); ++ii)
if (keyDownMap[*ii])
if (getKeyState(*ii, source))
return true;
}
return false;
@ -62,7 +63,7 @@ bool ActionMapper::isActing(int actionID, int source)
ButtonList::iterator i = ad->buttonList.begin();
for (; i != ad->buttonList.end(); i++)
{
if (keyDownMap[(*i)])
if (getKeyState(*i, source))
return true;
}
}
@ -86,7 +87,7 @@ void ActionMapper::addAction(int actionID, int k, int source)
{
if(std::find(ad->buttonList.begin(), ad->buttonList.end(), k) == ad->buttonList.end())
ad->buttonList.push_back(k);
keyDownMap[k] = core->getKeyState(k);
//keyStatus[k] = core->getKeyState(k);
}
}
@ -98,7 +99,7 @@ void ActionMapper::addAction(Event *event, int k, int state)
data.buttonList.push_back(k);
actionData.push_back(data);
keyDownMap[k] = core->getKeyState(k);
//keyStatus[k] = core->getKeyState(k);
}
Event* ActionMapper::addCreatedEvent(Event *event)
@ -131,6 +132,7 @@ void ActionMapper::disableInput()
inputEnabled = false;
}
/*
bool ActionMapper::pollAction(int actionID, int source)
{
if(source < 0)
@ -153,160 +155,34 @@ bool ActionMapper::_pollActionData(const ActionData& ad)
return true;
return false;
}
bool ActionMapper::getKeyState(int k)
{
if(!k)
return false;
bool keyState = false;
if (k >= 0 && k < KEY_MAXARRAY)
{
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_START+mouseExtraButtons)
{
keyState = core->mouse.buttons.extra[k - MOUSE_BUTTON_EXTRA_START];
}
else if (k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
{
int v = k - JOY_BUTTON_0;
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
if(Joystick *j = core->getJoystick(i))
if(j->isEnabled())
if( ((keyState = j->getButton(v))) )
break;
}
else if (k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS)
{
int v = k - JOY_AXIS_0_POS;
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
if(Joystick *j = core->getJoystick(i))
if(j->isEnabled())
{
float ax = j->getAxisUncalibrated(v);
keyState = ax > JOY_AXIS_THRESHOLD;
if(keyState)
break;
}
}
else if (k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG)
{
int v = k - JOY_AXIS_0_NEG;
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
if(Joystick *j = core->getJoystick(i))
if(j->isEnabled())
{
float ax = j->getAxisUncalibrated(v);
keyState = ax < -JOY_AXIS_THRESHOLD;
if(keyState)
break;
}
}
return keyState;
}
bool ActionMapper::getKeyState(int k, int source)
{
if(!k)
return false;
ActionSet& as = (*core->pActionSets)[source];
bool keyState = false;
if (k >= 0 && k < KEY_MAXARRAY)
{
keyState = core->getKeyState(k) && as.hasKey(k);
}
else if (k == MOUSE_BUTTON_LEFT)
{
keyState = core->mouse.buttons.left == DOWN && as.hasMouse(k);
}
else if (k == MOUSE_BUTTON_RIGHT)
{
keyState = core->mouse.buttons.right == DOWN && as.hasMouse(k);
}
else if (k == MOUSE_BUTTON_MIDDLE)
{
keyState = core->mouse.buttons.middle == DOWN && as.hasMouse(k);
}
else if (k >= MOUSE_BUTTON_EXTRA_START && k < MOUSE_BUTTON_EXTRA_START+mouseExtraButtons)
{
keyState = core->mouse.buttons.extra[k - MOUSE_BUTTON_EXTRA_START] && as.hasMouse(k);
}
else if (k >= JOY_BUTTON_0 && k < JOY_BUTTON_END)
{
Joystick *j = core->getJoystick(as.joystickID);
if(j && j->isEnabled())
keyState = j->getButton( - JOY_BUTTON_0);
}
else if (k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS)
{
Joystick *j = core->getJoystick(as.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(as.joystickID);
if(j && j->isEnabled())
{
float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_NEG);
keyState = ax < -JOY_AXIS_THRESHOLD;
}
}
return keyState;
}
*/
void ActionMapper::onUpdate (float dt)
{
if (inUpdate) return;
inUpdate = true;
if (inUpdate)
return;
if (cleared) cleared = false;
ActionDataSet::iterator i;
KeyDownMap oldKeyDownMap = keyDownMap;
for (i = actionData.begin(); i != actionData.end(); ++i)
inUpdate = true;
cleared = false;
for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i)
{
ButtonList::iterator j;
j = i->buttonList.begin();
for (; j != i->buttonList.end(); j++)
{
int k = (*j);
ActionData *ad = &(*i);
int keyState = ad->source < 0
? getKeyState(k) // any source goes
: getKeyState(k, ad->source); // specific source
const int k = (*j);
const ActionData *ad = &(*i);
const bool keyChanged = isKeyChanged(k, ad->source);
if (keyState != oldKeyDownMap[k])
if (keyChanged)
{
keyDownMap[k] = keyState;
bool keyState = getKeyState(k, ad->source);
if (inputEnabled)
{
if (ad->event)
{
if (ad->state==-1 || keyState == ad->state)
if (ad->state==-1 || keyState == !!ad->state)
{
ad->event->act();
}
@ -324,12 +200,42 @@ void ActionMapper::onUpdate (float dt)
out:
inUpdate = false;
}
bool ActionMapper::getKeyState(int k, int sourceID)
{
if(sourceID < 0)
return getKeyState(k);
return core->getActionStatus()[sourceID]->getKeyState(k);
}
bool ActionMapper::getKeyState(int k)
{
const std::vector<ActionButtonStatus*>& absv = core->getActionStatus();
for(size_t i = 0; i < absv.size(); ++i)
if(absv[i]->getKeyState(k))
return true;
return false;
}
void ActionMapper::clearActions()
{
cleared = true;
keyDownMap.clear();
actionData.clear();
}
bool ActionMapper::isKeyChanged(int k, int sourceID)
{
if(sourceID < 0)
return isKeyChanged(k);
return core->getActionStatus()[sourceID]->isKeyChanged(k);
}
bool ActionMapper::isKeyChanged(int k)
{
const std::vector<ActionButtonStatus*>& absv = core->getActionStatus();
for(size_t i = 0; i < absv.size(); ++i)
if(absv[i]->isKeyChanged(k))
return true;
return false;
}

View file

@ -28,6 +28,7 @@ class ActionMapper;
#include <map>
#include <list>
#include "ActionStatus.h"
#include "ActionSet.h"
#include "Joystick.h"
@ -46,23 +47,6 @@ struct ActionData
ButtonList buttonList;
};
enum ActionButtonType
{
// must start at > 512 (SDL scancodes end there)
MOUSE_BUTTON_LEFT = 1000,
MOUSE_BUTTON_RIGHT = 1001,
MOUSE_BUTTON_MIDDLE = 1002,
MOUSE_BUTTON_EXTRA_START = 1003,
JOY_BUTTON_0 = 2000,
JOY_BUTTON_END = JOY_BUTTON_0 + MAX_JOYSTICK_BTN, // one past end
JOY_AXIS_0_POS = 3000,
JOY_AXIS_0_NEG = 3100,
JOY_AXIS_END_POS = JOY_AXIS_0_POS + MAX_JOYSTICK_AXIS,
JOY_AXIS_END_NEG = JOY_AXIS_0_NEG + MAX_JOYSTICK_AXIS,
};
class ActionMapper
{
public:
@ -87,9 +71,6 @@ public:
typedef std::vector<ActionData> ActionDataSet;
ActionDataSet actionData;
typedef std::map <int, int> KeyDownMap;
KeyDownMap keyDownMap;
bool cleared;
virtual void enableInput();
@ -98,7 +79,7 @@ public:
Event *addCreatedEvent(Event *event);
void clearCreatedEvents();
bool pollAction(int actionID, int source);
//bool pollAction(int actionID, int source);
bool getKeyState(int k);
bool getKeyState(int k, int sourceID);
@ -111,7 +92,9 @@ protected:
bool inputEnabled;
void onUpdate (float dt);
private:
bool _pollActionData(const ActionData& ad);
bool isKeyChanged(int k);
bool isKeyChanged(int k, int sourceID);
//bool _pollActionData(const ActionData& ad);
};
#endif

103
BBGE/ActionStatus.cpp Normal file
View file

@ -0,0 +1,103 @@
#include "ActionStatus.h"
#include "Core.h"
#include "ActionSet.h"
ActionButtonStatus::ActionButtonStatus()
: joystickID(-1)
{
memset(status, 0, sizeof(status));
memset(changed, 0, sizeof(changed));
}
void ActionButtonStatus::import(const ActionSet& as)
{
joystickID = as.joystickID;
unsigned char found[ACTION_BUTTON_ENUM_SIZE];
memset(found, 0, sizeof(found));
for(size_t i = 0; i < as.inputSet.size(); ++i)
{
const ActionInput& inp = as.inputSet[i];
for(int j = 0; j < INP_COMBINED_SIZE; ++j)
found[inp.all[j]] = 1;
}
toQuery.clear();
for(int k = 1; k < sizeof(found); ++k) // ignore [0]
if(found[k])
toQuery.push_back(k);
update();
}
void ActionButtonStatus::update()
{
_queryAllStatus();
}
void ActionButtonStatus::_queryAllStatus()
{
//memset(status, 0, sizeof(status));
//memset(changed, 0, sizeof(changed));
// k==0 is always 0
//for(size_t i = 0; i < toQuery.size(); ++i)
for(int k = 1; k < ACTION_BUTTON_ENUM_SIZE; ++k)
{
//const int k = toQuery[i];
bool state = _queryStatus(k);
changed[k] = !!status[k] != state;
status[k] = state;
}
}
bool ActionButtonStatus::_queryStatus(int k) const
{
bool keyState = false;
if (k > 0 && k < KEY_MAXARRAY)
{
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;
}
}
return keyState;
}

53
BBGE/ActionStatus.h Normal file
View file

@ -0,0 +1,53 @@
#ifndef ACTIONSTATUS_H
#define ACTIONSTATUS_H
#include "GameKeys.h"
#include "Joystick.h"
class ActionSet;
const unsigned mouseExtraButtons = 8;
enum ActionButtonType
{
MOUSE_BUTTON_LEFT = KEY_MAXARRAY + 1,
MOUSE_BUTTON_RIGHT,
MOUSE_BUTTON_MIDDLE,
MOUSE_BUTTON_EXTRA_START,
MOUSE_BUTTON_EXTRA_END = MOUSE_BUTTON_EXTRA_START + mouseExtraButtons,
JOY_BUTTON_0 = MOUSE_BUTTON_EXTRA_END,
JOY_BUTTON_END = JOY_BUTTON_0 + MAX_JOYSTICK_BTN,
JOY_AXIS_0_POS = JOY_BUTTON_END,
JOY_AXIS_END_POS = JOY_AXIS_0_POS + MAX_JOYSTICK_AXIS,
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
};
class ActionButtonStatus
{
public:
ActionButtonStatus();
void update();
inline bool getKeyState(int k) const { return !!status[k]; }
inline bool isKeyChanged(int k) { return !!changed[k]; }
void import(const ActionSet& as);
inline const std::vector<int>& getToQuery() const {return toQuery; }
inline int getJoystickID() const { return joystickID; }
private:
void _queryAllStatus();
bool _queryStatus(int k) const;
int joystickID;
unsigned char status[ACTION_BUTTON_ENUM_SIZE];
unsigned char changed[ACTION_BUTTON_ENUM_SIZE];
std::vector<int> toQuery;
};
#endif

View file

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "AfterEffect.h"
#include "RenderBase.h"
#include "Shader.h"
#include <assert.h>

View file

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Core.h"
class Shader;
class Effect
{

View file

@ -399,7 +399,6 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n
afterEffectManager = 0;
loopDone = false;
core = this;
pActionSets = NULL;
for (int i = 0; i < KEY_MAXARRAY; i++)
{
@ -496,6 +495,8 @@ std::string Core::getUserDataFolder()
Core::~Core()
{
clearActionButtons();
if (particleManager)
{
delete particleManager;
@ -694,6 +695,9 @@ void Core::onUpdate(float dt)
onMouseInput();
// all input done; update button states
updateActionButtons();
globalScale.update(dt);
core->globalScaleChanged();
@ -3041,3 +3045,23 @@ Joystick *Core::getJoystick(int idx)
size_t i = idx;
return i < joysticks.size() ? joysticks[i] : NULL;
}
void Core::updateActionButtons()
{
for(size_t i = 0; i < actionStatus.size(); ++i)
actionStatus[i]->update();
}
void Core::clearActionButtons()
{
for(size_t i = 0; i < actionStatus.size(); ++i)
delete actionStatus[i];
actionStatus.clear();
}
Joystick *Core::getJoystickForSourceID(unsigned sourceID)
{
if(sourceID < (unsigned)actionStatus.size())
return getJoystick(actionStatus[sourceID]->getJoystickID());
return NULL;
}

View file

@ -24,7 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Base.h"
#include "RenderObject.h"
#include "SoundManager.h"
#include "ActionMapper.h"
#include "Event.h"
#include "StateManager.h"
#include "Effects.h"
@ -32,9 +31,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "DarkLayer.h"
#include "FrameBuffer.h"
#include "Shader.h"
#include "GameKeys.h"
@ -76,8 +72,6 @@ const int baseVirtualHeight = 600;
enum ButtonState { UP = 0, DOWN };
const unsigned mouseExtraButtons = 8;
struct MouseButtons
{
MouseButtons ()
@ -557,13 +551,17 @@ protected:
void setupFileAccess();
std::string _extraDataDir;
public:
std::vector<ActionButtonStatus*> actionStatus;
void updateActionButtons();
void clearActionButtons();
std::vector<ActionSet> *pActionSets;
public:
inline const std::vector<ActionButtonStatus*>& getActionStatus() { return actionStatus; }
Joystick *getJoystick(int idx); // warning: may return NULL/contain holes
// not the actual number of joysticks!
size_t getNumJoysticks() const { return joysticks.size(); }
Joystick *getJoystickForSourceID(unsigned sourceID);
private:
std::vector<Joystick*> joysticks;
};

View file

@ -470,6 +470,7 @@ SET(BBGE_SRCS
${BBGEDIR}/ActionInput.cpp
${BBGEDIR}/ActionMapper.cpp
${BBGEDIR}/ActionSet.cpp
${BBGEDIR}/ActionStatus.cpp
${BBGEDIR}/AfterEffect.cpp
${BBGEDIR}/Base.cpp
${BBGEDIR}/BitmapFont.cpp

View file

@ -192,6 +192,14 @@
RelativePath="..\..\BBGE\ActionSet.h"
>
</File>
<File
RelativePath="..\..\BBGE\ActionStatus.cpp"
>
</File>
<File
RelativePath="..\..\BBGE\ActionStatus.h"
>
</File>
<File
RelativePath="..\..\BBGE\AfterEffect.cpp"
>