mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-06-08 01:22:02 +00:00
wip replacing input handling system; compiles and runs but is broken
This commit is contained in:
parent
36059deae0
commit
af711f00b5
55 changed files with 1984 additions and 2074 deletions
|
@ -291,10 +291,10 @@ void AnimationEditor::applyState()
|
|||
|
||||
|
||||
|
||||
addAction(ACTION_SWIMLEFT, KEY_J, -1);
|
||||
addAction(ACTION_SWIMRIGHT, KEY_K, -1);
|
||||
addAction(ACTION_SWIMUP, KEY_UP, -1);
|
||||
addAction(ACTION_SWIMDOWN, KEY_DOWN, -1);
|
||||
addAction(ACTION_SWIMLEFT, KEY_J);
|
||||
addAction(ACTION_SWIMRIGHT, KEY_K);
|
||||
addAction(ACTION_SWIMUP, KEY_UP);
|
||||
addAction(ACTION_SWIMDOWN, KEY_DOWN);
|
||||
|
||||
|
||||
|
||||
|
@ -537,7 +537,7 @@ void AnimationEditor::redo()
|
|||
}
|
||||
}
|
||||
|
||||
void AnimationEditor::action(int id, int state, int source, InputDevice device)
|
||||
void AnimationEditor::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if (editingBone && state)
|
||||
{
|
||||
|
@ -726,14 +726,14 @@ void AnimationEditor::update(float dt)
|
|||
|
||||
if (editingStrip)
|
||||
{
|
||||
if (isActing(ACTION_SWIMLEFT, -1))
|
||||
if (isActing(ACTION_SWIMLEFT))
|
||||
moveBoneStripPoint(Vector(-dt, 0));
|
||||
if (isActing(ACTION_SWIMRIGHT, -1))
|
||||
if (isActing(ACTION_SWIMRIGHT))
|
||||
moveBoneStripPoint(Vector(dt, 0));
|
||||
|
||||
if (isActing(ACTION_SWIMUP, -1))
|
||||
if (isActing(ACTION_SWIMUP))
|
||||
moveBoneStripPoint(Vector(0, -dt));
|
||||
if (isActing(ACTION_SWIMDOWN, -1))
|
||||
if (isActing(ACTION_SWIMDOWN))
|
||||
moveBoneStripPoint(Vector(0, dt));
|
||||
}
|
||||
int spd = 1;
|
||||
|
|
|
@ -113,7 +113,7 @@ public:
|
|||
|
||||
std::vector<KeyframeWidget*> keyframeWidgets;
|
||||
|
||||
void action(int id, int state, int source, InputDevice device);
|
||||
void action(int id, int state, int source, InputDeviceType device);
|
||||
|
||||
void rebuildKeyframeWidgets();
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void AquariaGuiElement::setFocus(bool v)
|
|||
if (v)
|
||||
{
|
||||
currentFocus = this;
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK || dsq->getInputMode() == INPUT_KEYBOARD)
|
||||
if (dsq->getInputMode() == INP_DEV_JOYSTICK || dsq->getInputMode() == INP_DEV_KEYBOARD)
|
||||
core->setMousePosition(getGuiPosition());
|
||||
|
||||
AquariaGuiElement *gui=0, *guiThis = (AquariaGuiElement*)this;
|
||||
|
@ -162,49 +162,13 @@ void AquariaGuiElement::UpdateGlobalFocus(float dt)
|
|||
Direction AquariaGuiElement::GetDirection()
|
||||
{
|
||||
Direction dir = DIR_NONE;
|
||||
|
||||
// This joystick code is already supposed to send ACTION_MENU*.
|
||||
// Actually some places depend on the actions to be sent,
|
||||
// So checking this here might work for a few cases,
|
||||
// but others will break.
|
||||
// I'll leave this in here for now -- fg
|
||||
/*Vector p;
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled())
|
||||
{
|
||||
p = core->getJoystick(i)->position;
|
||||
if(!p.isLength2DIn(0.4f))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!p.isLength2DIn(0.4f))
|
||||
StateObject *obj = dsq->getTopStateObject(); // usually Game...
|
||||
if (obj)
|
||||
{
|
||||
if (fabsf(p.x) > fabsf(p.y))
|
||||
{
|
||||
if (p.x > 0)
|
||||
dir = DIR_RIGHT;
|
||||
else
|
||||
dir = DIR_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.y > 0)
|
||||
dir = DIR_DOWN;
|
||||
else
|
||||
dir = DIR_UP;
|
||||
}
|
||||
}
|
||||
else*/
|
||||
{
|
||||
StateObject *obj = dsq->getTopStateObject(); // usually Game...
|
||||
if (obj)
|
||||
{
|
||||
if (obj->isActing(ACTION_MENULEFT, -1)) dir = DIR_LEFT;
|
||||
else if (obj->isActing(ACTION_MENURIGHT, -1)) dir = DIR_RIGHT;
|
||||
else if (obj->isActing(ACTION_MENUUP, -1)) dir = DIR_UP;
|
||||
else if (obj->isActing(ACTION_MENUDOWN, -1)) dir = DIR_DOWN;
|
||||
}
|
||||
if (obj->isActing(ACTION_MENULEFT)) dir = DIR_LEFT;
|
||||
else if (obj->isActing(ACTION_MENURIGHT)) dir = DIR_RIGHT;
|
||||
else if (obj->isActing(ACTION_MENUUP)) dir = DIR_UP;
|
||||
else if (obj->isActing(ACTION_MENUDOWN)) dir = DIR_DOWN;
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
@ -343,9 +307,6 @@ void AquariaGuiQuad::onUpdate(float dt)
|
|||
Quad::onUpdate(dt);
|
||||
}
|
||||
|
||||
// Joystick input threshold at which we start sliding (0.0-1.0); must be
|
||||
// less than updateMovement() threshold.
|
||||
const float SLIDER_JOY_THRESHOLD = 0.39f;
|
||||
// Initial delay before repeating for slider input (seconds).
|
||||
const float SLIDER_REPEAT_DELAY = 0.4f;
|
||||
// Scale factor for delay as repeats continue.
|
||||
|
@ -382,26 +343,10 @@ bool AquariaSlider::doSliderInput(float dt)
|
|||
|
||||
float inputAmount; // How much to adjust by?
|
||||
|
||||
// disabled the jaxis threshold check;
|
||||
// ACTION_MENU* should be sent automatically when above the threshold -- fg
|
||||
/*Vector jpos;
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled())
|
||||
{
|
||||
jpos = core->getJoystick(i)->position;
|
||||
if(fabsf(jpos.x) > SLIDER_JOY_THRESHOLD)
|
||||
break;
|
||||
}*/
|
||||
|
||||
StateObject *obj = dsq->getTopStateObject();
|
||||
/*if (jpos.x <= -SLIDER_JOY_THRESHOLD)
|
||||
if (obj && obj->isActing(ACTION_MENULEFT))
|
||||
inputAmount = -0.1f;
|
||||
else if (jpos.x >= SLIDER_JOY_THRESHOLD)
|
||||
inputAmount = +0.1f;
|
||||
else*/ if (obj && obj->isActing(ACTION_MENULEFT, -1))
|
||||
inputAmount = -0.1f;
|
||||
else if (obj && obj->isActing(ACTION_MENURIGHT, -1))
|
||||
else if (obj && obj->isActing(ACTION_MENURIGHT))
|
||||
inputAmount = +0.1f;
|
||||
else
|
||||
inputAmount = 0;
|
||||
|
@ -484,27 +429,81 @@ bool AquariaCheckBox::isGuiVisible()
|
|||
|
||||
AquariaKeyConfig *AquariaKeyConfig::waitingForInput = 0;
|
||||
|
||||
enum KeyMapResult
|
||||
{
|
||||
KMR_NONE,
|
||||
KMR_ASSIGNED,
|
||||
KMR_CLEARED,
|
||||
KMR_CANCELLED
|
||||
};
|
||||
|
||||
AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputSetType inputSetType, int inputIdx)
|
||||
// created on the stack while waiting for keys to be pressed
|
||||
class InputSniffer : public IInputMapper
|
||||
{
|
||||
public:
|
||||
InputSniffer(InputDeviceType dev) : _dev(dev), _res(KMR_NONE) {}
|
||||
|
||||
virtual void input(const RawInput *inp)
|
||||
{
|
||||
if(_res != KMR_NONE)
|
||||
return;
|
||||
|
||||
if(inp->src.deviceType == INP_DEV_KEYBOARD && inp->src.ctrlType == INP_CTRL_BUTTON && inp->u.pressed)
|
||||
{
|
||||
switch(inp->src.ctrlID)
|
||||
{
|
||||
case KEY_ESCAPE: _res = KMR_CANCELLED; return;
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_DELETE: _res = KMR_CLEARED; return;
|
||||
}
|
||||
}
|
||||
// TODO controllerfixup: check if input is "interesting" enough
|
||||
if(inp->src.deviceType == _dev)
|
||||
{
|
||||
_res = KMR_ASSIGNED;
|
||||
stored = *inp;
|
||||
}
|
||||
}
|
||||
|
||||
KeyMapResult get(RawInput *inp) const
|
||||
{
|
||||
if(_res == KMR_ASSIGNED)
|
||||
*inp = stored;
|
||||
return _res;
|
||||
}
|
||||
|
||||
RawInput stored;
|
||||
InputDeviceType _dev;
|
||||
KeyMapResult _res;
|
||||
};
|
||||
|
||||
static KeyMapResult waitForInput(RawInput *raw, InputDeviceType dev)
|
||||
{
|
||||
InputSniffer sniff(dev);
|
||||
KeyMapResult km;
|
||||
for(;;)
|
||||
{
|
||||
km = sniff.get(raw);
|
||||
if(km != KMR_NONE)
|
||||
break;
|
||||
dsq->run(0.1f, true);
|
||||
}
|
||||
return km;
|
||||
}
|
||||
|
||||
AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputDeviceType dev, unsigned slot)
|
||||
: AquariaGuiElement(), RenderObject()
|
||||
, actionInputName(actionInputName)
|
||||
, inputSetType(inputSetType)
|
||||
, inputIdx(inputIdx)
|
||||
, inputDevType(dev)
|
||||
, inputSlot(slot)
|
||||
, inputField(ActionInput::GetField(dev, slot))
|
||||
, actionSetIndex(0)
|
||||
, rejectJoyAxis(false)
|
||||
{
|
||||
bg = new Quad();
|
||||
bg2 = new Quad();
|
||||
if (inputSetType == INPUTSET_OTHER)
|
||||
{
|
||||
bg->setWidthHeight(40, 20);
|
||||
bg2->setWidthHeight(40, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
bg->setWidthHeight(90, 20);
|
||||
bg2->setWidthHeight(90, 20);
|
||||
}
|
||||
bg->setWidthHeight(90, 20);
|
||||
bg2->setWidthHeight(90, 20);
|
||||
|
||||
bg->color = Vector(0.5f, 0.5f, 0.5f);
|
||||
bg->alphaMod = 0;
|
||||
|
@ -516,7 +515,6 @@ AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputSetT
|
|||
addChild(bg2, PM_POINTER);
|
||||
|
||||
|
||||
|
||||
keyConfigFont = new TTFText(&dsq->fontArialSmallest);
|
||||
|
||||
keyConfigFont->setAlign(ALIGN_CENTER);
|
||||
|
@ -589,342 +587,29 @@ void AquariaKeyConfig::onUpdate(float dt)
|
|||
|
||||
inLoop = true;
|
||||
|
||||
unsigned int *k = 0;
|
||||
ActionInput &ai = as.ensureActionInput(actionInputName);
|
||||
|
||||
ActionInput *ai = 0;
|
||||
|
||||
bool used = false;
|
||||
|
||||
if (inputSetType != INPUTSET_OTHER)
|
||||
{
|
||||
ai = as.getActionInputByName(actionInputName);
|
||||
|
||||
if (!ai)
|
||||
{
|
||||
exit_error("Could not find actionInput: " + actionInputName);
|
||||
}
|
||||
switch(inputSetType)
|
||||
{
|
||||
case INPUTSET_KEY:
|
||||
k = &ai->data.single.key[inputIdx];
|
||||
break;
|
||||
case INPUTSET_MOUSE:
|
||||
k = &ai->data.single.mse[inputIdx];
|
||||
break;
|
||||
case INPUTSET_JOY:
|
||||
k = &ai->data.single.joy[inputIdx];
|
||||
break;
|
||||
case INPUTSET_NONE:
|
||||
case INPUTSET_OTHER:
|
||||
k = 0;
|
||||
break;
|
||||
}
|
||||
used = k && *k;
|
||||
}
|
||||
|
||||
|
||||
if (inputSetType == INPUTSET_OTHER)
|
||||
{
|
||||
if (actionInputName == "s1ax")
|
||||
k = &as.joycfg.s1ax;
|
||||
else if (actionInputName == "s1ay")
|
||||
k = &as.joycfg.s1ay;
|
||||
else if (actionInputName == "s2ax")
|
||||
k = &as.joycfg.s2ax;
|
||||
else if (actionInputName == "s2ay")
|
||||
k = &as.joycfg.s2ay;
|
||||
used = k && int(*k) >= 0;
|
||||
}
|
||||
bool used = ai.hasEntry(inputSlot);
|
||||
|
||||
if(used)
|
||||
bg2->alphaMod = 0.3f;
|
||||
else
|
||||
bg2->alphaMod = 0;
|
||||
|
||||
if (waitingForInput == this)
|
||||
if (waitingForInput != this)
|
||||
keyConfigFont->setText(ai.prettyPrintField(inputField, as.joystickID));
|
||||
else
|
||||
{
|
||||
std::string s;
|
||||
s.reserve(6);
|
||||
s = "_";
|
||||
for (int i = 0; i < int(dsq->game->getTimer(5)); i++)
|
||||
const int tm = int(dsq->game->getTimer(5));
|
||||
for (int i = 0; i < tm; i++)
|
||||
{
|
||||
s += "_";
|
||||
}
|
||||
keyConfigFont->setText(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inputSetType != INPUTSET_OTHER)
|
||||
{
|
||||
keyConfigFont->setText(getInputCodeToUserString(*k, as.joystickID));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(*k >= 0)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << (*k);
|
||||
keyConfigFont->setText(os.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
keyConfigFont->setText(getInputCodeToUserString(0, as.joystickID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (waitingForInput == this)
|
||||
{
|
||||
switch(inputSetType)
|
||||
{
|
||||
case INPUTSET_OTHER:
|
||||
{
|
||||
if (k)
|
||||
{
|
||||
int ac = -1;
|
||||
bool clear = false;
|
||||
bool abort = false;
|
||||
for (int i = 0; i < KEY_MAXARRAY; i++)
|
||||
{
|
||||
if (core->getKeyState(i))
|
||||
{
|
||||
if(i == KEY_BACKSPACE || i == KEY_DELETE)
|
||||
clear = true;
|
||||
else if (i == KEY_ESCAPE)
|
||||
abort = true;
|
||||
else
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
#define K(k) case k: ac = i-k; break
|
||||
K(KEY_0);
|
||||
K(KEY_1);
|
||||
K(KEY_2);
|
||||
K(KEY_3);
|
||||
K(KEY_4);
|
||||
K(KEY_5);
|
||||
K(KEY_6);
|
||||
K(KEY_7);
|
||||
K(KEY_8);
|
||||
K(KEY_9);
|
||||
#undef K
|
||||
}
|
||||
}
|
||||
|
||||
while (dsq->game->getKeyState(i))
|
||||
{
|
||||
dsq->run(0.1f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ac < 0)
|
||||
{
|
||||
Joystick *j = core->getJoystick(as.joystickID);
|
||||
if(j)
|
||||
for(int i = 0; i < MAX_JOYSTICK_AXIS; ++i)
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(i);
|
||||
if(fabsf(ax) > JOY_AXIS_THRESHOLD)
|
||||
{
|
||||
ac = i;
|
||||
while (fabsf(j->getAxisUncalibrated(i)) > JOY_AXIS_THRESHOLD)
|
||||
dsq->run(0.1f, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ac >= 0 || abort || clear)
|
||||
{
|
||||
toggleEnterKey(0);
|
||||
waitingForInput = 0;
|
||||
AquariaGuiElement::canDirMoveGlobal = true;
|
||||
if(!abort)
|
||||
{
|
||||
if(clear || ac == *k)
|
||||
*k = -1;
|
||||
else
|
||||
*k = ac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INPUTSET_KEY:
|
||||
{
|
||||
for (int i = 0; i < KEY_MAXARRAY; i++)
|
||||
{
|
||||
if (core->getKeyState(i))
|
||||
{
|
||||
if(*k == i) // clear key if pressed again
|
||||
*k = 0;
|
||||
else if(i != KEY_ESCAPE)
|
||||
{
|
||||
if (i == KEY_DELETE || i == KEY_BACKSPACE)
|
||||
*k = 0;
|
||||
else
|
||||
*k = i;
|
||||
}
|
||||
|
||||
while (dsq->game->getKeyState(i))
|
||||
{
|
||||
dsq->run(0.1f, true);
|
||||
}
|
||||
|
||||
toggleEnterKey(0);
|
||||
waitingForInput = 0;
|
||||
AquariaGuiElement::canDirMoveGlobal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INPUTSET_MOUSE:
|
||||
{
|
||||
bool clear = false;
|
||||
bool abort = false;
|
||||
unsigned int ac = 0;
|
||||
if (core->getKeyState(KEY_DELETE) || core->getKeyState(KEY_BACKSPACE))
|
||||
{
|
||||
while(core->getKeyState(KEY_DELETE) || core->getKeyState(KEY_BACKSPACE))
|
||||
dsq->run(0.1f, true);
|
||||
clear = true;
|
||||
}
|
||||
else if(core->getKeyState(KEY_ESCAPE))
|
||||
{
|
||||
while(core->getKeyState(KEY_ESCAPE))
|
||||
dsq->run(0.1f, true);
|
||||
abort = true;
|
||||
}
|
||||
else if(dsq->mouse.rawButtonMask)
|
||||
{
|
||||
MouseButtons btns = dsq->mouse.buttons;
|
||||
|
||||
while(dsq->mouse.rawButtonMask)
|
||||
dsq->run(0.1f, true);
|
||||
|
||||
if(btns.left)
|
||||
ac = MOUSE_BUTTON_LEFT;
|
||||
else if(btns.right)
|
||||
ac = MOUSE_BUTTON_RIGHT;
|
||||
else if(btns.middle)
|
||||
ac = MOUSE_BUTTON_MIDDLE;
|
||||
else
|
||||
{
|
||||
for(unsigned i = 0; i < mouseExtraButtons; ++i)
|
||||
if(btns.extra[i])
|
||||
{
|
||||
ac = MOUSE_BUTTON_EXTRA_START+i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ac || clear || abort)
|
||||
{
|
||||
toggleEnterKey(0);
|
||||
waitingForInput = 0;
|
||||
AquariaGuiElement::canDirMoveGlobal = true;
|
||||
|
||||
if(!abort)
|
||||
{
|
||||
if(clear || *k == ac) // clear key if pressed again
|
||||
*k = 0;
|
||||
else
|
||||
*k = ac;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INPUTSET_JOY:
|
||||
{
|
||||
size_t ac = 0;
|
||||
bool clear = false;
|
||||
bool abort = false;
|
||||
if (core->getKeyState(KEY_DELETE) || core->getKeyState(KEY_BACKSPACE))
|
||||
{
|
||||
clear = true;
|
||||
}
|
||||
else if(core->getKeyState(KEY_ESCAPE))
|
||||
{
|
||||
abort = true;
|
||||
while(core->getKeyState(KEY_ESCAPE))
|
||||
dsq->run(0.1f, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Joystick *j = core->getJoystick(as.joystickID);
|
||||
if(j)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_JOYSTICK_BTN; i++)
|
||||
if (j->getButton(i))
|
||||
{
|
||||
ac = JOY_BUTTON_0 + i;
|
||||
while (j->getButton(i))
|
||||
dsq->run(0.1f, true); // skip recursion check; we're already in the menu so this would always warn
|
||||
break;
|
||||
}
|
||||
|
||||
if(!ac)
|
||||
for(size_t i = 0; i < MAX_JOYSTICK_AXIS; ++i)
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(i);
|
||||
if(fabsf(ax) > JOY_AXIS_THRESHOLD)
|
||||
{
|
||||
ac = (ax < 0.0f ? JOY_AXIS_0_NEG : JOY_AXIS_0_POS) + i;
|
||||
while (fabsf(j->getAxisUncalibrated(i)) > JOY_AXIS_THRESHOLD)
|
||||
dsq->run(0.1f, true);
|
||||
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;
|
||||
}
|
||||
|
||||
if(abort || ac || clear)
|
||||
{
|
||||
toggleEnterKey(0);
|
||||
waitingForInput = 0;
|
||||
AquariaGuiElement::canDirMoveGlobal = true;
|
||||
|
||||
if(rejectJoyAxis && (
|
||||
(ac >= JOY_AXIS_0_POS && ac < JOY_AXIS_END_POS)
|
||||
|| (ac >= JOY_AXIS_0_NEG && ac < JOY_AXIS_END_NEG)
|
||||
))
|
||||
{
|
||||
dsq->sound->playSfx("denied");
|
||||
abort = true;
|
||||
}
|
||||
|
||||
if(!abort)
|
||||
{
|
||||
if(clear || *k == ac) // clear key if pressed again
|
||||
*k = 0;
|
||||
else
|
||||
*k = ac;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INPUTSET_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Vector p = bg->getWorldPosition();
|
||||
|
||||
|
@ -938,7 +623,7 @@ void AquariaKeyConfig::onUpdate(float dt)
|
|||
toggleEnterKey(-1);
|
||||
}
|
||||
|
||||
|
||||
// FIXME controllerfixup: don't rely on mouse emulation here?
|
||||
if (!keyDown && (core->mouse.buttons.left || core->mouse.buttons.right))
|
||||
{
|
||||
keyDown = true;
|
||||
|
@ -958,6 +643,19 @@ void AquariaKeyConfig::onUpdate(float dt)
|
|||
waitingForInput = this;
|
||||
toggleEnterKey(1);
|
||||
AquariaGuiElement::canDirMoveGlobal = false;
|
||||
|
||||
RawInput raw;
|
||||
switch(waitForInput(&raw, inputDevType))
|
||||
{
|
||||
case KMR_ASSIGNED:
|
||||
ai.ImportField(raw, inputField);
|
||||
break;
|
||||
case KMR_CLEARED:
|
||||
ai.clearEntry(inputField);
|
||||
break;
|
||||
case KMR_CANCELLED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1218,7 +916,7 @@ void AquariaButton::goDown()
|
|||
buttonlabel->position = Vector(0, 7);
|
||||
}
|
||||
|
||||
void AquariaButton::action(int actionID, int state, int source, InputDevice device)
|
||||
void AquariaButton::action(int actionID, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if(actionID == ACTION_PRIMARY)
|
||||
{
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
bool useQuad(const std::string &tex);
|
||||
void useGlow(const std::string &tex, int w, int h);
|
||||
void useSound(const std::string &tex);
|
||||
virtual void action(int actionID, int state, int source, InputDevice device) {}
|
||||
virtual void action(int actionID, int state, int source, InputDeviceType device) {}
|
||||
|
||||
virtual bool isCursorInMenuItem();
|
||||
Vector getGuiPosition();
|
||||
|
@ -166,7 +166,8 @@ protected:
|
|||
class AquariaKeyConfig : public AquariaGuiElement, public RenderObject
|
||||
{
|
||||
public:
|
||||
AquariaKeyConfig(const std::string &actionInputName, InputSetType type, int idx);
|
||||
// field goes from 0 to INP_NUMFIELDS-1
|
||||
AquariaKeyConfig(const std::string &actionInputName, InputDeviceType type, unsigned field);
|
||||
void destroy();
|
||||
|
||||
Vector getGuiPosition();
|
||||
|
@ -186,8 +187,8 @@ protected:
|
|||
|
||||
|
||||
std::string actionInputName;
|
||||
InputSetType inputSetType;
|
||||
int inputIdx;
|
||||
const InputDeviceType inputDevType;
|
||||
const unsigned inputSlot, inputField;
|
||||
TTFText *keyConfigFont;
|
||||
Quad *bg, *bg2;
|
||||
size_t actionSetIndex;
|
||||
|
@ -267,7 +268,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
virtual void action(int actionID, int state, int source, InputDevice device);
|
||||
virtual void action(int actionID, int state, int source, InputDeviceType device);
|
||||
virtual void onUpdate(float dt);
|
||||
virtual void onToggleHighlight(bool on);
|
||||
|
||||
|
|
|
@ -128,34 +128,32 @@ void Avatar::bindInput()
|
|||
ActionMapper::clearActions();
|
||||
ActionMapper::clearCreatedEvents();
|
||||
|
||||
for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i)
|
||||
const NamedAction actions[] =
|
||||
{
|
||||
const ActionSet& as = dsq->user.control.actionSets[i];
|
||||
int sourceID = (int)i;
|
||||
{ "PrimaryAction", ACTION_PRIMARY},
|
||||
{ "SecondaryAction", ACTION_SECONDARY},
|
||||
|
||||
as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID);
|
||||
as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID);
|
||||
{ "SwimUp", ACTION_SWIMUP},
|
||||
{ "SwimDown", ACTION_SWIMDOWN},
|
||||
{ "SwimLeft", ACTION_SWIMLEFT},
|
||||
{ "SwimRight", ACTION_SWIMRIGHT},
|
||||
|
||||
as.importAction(this, "SwimUp", ACTION_SWIMUP, sourceID);
|
||||
as.importAction(this, "SwimDown", ACTION_SWIMDOWN, sourceID);
|
||||
as.importAction(this, "SwimLeft", ACTION_SWIMLEFT, sourceID);
|
||||
as.importAction(this, "SwimRight", ACTION_SWIMRIGHT, sourceID);
|
||||
{ "SongSlot1", ACTION_SONGSLOT1},
|
||||
{ "SongSlot2", ACTION_SONGSLOT2},
|
||||
{ "SongSlot3", ACTION_SONGSLOT3},
|
||||
{ "SongSlot4", ACTION_SONGSLOT4},
|
||||
{ "SongSlot5", ACTION_SONGSLOT5},
|
||||
{ "SongSlot6", ACTION_SONGSLOT6},
|
||||
{ "SongSlot7", ACTION_SONGSLOT7},
|
||||
{ "SongSlot8", ACTION_SONGSLOT8},
|
||||
{ "SongSlot9", ACTION_SONGSLOT9},
|
||||
{ "SongSlot10", ACTION_SONGSLOT10},
|
||||
|
||||
as.importAction(this, "SongSlot1", ACTION_SONGSLOT1, sourceID);
|
||||
as.importAction(this, "SongSlot2", ACTION_SONGSLOT2, sourceID);
|
||||
as.importAction(this, "SongSlot3", ACTION_SONGSLOT3, sourceID);
|
||||
as.importAction(this, "SongSlot4", ACTION_SONGSLOT4, sourceID);
|
||||
as.importAction(this, "SongSlot5", ACTION_SONGSLOT5, sourceID);
|
||||
as.importAction(this, "SongSlot6", ACTION_SONGSLOT6, sourceID);
|
||||
as.importAction(this, "SongSlot7", ACTION_SONGSLOT7, sourceID);
|
||||
as.importAction(this, "SongSlot8", ACTION_SONGSLOT8, sourceID);
|
||||
as.importAction(this, "SongSlot9", ACTION_SONGSLOT9, sourceID);
|
||||
as.importAction(this, "SongSlot10", ACTION_SONGSLOT10, sourceID);
|
||||
|
||||
as.importAction(this, "Revert", ACTION_REVERT, sourceID);
|
||||
as.importAction(this, "Look", ACTION_LOOK, sourceID);
|
||||
as.importAction(this, "Roll", ACTION_ROLL, sourceID);
|
||||
}
|
||||
{ "Revert", ACTION_REVERT},
|
||||
{ "Look", ACTION_LOOK},
|
||||
{ "Roll", ACTION_ROLL}
|
||||
};
|
||||
ImportInput(actions);
|
||||
}
|
||||
|
||||
// note: z is set to 1.0 when we want the aim to be used as the shot direction
|
||||
|
@ -163,31 +161,22 @@ void Avatar::bindInput()
|
|||
Vector Avatar::getAim()
|
||||
{
|
||||
Vector d;
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK)
|
||||
float z = 1;
|
||||
if (dsq->getInputMode() == INP_DEV_JOYSTICK)
|
||||
{
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled() && !j->rightStick.isZero())
|
||||
{
|
||||
d = j->rightStick * 300;
|
||||
d.z = 1;
|
||||
break;
|
||||
}
|
||||
d = dsq->playerInput.getStick2();
|
||||
|
||||
if(d.isZero())
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled() && !j->position.isZero())
|
||||
{
|
||||
d = j->position * 300;
|
||||
break;
|
||||
}
|
||||
{
|
||||
d = dsq->playerInput.getStick1();
|
||||
z = 0;
|
||||
}
|
||||
d *= 300;
|
||||
d.z = z;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = dsq->getGameCursorPosition() - position;
|
||||
d.z = 1;
|
||||
}
|
||||
d.z = z;
|
||||
|
||||
if (d.isZero())
|
||||
d = getForwardAim();
|
||||
|
@ -209,7 +198,7 @@ void Avatar::onAnimationKeyPassed(int key)
|
|||
Entity::onAnimationKeyPassed(key);
|
||||
}
|
||||
|
||||
Vector randCirclePos(Vector position, int radius)
|
||||
static Vector randCirclePos(Vector position, int radius)
|
||||
{
|
||||
float a = ((rand()%360)*(2*PI))/360.0f;
|
||||
return position + Vector(sinf(a), cosf(a))*radius;
|
||||
|
@ -1100,7 +1089,7 @@ void Avatar::onDamage(DamageData &d)
|
|||
if (healthWillBe<=0)
|
||||
t = 2;
|
||||
|
||||
dsq->rumble(d.damage, d.damage, 0.4f, _lastActionSourceID, _lastActionInputDevice);
|
||||
dsq->rumble(d.damage, d.damage, 0.4f);
|
||||
if (d.damage > 0)
|
||||
{
|
||||
//dsq->shakeCamera(5, t);
|
||||
|
@ -1312,12 +1301,12 @@ void Avatar::clearTargets()
|
|||
}
|
||||
}
|
||||
|
||||
void Avatar::openSingingInterface(InputDevice device)
|
||||
void Avatar::openSingingInterface(InputDeviceType device)
|
||||
{
|
||||
if (!singing && health > 0 && !isEntityDead() && !blockSinging)
|
||||
{
|
||||
//core->mouse.position = Vector(400,300);
|
||||
if (device != INPUT_MOUSE)
|
||||
if (device != INP_DEV_MOUSE)
|
||||
{
|
||||
core->centerMouse();
|
||||
//core->setMousePosition(Vector(400,300));
|
||||
|
@ -1340,7 +1329,7 @@ void Avatar::openSingingInterface(InputDevice device)
|
|||
dsq->game->songLineRender->clear();
|
||||
|
||||
|
||||
if (device == INPUT_JOYSTICK)
|
||||
if (device == INP_DEV_JOYSTICK)
|
||||
{
|
||||
core->setMousePosition(core->center);
|
||||
}
|
||||
|
@ -1730,7 +1719,7 @@ void Avatar::updateSingingInterface(float dt)
|
|||
{
|
||||
if (songIcons.size()>0 && songIcons[0]->alpha.x > 0)
|
||||
{
|
||||
if (dsq->getInputMode() != INPUT_JOYSTICK && !core->mouse.change.isZero())
|
||||
if (dsq->getInputMode() != INP_DEV_JOYSTICK && !core->mouse.change.isZero())
|
||||
{
|
||||
if (dsq->game->songLineRender && songIcons[0]->alpha.x == 1)
|
||||
{
|
||||
|
@ -1756,9 +1745,10 @@ void Avatar::updateSingingInterface(float dt)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK)
|
||||
if (dsq->getInputMode() == INP_DEV_JOYSTICK)
|
||||
{
|
||||
Vector d;
|
||||
/* // FIXME controllerfixup
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled())
|
||||
|
@ -1767,6 +1757,7 @@ void Avatar::updateSingingInterface(float dt)
|
|||
if(!d.isZero())
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
if (d.isLength2DIn(JOYSTICK_NOTE_THRESHOLD))
|
||||
{
|
||||
|
@ -1948,7 +1939,7 @@ void Avatar::updateTargets(float dt, bool override)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ((dsq->getInputMode() == INPUT_MOUSE || dsq->getInputMode() == INPUT_KEYBOARD) && !(wasDown && core->mouse.buttons.right))
|
||||
if ((dsq->getInputMode() == INP_DEV_MOUSE || dsq->getInputMode() == INP_DEV_KEYBOARD) && !(wasDown && core->mouse.buttons.right))
|
||||
{
|
||||
wasDown = false;
|
||||
float mod = 1;
|
||||
|
@ -2108,11 +2099,11 @@ void Avatar::updateTargetQuads(float dt)
|
|||
targetQuads[i]->position = cursorpos;
|
||||
if (dsq->continuity.form == FORM_ENERGY && isInputEnabled())
|
||||
{
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK && targetQuads[i]->isRunning())
|
||||
if (dsq->getInputMode() == INP_DEV_JOYSTICK && targetQuads[i]->isRunning())
|
||||
{
|
||||
targetQuads[i]->stop();
|
||||
}
|
||||
else if (dsq->getInputMode() != INPUT_JOYSTICK && !targetQuads[i]->isRunning())
|
||||
else if (dsq->getInputMode() != INP_DEV_JOYSTICK && !targetQuads[i]->isRunning())
|
||||
{
|
||||
targetQuads[i]->start();
|
||||
}
|
||||
|
@ -2147,7 +2138,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot)
|
|||
p = boneLeftArm->getWorldPosition();
|
||||
//&& !dsq->game->isObstructed(TileVector(position))
|
||||
/*
|
||||
if (dsq->inputMode == INPUT_MOUSE && state.lockedToWall )
|
||||
if (dsq->inputMode == INP_DEV_MOUSE && state.lockedToWall )
|
||||
dir = dsq->getGameCursorPosition() - p;
|
||||
else
|
||||
*/
|
||||
|
@ -2168,7 +2159,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot)
|
|||
/*
|
||||
if (target)
|
||||
{
|
||||
if (dsq->inputMode != INPUT_JOYSTICK && vel.isLength2DIn(50))
|
||||
if (dsq->inputMode != INP_DEV_JOYSTICK && vel.isLength2DIn(50))
|
||||
{
|
||||
}
|
||||
else
|
||||
|
@ -2189,7 +2180,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot)
|
|||
bool clearTargets = false;
|
||||
|
||||
// allow autoAim if desired
|
||||
if ((dsq->getInputMode() == INPUT_JOYSTICK && !aimAt) || dsq->user.control.autoAim)
|
||||
if ((dsq->getInputMode() == INP_DEV_JOYSTICK && !aimAt) || dsq->user.control.autoAim)
|
||||
{
|
||||
if (targets.empty())
|
||||
{
|
||||
|
@ -2252,7 +2243,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot)
|
|||
}
|
||||
else
|
||||
{
|
||||
//if (!dir.isLength2DIn(2) || dsq->inputMode == INPUT_JOYSTICK)
|
||||
//if (!dir.isLength2DIn(2) || dsq->inputMode == INP_DEV_JOYSTICK)
|
||||
if (true)
|
||||
{
|
||||
s = dsq->game->fireShot(shot, this);
|
||||
|
@ -2998,12 +2989,12 @@ bool Avatar::isMouseInputEnabled()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Avatar::rmbd(int source, InputDevice device)
|
||||
void Avatar::rmbd(int source, InputDeviceType device)
|
||||
{
|
||||
if (!isMouseInputEnabled() || isEntityDead()) return;
|
||||
if (dsq->continuity.form == FORM_NORMAL )
|
||||
{
|
||||
if (device == INPUT_MOUSE)
|
||||
if (device == INP_DEV_MOUSE)
|
||||
{
|
||||
Vector diff = getVectorToCursorFromScreenCentre();
|
||||
if (diff.getSquaredLength2D() < sqr(openSingingInterfaceRadius))
|
||||
|
@ -3020,7 +3011,7 @@ void Avatar::rmbd(int source, InputDevice device)
|
|||
}
|
||||
}
|
||||
|
||||
void Avatar::rmbu(int source, InputDevice device)
|
||||
void Avatar::rmbu(int source, InputDeviceType device)
|
||||
{
|
||||
if (!isMouseInputEnabled() || isEntityDead()) return;
|
||||
|
||||
|
@ -3168,7 +3159,7 @@ void Avatar::onUpdateBoneLock()
|
|||
rotateToVec(wallNormal, 0.01f);
|
||||
}
|
||||
|
||||
void Avatar::lmbd(int source, InputDevice device)
|
||||
void Avatar::lmbd(int source, InputDeviceType device)
|
||||
{
|
||||
if (!isMouseInputEnabled()) return;
|
||||
|
||||
|
@ -3210,7 +3201,7 @@ void Avatar::fallOffWall()
|
|||
}
|
||||
}
|
||||
|
||||
void Avatar::lmbu(int source, InputDevice device)
|
||||
void Avatar::lmbu(int source, InputDeviceType device)
|
||||
{
|
||||
if (!isMouseInputEnabled()) return;
|
||||
|
||||
|
@ -3886,8 +3877,6 @@ Avatar::Avatar() : Entity(), ActionMapper()
|
|||
|
||||
blockBackFlip = false;
|
||||
elementEffectMult = 1;
|
||||
_lastActionSourceID = 9999;
|
||||
_lastActionInputDevice = INPUT_NODEVICE;
|
||||
}
|
||||
|
||||
void Avatar::revert()
|
||||
|
@ -4056,11 +4045,11 @@ void Avatar::startBurst()
|
|||
{
|
||||
if (!riding && canBurst() && (joystickMove || getVectorToCursor().getSquaredLength2D() > sqr(BURST_DISTANCE))
|
||||
&& getState() != STATE_PUSH && (!skeletalSprite.getCurrentAnimation() || (skeletalSprite.getCurrentAnimation()->name != "spin"))
|
||||
&& _isUnderWater && !isActing(ACTION_ROLL, -1))
|
||||
&& _isUnderWater && !isActing(ACTION_ROLL))
|
||||
{
|
||||
if (!bursting && burst == 1)
|
||||
{
|
||||
dsq->rumble(0.2f, 0.2f, 0.2f, _lastActionSourceID, _lastActionInputDevice);
|
||||
dsq->rumble(0.2f, 0.2f, 0.2f);
|
||||
if (dsq->continuity.form != FORM_BEAST)
|
||||
wakeEmitter.start();
|
||||
dsq->game->playBurstSound(pushingOffWallEffect>0);
|
||||
|
@ -4133,7 +4122,7 @@ void Avatar::startWallBurst(bool useCursor)
|
|||
{
|
||||
lastBurstType = BURST_WALL;
|
||||
|
||||
dsq->rumble(0.22f, 0.22f, 0.2f, _lastActionSourceID, _lastActionInputDevice);
|
||||
dsq->rumble(0.22f, 0.22f, 0.2f);
|
||||
bittenEntities.clear();
|
||||
if (useCursor)
|
||||
{
|
||||
|
@ -4171,10 +4160,10 @@ void Avatar::startWallBurst(bool useCursor)
|
|||
|
||||
bool Avatar::isActionAndGetDir(Vector& dir)
|
||||
{
|
||||
bool dL = isActing(ACTION_SWIMLEFT, -1);
|
||||
bool dR = isActing(ACTION_SWIMRIGHT, -1);
|
||||
bool dU = isActing(ACTION_SWIMUP, -1);
|
||||
bool dD = isActing(ACTION_SWIMDOWN, -1);
|
||||
bool dL = isActing(ACTION_SWIMLEFT);
|
||||
bool dR = isActing(ACTION_SWIMRIGHT);
|
||||
bool dU = isActing(ACTION_SWIMUP);
|
||||
bool dD = isActing(ACTION_SWIMDOWN);
|
||||
Vector a;
|
||||
if (dL)
|
||||
a += Vector(-1,0);
|
||||
|
@ -4198,7 +4187,8 @@ Vector Avatar::getFakeCursorPosition()
|
|||
if(isActionAndGetDir(dir))
|
||||
return dir * 350;
|
||||
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
// FIXME controllerfixup
|
||||
/*for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
if(Joystick *j = core->getJoystick(i))
|
||||
if(j->isEnabled())
|
||||
{
|
||||
|
@ -4209,7 +4199,7 @@ Vector Avatar::getFakeCursorPosition()
|
|||
const float distance = minMouse + ((axisInput - JOYSTICK_LOW_THRESHOLD) * axisMult);
|
||||
return (j->position * (distance / axisInput));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
@ -4220,7 +4210,7 @@ Vector Avatar::getVectorToCursorFromScreenCentre()
|
|||
return getVectorToCursor();
|
||||
else
|
||||
{
|
||||
if (dsq->getInputMode() != INPUT_MOUSE)
|
||||
if (dsq->getInputMode() != INP_DEV_MOUSE)
|
||||
return getFakeCursorPosition();
|
||||
return (core->mouse.position+offset) - Vector(400,300);
|
||||
}
|
||||
|
@ -4232,21 +4222,18 @@ Vector Avatar::getVectorToCursor(bool trueMouse)
|
|||
Vector pos = dsq->getGameCursorPosition();
|
||||
|
||||
|
||||
if (!trueMouse && dsq->getInputMode() != INPUT_MOUSE)
|
||||
if (!trueMouse && dsq->getInputMode() != INP_DEV_MOUSE)
|
||||
return getFakeCursorPosition();
|
||||
|
||||
return pos - (position+offset);
|
||||
//return core->mouse.position - Vector(400,300);
|
||||
}
|
||||
|
||||
void Avatar::action(int id, int state, int source, InputDevice device)
|
||||
void Avatar::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if(dsq->game->isIgnoreAction((AquariaActions)id))
|
||||
return;
|
||||
|
||||
_lastActionSourceID = source;
|
||||
_lastActionInputDevice = device;
|
||||
|
||||
if (id == ACTION_PRIMARY) { if (state) lmbd(source, device); else lmbu(source, device); }
|
||||
if (id == ACTION_SECONDARY) { if (state) rmbd(source, device); else rmbu(source, device); }
|
||||
|
||||
|
@ -4313,7 +4300,7 @@ void Avatar::action(int id, int state, int source, InputDevice device)
|
|||
// done for wall bursts, but the movement there is fast
|
||||
// enough that people probably won't notice, so I skipped
|
||||
// that. Sorry about the ugliness. --achurch
|
||||
if (device != INPUT_MOUSE)
|
||||
if (device != INP_DEV_MOUSE)
|
||||
skeletalSprite.transitionAnimate("swim", ANIM_TRANSITION, -1);
|
||||
}
|
||||
}
|
||||
|
@ -4515,7 +4502,7 @@ void Avatar::splash(bool down)
|
|||
//dsq->postProcessingFx.disable(FXT_RADIALBLUR);
|
||||
if (_isUnderWater && core->afterEffectManager)
|
||||
core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.08f,0.05f,22,0.2f, 1.2f));
|
||||
dsq->rumble(0.7f, 0.7f, 0.2f, _lastActionSourceID, _lastActionInputDevice);
|
||||
dsq->rumble(0.7f, 0.7f, 0.2f);
|
||||
plungeEmitter.start();
|
||||
|
||||
core->sound->playSfx("GoUnder");
|
||||
|
@ -4992,13 +4979,13 @@ void Avatar::updateRoll(float dt)
|
|||
stopRoll();
|
||||
}
|
||||
}
|
||||
const bool rollact = isActing(ACTION_ROLL, -1);
|
||||
const bool rollact = isActing(ACTION_ROLL);
|
||||
if (!_isUnderWater && rollact)
|
||||
{
|
||||
stopRoll();
|
||||
}
|
||||
|
||||
if (!core->mouse.buttons.left && dsq->getInputMode() == INPUT_MOUSE && !rollact)
|
||||
if (!core->mouse.buttons.left && dsq->getInputMode() == INP_DEV_MOUSE && !rollact)
|
||||
{
|
||||
if (rolling)
|
||||
stopRoll();
|
||||
|
@ -5390,7 +5377,7 @@ void Avatar::onUpdate(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
if (!dsq->game->isPaused() && isActing(ACTION_LOOK, -1) && !dsq->game->avatar->isSinging() && dsq->game->avatar->isInputEnabled() && !dsq->game->isInGameMenu())
|
||||
if (!dsq->game->isPaused() && isActing(ACTION_LOOK) && !dsq->game->avatar->isSinging() && dsq->game->avatar->isInputEnabled() && !dsq->game->isInGameMenu())
|
||||
{
|
||||
looking = 1;
|
||||
}
|
||||
|
@ -5790,7 +5777,7 @@ void Avatar::onUpdate(float dt)
|
|||
// revert stuff
|
||||
float revertGrace = 0.4f;
|
||||
static bool revertButtonsAreDown = false;
|
||||
if (inputEnabled && (dsq->getInputMode() == INPUT_KEYBOARD || dsq->getInputMode() == INPUT_MOUSE) && (!pathToActivate && !entityToActivate))
|
||||
if (inputEnabled && (dsq->getInputMode() == INP_DEV_KEYBOARD || dsq->getInputMode() == INP_DEV_MOUSE) && (!pathToActivate && !entityToActivate))
|
||||
{
|
||||
if (dsq->continuity.form != FORM_NORMAL && (core->mouse.pure_buttons.left && core->mouse.pure_buttons.right) && getVectorToCursor(true).isLength2DIn(minMouse))
|
||||
{
|
||||
|
@ -6133,11 +6120,11 @@ void Avatar::onUpdate(float dt)
|
|||
|
||||
float len = 0;
|
||||
|
||||
if (dsq->isMiniMapCursorOkay() && !isActing(ACTION_ROLL, -1) &&
|
||||
if (dsq->isMiniMapCursorOkay() && !isActing(ACTION_ROLL) &&
|
||||
_isUnderWater && !riding && !boneLock.on &&
|
||||
(movingOn || ((dsq->getInputMode() == INPUT_JOYSTICK || dsq->getInputMode()== INPUT_KEYBOARD) || (core->mouse.buttons.left || bursting))))
|
||||
(movingOn || ((dsq->getInputMode() == INP_DEV_JOYSTICK || dsq->getInputMode()== INP_DEV_KEYBOARD) || (/*core->mouse.buttons.left ||*/ bursting))))
|
||||
{
|
||||
const bool isMouse = dsq->getInputMode() == INPUT_MOUSE;
|
||||
const bool isMouse = dsq->getInputMode() == INP_DEV_MOUSE;
|
||||
if (isMouse || !this->singing)
|
||||
{
|
||||
addVec = getVectorToCursorFromScreenCentre();//getVectorToCursor();
|
||||
|
@ -6145,7 +6132,7 @@ void Avatar::onUpdate(float dt)
|
|||
if (isMouse)
|
||||
{
|
||||
static Vector lastAddVec;
|
||||
if (!isActing(ACTION_PRIMARY, -1) && bursting)
|
||||
if (!isActing(ACTION_PRIMARY) && bursting)
|
||||
{
|
||||
addVec = lastAddVec;
|
||||
}
|
||||
|
@ -6158,7 +6145,7 @@ void Avatar::onUpdate(float dt)
|
|||
|
||||
if (addVec.isLength2DIn(minMouse))
|
||||
{
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK)
|
||||
if (dsq->getInputMode() == INP_DEV_JOYSTICK)
|
||||
addVec = Vector(0,0,0);
|
||||
}
|
||||
|
||||
|
@ -6187,7 +6174,7 @@ void Avatar::onUpdate(float dt)
|
|||
// For joystick/keyboard control, don't stop unless
|
||||
// the Swim (primary action) button is pressed with
|
||||
// no movement input. --achurch
|
||||
if ((isMouse || isActing(ACTION_PRIMARY, -1))
|
||||
if ((isMouse || isActing(ACTION_PRIMARY))
|
||||
&& addVec.isLength2DIn(STOP_DISTANCE))
|
||||
{
|
||||
vel *= 0.9f;
|
||||
|
@ -6275,14 +6262,14 @@ void Avatar::onUpdate(float dt)
|
|||
// here for roll key?
|
||||
// seems like this isn't reached
|
||||
//if (isActing("roll"))
|
||||
if (isActing(ACTION_ROLL, -1))
|
||||
if (isActing(ACTION_ROLL))
|
||||
{
|
||||
//debugLog("here");
|
||||
}
|
||||
else
|
||||
{
|
||||
float t = 0;
|
||||
if (dsq->getInputMode() == INPUT_KEYBOARD)
|
||||
if (dsq->getInputMode() == INP_DEV_KEYBOARD)
|
||||
t = 0.1f;
|
||||
rotateToVec(addVec, t);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ public:
|
|||
Avatar();
|
||||
virtual ~Avatar();
|
||||
void destroy();
|
||||
void action(int actionID, int state, int source, InputDevice device);
|
||||
void action(int actionID, int state, int source, InputDeviceType device);
|
||||
AvatarState state;
|
||||
float burst, burstTimer;
|
||||
float burstDelay;
|
||||
|
@ -179,7 +179,7 @@ public:
|
|||
|
||||
void startBurstCommon();
|
||||
|
||||
void openSingingInterface(InputDevice device);
|
||||
void openSingingInterface(InputDeviceType device);
|
||||
void closeSingingInterface();
|
||||
void updateSingingInterface(float dt);
|
||||
|
||||
|
@ -331,9 +331,6 @@ public:
|
|||
|
||||
bool blockBackFlip;
|
||||
|
||||
int getLastActionSourceID() const { return _lastActionSourceID; }
|
||||
InputDevice getLastActionInputDevice() const { return _lastActionInputDevice; }
|
||||
|
||||
protected:
|
||||
void setSongIconPositions();
|
||||
|
||||
|
@ -440,11 +437,11 @@ protected:
|
|||
Quad *glow;
|
||||
bool swimming;
|
||||
|
||||
void lmbd(int source, InputDevice device);
|
||||
void lmbu(int source, InputDevice device);
|
||||
void lmbd(int source, InputDeviceType device);
|
||||
void lmbu(int source, InputDeviceType device);
|
||||
|
||||
void rmbd(int source, InputDevice device);
|
||||
void rmbu(int source, InputDevice device);
|
||||
void rmbd(int source, InputDeviceType device);
|
||||
void rmbu(int source, InputDeviceType device);
|
||||
|
||||
bool charging;
|
||||
|
||||
|
@ -467,10 +464,6 @@ protected:
|
|||
|
||||
int _collisionAvoidRange;
|
||||
float _collisionAvoidMod;
|
||||
|
||||
int _lastActionSourceID;
|
||||
InputDevice _lastActionInputDevice;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
218
Aquaria/DSQ.cpp
218
Aquaria/DSQ.cpp
|
@ -193,7 +193,7 @@ DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir)
|
|||
subbox = 0;
|
||||
modSelectorScr = 0;
|
||||
blackout = 0;
|
||||
lastInputMode = INPUT_MOUSE;
|
||||
lastInputMode = INP_DEV_MOUSE;
|
||||
overlay = 0;
|
||||
recentSaveSlot = -1;
|
||||
arialFontData = 0;
|
||||
|
@ -249,24 +249,26 @@ void DSQ::onWindowResize(int w, int h)
|
|||
screenTransition->reloadDevice();
|
||||
}
|
||||
|
||||
void DSQ::rumble(float leftMotor, float rightMotor, float time, int source, InputDevice device)
|
||||
void DSQ::rumble(float leftMotor, float rightMotor, float time, int playerID /* = -1 */)
|
||||
{
|
||||
if (device == INPUT_JOYSTICK)
|
||||
{
|
||||
if(source < 0)
|
||||
for(size_t i = 0; i < user.control.actionSets.size(); ++i)
|
||||
{
|
||||
const ActionSet& as = user.control.actionSets[i];
|
||||
if(Joystick *j = core->getJoystick(as.joystickID))
|
||||
j->rumble(leftMotor, rightMotor, time);
|
||||
}
|
||||
else if(source < (int)user.control.actionSets.size())
|
||||
if(lastInputMode != INP_DEV_JOYSTICK)
|
||||
return;
|
||||
|
||||
/* // FIXME controllerfixup
|
||||
if(source < 0)
|
||||
for(size_t i = 0; i < user.control.actionSets.size(); ++i)
|
||||
{
|
||||
const ActionSet& as = user.control.actionSets[source];
|
||||
const ActionSet& as = user.control.actionSets[i];
|
||||
if(Joystick *j = core->getJoystick(as.joystickID))
|
||||
j->rumble(leftMotor, rightMotor, time);
|
||||
}
|
||||
else if(source < (int)user.control.actionSets.size())
|
||||
{
|
||||
const ActionSet& as = user.control.actionSets[source];
|
||||
if(Joystick *j = core->getJoystick(as.joystickID))
|
||||
j->rumble(leftMotor, rightMotor, time);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void DSQ::newGame()
|
||||
|
@ -502,7 +504,6 @@ void DSQ::debugMenu()
|
|||
if (core->getShiftState())
|
||||
|
||||
{
|
||||
core->frameOutputMode = false;
|
||||
dsq->game->togglePause(true);
|
||||
std::string s = dsq->getUserInputString(stringbank.get(2012), "");
|
||||
stringToUpper(s);
|
||||
|
@ -630,32 +631,6 @@ void DSQ::debugMenu()
|
|||
is >> read >> nm;
|
||||
dsq->continuity.setCostume(nm);
|
||||
}
|
||||
else if (c == 'R')
|
||||
{
|
||||
dsq->demo.toggleRecord(true);
|
||||
}
|
||||
else if (c == 'P')
|
||||
{
|
||||
dsq->demo.togglePlayback(true);
|
||||
}
|
||||
else if (c == 'T')
|
||||
{
|
||||
if (dsq->demo.frames.size()> 0)
|
||||
{
|
||||
dsq->game->avatar->position = dsq->demo.frames[0].avatarPos;
|
||||
dsq->game->avatar->rotation.z = dsq->demo.frames[0].rot;
|
||||
}
|
||||
}
|
||||
else if (c == 'U')
|
||||
{
|
||||
dsq->demo.renderFramesToDisk();
|
||||
|
||||
|
||||
}
|
||||
else if (c == 'K')
|
||||
{
|
||||
dsq->demo.clearRecordedFrames();
|
||||
}
|
||||
else if (c == 'H')
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
@ -1684,21 +1659,21 @@ void DSQ::toggleVersionLabel(bool on)
|
|||
versionLabel->alpha.interpolateTo(a, 1);
|
||||
}
|
||||
|
||||
void DSQ::setInputMode(InputDevice mode)
|
||||
void DSQ::setInputMode(InputDeviceType mode)
|
||||
{
|
||||
lastInputMode = mode;
|
||||
switch(mode)
|
||||
{
|
||||
case INPUT_JOYSTICK:
|
||||
case INP_DEV_JOYSTICK:
|
||||
core->joystickAsMouse = true;
|
||||
break;
|
||||
case INPUT_MOUSE:
|
||||
case INP_DEV_MOUSE:
|
||||
setMousePosition(core->mouse.position);
|
||||
core->joystickAsMouse = false;
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
case INP_DEV_KEYBOARD:
|
||||
break;
|
||||
case INPUT_NODEVICE:
|
||||
case INP_DEV_NODEVICE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3665,7 +3640,7 @@ void DSQ::watch(float t, int canQuit)
|
|||
}
|
||||
}
|
||||
|
||||
void DSQ::action(int id, int state, int source, InputDevice device)
|
||||
void DSQ::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
Core::action(id, state, source, device);
|
||||
|
||||
|
@ -3693,10 +3668,8 @@ void DSQ::action(int id, int state, int source, InputDevice device)
|
|||
void DSQ::bindInput()
|
||||
{
|
||||
clearActions();
|
||||
almb.clear();
|
||||
armb.clear();
|
||||
|
||||
addAction(ACTION_ESC, KEY_ESCAPE, -1);
|
||||
addAction(ACTION_ESC, KEY_ESCAPE);
|
||||
addAction(MakeFunctionEvent(DSQ, onSwitchScreenMode), KEY_RETURN, 1);
|
||||
|
||||
if (isDeveloperKeys())
|
||||
|
@ -3708,20 +3681,16 @@ void DSQ::bindInput()
|
|||
}
|
||||
addAction(MakeFunctionEvent(DSQ, debugMenu), KEY_BACKSPACE, 0);
|
||||
//addAction(MakeFunctionEvent(DSQ, takeScreenshotKey ), KEY_P, 0);
|
||||
|
||||
for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i)
|
||||
{
|
||||
ActionSet& as = dsq->user.control.actionSets[i];
|
||||
int sourceID = (int)i;
|
||||
|
||||
as.importAction(this, "Escape", ACTION_ESC, sourceID);
|
||||
as.importAction(this, "Screenshot", ACTION_SCREENSHOT, sourceID);
|
||||
|
||||
if(ActionInput *a = as.getActionInputByName("PrimaryAction"))
|
||||
almb.push_back(a);
|
||||
if(ActionInput *a = as.getActionInputByName("SecondaryAction"))
|
||||
armb.push_back(a);
|
||||
}
|
||||
const NamedAction actions[] =
|
||||
{
|
||||
{ "Escape", ACTION_ESC },
|
||||
{ "Screenshot", ACTION_SCREENSHOT }
|
||||
};
|
||||
ImportInput(actions);
|
||||
|
||||
if(game)
|
||||
game->bindInput();
|
||||
}
|
||||
|
||||
void DSQ::jiggleCursor()
|
||||
|
@ -3731,13 +3700,15 @@ void DSQ::jiggleCursor()
|
|||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
|
||||
#if 0 // FIXME controllerfixup
|
||||
void DSQ::updateActionButtons()
|
||||
{
|
||||
// HACK: not optimal
|
||||
|
||||
#if 0
|
||||
// This must be done *before* Core::updateActionButtons()
|
||||
// for LMB/RMB emulation to work properly -- fg
|
||||
if (/*inputMode != INPUT_KEYBOARD &&*/ game->isActive())
|
||||
if (/*inputMode != INP_DEV_KEYBOARD &&*/ game->isActive())
|
||||
{
|
||||
for(size_t i = 0; i < almb.size(); ++i)
|
||||
if (ActionMapper::getKeyState(almb[i]->data.single.key[0]) || ActionMapper::getKeyState(almb[i]->data.single.key[1]))
|
||||
|
@ -3768,9 +3739,11 @@ void DSQ::updateActionButtons()
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Core::updateActionButtons();
|
||||
}
|
||||
#endif
|
||||
|
||||
static float skipSfxVol = 1.0;
|
||||
void DSQ::onUpdate(float dt)
|
||||
|
@ -3828,7 +3801,7 @@ void DSQ::onUpdate(float dt)
|
|||
|
||||
if (dsq->game && watchForQuit && isNested())
|
||||
{
|
||||
if (dsq->game->isActing(ACTION_ESC, -1))
|
||||
if (dsq->game->isActing(ACTION_ESC))
|
||||
{
|
||||
watchQuitFlag = true;
|
||||
quitNestedMain();
|
||||
|
@ -3851,11 +3824,10 @@ void DSQ::onUpdate(float dt)
|
|||
|
||||
subtitlePlayer.update(dt);
|
||||
|
||||
demo.update(dt);
|
||||
|
||||
#if 0 //KILL
|
||||
if (joystickEnabled)
|
||||
{
|
||||
if (dsq->getInputMode() != INPUT_JOYSTICK)
|
||||
if (dsq->getInputMode() != INP_DEV_JOYSTICK)
|
||||
{
|
||||
const float thresh = JOY_AXIS_THRESHOLD;
|
||||
for(size_t i = 0; i < getNumJoysticks(); ++i)
|
||||
|
@ -3864,39 +3836,29 @@ void DSQ::onUpdate(float dt)
|
|||
if (j->anyButton() || !j->position.isLength2DIn(thresh) || !j->rightStick.isLength2DIn(thresh))
|
||||
{
|
||||
//debugLog("setting joystick input mode");
|
||||
dsq->setInputMode(INPUT_JOYSTICK);
|
||||
dsq->setInputMode(INP_DEV_JOYSTICK);
|
||||
}
|
||||
}
|
||||
else if (dsq->getInputMode() != INPUT_MOUSE)
|
||||
else if (dsq->getInputMode() != INP_DEV_MOUSE)
|
||||
{
|
||||
if ((!core->mouse.change.isLength2DIn(5) || (core->getMouseButtonState(0) || core->getMouseButtonState(1))) /*&& !core->joystick.anyButton()*/)
|
||||
if ((!mouse.change.isLength2DIn(5) || (getKeyState(MOUSE_BUTTON_LEFT) || getKeyState(MOUSE_BUTTON_RIGHT)) /*&& !core->joystick.anyButton()*/)
|
||||
{
|
||||
//debugLog("setting mouse input mode");
|
||||
dsq->setInputMode(INPUT_MOUSE);
|
||||
setInputMode(INP_DEV_MOUSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dsq->game->avatar)
|
||||
{
|
||||
if (dsq->game->avatar->isActing(ACTION_SWIMUP, -1) ||
|
||||
dsq->game->avatar->isActing(ACTION_SWIMDOWN, -1) ||
|
||||
dsq->game->avatar->isActing(ACTION_SWIMLEFT, -1) ||
|
||||
dsq->game->avatar->isActing(ACTION_SWIMRIGHT, -1))
|
||||
{
|
||||
dsq->setInputMode(INPUT_KEYBOARD);
|
||||
}
|
||||
}
|
||||
|
||||
// check the actual values, since mouse.buttons.left might be overwritten by keys
|
||||
int cb = 0;
|
||||
int cb = MOUSE_BUTTON_LEFT;
|
||||
if (user.control.flipInputButtons)
|
||||
cb = 1;
|
||||
cb = MOUSE_BUTTON_RIGHT;
|
||||
|
||||
if (dsq->getInputMode() == INPUT_KEYBOARD && (core->getMouseButtonState(cb)))
|
||||
if (dsq->getInputMode() == INP_DEV_KEYBOARD && getKeyState(cb))
|
||||
{
|
||||
dsq->setInputMode(INPUT_MOUSE);
|
||||
dsq->setInputMode(INP_DEV_MOUSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (isDeveloperKeys() && cmDebug && cmDebug->alpha == 1 && fpsText)
|
||||
|
@ -3935,16 +3897,18 @@ void DSQ::onUpdate(float dt)
|
|||
os << "inputMode: ";
|
||||
switch(dsq->getInputMode())
|
||||
{
|
||||
case INPUT_MOUSE:
|
||||
case INP_DEV_MOUSE:
|
||||
os << "mouse";
|
||||
break;
|
||||
case INPUT_JOYSTICK:
|
||||
case INP_DEV_JOYSTICK:
|
||||
os << "joystick";
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
case INP_DEV_KEYBOARD:
|
||||
os << "keyboard";
|
||||
break;
|
||||
case INP_DEV_NODEVICE:
|
||||
os << "nodevice";
|
||||
break;
|
||||
case INPUT_NODEVICE:
|
||||
break;
|
||||
}
|
||||
os << std::endl;
|
||||
Bone *b = dsq->game->avatar->skeletalSprite.getBoneByIdx(1);
|
||||
|
@ -3964,7 +3928,7 @@ void DSQ::onUpdate(float dt)
|
|||
os << std::endl;
|
||||
os << "globalScale: " << core->globalScale.x << std::endl;
|
||||
os << "mousePos:(" << core->mouse.position.x << ", " << core->mouse.position.y << ") mouseChange:(" << core->mouse.change.x << ", " << core->mouse.change.y << ")\n";
|
||||
for(size_t i = 0; i < getNumJoysticks(); ++i)
|
||||
/*for(size_t i = 0; i < getNumJoysticks(); ++i)
|
||||
if(Joystick *j = getJoystick(i))
|
||||
{
|
||||
os << "J[" << i << "," << (j->isEnabled() ? " on" : "off") << "]:[";
|
||||
|
@ -3974,7 +3938,7 @@ void DSQ::onUpdate(float dt)
|
|||
else
|
||||
os << '-';
|
||||
os << "], (" << j->position.x << ", " << j->position.y << "), ("<< j->rightStick.x << ", " << j->rightStick.y << ")\n";
|
||||
}
|
||||
}*/ // FIXME controllerfixup
|
||||
os << "altState: " << core->getKeyState(KEY_LALT) << " | " << core->getKeyState(KEY_RALT) << " mb: " << mouse.buttons.left << mouse.buttons.middle << mouse.buttons.right << std::endl;
|
||||
os << "PMFree: " << particleManager->getFree() << " Active: " << particleManager->getNumActive() << std::endl;
|
||||
os << "cameraPos: (" << dsq->cameraPos.x << ", " << dsq->cameraPos.y << ")" << std::endl;
|
||||
|
@ -4226,17 +4190,6 @@ void DSQ::modifyDt(float &dt)
|
|||
|
||||
gameSpeed.update(dt);
|
||||
dt *= gameSpeed.x;
|
||||
|
||||
if (frameOutputMode)
|
||||
{
|
||||
dt = 1.0f/60.0f;
|
||||
doScreenshot = true;
|
||||
}
|
||||
|
||||
if (dsq->demo.mode == Demo::DEMOMODE_RECORD)
|
||||
{
|
||||
dt = 1.0f/60.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void DSQ::removeElement(Element *element)
|
||||
|
@ -4485,48 +4438,12 @@ void DSQ::fixupJoysticks()
|
|||
if(Joystick *j = getJoystick(i))
|
||||
j->setEnabled(false);
|
||||
|
||||
// Re-enable joysticks that are in use
|
||||
for(size_t i = 0; i < user.control.actionSets.size(); ++i)
|
||||
{
|
||||
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();
|
||||
|
||||
std::vector<int> allkeys;
|
||||
// Don't need joysticks keys for this
|
||||
for(int i = 0; i < MOUSE_BUTTON_EXTRA_END; ++i)
|
||||
allkeys.push_back(i);
|
||||
|
||||
// create sentinel
|
||||
ActionButtonStatus *allbtn = new ActionButtonStatus;
|
||||
allbtn->importQuery(&allkeys[0], allkeys.size());
|
||||
actionStatus.push_back(allbtn);
|
||||
|
||||
// create the rest
|
||||
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()+1 == actionStatus.size());
|
||||
|
||||
// ignore sentinel
|
||||
for(size_t i = 1; i < actionStatus.size(); ++i)
|
||||
{
|
||||
const ActionSet& as = user.control.actionSets[i-1];
|
||||
ActionButtonStatus *abs = actionStatus[i];
|
||||
abs->import(as);
|
||||
}
|
||||
}
|
||||
|
||||
void DSQ::loadStringBank()
|
||||
|
@ -4547,34 +4464,23 @@ void DSQ::loadStringBank()
|
|||
stringbank.load(fname);
|
||||
|
||||
if (mod.isActive()) {
|
||||
// FIXME (after controllerfixup) load mod stringbanks HERE, not up there
|
||||
fname = localisePath(mod.getPath() + "stringbank.txt", mod.getPath());
|
||||
stringbank.load(fname);
|
||||
}
|
||||
}
|
||||
|
||||
InputDevice DSQ::getInputMode() const
|
||||
InputDeviceType DSQ::getInputMode() const
|
||||
{
|
||||
return lastInputMode;
|
||||
}
|
||||
|
||||
InputDevice DSQ::getInputMode(int source) const
|
||||
{
|
||||
assert(source >= 0 && size_t(source) < _inputModes.size());
|
||||
return _inputModes[source];
|
||||
}
|
||||
|
||||
InputDevice DSQ::getInputModeSafe(int source) const
|
||||
{
|
||||
return source < 0 ? lastInputMode :
|
||||
(size_t(source) < _inputModes.size() ? _inputModes[source] : INPUT_NODEVICE);
|
||||
}
|
||||
|
||||
bool DSQ::useMouseInput() const
|
||||
{
|
||||
return lastInputMode == INPUT_MOUSE;
|
||||
return lastInputMode == INP_DEV_MOUSE;
|
||||
}
|
||||
|
||||
bool DSQ::useJoystickInput() const
|
||||
{
|
||||
return lastInputMode == INPUT_JOYSTICK;
|
||||
return lastInputMode == INP_DEV_JOYSTICK;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "Continuity.h"
|
||||
#include "SubtitlePlayer.h"
|
||||
#include "StringBank.h"
|
||||
|
||||
#include "GameInput.h"
|
||||
#include "TTFFont.h"
|
||||
|
||||
#define AQUARIA_BUILD_MAPVIS
|
||||
|
@ -133,42 +133,6 @@ extern GameplayVariables *vars;
|
|||
|
||||
#include "UserSettings.h"
|
||||
|
||||
struct DemoFrame
|
||||
{
|
||||
float t;
|
||||
Vector avatarPos, vel, vel2;
|
||||
Mouse mouse;
|
||||
float rot;
|
||||
};
|
||||
|
||||
class Demo
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
DEMOMODE_NONE = -1,
|
||||
DEMOMODE_RECORD = 0,
|
||||
DEMOMODE_PLAYBACK = 1
|
||||
};
|
||||
Demo();
|
||||
void toggleRecord(bool on);
|
||||
void togglePlayback(bool on);
|
||||
void renderFramesToDisk();
|
||||
void clearRecordedFrames();
|
||||
|
||||
void update(float dt);
|
||||
|
||||
bool getQuitKey();
|
||||
|
||||
void save(const std::string &name);
|
||||
void load(const std::string &name);
|
||||
|
||||
unsigned int frame;
|
||||
float time;
|
||||
float timeDiff;
|
||||
std::vector <DemoFrame> frames;
|
||||
int mode;
|
||||
};
|
||||
|
||||
enum NagType
|
||||
{
|
||||
NAG_TOTITLE = 0,
|
||||
|
@ -208,7 +172,7 @@ public:
|
|||
|
||||
void nag(NagType type);
|
||||
|
||||
void action(int id, int state, int source, InputDevice device);
|
||||
void action(int id, int state, int source, InputDeviceType device);
|
||||
|
||||
void title(bool fadeMusic=true);
|
||||
|
||||
|
@ -343,18 +307,16 @@ public:
|
|||
|
||||
InterpolatedVector gameSpeed;
|
||||
|
||||
GameInput playerInput;
|
||||
private:
|
||||
InputDevice lastInputMode; // really don't want to expose this one
|
||||
std::vector<InputDevice> _inputModes; // index: FIXME ADD INFO
|
||||
InputDeviceType lastInputMode; // really don't want to expose this one
|
||||
public:
|
||||
void setInputMode(InputDevice mode);
|
||||
InputDevice getInputMode() const;
|
||||
InputDevice getInputMode(int source) const;
|
||||
InputDevice getInputModeSafe(int source) const;
|
||||
void setInputMode(InputDeviceType mode);
|
||||
InputDeviceType getInputMode() const;
|
||||
bool useMouseInput() const;
|
||||
bool useJoystickInput() const;
|
||||
|
||||
void rumble(float leftMotor, float rightMotor, float time, int source, InputDevice device);
|
||||
void rumble(float leftMotor, float rightMotor, float time, int playerID = -1);
|
||||
void vision(std::string folder, int num, bool ignoreMusic = false);
|
||||
|
||||
void run(float runTime = -1, bool skipRecurseCheck = false); // same as Core::run() but with recursion check
|
||||
|
@ -394,8 +356,6 @@ public:
|
|||
|
||||
std::string returnToScene;
|
||||
|
||||
Demo demo;
|
||||
|
||||
DebugFont *fpsText, *cmDebug;
|
||||
#ifdef AQUARIA_BUILD_CONSOLE
|
||||
DebugFont *console;
|
||||
|
@ -492,8 +452,6 @@ protected:
|
|||
bool _canSkipCutscene;
|
||||
bool skippingCutscene;
|
||||
|
||||
std::vector<ActionInput*> almb, armb;
|
||||
|
||||
void recreateBlackBars();
|
||||
|
||||
bool watchQuitFlag, watchForQuit;
|
||||
|
@ -550,12 +508,10 @@ protected:
|
|||
virtual void onJoystickAdded(int deviceID);
|
||||
virtual void onJoystickRemoved(int instanceID);
|
||||
|
||||
virtual void updateActionButtons();
|
||||
//virtual void updateActionButtons();
|
||||
|
||||
public:
|
||||
void fixupJoysticks();
|
||||
void initActionButtons();
|
||||
void importActionButtons();
|
||||
};
|
||||
|
||||
extern DSQ *dsq;
|
||||
|
|
|
@ -1303,13 +1303,13 @@ bool Entity::updateCurrents(float dt)
|
|||
dist.normalize2D();
|
||||
float v = dist.x;
|
||||
float scale = 0.2f;
|
||||
if (getEntityType() == ET_AVATAR)
|
||||
if (getEntityType() == ET_AVATAR) // FIXME (after controllerfixup) should be moved to avatar update
|
||||
{
|
||||
Avatar *a = dsq->game->avatar;
|
||||
if (v < 0)
|
||||
dsq->rumble((-v)*scale, (1.0f+v)*scale, 0.2f, a->getLastActionSourceID(), a->getLastActionInputDevice());
|
||||
dsq->rumble((-v)*scale, (1.0f+v)*scale, 0.2f);
|
||||
else
|
||||
dsq->rumble((1.0f-v)*scale, (v)*scale, 0.1f, a->getLastActionSourceID(), a->getLastActionInputDevice());
|
||||
dsq->rumble((1.0f-v)*scale, (v)*scale, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
105
Aquaria/Game.cpp
105
Aquaria/Game.cpp
|
@ -2511,10 +2511,10 @@ float Game::getHalfTimer(float mod)
|
|||
|
||||
void Game::toggleHelpScreen()
|
||||
{
|
||||
action(ACTION_TOGGLEHELPSCREEN, 0, -1, INPUT_NODEVICE);
|
||||
action(ACTION_TOGGLEHELPSCREEN, 0, -1, INP_DEV_NODEVICE);
|
||||
}
|
||||
|
||||
void Game::action(int id, int state, int source, InputDevice device)
|
||||
void Game::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
for (size_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
|
@ -2557,16 +2557,6 @@ void Game::action(int id, int state, int source, InputDevice device)
|
|||
{
|
||||
if (id == ACTION_TOGGLEGRID && !state) toggleGridRender();
|
||||
}
|
||||
|
||||
// Forward these to Lua scripts (because digital swim movement should be seen as menu movement as well)
|
||||
if(id == ACTION_SWIMLEFT)
|
||||
action(ACTION_MENULEFT, state, source, device);
|
||||
else if(id == ACTION_SWIMRIGHT)
|
||||
action(ACTION_MENURIGHT, state, source, device);
|
||||
else if(id == ACTION_SWIMUP)
|
||||
action(ACTION_MENUUP, state, source, device);
|
||||
else if(id == ACTION_SWIMDOWN)
|
||||
action(ACTION_MENUDOWN, state, source, device);
|
||||
}
|
||||
|
||||
void Game::toggleWorldMap()
|
||||
|
@ -3219,69 +3209,62 @@ void Game::bindInput()
|
|||
ActionMapper::clearActions();
|
||||
//ActionMapper::clearCreatedEvents();
|
||||
|
||||
addAction(ACTION_ESC, KEY_ESCAPE, -1);
|
||||
addAction(ACTION_ESC, KEY_ESCAPE);
|
||||
|
||||
|
||||
#ifdef AQUARIA_BUILD_SCENEEDITOR
|
||||
if (dsq->canOpenEditor())
|
||||
{
|
||||
addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB, -1);
|
||||
addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dsq->canOpenEditor())
|
||||
{
|
||||
//addAction(MakeFunctionEvent(Game, toggleMiniMapRender), KEY_M, 0);
|
||||
addAction(ACTION_TOGGLEGRID, KEY_F9, -1);
|
||||
addAction(ACTION_TOGGLEGRID, KEY_F9);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i)
|
||||
const NamedAction actions[] =
|
||||
{
|
||||
const ActionSet& as = dsq->user.control.actionSets[i];
|
||||
int sourceID = (int)i;
|
||||
{ "PrimaryAction", ACTION_PRIMARY},
|
||||
{ "SecondaryAction", ACTION_SECONDARY},
|
||||
|
||||
as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID);
|
||||
as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID);
|
||||
|
||||
as.importAction(this, "Escape", ACTION_ESC, sourceID);
|
||||
as.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP, sourceID);
|
||||
as.importAction(this, "ToggleHelp", ACTION_TOGGLEHELPSCREEN, sourceID);
|
||||
{ "Escape", ACTION_ESC},
|
||||
{ "WorldMap", ACTION_TOGGLEWORLDMAP},
|
||||
{ "ToggleHelp", ACTION_TOGGLEHELPSCREEN},
|
||||
|
||||
// used for scrolling help text
|
||||
as.importAction(this, "SwimUp", ACTION_SWIMUP, sourceID);
|
||||
as.importAction(this, "SwimDown", ACTION_SWIMDOWN, sourceID);
|
||||
as.importAction(this, "SwimLeft", ACTION_SWIMLEFT, sourceID);
|
||||
as.importAction(this, "SwimRight", ACTION_SWIMRIGHT, sourceID);
|
||||
{ "SwimUp", ACTION_SWIMUP},
|
||||
{ "SwimDown", ACTION_SWIMDOWN},
|
||||
{ "SwimLeft", ACTION_SWIMLEFT},
|
||||
{ "SwimRight", ACTION_SWIMRIGHT},
|
||||
|
||||
as.importAction(this, "MenuUp", ACTION_MENUUP, sourceID);
|
||||
as.importAction(this, "MenuDown", ACTION_MENUDOWN, sourceID);
|
||||
as.importAction(this, "MenuLeft", ACTION_MENULEFT, sourceID);
|
||||
as.importAction(this, "MenuRight", ACTION_MENURIGHT, sourceID);
|
||||
|
||||
as.importAction(this, "PrevPage", ACTION_PREVPAGE, sourceID);
|
||||
as.importAction(this, "NextPage", ACTION_NEXTPAGE, sourceID);
|
||||
as.importAction(this, "CookFood", ACTION_COOKFOOD, sourceID);
|
||||
as.importAction(this, "FoodLeft", ACTION_FOODLEFT, sourceID);
|
||||
as.importAction(this, "FoodRight", ACTION_FOODRIGHT, sourceID);
|
||||
as.importAction(this, "FoodDrop", ACTION_FOODDROP, sourceID);
|
||||
{ "PrevPage", ACTION_PREVPAGE},
|
||||
{ "NextPage", ACTION_NEXTPAGE},
|
||||
{ "CookFood", ACTION_COOKFOOD},
|
||||
{ "FoodLeft", ACTION_FOODLEFT},
|
||||
{ "FoodRight", ACTION_FOODRIGHT},
|
||||
{ "FoodDrop", ACTION_FOODDROP},
|
||||
|
||||
// To capture quick song keys via script
|
||||
as.importAction(this, "SongSlot1", ACTION_SONGSLOT1, sourceID);
|
||||
as.importAction(this, "SongSlot2", ACTION_SONGSLOT2, sourceID);
|
||||
as.importAction(this, "SongSlot3", ACTION_SONGSLOT3, sourceID);
|
||||
as.importAction(this, "SongSlot4", ACTION_SONGSLOT4, sourceID);
|
||||
as.importAction(this, "SongSlot5", ACTION_SONGSLOT5, sourceID);
|
||||
as.importAction(this, "SongSlot6", ACTION_SONGSLOT6, sourceID);
|
||||
as.importAction(this, "SongSlot7", ACTION_SONGSLOT7, sourceID);
|
||||
as.importAction(this, "SongSlot8", ACTION_SONGSLOT8, sourceID);
|
||||
as.importAction(this, "SongSlot9", ACTION_SONGSLOT9, sourceID);
|
||||
as.importAction(this, "SongSlot10", ACTION_SONGSLOT10, sourceID);
|
||||
{ "SongSlot1", ACTION_SONGSLOT1},
|
||||
{ "SongSlot2", ACTION_SONGSLOT2},
|
||||
{ "SongSlot3", ACTION_SONGSLOT3},
|
||||
{ "SongSlot4", ACTION_SONGSLOT4},
|
||||
{ "SongSlot5", ACTION_SONGSLOT5},
|
||||
{ "SongSlot6", ACTION_SONGSLOT6},
|
||||
{ "SongSlot7", ACTION_SONGSLOT7},
|
||||
{ "SongSlot8", ACTION_SONGSLOT8},
|
||||
{ "SongSlot9", ACTION_SONGSLOT9},
|
||||
{ "SongSlot10", ACTION_SONGSLOT10},
|
||||
|
||||
as.importAction(this, "Revert", ACTION_REVERT, sourceID);
|
||||
{ "Revert", ACTION_REVERT},
|
||||
|
||||
as.importAction(this, "Look", ACTION_LOOK, sourceID);
|
||||
as.importAction(this, "Roll", ACTION_ROLL, sourceID);
|
||||
}
|
||||
{ "Look", ACTION_LOOK},
|
||||
{ "Roll", ACTION_ROLL}
|
||||
};
|
||||
ImportInput(actions);
|
||||
|
||||
if (avatar)
|
||||
avatar->bindInput();
|
||||
|
@ -3776,7 +3759,7 @@ bool Game::updateMusic()
|
|||
return false;
|
||||
}
|
||||
|
||||
void Game::onPressEscape(int source, InputDevice device)
|
||||
void Game::onPressEscape(int source, InputDeviceType device)
|
||||
{
|
||||
if (dsq->isInCutscene())
|
||||
{
|
||||
|
@ -4240,13 +4223,13 @@ void Game::updateCursor(float dt)
|
|||
{
|
||||
bool rotate = false;
|
||||
|
||||
if (dsq->getInputMode() == INPUT_MOUSE)
|
||||
if (dsq->getInputMode() == INP_DEV_MOUSE)
|
||||
{
|
||||
dsq->cursor->offset.stop();
|
||||
dsq->cursor->offset = Vector(0,0);
|
||||
//debugLog("offset lerp stop in mouse!");
|
||||
}
|
||||
else if (dsq->getInputMode() == INPUT_JOYSTICK)
|
||||
else if (dsq->getInputMode() == INP_DEV_JOYSTICK)
|
||||
{
|
||||
if (!dsq->game->isPaused() || dsq->game->isInGameMenu() || !dsq->game->avatar->isInputEnabled())
|
||||
{
|
||||
|
@ -4279,7 +4262,7 @@ void Game::updateCursor(float dt)
|
|||
// Don't show the cursor in keyboard/joystick mode if it's not
|
||||
// already visible (this keeps the cursor from appearing for an
|
||||
// instant during map fadeout).
|
||||
if (dsq->getInputMode() == INPUT_MOUSE || isSceneEditorActive() || dsq->game->isPaused())
|
||||
if (dsq->getInputMode() == INP_DEV_MOUSE || isSceneEditorActive() || dsq->game->isPaused())
|
||||
dsq->cursor->alphaMod = 0.5;
|
||||
|
||||
/*
|
||||
|
@ -4290,7 +4273,7 @@ void Game::updateCursor(float dt)
|
|||
else if (avatar)
|
||||
{
|
||||
//Vector v = avatar->getVectorToCursorFromScreenCentre();
|
||||
if (dsq->getInputMode() == INPUT_JOYSTICK)// && !avatar->isSinging() && !dsq->game->isInGameMenu() && !dsq->game->isPaused())
|
||||
if (dsq->getInputMode() == INP_DEV_JOYSTICK)// && !avatar->isSinging() && !dsq->game->isInGameMenu() && !dsq->game->isPaused())
|
||||
{
|
||||
dsq->cursor->alphaMod = 0;
|
||||
if (!avatar->isSinging())
|
||||
|
@ -4518,7 +4501,7 @@ void Game::update(float dt)
|
|||
if (inHelpScreen)
|
||||
{
|
||||
const float helpTextScrollSpeed = 400.0f;
|
||||
if (isActing(ACTION_SWIMDOWN, -1))
|
||||
if (isActing(ACTION_SWIMDOWN))
|
||||
{
|
||||
helpText->offset.stop();
|
||||
helpText->offset.y -= helpTextScrollSpeed * dt;
|
||||
|
@ -4527,7 +4510,7 @@ void Game::update(float dt)
|
|||
helpText->offset.y = -helpText->getHeight() + core->getVirtualHeight();
|
||||
}
|
||||
}
|
||||
if (isActing(ACTION_SWIMUP, -1))
|
||||
if (isActing(ACTION_SWIMUP))
|
||||
{
|
||||
helpText->offset.stop();
|
||||
helpText->offset.y += helpTextScrollSpeed * dt;
|
||||
|
@ -5027,8 +5010,6 @@ void Game::removeState()
|
|||
dsq->overlay->alpha.interpolateTo(1, fadeTime);
|
||||
dsq->run(fadeTime);
|
||||
|
||||
dsq->rumble(0,0,0,-1, INPUT_JOYSTICK);
|
||||
|
||||
dsq->sound->clearFadingSfx();
|
||||
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ public:
|
|||
|
||||
void toggleWorldMap();
|
||||
|
||||
void action(int id, int state, int source, InputDevice device);
|
||||
void action(int id, int state, int source, InputDeviceType device);
|
||||
|
||||
InGameMenu *getInGameMenu() { return themenu; }
|
||||
|
||||
|
@ -508,7 +508,7 @@ protected:
|
|||
float deathTimer;
|
||||
|
||||
|
||||
void onPressEscape(int source, InputDevice device);
|
||||
void onPressEscape(int source, InputDeviceType device);
|
||||
|
||||
bool paused;
|
||||
bool worldPaused;
|
||||
|
@ -540,7 +540,7 @@ private:
|
|||
static unsigned char grid[MAX_GRID][MAX_GRID];
|
||||
};
|
||||
|
||||
extern Game *game;
|
||||
extern Game *game; // FIXME: dupe of dsq->game, kill this
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
|
|
|
@ -142,7 +142,9 @@ enum AquariaActions
|
|||
ACTION_LOOK ,
|
||||
ACTION_TOGGLEHELPSCREEN,
|
||||
ACTION_PLACE_AVATAR,
|
||||
ACTION_SCREENSHOT
|
||||
ACTION_SCREENSHOT,
|
||||
|
||||
ACTION_SIZE // for array bounds
|
||||
};
|
||||
|
||||
enum AuraType
|
||||
|
|
41
Aquaria/GameInput.cpp
Normal file
41
Aquaria/GameInput.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "GameInput.h"
|
||||
#include "GameKeys.h"
|
||||
#include "Joystick.h"
|
||||
#include <assert.h>
|
||||
|
||||
// we use the game actions and 2 analog sticks (where 1 stick is 2 axes)
|
||||
GameInput::GameInput() : GameControlState(ACTION_SIZE, 2+2)
|
||||
{
|
||||
memset(&_emuActions[0], 0, sizeof(_emuActions));
|
||||
}
|
||||
|
||||
Vector GameInput::getStick1() const
|
||||
{
|
||||
return Vector(axes[0], axes[1]);
|
||||
}
|
||||
|
||||
Vector GameInput::getStick2() const
|
||||
{
|
||||
return Vector(axes[2], axes[3]);
|
||||
}
|
||||
|
||||
void GameInput::update()
|
||||
{
|
||||
Vector dir = getStick1();
|
||||
|
||||
// Menu input is fired by sufficient analog input or normal dpad input
|
||||
emulateAction(ACTION_MENULEFT, dir.x > JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMLEFT]);
|
||||
emulateAction(ACTION_MENURIGHT, dir.x < -JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMRIGHT]);
|
||||
emulateAction(ACTION_MENUDOWN, dir.y > JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMDOWN]);
|
||||
emulateAction(ACTION_MENUUP, dir.y < -JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMUP]);
|
||||
}
|
||||
|
||||
void GameInput::emulateAction(unsigned ac, bool on)
|
||||
{
|
||||
assert(ac < sizeof(_emuActions));
|
||||
if(_emuActions[ac] != on)
|
||||
{
|
||||
_emuActions[ac] = on;
|
||||
IInputMapper::ForwardAction(ac, on, -1, INP_DEV_NODEVICE);
|
||||
}
|
||||
}
|
21
Aquaria/GameInput.h
Normal file
21
Aquaria/GameInput.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef GAMEINPUT_H
|
||||
#define GAMEINPUT_H
|
||||
|
||||
#include "Vector.h"
|
||||
#include "InputMapper.h"
|
||||
#include "GameEnums.h"
|
||||
|
||||
class GameInput : public GameControlState
|
||||
{
|
||||
public:
|
||||
GameInput();
|
||||
void update();
|
||||
Vector getStick1() const;
|
||||
Vector getStick2() const;
|
||||
|
||||
private:
|
||||
void emulateAction(unsigned ac, bool on);
|
||||
bool _emuActions[ACTION_SIZE];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -91,7 +91,7 @@ public:
|
|||
Vector getAvatarWorldMapPosition();
|
||||
Vector getWorldToTile(WorldMapTile *tile, Vector position, bool fromCenter, bool tilePos);
|
||||
void setProperTileColor(WorldMapTile *tile);
|
||||
void action(int id, int state, int source, InputDevice device);
|
||||
void action(int id, int state, int source, InputDeviceType device);
|
||||
GemMover* addGem(GemData *gemData);
|
||||
void bindInput();
|
||||
void createGemHint(const std::string &gfx);
|
||||
|
|
|
@ -646,7 +646,7 @@ void FoodSlot::onUpdate(float dt)
|
|||
{
|
||||
if (!themenu->recipeMenu.on)
|
||||
{
|
||||
if (dsq->getInputMode() == INPUT_MOUSE)
|
||||
if (dsq->getInputMode() == INP_DEV_MOUSE)
|
||||
{
|
||||
Vector diff = core->mouse.position - getWorldPosition();
|
||||
position += diff;
|
||||
|
@ -925,32 +925,25 @@ InGameMenu::~InGameMenu()
|
|||
|
||||
void InGameMenu::bindInput()
|
||||
{
|
||||
addAction(ACTION_ESC, KEY_ESCAPE, -1);
|
||||
addAction(ACTION_ESC, KEY_ESCAPE);
|
||||
|
||||
for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i)
|
||||
const NamedAction actions[] =
|
||||
{
|
||||
const ActionSet& as = dsq->user.control.actionSets[i];
|
||||
int sourceID = (int)i;
|
||||
{ "PrimaryAction", ACTION_PRIMARY},
|
||||
{ "SecondaryAction", ACTION_SECONDARY},
|
||||
|
||||
as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID);
|
||||
as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID);
|
||||
{ "Escape", ACTION_ESC},
|
||||
{ "WorldMap", ACTION_TOGGLEWORLDMAP},
|
||||
{ "ToggleHelp", ACTION_TOGGLEHELPSCREEN},
|
||||
|
||||
as.importAction(this, "Escape", ACTION_ESC, sourceID);
|
||||
as.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP, sourceID);
|
||||
as.importAction(this, "ToggleHelp", ACTION_TOGGLEHELPSCREEN, sourceID);
|
||||
|
||||
as.importAction(this, "PrevPage", ACTION_PREVPAGE, sourceID);
|
||||
as.importAction(this, "NextPage", ACTION_NEXTPAGE, sourceID);
|
||||
as.importAction(this, "CookFood", ACTION_COOKFOOD, sourceID);
|
||||
as.importAction(this, "FoodLeft", ACTION_FOODLEFT, sourceID);
|
||||
as.importAction(this, "FoodRight", ACTION_FOODRIGHT, sourceID);
|
||||
as.importAction(this, "FoodDrop", ACTION_FOODDROP, sourceID);
|
||||
|
||||
as.importAction(this, "MenuUp", ACTION_MENUUP, sourceID);
|
||||
as.importAction(this, "MenuDown", ACTION_MENUDOWN, sourceID);
|
||||
as.importAction(this, "MenuLeft", ACTION_MENULEFT, sourceID);
|
||||
as.importAction(this, "MenuRight", ACTION_MENURIGHT, sourceID);
|
||||
}
|
||||
{ "PrevPage", ACTION_PREVPAGE},
|
||||
{ "NextPage", ACTION_NEXTPAGE},
|
||||
{ "CookFood", ACTION_COOKFOOD},
|
||||
{ "FoodLeft", ACTION_FOODLEFT},
|
||||
{ "FoodRight", ACTION_FOODRIGHT},
|
||||
{ "FoodDrop", ACTION_FOODDROP}
|
||||
};
|
||||
ImportInput(actions);
|
||||
}
|
||||
|
||||
void InGameMenu::reset()
|
||||
|
@ -981,7 +974,7 @@ void InGameMenu::onContinuityReset()
|
|||
lastOptionsMenuPage = MENUPAGE_NONE;
|
||||
}
|
||||
|
||||
void InGameMenu::action(int id, int state, int source, InputDevice device)
|
||||
void InGameMenu::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if(game->isIgnoreAction((AquariaActions)id))
|
||||
return;
|
||||
|
@ -1532,25 +1525,25 @@ void InGameMenu::addKeyConfigLine(RenderObject *group, const std::string &label,
|
|||
group->addChild(lb, PM_POINTER);
|
||||
x += KEYCONFIG_FIRST_COL_DISTANCE;
|
||||
|
||||
AquariaKeyConfig *m = new AquariaKeyConfig(actionInputName, INPUTSET_MOUSE, 0);
|
||||
AquariaKeyConfig *m = new AquariaKeyConfig(actionInputName, INP_DEV_MOUSE, 0);
|
||||
m->position = Vector(x,y);
|
||||
group->addChild(m, PM_POINTER);
|
||||
keyConfigs.push_back(m);
|
||||
x += KEYCONFIG_COL_DISTANCE;
|
||||
|
||||
AquariaKeyConfig *k1 = new AquariaKeyConfig(actionInputName, INPUTSET_KEY, 0);
|
||||
AquariaKeyConfig *k1 = new AquariaKeyConfig(actionInputName, INP_DEV_KEYBOARD, 0);
|
||||
k1->position = Vector(x,y);
|
||||
group->addChild(k1, PM_POINTER);
|
||||
keyConfigs.push_back(k1);
|
||||
x += KEYCONFIG_COL_DISTANCE;
|
||||
|
||||
AquariaKeyConfig *k2 = new AquariaKeyConfig(actionInputName, INPUTSET_KEY, 1);
|
||||
AquariaKeyConfig *k2 = new AquariaKeyConfig(actionInputName, INP_DEV_KEYBOARD, 1);
|
||||
k2->position = Vector(x,y);
|
||||
group->addChild(k2, PM_POINTER);
|
||||
keyConfigs.push_back(k2);
|
||||
x += KEYCONFIG_COL_DISTANCE;
|
||||
|
||||
AquariaKeyConfig *j1 = new AquariaKeyConfig(actionInputName, INPUTSET_JOY, 0);
|
||||
AquariaKeyConfig *j1 = new AquariaKeyConfig(actionInputName, INP_DEV_JOYSTICK, 0);
|
||||
j1->position = Vector(x,y);
|
||||
group->addChild(j1, PM_POINTER);
|
||||
keyConfigs.push_back(j1);
|
||||
|
@ -1567,6 +1560,7 @@ void InGameMenu::addKeyConfigLine(RenderObject *group, const std::string &label,
|
|||
k2->setDirMove(DIR_LEFT, k1);
|
||||
}
|
||||
|
||||
/* FIXME controllerfixup
|
||||
AquariaKeyConfig *InGameMenu::addAxesConfigLine(RenderObject *group, const std::string &label, const std::string &actionInputName, int offx, int y)
|
||||
{
|
||||
TTFText *lb = new TTFText(&dsq->fontArialSmallest);
|
||||
|
@ -1584,7 +1578,7 @@ AquariaKeyConfig *InGameMenu::addAxesConfigLine(RenderObject *group, const std::
|
|||
|
||||
return i1;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void InGameMenu::switchToSongMenu()
|
||||
{
|
||||
|
@ -2152,7 +2146,7 @@ void InGameMenu::create()
|
|||
addKeyConfigLine(kk, SB(2127), "Look", offx, y+=yi);
|
||||
|
||||
y+=yi+yi/2;
|
||||
AquariaKeyConfig* s1x = addAxesConfigLine(kk, SB(2117), "s1ax", offx, y);
|
||||
/*AquariaKeyConfig* s1x = addAxesConfigLine(kk, SB(2117), "s1ax", offx, y);
|
||||
AquariaKeyConfig* s1y = addAxesConfigLine(kk, SB(2118), "s1ay", offx+130, y);
|
||||
AquariaKeyConfig* s2x = addAxesConfigLine(kk, SB(2119), "s2ax", offx+260, y);
|
||||
AquariaKeyConfig* s2y = addAxesConfigLine(kk, SB(2120), "s2ay", offx+380, y);
|
||||
|
@ -2167,7 +2161,7 @@ void InGameMenu::create()
|
|||
s2x->setDirMove(DIR_RIGHT, s2y);
|
||||
|
||||
s2y->setDirMove(DIR_LEFT, s2x);
|
||||
s2y->setDirMove(DIR_RIGHT, s2y);
|
||||
s2y->setDirMove(DIR_RIGHT, s2y);*/ // FIXME controllerfixup
|
||||
}
|
||||
|
||||
// PART 2
|
||||
|
@ -4263,10 +4257,10 @@ void InGameMenu::updateJoystickText()
|
|||
if(j)
|
||||
{
|
||||
joystickNameText->setText(j->getName());
|
||||
int numb = j->getNumButtons();
|
||||
for(int i = 0; i < numb; ++i)
|
||||
/*int numb = j->getNumButtons();
|
||||
for(int i = 0; i < numb; ++i) // FIXME controllerfixup
|
||||
if(j->getButton(i))
|
||||
jbt << i << " ";
|
||||
jbt << i << " ";*/
|
||||
}
|
||||
else if(as.joystickID == ACTIONSET_REASSIGN_JOYSTICK)
|
||||
{
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
void onContinuityReset();
|
||||
|
||||
void bindInput();
|
||||
virtual void action(int actionID, int state, int source, InputDevice device);
|
||||
virtual void action(int actionID, int state, int source, InputDeviceType device);
|
||||
|
||||
void refreshFoodSlots(bool effects);
|
||||
|
||||
|
|
|
@ -413,7 +413,7 @@ void MiniMapRender::onUpdate(float dt)
|
|||
{
|
||||
doubleClickDelay = 0;
|
||||
if (!core->isStateJumpPending())
|
||||
dsq->game->action(ACTION_TOGGLEMENU, 1, -1, INPUT_NODEVICE);
|
||||
dsq->game->action(ACTION_TOGGLEMENU, 1, -1, INP_DEV_NODEVICE);
|
||||
btn = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -119,7 +119,7 @@ void ModSelectorScreen::onUpdate(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
if(!AquariaGuiElement::currentFocus && dsq->getInputMode() == INPUT_JOYSTICK)
|
||||
if(!AquariaGuiElement::currentFocus && dsq->getInputMode() == INP_DEV_JOYSTICK)
|
||||
{
|
||||
AquariaGuiElement *closest = AquariaGuiElement::getClosestGuiElement(core->mouse.position);
|
||||
if(closest)
|
||||
|
|
|
@ -166,7 +166,7 @@ public:
|
|||
|
||||
void setSubText(const std::string& s);
|
||||
|
||||
virtual void action(int actionID, int state, int source, InputDevice device) {}
|
||||
virtual void action(int actionID, int state, int source, InputDeviceType device) {}
|
||||
|
||||
protected:
|
||||
virtual void onUpdate(float dt);
|
||||
|
|
|
@ -637,7 +637,7 @@ void Path::update(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
bool Path::action(int id, int state, int source, InputDevice device)
|
||||
bool Path::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if (hasScript())
|
||||
{
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
void addNode(size_t idx);
|
||||
void update(float dt);
|
||||
void setActive(bool v);
|
||||
bool action(int id, int state, int source, InputDevice device);
|
||||
bool action(int id, int state, int source, InputDeviceType device);
|
||||
void setEmitter(const std::string& name);
|
||||
|
||||
PathNode *getPathNode(size_t idx);
|
||||
|
|
|
@ -577,37 +577,37 @@ void SceneEditor::init()
|
|||
|
||||
|
||||
|
||||
addAction(ACTION_ZOOMIN, KEY_PGUP, -1);
|
||||
addAction(ACTION_ZOOMOUT, KEY_PGDN, -1);
|
||||
addAction(ACTION_ZOOMIN, KEY_PGUP);
|
||||
addAction(ACTION_ZOOMOUT, KEY_PGDN);
|
||||
|
||||
addAction(ACTION_CAMLEFT, KEY_A, -1);
|
||||
addAction(ACTION_CAMRIGHT, KEY_D, -1);
|
||||
addAction(ACTION_CAMUP, KEY_W, -1);
|
||||
addAction(ACTION_CAMDOWN, KEY_S, -1);
|
||||
addAction(ACTION_CAMLEFT, KEY_A);
|
||||
addAction(ACTION_CAMRIGHT, KEY_D);
|
||||
addAction(ACTION_CAMUP, KEY_W);
|
||||
addAction(ACTION_CAMDOWN, KEY_S);
|
||||
|
||||
addAction(ACTION_BGLAYEREND, KEY_0, -1);
|
||||
addAction(ACTION_BGLAYEREND, KEY_0);
|
||||
|
||||
addAction(ACTION_BGLAYER1, KEY_1, -1);
|
||||
addAction(ACTION_BGLAYER2, KEY_2, -1);
|
||||
addAction(ACTION_BGLAYER3, KEY_3, -1);
|
||||
addAction(ACTION_BGLAYER4, KEY_4, -1);
|
||||
addAction(ACTION_BGLAYER5, KEY_5, -1);
|
||||
addAction(ACTION_BGLAYER6, KEY_6, -1);
|
||||
addAction(ACTION_BGLAYER7, KEY_7, -1);
|
||||
addAction(ACTION_BGLAYER8, KEY_8, -1);
|
||||
addAction(ACTION_BGLAYER9, KEY_9, -1);
|
||||
addAction(ACTION_BGLAYER1, KEY_1);
|
||||
addAction(ACTION_BGLAYER2, KEY_2);
|
||||
addAction(ACTION_BGLAYER3, KEY_3);
|
||||
addAction(ACTION_BGLAYER4, KEY_4);
|
||||
addAction(ACTION_BGLAYER5, KEY_5);
|
||||
addAction(ACTION_BGLAYER6, KEY_6);
|
||||
addAction(ACTION_BGLAYER7, KEY_7);
|
||||
addAction(ACTION_BGLAYER8, KEY_8);
|
||||
addAction(ACTION_BGLAYER9, KEY_9);
|
||||
|
||||
addAction(ACTION_BGLAYER10, KEY_B, -1);
|
||||
addAction(ACTION_BGLAYER11, KEY_N, -1);
|
||||
addAction(ACTION_BGLAYER12, KEY_M, -1);
|
||||
addAction(ACTION_BGLAYER10, KEY_B);
|
||||
addAction(ACTION_BGLAYER11, KEY_N);
|
||||
addAction(ACTION_BGLAYER12, KEY_M);
|
||||
|
||||
addAction(ACTION_BGLAYER13, KEY_J, -1);
|
||||
addAction(ACTION_BGLAYER13, KEY_J);
|
||||
|
||||
addAction(ACTION_BGLAYER14, KEY_COMMA, -1);
|
||||
addAction(ACTION_BGLAYER15, KEY_PERIOD, -1);
|
||||
addAction(ACTION_BGLAYER16, KEY_SLASH, -1);
|
||||
addAction(ACTION_BGLAYER14, KEY_COMMA);
|
||||
addAction(ACTION_BGLAYER15, KEY_PERIOD);
|
||||
addAction(ACTION_BGLAYER16, KEY_SLASH);
|
||||
|
||||
addAction(ACTION_MULTISELECT, KEY_LALT, -1);
|
||||
addAction(ACTION_MULTISELECT, KEY_LALT);
|
||||
|
||||
placer = new Quad;
|
||||
dsq->game->addRenderObject(placer, LR_HUD);
|
||||
|
@ -1845,7 +1845,7 @@ void SceneEditor::removeEntity()
|
|||
void SceneEditor::placeAvatar()
|
||||
{
|
||||
dsq->game->avatar->position = dsq->getGameCursorPosition();
|
||||
dsq->game->action(ACTION_PLACE_AVATAR, 0, -1, INPUT_NODEVICE);
|
||||
dsq->game->action(ACTION_PLACE_AVATAR, 0, -1, INP_DEV_NODEVICE);
|
||||
}
|
||||
|
||||
void SceneEditor::scaleElementUp()
|
||||
|
@ -1952,7 +1952,7 @@ void SceneEditor::updateMultiSelect()
|
|||
}
|
||||
}
|
||||
|
||||
void SceneEditor::action(int id, int state, int source, InputDevice device)
|
||||
void SceneEditor::action(int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if (core->getCtrlState() && editingElement)
|
||||
{
|
||||
|
@ -2788,11 +2788,11 @@ void SceneEditor::update(float dt)
|
|||
{
|
||||
case ET_ELEMENTS:
|
||||
editingEntity = 0;
|
||||
if (isActing(ACTION_MULTISELECT, -1) || !selectedElements.empty())
|
||||
if (isActing(ACTION_MULTISELECT) || !selectedElements.empty())
|
||||
{
|
||||
editingElement = 0;
|
||||
}
|
||||
if (state == ES_SELECTING && !isActing(ACTION_MULTISELECT, -1))
|
||||
if (state == ES_SELECTING && !isActing(ACTION_MULTISELECT))
|
||||
editingElement = this->getElementAtCursor();
|
||||
|
||||
if (editingElement)
|
||||
|
@ -2825,13 +2825,13 @@ void SceneEditor::update(float dt)
|
|||
int camSpeed = 500/zoom.x;
|
||||
if (core->getShiftState())
|
||||
camSpeed = 5000/zoom.x;
|
||||
if (isActing(ACTION_CAMLEFT, -1))
|
||||
if (isActing(ACTION_CAMLEFT))
|
||||
dsq->cameraPos.x -= dt*camSpeed;
|
||||
if (isActing(ACTION_CAMRIGHT, -1))
|
||||
if (isActing(ACTION_CAMRIGHT))
|
||||
dsq->cameraPos.x += dt*camSpeed;
|
||||
if (isActing(ACTION_CAMUP, -1))
|
||||
if (isActing(ACTION_CAMUP))
|
||||
dsq->cameraPos.y -= dt*camSpeed;
|
||||
if (isActing(ACTION_CAMDOWN, -1))
|
||||
if (isActing(ACTION_CAMDOWN))
|
||||
dsq->cameraPos.y += dt*camSpeed;
|
||||
if (core->mouse.buttons.middle && !core->mouse.change.isZero())
|
||||
{
|
||||
|
@ -2841,9 +2841,9 @@ void SceneEditor::update(float dt)
|
|||
|
||||
float spd = 0.5;
|
||||
const Vector oldZoom = zoom;
|
||||
if (isActing(ACTION_ZOOMOUT, -1))
|
||||
if (isActing(ACTION_ZOOMOUT))
|
||||
zoom /= (1 + spd*dt);
|
||||
else if (isActing(ACTION_ZOOMIN, -1))
|
||||
else if (isActing(ACTION_ZOOMIN))
|
||||
zoom *= (1 + spd*dt);
|
||||
else if (core->mouse.scrollWheelChange < 0)
|
||||
{
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
void flipElementVert();
|
||||
void deleteSelectedElement();
|
||||
void deleteElement(int selectedIdx);
|
||||
virtual void action(int id, int state, int source, InputDevice device);
|
||||
virtual void action(int id, int state, int source, InputDeviceType device);
|
||||
void scaleElementUp();
|
||||
void scaleElementDown();
|
||||
void scaleElement1();
|
||||
|
|
|
@ -2081,7 +2081,7 @@ luaFunc(sendAction)
|
|||
int state = lua_tointeger(L, 2);
|
||||
int mask = lua_tointeger(L, 3);
|
||||
int source = lua_tointeger(L, 4);
|
||||
InputDevice device = (InputDevice)lua_tointeger(L, 5);
|
||||
InputDeviceType device = (InputDeviceType)lua_tointeger(L, 5);
|
||||
if(!mask)
|
||||
mask = -1;
|
||||
if(mask & 1)
|
||||
|
@ -2117,12 +2117,8 @@ luaFunc(shakeCamera)
|
|||
|
||||
luaFunc(rumble)
|
||||
{
|
||||
int source = lua_tointeger(L, 4) - 1;
|
||||
Avatar *a = dsq->game->avatar;
|
||||
InputDevice device = (InputDevice)lua_tointeger(L, 5);
|
||||
if(device == INPUT_NODEVICE) // default: use avatar status
|
||||
device = a ? a->getLastActionInputDevice() : INPUT_NODEVICE;
|
||||
dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), source, device);
|
||||
int playerID = lua_tointeger(L, 4) - 1;
|
||||
dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), playerID);
|
||||
luaReturnNil();
|
||||
}
|
||||
|
||||
|
@ -5014,24 +5010,24 @@ luaFunc(screenFadeGo)
|
|||
|
||||
luaFunc(isEscapeKey)
|
||||
{
|
||||
int source = lua_tointeger(L, 1) - 1;
|
||||
bool isDown = dsq->game->isActing(ACTION_ESC, source);
|
||||
int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup
|
||||
bool isDown = dsq->game->isActing(ACTION_ESC);
|
||||
luaReturnBool(isDown);
|
||||
}
|
||||
|
||||
luaFunc(isLeftMouse)
|
||||
{
|
||||
int source = lua_tointeger(L, 1) - 1;
|
||||
bool isDown = (source < 0 && core->mouse.buttons.left)
|
||||
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_PRIMARY, source));
|
||||
int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup
|
||||
bool isDown = (playerID < 0 && core->mouse.buttons.left)
|
||||
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_PRIMARY));
|
||||
luaReturnBool(isDown);
|
||||
}
|
||||
|
||||
luaFunc(isRightMouse)
|
||||
{
|
||||
int source = lua_tointeger(L, 1) - 1;
|
||||
bool isDown = (source < 0 && core->mouse.buttons.right)
|
||||
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_SECONDARY, source));
|
||||
int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup
|
||||
bool isDown = (playerID < 0 && core->mouse.buttons.right)
|
||||
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_SECONDARY));
|
||||
luaReturnBool(isDown);
|
||||
}
|
||||
|
||||
|
@ -8395,32 +8391,33 @@ luaFunc(disableInput)
|
|||
|
||||
luaFunc(getInputMode)
|
||||
{
|
||||
int source = lua_tointeger(L, 1);
|
||||
luaReturnInt(dsq->getInputModeSafe(source - 1));
|
||||
//int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup?
|
||||
luaReturnInt(dsq->getInputMode());
|
||||
}
|
||||
|
||||
static Joystick *_getJoystick(lua_State *L, int idx = 1)
|
||||
// FIXME: repair for controllerfixup
|
||||
/*static Joystick *_getJoystick(lua_State *L, int idx = 1)
|
||||
{
|
||||
int source = lua_tointeger(L, idx) - 1;
|
||||
if(source < 0)
|
||||
return core->getJoystick(0); // HACK: FIXME: do something sensible instead
|
||||
|
||||
return core->getJoystickForSourceID(source);
|
||||
}
|
||||
}*/
|
||||
|
||||
luaFunc(getJoystickAxisLeft)
|
||||
{
|
||||
Vector v;
|
||||
if(Joystick *j = _getJoystick(L))
|
||||
v = j->position;
|
||||
//if(Joystick *j = _getJoystick(L))
|
||||
// v = j->position;
|
||||
luaReturnVec2(v.x, v.y);
|
||||
}
|
||||
|
||||
luaFunc(getJoystickAxisRight)
|
||||
{
|
||||
Vector v;
|
||||
if(Joystick *j = _getJoystick(L))
|
||||
v = j->rightStick;
|
||||
//if(Joystick *j = _getJoystick(L))
|
||||
// v = j->rightStick;
|
||||
luaReturnVec2(v.x, v.y);
|
||||
}
|
||||
|
||||
|
@ -11449,9 +11446,9 @@ static const struct {
|
|||
|
||||
luaConstant(TILE_SIZE),
|
||||
|
||||
luaConstant(INPUT_MOUSE),
|
||||
luaConstant(INPUT_JOYSTICK),
|
||||
luaConstant(INPUT_KEYBOARD),
|
||||
luaConstant(INP_DEV_MOUSE),
|
||||
luaConstant(INP_DEV_JOYSTICK),
|
||||
luaConstant(INP_DEV_KEYBOARD),
|
||||
|
||||
luaConstant(ANIMLAYER_FLOURISH),
|
||||
luaConstant(ANIMLAYER_OVERRIDE),
|
||||
|
|
|
@ -135,8 +135,6 @@ GameOver::GameOver() : StateObject()
|
|||
|
||||
void GameOver::applyState()
|
||||
{
|
||||
const bool frameOutputGameOver = false;
|
||||
|
||||
core->sound->fadeMusic(SFT_OUT, 1);
|
||||
|
||||
|
||||
|
@ -147,12 +145,6 @@ void GameOver::applyState()
|
|||
|
||||
core->sound->playSfx("Death");
|
||||
|
||||
if (frameOutputGameOver)
|
||||
{
|
||||
dsq->fpsText->alpha = 0;
|
||||
core->frameOutputMode = true;
|
||||
}
|
||||
|
||||
Quad *q = new Quad;
|
||||
{
|
||||
q->color = 0;
|
||||
|
@ -248,13 +240,6 @@ void GameOver::applyState()
|
|||
}
|
||||
else
|
||||
dsq->title();
|
||||
|
||||
|
||||
|
||||
if (frameOutputGameOver)
|
||||
core->frameOutputMode = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void GameOver::removeState()
|
||||
|
|
|
@ -218,7 +218,7 @@ void UserSettings::save()
|
|||
{
|
||||
XMLElement *xml_action = doc.NewElement("Action");
|
||||
const ActionInput& ai = as.inputSet[i];
|
||||
xml_action->SetAttribute("name", ai.name.c_str());
|
||||
xml_action->SetAttribute("name", ai.getName().c_str());
|
||||
xml_action->SetAttribute("input", ai.toString().c_str());
|
||||
|
||||
xml_actionSet->InsertEndChild(xml_action);
|
||||
|
@ -280,30 +280,30 @@ void UserSettings::save()
|
|||
static void ensureDefaultActions(ActionSet& as)
|
||||
{
|
||||
as.clearActions();
|
||||
as.addActionInput("PrimaryAction");
|
||||
as.addActionInput("SecondaryAction");
|
||||
as.addActionInput("SwimUp");
|
||||
as.addActionInput("SwimDown");
|
||||
as.addActionInput("SwimLeft");
|
||||
as.addActionInput("SwimRight");
|
||||
as.addActionInput("Roll");
|
||||
as.addActionInput("Revert");
|
||||
as.addActionInput("WorldMap");
|
||||
as.addActionInput("Escape");
|
||||
as.addActionInput("PrevPage");
|
||||
as.addActionInput("NextPage");
|
||||
as.addActionInput("CookFood");
|
||||
as.addActionInput("FoodLeft");
|
||||
as.addActionInput("FoodRight");
|
||||
as.addActionInput("FoodDrop");
|
||||
as.addActionInput("Look");
|
||||
as.addActionInput("ToggleHelp");
|
||||
as.addActionInput("Screenshot");
|
||||
as.ensureActionInput("PrimaryAction");
|
||||
as.ensureActionInput("SecondaryAction");
|
||||
as.ensureActionInput("SwimUp");
|
||||
as.ensureActionInput("SwimDown");
|
||||
as.ensureActionInput("SwimLeft");
|
||||
as.ensureActionInput("SwimRight");
|
||||
as.ensureActionInput("Roll");
|
||||
as.ensureActionInput("Revert");
|
||||
as.ensureActionInput("WorldMap");
|
||||
as.ensureActionInput("Escape");
|
||||
as.ensureActionInput("PrevPage");
|
||||
as.ensureActionInput("NextPage");
|
||||
as.ensureActionInput("CookFood");
|
||||
as.ensureActionInput("FoodLeft");
|
||||
as.ensureActionInput("FoodRight");
|
||||
as.ensureActionInput("FoodDrop");
|
||||
as.ensureActionInput("Look");
|
||||
as.ensureActionInput("ToggleHelp");
|
||||
as.ensureActionInput("Screenshot");
|
||||
for(int i = 1; i <= 10; ++i)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "SongSlot" << i;
|
||||
as.addActionInput(os.str());
|
||||
as.ensureActionInput(os.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,8 +505,8 @@ void UserSettings::load(bool doApply, const std::string &overrideFile)
|
|||
const char *input = xml_action->Attribute("input");
|
||||
if (name && *name && input && *input)
|
||||
{
|
||||
ActionInput *ai = as.addActionInput(name);
|
||||
ai->fromString(input);
|
||||
ActionInput& ai = as.ensureActionInput(name);
|
||||
ai.fromString(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,30 +584,10 @@ void UserSettings::apply()
|
|||
|
||||
dsq->loops.updateVolume();
|
||||
|
||||
for(size_t i = 0; i < control.actionSets.size(); ++i)
|
||||
{
|
||||
ActionSet& as = control.actionSets[i];
|
||||
Joystick *j = core->getJoystick(as.joystickID);
|
||||
if(j)
|
||||
{
|
||||
j->s1ax = as.joycfg.s1ax;
|
||||
j->s1ay = as.joycfg.s1ay;
|
||||
j->s2ax = as.joycfg.s2ax;
|
||||
j->s2ay = as.joycfg.s2ay;
|
||||
j->deadZone1 = as.joycfg.s1dead;
|
||||
j->deadZone2 = as.joycfg.s2dead;
|
||||
}
|
||||
}
|
||||
dsq->initActionButtons();
|
||||
dsq->fixupJoysticks();
|
||||
|
||||
core->debugLogActive = system.debugLogOn;
|
||||
|
||||
if (dsq->game)
|
||||
{
|
||||
dsq->game->bindInput();
|
||||
}
|
||||
|
||||
dsq->bindInput();
|
||||
|
||||
core->settings.prebufferSounds = audio.prebuffer;
|
||||
|
|
|
@ -794,21 +794,19 @@ void WorldMapRender::bindInput()
|
|||
clearActions();
|
||||
clearCreatedEvents();
|
||||
|
||||
addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB, -1);
|
||||
addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB);
|
||||
|
||||
for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i)
|
||||
const NamedAction actions[] =
|
||||
{
|
||||
const ActionSet& as = dsq->user.control.actionSets[i];
|
||||
int sourceID = (int)i;
|
||||
{ "PrimaryAction", ACTION_PRIMARY },
|
||||
{ "SecondaryAction", ACTION_SECONDARY },
|
||||
|
||||
as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID);
|
||||
as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID);
|
||||
|
||||
as.importAction(this, "SwimLeft", ACTION_SWIMLEFT, sourceID);
|
||||
as.importAction(this, "SwimRight", ACTION_SWIMRIGHT, sourceID);
|
||||
as.importAction(this, "SwimUp", ACTION_SWIMUP, sourceID);
|
||||
as.importAction(this, "SwimDown", ACTION_SWIMDOWN, sourceID);
|
||||
}
|
||||
{ "SwimLeft", ACTION_SWIMLEFT },
|
||||
{ "SwimRight", ACTION_SWIMRIGHT },
|
||||
{ "SwimUp", ACTION_SWIMUP },
|
||||
{ "SwimDown", ACTION_SWIMDOWN }
|
||||
};
|
||||
ImportInput(actions);
|
||||
}
|
||||
|
||||
void WorldMapRender::destroy()
|
||||
|
@ -992,15 +990,15 @@ void WorldMapRender::onUpdate(float dt)
|
|||
{
|
||||
float scrollSpeed = 2.0f;
|
||||
float amt = (400*dt)/scale.x;
|
||||
if (isActing(ACTION_SWIMLEFT, -1))
|
||||
if (isActing(ACTION_SWIMLEFT))
|
||||
{
|
||||
internalOffset += Vector(amt, 0);
|
||||
}
|
||||
if (isActing(ACTION_SWIMRIGHT, -1))
|
||||
if (isActing(ACTION_SWIMRIGHT))
|
||||
{
|
||||
internalOffset += Vector(-amt, 0);
|
||||
}
|
||||
if (isActing(ACTION_SWIMDOWN, -1))
|
||||
if (isActing(ACTION_SWIMDOWN))
|
||||
{
|
||||
if (core->getShiftState())
|
||||
{
|
||||
|
@ -1012,7 +1010,7 @@ void WorldMapRender::onUpdate(float dt)
|
|||
internalOffset += Vector(0, -amt);
|
||||
}
|
||||
}
|
||||
if (isActing(ACTION_SWIMUP, -1))
|
||||
if (isActing(ACTION_SWIMUP))
|
||||
{
|
||||
if (core->getShiftState())
|
||||
{
|
||||
|
@ -1024,10 +1022,10 @@ void WorldMapRender::onUpdate(float dt)
|
|||
internalOffset += Vector(0, amt);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // FIXME controllerfixup
|
||||
if (core->joystickEnabled)
|
||||
{
|
||||
if (isActing(ACTION_SECONDARY, -1))
|
||||
if (isActing(ACTION_SECONDARY))
|
||||
{
|
||||
Vector jpos;
|
||||
for(size_t i = 0; i < core->getNumJoysticks(); ++i)
|
||||
|
@ -1061,6 +1059,7 @@ void WorldMapRender::onUpdate(float dt)
|
|||
internalOffset += jpos * (-400*dt / scale.x);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (activeTile && activeTile->layer == 1)
|
||||
|
@ -1501,7 +1500,7 @@ void WorldMapRender::updateEditor()
|
|||
areaLabel->setText(os.str());
|
||||
}
|
||||
|
||||
void WorldMapRender::action (int id, int state, int source, InputDevice device)
|
||||
void WorldMapRender::action (int id, int state, int source, InputDeviceType device)
|
||||
{
|
||||
if (isOn())
|
||||
{
|
||||
|
|
|
@ -26,267 +26,267 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#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)
|
||||
static const char *jaxisname(int joystickID, unsigned axis)
|
||||
{
|
||||
Joystick *j = core->getJoystick(joystickID);
|
||||
return j ? j->getAxisName(axis) : NULL;
|
||||
const char *s = j ? j->getAxisName(axis - 1) : NULL;
|
||||
return s && *s ? s : NULL;
|
||||
}
|
||||
|
||||
static const char *jbtnname(int joystickID, int btn)
|
||||
static const char *jbtnname(int joystickID, unsigned btn)
|
||||
{
|
||||
Joystick *j = core->getJoystick(joystickID);
|
||||
return j ? j->getButtonName(btn) : NULL;
|
||||
const char *s = j ? j->getButtonName(btn - 1) : NULL;
|
||||
return s && *s ? s : NULL;
|
||||
}
|
||||
|
||||
std::string getInputCodeToString(int k)
|
||||
struct JoyHatDir
|
||||
{
|
||||
std::string s = inputcode2string(k);
|
||||
return s.empty() ? "0" : s;
|
||||
char c, pretty;
|
||||
int x, y;
|
||||
};
|
||||
static const JoyHatDir s_joyhat[] =
|
||||
{
|
||||
{ 'u', '^', 0, -1 },
|
||||
{ 'd', 'v', 0, 1 },
|
||||
{ 'l', '<', -1, 0 },
|
||||
{ 'r', '>', 0, 1 },
|
||||
{ 0, 0, 0, 0 }, // terminator
|
||||
};
|
||||
|
||||
static std::string num2str(unsigned x)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << x;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string getInputCodeToUserString(unsigned int k, size_t joystickID)
|
||||
static std::string getMouseButtonToString(unsigned b)
|
||||
{
|
||||
const char *pretty = NULL, *tail = NULL;
|
||||
static const char *buf[] = { "LMB", "MMB", "RMB" };
|
||||
if(b && b < 4) // 1 2 3
|
||||
return buf[b-1];
|
||||
return num2str(b);
|
||||
}
|
||||
|
||||
static const char *getRawSDLKeyName(unsigned k)
|
||||
{
|
||||
const char *s = NULL;
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
s = SDL_GetScancodeName((SDL_Scancode)k);
|
||||
#else
|
||||
s = SDL_GetKeyName((SDLKey)k);
|
||||
#endif
|
||||
return s && *s ? s : NULL;
|
||||
}
|
||||
|
||||
static const char *getPrettySDLKeyName(unsigned k)
|
||||
{
|
||||
const char *s;
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
// 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);
|
||||
}
|
||||
const SDL_Keycode kcode = SDL_GetKeyFromScancode((SDL_Scancode)k);
|
||||
if(kcode == SDLK_UNKNOWN)
|
||||
s = SDL_GetScancodeName((SDL_Scancode)k);
|
||||
else
|
||||
s = SDL_GetKeyName(kcode);
|
||||
#else
|
||||
s = SDL_GetKeyName((SDLKey)k);
|
||||
#endif
|
||||
return s && *s ? s : NULL;
|
||||
}
|
||||
|
||||
static unsigned getKeyCodeFromSDLName(const char *s)
|
||||
{
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
return SDL_GetScancodeFromName(s);
|
||||
#endif
|
||||
return SDL_GetKeyFromName(s);
|
||||
}
|
||||
|
||||
static std::string getKeyToString(unsigned k)
|
||||
{
|
||||
assert(k < KEY_MAXARRAY);
|
||||
const char *s = getLegacyKeyNameFromInputCode(k);
|
||||
if(s)
|
||||
return s;
|
||||
s = getRawSDLKeyName(k);
|
||||
if(s)
|
||||
return s;
|
||||
|
||||
return num2str(k);
|
||||
}
|
||||
|
||||
static std::string getJoystickDataToString(const ActionInput::JoyData& jd)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
switch(jd.ctrlType)
|
||||
{
|
||||
// Maybe we're upgrading from an old config?
|
||||
// This handles KEY_* and some old mouse/joystick names.
|
||||
k = getInputCodeFromKeyName(s.c_str());
|
||||
case INP_CTRL_BUTTON:
|
||||
os << jd.ctrlID;
|
||||
break;
|
||||
case INP_CTRL_AXIS:
|
||||
os << 'A' << ((jd.x < 0 || jd.y < 0) ? '-' : '+') << jd.ctrlID;
|
||||
break;
|
||||
case INP_CTRL_HAT:
|
||||
os << 'H';
|
||||
for(const JoyHatDir *hd = &s_joyhat[0]; hd->c; ++hd)
|
||||
if(jd.x == hd->x && jd.y == hd->y)
|
||||
{
|
||||
os << hd->c << jd.ctrlID;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// Non-configurable keys
|
||||
if(k == KEY_ESCAPE)
|
||||
return 0;
|
||||
|
||||
if(k < ACTION_BUTTON_ENUM_SIZE)
|
||||
return k;
|
||||
static std::string getJoystickDataToPrettyString(const ActionInput::JoyData& jd, int joystickID)
|
||||
{
|
||||
if(!jd.ctrlID)
|
||||
return std::string();
|
||||
|
||||
std::ostringstream os;
|
||||
os << "ActionButton out of range: [" << s << "] = " << k;
|
||||
errorLog(os.str());
|
||||
return 0;
|
||||
static const char *axislabels[] = { "(-)", "", "(+)" };
|
||||
|
||||
switch(jd.ctrlType)
|
||||
{
|
||||
case INP_CTRL_BUTTON:
|
||||
{
|
||||
const char *s = jbtnname(joystickID, jd.ctrlID);
|
||||
if(s)
|
||||
os << s;
|
||||
else
|
||||
os << jd.ctrlID;
|
||||
}
|
||||
break;
|
||||
|
||||
case INP_CTRL_AXIS:
|
||||
{
|
||||
const char *s = jaxisname(joystickID, jd.ctrlID);
|
||||
if(s)
|
||||
os << s;
|
||||
else
|
||||
os << "A:" << jd.ctrlID;
|
||||
os << axislabels[jd.x + 1] << axislabels[jd.y + 1];
|
||||
}
|
||||
break;
|
||||
|
||||
case INP_CTRL_HAT:
|
||||
{
|
||||
os << "H:" << jd.ctrlID << ":";
|
||||
for(const JoyHatDir *hd = &s_joyhat[0]; hd->c; ++hd)
|
||||
if(jd.x == hd->x && jd.y == hd->y)
|
||||
{
|
||||
os << hd->pretty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
static unsigned getMouseButtonFromString_Legacy(const std::string& s)
|
||||
{
|
||||
if(s == "LMB")
|
||||
return MOUSE_BUTTON_LEFT;
|
||||
else if(s == "RMB")
|
||||
return MOUSE_BUTTON_RIGHT;
|
||||
else if(s == "MMB")
|
||||
return MOUSE_BUTTON_MIDDLE;
|
||||
|
||||
return getLegacyInputCodeFromKeyName(s.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ActionInput::ActionInput()
|
||||
static unsigned getMouseButtonFromString(const std::string& s)
|
||||
{
|
||||
for (int i = 0; i < INP_COMBINED_SIZE; i++)
|
||||
data.all[i] = 0;
|
||||
if(s.empty() || s == "0")
|
||||
return 0;
|
||||
|
||||
unsigned k = getMouseButtonFromString_Legacy(s);
|
||||
switch(k)
|
||||
{
|
||||
case MOUSE_BUTTON_LEFT: return 1;
|
||||
case MOUSE_BUTTON_RIGHT: return 2;
|
||||
case MOUSE_BUTTON_MIDDLE: return 3;
|
||||
default: ;
|
||||
}
|
||||
|
||||
return atoi(s.c_str());
|
||||
}
|
||||
|
||||
static unsigned getKeyFromString(const std::string& s)
|
||||
{
|
||||
if(s.empty() || s == "0")
|
||||
return 0;
|
||||
|
||||
unsigned k = getLegacyInputCodeFromKeyName(s.c_str()); // fallback
|
||||
if(k)
|
||||
return k;
|
||||
k = getKeyCodeFromSDLName(s.c_str());
|
||||
if(k)
|
||||
return k;
|
||||
|
||||
return atoi(s.c_str());
|
||||
}
|
||||
|
||||
static ActionInput::JoyData getJostickDataFromString(const std::string& s)
|
||||
{
|
||||
ActionInput::JoyData jd;
|
||||
|
||||
if(s.length() && s != "0")
|
||||
{
|
||||
switch(s[0])
|
||||
{
|
||||
case 'A': // axis
|
||||
{
|
||||
jd.ctrlType = INP_CTRL_AXIS;
|
||||
int ax = atoi(s.c_str() + 1);
|
||||
jd.ctrlID = ax < 0 ? -ax : ax;
|
||||
jd.x = ax < 0 ? -1 : 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H': // hat
|
||||
jd.ctrlType = INP_CTRL_HAT;
|
||||
if(s.length() > 1)
|
||||
for(const JoyHatDir *hd = &s_joyhat[0]; hd->c; ++hd)
|
||||
if(hd->c == s[1])
|
||||
{
|
||||
jd.x = hd->x;
|
||||
jd.y = hd->y;
|
||||
jd.ctrlID = atoi(s.c_str() + 2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: // button
|
||||
jd.ctrlType = INP_CTRL_BUTTON;
|
||||
jd.ctrlID = atoi(s.c_str() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return jd;
|
||||
}
|
||||
|
||||
ActionInput::JoyData::JoyData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
ActionInput::ActionInput(const std::string& name_)
|
||||
: name(name_)
|
||||
{
|
||||
for (int i = 0; i < INP_MSESIZE; i++)
|
||||
mse[i] = 0;
|
||||
for (int i = 0; i < INP_KEYSIZE; i++)
|
||||
key[i] = 0;
|
||||
// joy[] inited by its own ctor
|
||||
}
|
||||
|
||||
std::string ActionInput::toString() const
|
||||
|
@ -295,15 +295,15 @@ std::string ActionInput::toString() const
|
|||
|
||||
for (int i = 0; i < INP_MSESIZE; i++)
|
||||
{
|
||||
os << getInputCodeToString(data.single.mse[i]) << " ";
|
||||
os << getMouseButtonToString(mse[i]) << " ";
|
||||
}
|
||||
for (int i = 0; i < INP_KEYSIZE; i++)
|
||||
{
|
||||
os << getInputCodeToString(data.single.key[i]) << " ";
|
||||
os << getKeyToString(key[i]) << " ";
|
||||
}
|
||||
for (int i = 0; i < INP_JOYSIZE; i++)
|
||||
{
|
||||
os << getInputCodeToString(data.single.joy[i]) << " ";
|
||||
os << getJoystickDataToString(joy[i]) << " ";
|
||||
}
|
||||
|
||||
return os.str();
|
||||
|
@ -316,17 +316,231 @@ void ActionInput::fromString(const std::string &read)
|
|||
for (int i = 0; i < INP_MSESIZE; i++)
|
||||
{
|
||||
is >> str;
|
||||
data.single.mse[i] = getStringToInputCode(str);
|
||||
mse[i] = getMouseButtonFromString(str);
|
||||
}
|
||||
for (int i = 0; i < INP_KEYSIZE; i++)
|
||||
{
|
||||
is >> str;
|
||||
data.single.key[i] = getStringToInputCode(str);
|
||||
key[i] = getKeyFromString(str);
|
||||
}
|
||||
for (int i = 0; i < INP_JOYSIZE; i++)
|
||||
{
|
||||
is >> str;
|
||||
data.single.joy[i] = getStringToInputCode(str);
|
||||
joy[i] = getJostickDataFromString(str);
|
||||
}
|
||||
}
|
||||
|
||||
struct TypeAndSlot
|
||||
{
|
||||
InputDeviceType type;
|
||||
unsigned slot;
|
||||
};
|
||||
static TypeAndSlot getTypeAndSlot(unsigned field)
|
||||
{
|
||||
TypeAndSlot ts;
|
||||
if(field < INP_MSESIZE)
|
||||
{
|
||||
ts.type = INP_DEV_MOUSE;
|
||||
ts.slot = field;
|
||||
}
|
||||
else if(field < INP_MSESIZE + INP_KEYSIZE)
|
||||
{
|
||||
ts.type = INP_DEV_KEYBOARD;
|
||||
ts.slot = field - INP_MSESIZE;
|
||||
}
|
||||
else if(field < INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE)
|
||||
{
|
||||
ts.type = INP_DEV_JOYSTICK;
|
||||
ts.slot = field - (INP_MSESIZE + INP_KEYSIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
ts.type = InputDeviceType(-1);
|
||||
ts.slot = unsigned(-1);
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
unsigned ActionInput::GetField(InputDeviceType dev, unsigned slot)
|
||||
{
|
||||
unsigned base = 0;
|
||||
switch(dev)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
base = 0;
|
||||
assert(slot < INP_MSESIZE);
|
||||
break;
|
||||
case INP_DEV_KEYBOARD:
|
||||
base = INP_MSESIZE;
|
||||
assert(slot < INP_KEYSIZE);
|
||||
break;
|
||||
case INP_DEV_JOYSTICK:
|
||||
base = INP_MSESIZE+INP_KEYSIZE;
|
||||
assert(slot < INP_JOYSIZE);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
return base + slot;
|
||||
}
|
||||
|
||||
|
||||
std::string ActionInput::prettyPrintField(unsigned field, int joystickID /* = -1 */) const
|
||||
{
|
||||
TypeAndSlot ts = getTypeAndSlot(field);
|
||||
switch(ts.type)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
return getMouseButtonToString(mse[field]);
|
||||
case INP_DEV_KEYBOARD:
|
||||
{
|
||||
unsigned k = key[ts.slot];
|
||||
const char *s = getPrettySDLKeyName(k);
|
||||
if(s)
|
||||
return s;
|
||||
return getKeyToString(k);
|
||||
}
|
||||
case INP_DEV_JOYSTICK:
|
||||
{
|
||||
const JoyData& jd = joy[ts.slot];
|
||||
return getJoystickDataToPrettyString(jd, joystickID);
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
bool ActionInput::ImportField(const RawInput& inp, unsigned field)
|
||||
{
|
||||
TypeAndSlot ts = getTypeAndSlot(field);
|
||||
return ts.type == inp.src.deviceType && Import(inp, ts.slot);
|
||||
}
|
||||
|
||||
bool ActionInput::Import(const RawInput& inp, unsigned slot)
|
||||
{
|
||||
switch(inp.src.deviceType)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
{
|
||||
if(slot >= INP_MSESIZE)
|
||||
return false;
|
||||
if(inp.src.ctrlID == INP_CTRL_BUTTON)
|
||||
{
|
||||
mse[slot] = inp.src.ctrlID + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case INP_DEV_KEYBOARD:
|
||||
{
|
||||
if(slot >= INP_KEYSIZE)
|
||||
return false;
|
||||
if(inp.src.ctrlID == INP_CTRL_BUTTON)
|
||||
{
|
||||
key[slot] = inp.src.ctrlID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case INP_DEV_JOYSTICK:
|
||||
{
|
||||
if(slot >= INP_JOYSIZE)
|
||||
return false;
|
||||
JoyData jd;
|
||||
InputControlType t = inp.src.ctrlType;
|
||||
if(t == INP_CTRL_BUTTON || t == INP_CTRL_AXIS || t == INP_CTRL_HAT)
|
||||
{
|
||||
jd.ctrlType = t;
|
||||
jd.ctrlID = inp.src.ctrlID + 1;
|
||||
jd.x = inp.u.ivec.x;
|
||||
jd.y = inp.u.ivec.y;
|
||||
if(t == INP_CTRL_AXIS)
|
||||
jd.x = inp.u.axis < 0 ? -1 : 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ActionInput::Export(RawInput& inp, unsigned field) const
|
||||
{
|
||||
TypeAndSlot ts = getTypeAndSlot(field);
|
||||
inp.src.deviceType = ts.type;
|
||||
inp.src.ctrlType = INP_CTRL_BUTTON;
|
||||
inp.u.pressed = 1;
|
||||
|
||||
switch(ts.type)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
{
|
||||
unsigned m = mse[ts.slot];
|
||||
if(!m)
|
||||
return false;
|
||||
inp.src.ctrlID = m - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
case INP_DEV_KEYBOARD:
|
||||
{
|
||||
unsigned k = key[ts.slot];
|
||||
if(!k)
|
||||
return false;
|
||||
inp.src.ctrlID = k;
|
||||
}
|
||||
case INP_DEV_JOYSTICK:
|
||||
{
|
||||
const JoyData& jd = joy[field - (INP_MSESIZE + INP_KEYSIZE)];
|
||||
if(!jd.ctrlID)
|
||||
return false;
|
||||
inp.src.ctrlType = jd.ctrlType;
|
||||
inp.src.ctrlID = jd.ctrlID - 1;
|
||||
inp.u.ivec.x = jd.x;
|
||||
inp.u.ivec.y = jd.y;
|
||||
if(jd.ctrlType == INP_CTRL_AXIS)
|
||||
inp.u.axis = jd.x < 0 ? -1 : 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ActionInput::hasEntry(unsigned field) const
|
||||
{
|
||||
TypeAndSlot ts = getTypeAndSlot(field);
|
||||
|
||||
switch(ts.type)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
return mse[ts.slot];
|
||||
case INP_DEV_KEYBOARD:
|
||||
return key[ts.slot];
|
||||
case INP_DEV_JOYSTICK:
|
||||
return joy[ts.slot].ctrlID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ActionInput::clearEntry(unsigned field)
|
||||
{
|
||||
TypeAndSlot ts = getTypeAndSlot(field);
|
||||
|
||||
switch(ts.type)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
mse[ts.slot] = 0;
|
||||
break;
|
||||
case INP_DEV_KEYBOARD:
|
||||
key[ts.slot] = 0;
|
||||
break;
|
||||
case INP_DEV_JOYSTICK:
|
||||
joy[ts.slot].ctrlID = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,56 +22,60 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define ACTIONINPUT_H
|
||||
|
||||
#include <string>
|
||||
#include "InputSystem.h"
|
||||
|
||||
// Slots for each input/key type
|
||||
enum ActionInputSize
|
||||
{
|
||||
INP_MSESIZE = 1,
|
||||
INP_KEYSIZE = 2,
|
||||
INP_JOYSIZE = 1,
|
||||
INP_COMBINED_SIZE = INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE
|
||||
INP_NUMFIELDS = INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE
|
||||
};
|
||||
|
||||
std::string getInputCodeToString(int k);
|
||||
std::string getInputCodeToUserString(unsigned int k, size_t joystickID);
|
||||
int getStringToInputCode(const std::string& s);
|
||||
|
||||
// Mapping for one input action ("Cook", "SwimLeft", etc)
|
||||
class ActionInput
|
||||
{
|
||||
public:
|
||||
ActionInput();
|
||||
|
||||
std::string name;
|
||||
|
||||
union
|
||||
public: // only public because some static funcs in the cpp file need this. Don't use elsewhere!
|
||||
struct JoyData
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int mse[INP_MSESIZE];
|
||||
unsigned int key[INP_KEYSIZE];
|
||||
unsigned int joy[INP_JOYSIZE];
|
||||
} single;
|
||||
int all[INP_COMBINED_SIZE];
|
||||
} data;
|
||||
JoyData();
|
||||
InputControlType ctrlType;
|
||||
unsigned ctrlID; // 0 = not set, otherwise actual id + 1
|
||||
int x, y; // each [-1..+1]: (x,y) for hat direction, (x) for axis direction
|
||||
};
|
||||
inline const std::string& getName() const { return name; }
|
||||
private:
|
||||
unsigned mse[INP_MSESIZE]; // stores button+1, 0 = not set
|
||||
unsigned key[INP_KEYSIZE]; // 0 = no key
|
||||
JoyData joy[INP_JOYSIZE];
|
||||
std::string name;
|
||||
public:
|
||||
|
||||
ActionInput(const std::string& name_);
|
||||
|
||||
// indexing:
|
||||
// slot -> per-category (start at 0 for each INP_*)
|
||||
// field: absolute, [0 ..INP_NUMFIELDS)
|
||||
|
||||
static unsigned GetField(InputDeviceType dev, unsigned slot);
|
||||
|
||||
bool Import(const RawInput& inp, unsigned slot); // autodetects type, slot is per-category
|
||||
bool ImportField(const RawInput& inp, unsigned field); // returns false if field and type of inp don't match
|
||||
bool Export(RawInput& inp, unsigned field) const; // returns false if no mapping present
|
||||
|
||||
// for checking whether a key/button/etc is configured
|
||||
bool hasEntry(unsigned field) const;
|
||||
void clearEntry(unsigned field);
|
||||
|
||||
// for config (de-)serialization
|
||||
std::string toString() const;
|
||||
void fromString(const std::string &read);
|
||||
};
|
||||
|
||||
enum InputSetType
|
||||
{
|
||||
INPUTSET_NONE = 0,
|
||||
INPUTSET_KEY = 1,
|
||||
INPUTSET_JOY = 2,
|
||||
INPUTSET_MOUSE = 3,
|
||||
INPUTSET_OTHER = 4
|
||||
};
|
||||
|
||||
enum InputDevice
|
||||
{
|
||||
INPUT_NODEVICE = 0,
|
||||
INPUT_MOUSE,
|
||||
INPUT_JOYSTICK,
|
||||
INPUT_KEYBOARD
|
||||
// for the UI (field is in [0..INP_COMBINED_SIZE])
|
||||
std::string prettyPrintField(unsigned field, int joystickID = -1) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,76 +18,70 @@ See the GNU General Public License for more details.
|
|||
#include "ActionMapper.h"
|
||||
#include "Core.h"
|
||||
|
||||
typedef std::vector<unsigned> ButtonList;
|
||||
|
||||
InputDevice getDeviceForActionbutton(int k)
|
||||
// TODO: clean this up, make single vector of tagged unions, sorted by key
|
||||
struct LegacyActionData
|
||||
{
|
||||
if(k <= KEY_MAXARRAY)
|
||||
return INPUT_KEYBOARD;
|
||||
if(k < MOUSE_BUTTON_EXTRA_END)
|
||||
return INPUT_MOUSE;
|
||||
return INPUT_JOYSTICK;
|
||||
}
|
||||
LegacyActionData()
|
||||
: id(-1), state(-1)
|
||||
, event(0)
|
||||
{
|
||||
}
|
||||
|
||||
int id; // -1 if no associated event
|
||||
int state; // -1, 0, or 1
|
||||
Event *event;
|
||||
ButtonList buttonList;
|
||||
};
|
||||
|
||||
enum ActionState
|
||||
{
|
||||
ACSTATE_ACTIVE = 0x1, // action is active right now (button is held down)
|
||||
ACSTATE_ACCEPTED = 0x2 // handle that action when it comes in
|
||||
};
|
||||
|
||||
ActionMapper::ActionMapper()
|
||||
{
|
||||
cleared = false;
|
||||
inputEnabled = true;
|
||||
inUpdate = false;
|
||||
//memset(keyStatus, 0, sizeof(keyStatus));
|
||||
InputMapper::RegisterActionMapper(this);
|
||||
}
|
||||
|
||||
ActionMapper::~ActionMapper()
|
||||
{
|
||||
InputMapper::UnregisterActionMapper(this);
|
||||
clearCreatedEvents();
|
||||
}
|
||||
|
||||
ActionData *ActionMapper::getActionDataByIDAndSource(int actionID, int source)
|
||||
LegacyActionData *ActionMapper::getActionDataByID(int actionID)
|
||||
{
|
||||
for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i)
|
||||
{
|
||||
if (i->id == actionID && i->source == source)
|
||||
if (i->id == actionID)
|
||||
return &(*i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ActionMapper::isActing(int actionID, int source)
|
||||
bool ActionMapper::isActing(unsigned actionID) const
|
||||
{
|
||||
if(source < 0)
|
||||
{
|
||||
for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i)
|
||||
{
|
||||
ActionData& ad = *i;
|
||||
if(ad.id == actionID)
|
||||
for (ButtonList::iterator ii = ad.buttonList.begin(); ii != ad.buttonList.end(); ++ii)
|
||||
if (getKeyState(*ii, source))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionData *ad = getActionDataByIDAndSource(actionID, source);
|
||||
if (ad)
|
||||
{
|
||||
ButtonList::iterator i = ad->buttonList.begin();
|
||||
for (; i != ad->buttonList.end(); i++)
|
||||
{
|
||||
if (getKeyState(*i, source))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return actionID < _activeActions.size() ? _activeActions[actionID] : false;
|
||||
}
|
||||
|
||||
void ActionMapper::addAction(int actionID, int k, int source)
|
||||
void ActionMapper::addAction(unsigned actionID, unsigned k)
|
||||
{
|
||||
ActionData *ad = getActionDataByIDAndSource(actionID, source);
|
||||
assert(k);
|
||||
if(!k)
|
||||
return;
|
||||
|
||||
LegacyActionData *ad = getActionDataByID(actionID);
|
||||
|
||||
if (!ad)
|
||||
{
|
||||
ActionData data;
|
||||
LegacyActionData data;
|
||||
data.id = actionID;
|
||||
data.source = source;
|
||||
actionData.push_back(data);
|
||||
ad = &actionData.back();
|
||||
}
|
||||
|
@ -96,19 +90,16 @@ 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);
|
||||
//keyStatus[k] = core->getKeyState(k);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMapper::addAction(Event *event, int k, int state)
|
||||
void ActionMapper::addAction(Event *event, unsigned k, int state)
|
||||
{
|
||||
ActionData data;
|
||||
LegacyActionData data;
|
||||
data.event = event;
|
||||
data.state = state;
|
||||
data.buttonList.push_back(k);
|
||||
actionData.push_back(data);
|
||||
|
||||
//keyStatus[k] = core->getKeyState(k);
|
||||
}
|
||||
|
||||
Event* ActionMapper::addCreatedEvent(Event *event)
|
||||
|
@ -141,89 +132,77 @@ void ActionMapper::disableInput()
|
|||
inputEnabled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
bool ActionMapper::pollAction(int actionID, int source)
|
||||
{
|
||||
if(source < 0)
|
||||
{
|
||||
for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); i++)
|
||||
if(i->id == actionID && _pollActionData(*i))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionData *ad = getActionDataByIDAndSource(actionID, source);
|
||||
return ad && _pollActionData(*ad);
|
||||
}
|
||||
|
||||
bool ActionMapper::_pollActionData(const ActionData& ad)
|
||||
{
|
||||
const ButtonList& blist = ad.buttonList;
|
||||
for (ButtonList::const_iterator j = blist.begin(); j != blist.end(); j++)
|
||||
if (getKeyState((*j)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
void ActionMapper::onUpdate (float dt)
|
||||
{
|
||||
if (inUpdate)
|
||||
return;
|
||||
|
||||
inUpdate = true;
|
||||
cleared = false;
|
||||
|
||||
for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i)
|
||||
if(inputEnabled && !inUpdate)
|
||||
{
|
||||
for (ButtonList::iterator j = i->buttonList.begin(); j != i->buttonList.end(); j++)
|
||||
{
|
||||
const int k = (*j);
|
||||
const ActionData *ad = &(*i);
|
||||
const bool keyChanged = isKeyChanged(k, ad->source);
|
||||
inUpdate = true;
|
||||
updateDirectInput();
|
||||
updateActions();
|
||||
inUpdate = false;
|
||||
}
|
||||
|
||||
if (keyChanged)
|
||||
_actionChanges.clear();
|
||||
_inputChanges.clear();
|
||||
|
||||
}
|
||||
|
||||
void ActionMapper::updateActions()
|
||||
{
|
||||
// Trigger queued events and propagate changes
|
||||
for(size_t i = 0; i < _actionChanges.size(); ++i)
|
||||
{
|
||||
const ActionUpdate& am = _actionChanges[i];
|
||||
if(am.id >= _activeActions.size())
|
||||
_activeActions.resize(am.id);
|
||||
_activeActions[am.id] = am.state;
|
||||
action(am.id, am.state, am.playerID, am.device);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMapper::updateDirectInput()
|
||||
{
|
||||
cleared = false;
|
||||
for(size_t q = 0; q < _inputChanges.size(); ++q)
|
||||
{
|
||||
int ik = _inputChanges[q];
|
||||
bool keyState;
|
||||
unsigned k;
|
||||
if(ik < 0)
|
||||
{
|
||||
keyState = false;
|
||||
k = -ik;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyState = true;
|
||||
k = ik;
|
||||
}
|
||||
|
||||
for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i)
|
||||
{
|
||||
const LegacyActionData& ad = (*i);
|
||||
for (ButtonList::const_iterator j = ad.buttonList.begin(); j != ad.buttonList.end(); j++)
|
||||
{
|
||||
bool keyState = getKeyState(k, ad->source);
|
||||
if (inputEnabled)
|
||||
if(k == (*j))
|
||||
{
|
||||
if (ad->event)
|
||||
if (ad.event)
|
||||
{
|
||||
if (ad->state==-1 || keyState == !!ad->state)
|
||||
if (ad.state==-1 || keyState == !!ad.state)
|
||||
{
|
||||
ad->event->act();
|
||||
ad.event->act();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action(ad->id, keyState, ad->source, getDeviceForActionbutton(k));
|
||||
action(ad.id, keyState, -1, INP_DEV_NODEVICE);
|
||||
}
|
||||
if (core->loopDone) goto out;
|
||||
if (core->loopDone || cleared)
|
||||
return;
|
||||
}
|
||||
if (cleared) { cleared = false; goto out; } // actionData has been cleared, stop iteration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// all including sentinel
|
||||
const int m = core->getMaxActionStatusIndex();
|
||||
for(int i = -1; i <= m; ++i)
|
||||
if(core->getActionStatus(i)->getKeyState(k))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ActionMapper::clearActions()
|
||||
|
@ -232,19 +211,47 @@ void ActionMapper::clearActions()
|
|||
actionData.clear();
|
||||
}
|
||||
|
||||
bool ActionMapper::isKeyChanged(int k, int sourceID)
|
||||
void ActionMapper::recvAction(unsigned actionID, bool keyState, int playerID, InputDeviceType device)
|
||||
{
|
||||
if(sourceID < 0)
|
||||
return isKeyChanged(k);
|
||||
return core->getActionStatus(sourceID)->isKeyChanged(k);
|
||||
if(!inputEnabled)
|
||||
return;
|
||||
|
||||
// enqueue change for later
|
||||
// Since the update order isn't actually *defined* anywhere but it'm almost sure there
|
||||
// will be subtle bugs if things aren't updated in the "right" order
|
||||
// (aka as it happened to be, so far),
|
||||
// use a queue so that the code can keep believing it's polling changes, while in fact
|
||||
// under the hood it's a push-based system.
|
||||
// Pushing every change to a queue also ensures we can't miss a button press that
|
||||
// lasts shorter than one frame.
|
||||
ActionUpdate am;
|
||||
am.id = actionID;
|
||||
am.state = keyState;
|
||||
am.playerID = playerID;
|
||||
am.device = device;
|
||||
_actionChanges.push_back(am);
|
||||
}
|
||||
|
||||
bool ActionMapper::isKeyChanged(int k)
|
||||
void ActionMapper::recvDirectInput(unsigned k, bool keyState)
|
||||
{
|
||||
// all including sentinel
|
||||
const int m = core->getMaxActionStatusIndex();
|
||||
for(int i = -1; i <= m; ++i)
|
||||
if(core->getActionStatus(i)->isKeyChanged(k))
|
||||
return true;
|
||||
return false;
|
||||
if(!inputEnabled)
|
||||
return;
|
||||
|
||||
_inputChanges.push_back(keyState ? (int)k : -(int)k);
|
||||
}
|
||||
|
||||
void ActionMapper::ImportInput(const NamedAction *actions, size_t N)
|
||||
{
|
||||
// FIXME controllerfixup
|
||||
InputMapper *im = NULL;
|
||||
ActionSet as;
|
||||
|
||||
/*
|
||||
for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i)
|
||||
{
|
||||
const ActionSet& as = dsq->user.control.actionSets[i];
|
||||
*/
|
||||
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
as.importAction(im, actions[i].name, actions[i].actionID);
|
||||
}
|
||||
|
|
|
@ -24,43 +24,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "Base.h"
|
||||
#include "ActionInput.h"
|
||||
|
||||
InputDevice getDeviceForActionbutton(int k);
|
||||
|
||||
class Event;
|
||||
class ActionMapper;
|
||||
|
||||
#include "ActionStatus.h"
|
||||
#include "ActionSet.h"
|
||||
#include "Joystick.h"
|
||||
|
||||
typedef std::vector<int> ButtonList;
|
||||
|
||||
struct ActionData
|
||||
{
|
||||
ActionData()
|
||||
: id(-1), state(-1), source(-1)
|
||||
, event(0)
|
||||
{
|
||||
}
|
||||
|
||||
int id, state, source;
|
||||
Event *event;
|
||||
ButtonList buttonList;
|
||||
};
|
||||
struct LegacyActionData;
|
||||
|
||||
class ActionMapper
|
||||
{
|
||||
public:
|
||||
struct NamedAction // for importing
|
||||
{
|
||||
const char * const name;
|
||||
unsigned actionID;
|
||||
};
|
||||
|
||||
// funcs
|
||||
ActionMapper();
|
||||
virtual ~ActionMapper();
|
||||
|
||||
void addAction(Event *event, int k, int state=-1);
|
||||
void addAction(int actionID, int k, int source);
|
||||
// Overridden to react to events (both legacy and input-mapped)
|
||||
virtual void action(int actionID, int state, int playerID, InputDeviceType device) = 0;
|
||||
|
||||
bool isActing(int actionID, int source);
|
||||
virtual void action(int actionID, int state, int source, InputDevice device) = 0;
|
||||
|
||||
// Legacy actions -- binds keys directly to actions.
|
||||
// This bypasses the input mapper and checks for keys directly!
|
||||
void addAction(Event *event, unsigned k, int state = -1);
|
||||
void addAction(unsigned actionID, unsigned k);
|
||||
bool isActing(unsigned actionID) const;
|
||||
|
||||
|
||||
void clearActions();
|
||||
|
@ -69,7 +62,7 @@ public:
|
|||
|
||||
// vars
|
||||
|
||||
typedef std::vector<ActionData> ActionDataSet;
|
||||
typedef std::vector<LegacyActionData> ActionDataSet;
|
||||
ActionDataSet actionData;
|
||||
|
||||
bool cleared;
|
||||
|
@ -80,22 +73,41 @@ public:
|
|||
Event *addCreatedEvent(Event *event);
|
||||
void clearCreatedEvents();
|
||||
|
||||
//bool pollAction(int actionID, int source);
|
||||
bool getKeyState(int k);
|
||||
bool getKeyState(int k, int sourceID);
|
||||
|
||||
ActionData *getActionDataByIDAndSource(int actionID, int source);
|
||||
// called by InputMapper whenever stuff happens
|
||||
void recvAction(unsigned actionID, bool state, int playerID, InputDeviceType device);
|
||||
void recvDirectInput(unsigned k, bool state);
|
||||
|
||||
protected:
|
||||
template<size_t N> static void ImportInput(const NamedAction (&a)[N])
|
||||
{
|
||||
ImportInput(&a[0], N);
|
||||
}
|
||||
static void ImportInput(const NamedAction *actions, size_t N);
|
||||
|
||||
std::vector<Event*>createdEvents;
|
||||
std::vector<Event*> createdEvents;
|
||||
|
||||
bool inUpdate;
|
||||
bool inputEnabled;
|
||||
void onUpdate (float dt);
|
||||
|
||||
private:
|
||||
bool isKeyChanged(int k);
|
||||
bool isKeyChanged(int k, int sourceID);
|
||||
//bool _pollActionData(const ActionData& ad);
|
||||
void updateDirectInput();
|
||||
void updateActions();
|
||||
|
||||
LegacyActionData *getActionDataByID(int actionID);
|
||||
|
||||
struct ActionUpdate
|
||||
{
|
||||
unsigned id;
|
||||
int playerID;
|
||||
bool state;
|
||||
InputDeviceType device;
|
||||
};
|
||||
std::vector<ActionUpdate> _actionChanges;
|
||||
std::vector<int> _inputChanges; // >0: pressed, <0: released
|
||||
|
||||
bool inUpdate;
|
||||
std::vector<unsigned char> _activeActions;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,6 @@ JoystickConfig::JoystickConfig()
|
|||
|
||||
ActionSet::ActionSet()
|
||||
{
|
||||
inputMode = INPUT_NODEVICE;
|
||||
enabled = true;
|
||||
joystickID = ACTIONSET_REASSIGN_JOYSTICK;
|
||||
}
|
||||
|
@ -132,11 +131,11 @@ void ActionSet::updateJoystick()
|
|||
j->setEnabled(true);
|
||||
}
|
||||
|
||||
ActionInput *ActionSet::getActionInputByName(const std::string &name)
|
||||
const ActionInput *ActionSet::getActionInputByName(const std::string &name) const
|
||||
{
|
||||
for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++)
|
||||
for (ActionInputSet::const_iterator i = inputSet.begin(); i != inputSet.end(); i++)
|
||||
{
|
||||
if (nocasecmp((*i).name, name) == 0)
|
||||
if (nocasecmp(i->getName(), name) == 0)
|
||||
{
|
||||
return &(*i);
|
||||
}
|
||||
|
@ -144,52 +143,34 @@ ActionInput *ActionSet::getActionInputByName(const std::string &name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ActionSet::importAction(ActionMapper *mapper, const std::string &name, int actionID, int sourceID) const
|
||||
void ActionSet::importAction(InputMapper *mapper, const std::string &name, unsigned actionID) const
|
||||
{
|
||||
if (!enabled) return;
|
||||
if (!mapper) return;
|
||||
|
||||
for (size_t i = 0; i < inputSet.size(); i++)
|
||||
const ActionInput *ac = getActionInputByName(name);
|
||||
if(!ac)
|
||||
{
|
||||
const ActionInput *actionInput = &inputSet[i];
|
||||
if (actionInput->name == name)
|
||||
{
|
||||
for (int i = 0; i < INP_COMBINED_SIZE; i++)
|
||||
if (actionInput->data.all[i])
|
||||
mapper->addAction(actionID, actionInput->data.all[i], sourceID);
|
||||
return;
|
||||
}
|
||||
errorLog("ActionSet::importAction: Undefined action name: " + name);
|
||||
return;
|
||||
}
|
||||
|
||||
RawInput raw;
|
||||
for(unsigned i = 0; i < INP_NUMFIELDS; ++i)
|
||||
if(ac->Export(raw, i))
|
||||
if(!mapper->addMapping(InputMapper::TO_BUTTON, raw, actionID))
|
||||
errorLog("Failed to map action: " + name);
|
||||
}
|
||||
|
||||
void ActionSet::importAction(ActionMapper *mapper, const std::string &name, Event *event, int state) const
|
||||
ActionInput& ActionSet::ensureActionInput(const std::string &name)
|
||||
{
|
||||
if (!enabled) return;
|
||||
if (!mapper) return;
|
||||
for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++)
|
||||
if (nocasecmp(i->getName(), name) == 0)
|
||||
return *i;
|
||||
|
||||
for (size_t i = 0; i < inputSet.size(); i++)
|
||||
{
|
||||
const ActionInput *actionInput = &inputSet[i];
|
||||
if (actionInput->name == name)
|
||||
{
|
||||
for (int i = 0; i < INP_COMBINED_SIZE; i++)
|
||||
if (actionInput->data.all[i])
|
||||
mapper->addAction(event, actionInput->data.all[i], state);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionInput *ActionSet::addActionInput(const std::string &name)
|
||||
{
|
||||
ActionInput *a = getActionInputByName(name);
|
||||
if(a)
|
||||
return a;
|
||||
|
||||
ActionInput newa;
|
||||
newa.name = name;
|
||||
ActionInput newa(name);
|
||||
inputSet.push_back(newa);
|
||||
return &inputSet.back();
|
||||
return inputSet.back();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,9 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "ActionInput.h"
|
||||
|
||||
typedef std::vector<ActionInput> ActionInputSet;
|
||||
|
||||
class ActionMapper;
|
||||
class InputMapper;
|
||||
class Event;
|
||||
|
||||
const int ACTIONSET_REASSIGN_JOYSTICK = -2;
|
||||
|
@ -41,14 +39,16 @@ struct JoystickConfig
|
|||
float s1dead, s2dead;
|
||||
};
|
||||
|
||||
// One ActionSet is a serializable configuration of input mappings.
|
||||
class ActionSet
|
||||
{
|
||||
typedef std::vector<ActionInput> ActionInputSet;
|
||||
|
||||
public:
|
||||
ActionSet();
|
||||
|
||||
// import this ActionSet into ActionMapper
|
||||
void importAction(ActionMapper *mapper, const std::string &name, Event *event, int state) const;
|
||||
void importAction(ActionMapper *mapper, const std::string &name, int actionID, int sourceID) const;
|
||||
// import this ActionSet into InputMapper. Should be called via ActionMapper::ImportInput() only!
|
||||
void importAction(InputMapper *mapper, const std::string &name, unsigned actionID) const;
|
||||
void clearActions();
|
||||
int assignJoystickByName(bool force); // -1 if no such joystick found
|
||||
void assignJoystickIdx(int idx, bool updateValues);
|
||||
|
@ -56,11 +56,10 @@ public:
|
|||
// note: this only ENABLES joysticks if they are needed, but never disables any
|
||||
void updateJoystick();
|
||||
|
||||
ActionInput *addActionInput(const std::string &name);
|
||||
ActionInput *getActionInputByName(const std::string &name);
|
||||
ActionInput& ensureActionInput(const std::string &name);
|
||||
const ActionInput *getActionInputByName(const std::string &name) const;
|
||||
|
||||
InputDevice inputMode;
|
||||
size_t joystickID; // >= 0: use that, -1 = no joystick, or ACTIONSET_REASSIGN_JOYSTICK
|
||||
int joystickID; // >= 0: use that, -1 = no joystick, or ACTIONSET_REASSIGN_JOYSTICK
|
||||
|
||||
// --- Saved in config ---
|
||||
ActionInputSet inputSet;
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
#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)
|
||||
if(unsigned(inp.data.all[j]) < ACTION_BUTTON_ENUM_SIZE)
|
||||
found[inp.data.all[j]] = 1;
|
||||
}
|
||||
|
||||
toQuery.clear();
|
||||
for(int k = 1; k < sizeof(found); ++k) // ignore [0]
|
||||
if(found[k])
|
||||
toQuery.push_back(k);
|
||||
|
||||
memset(status, 0, sizeof(status));
|
||||
memset(changed, 0, sizeof(changed));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ActionButtonStatus::importQuery(const int *pKeys, size_t num)
|
||||
{
|
||||
unsigned char found[ACTION_BUTTON_ENUM_SIZE];
|
||||
memset(found, 0, sizeof(found));
|
||||
for(size_t i = 0; i < num; ++i)
|
||||
if(unsigned(pKeys[i]) < ACTION_BUTTON_ENUM_SIZE)
|
||||
found[pKeys[i]] = 1;
|
||||
|
||||
toQuery.clear();
|
||||
for(int k = 1; k < sizeof(found); ++k) // ignore [0]
|
||||
if(found[k])
|
||||
toQuery.push_back(k);
|
||||
|
||||
memset(status, 0, sizeof(status));
|
||||
memset(changed, 0, sizeof(changed));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ActionButtonStatus::update()
|
||||
{
|
||||
_queryAllStatus();
|
||||
}
|
||||
|
||||
void ActionButtonStatus::_queryAllStatus()
|
||||
{
|
||||
// k==0 is always 0
|
||||
for(size_t i = 0; i < toQuery.size(); ++i)
|
||||
{
|
||||
const int k = toQuery[i];
|
||||
bool state = _queryStatus(k);
|
||||
changed[k] = !!status[k] != state;
|
||||
status[k] = state;
|
||||
}
|
||||
}
|
||||
|
||||
bool ActionButtonStatus::_queryStatus(int k) const
|
||||
{
|
||||
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)
|
||||
{
|
||||
float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_POS);
|
||||
return ax > JOY_AXIS_THRESHOLD;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
#ifndef ACTIONSTATUS_H
|
||||
#define ACTIONSTATUS_H
|
||||
|
||||
#include "GameKeys.h"
|
||||
#include "Joystick.h"
|
||||
|
||||
class ActionSet;
|
||||
|
||||
const unsigned mouseExtraButtons = 8;
|
||||
|
||||
// *_END is non-inclusive!
|
||||
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,
|
||||
|
||||
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:
|
||||
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);
|
||||
void importQuery(const int *pKeys, size_t num);
|
||||
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
|
181
BBGE/Core.cpp
181
BBGE/Core.cpp
|
@ -360,8 +360,6 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n
|
|||
mouseCircle = 0;
|
||||
overrideStartLayer = 0;
|
||||
overrideEndLayer = 0;
|
||||
frameOutputMode = false;
|
||||
updateMouse = true;
|
||||
particlesPaused = false;
|
||||
joystickAsMouse = false;
|
||||
currentLayerPass = 0;
|
||||
|
@ -384,11 +382,6 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n
|
|||
loopDone = false;
|
||||
core = this;
|
||||
|
||||
for (int i = 0; i < KEY_MAXARRAY; i++)
|
||||
{
|
||||
keys[i] = 0;
|
||||
}
|
||||
|
||||
globalResolutionScale = globalScale = Vector(1,1,1);
|
||||
|
||||
initRenderObjectLayers(numRenderLayers);
|
||||
|
@ -476,8 +469,6 @@ std::string Core::getUserDataFolder()
|
|||
|
||||
Core::~Core()
|
||||
{
|
||||
clearActionButtons();
|
||||
|
||||
if (particleManager)
|
||||
{
|
||||
delete particleManager;
|
||||
|
@ -534,7 +525,7 @@ void Core::init()
|
|||
{
|
||||
setupFileAccess();
|
||||
|
||||
unsigned sdlflags = SDL_INIT_EVERYTHING;
|
||||
unsigned sdlflags = SDL_INIT_EVERYTHING & ~SDL_INIT_TIMER;
|
||||
|
||||
quitNestedMainFlag = false;
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
|
@ -587,27 +578,9 @@ Vector Core::getGamePosition(const Vector &v)
|
|||
return cameraPos + (v * invGlobalScale);
|
||||
}
|
||||
|
||||
bool Core::getMouseButtonState(int m)
|
||||
bool Core::getKeyState(unsigned k) const
|
||||
{
|
||||
int mcode=m;
|
||||
|
||||
switch(m)
|
||||
{
|
||||
case 0: mcode=1; break;
|
||||
case 1: mcode=3; break;
|
||||
case 2: mcode=2; break;
|
||||
}
|
||||
|
||||
Uint8 mousestate = SDL_GetMouseState(0,0);
|
||||
|
||||
return mousestate & SDL_BUTTON(mcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Core::getKeyState(int k)
|
||||
{
|
||||
assert(k < KEY_MAXARRAY);
|
||||
return k > 0 && k < KEY_MAXARRAY ? keys[k] : 0;
|
||||
return rawInput.isKeyPressed(k);
|
||||
}
|
||||
|
||||
void Core::initJoystickLibrary()
|
||||
|
@ -652,12 +625,6 @@ void Core::detectJoysticks()
|
|||
bool Core::initInputLibrary()
|
||||
{
|
||||
core->mouse.position = Vector(getWindowWidth()/2, getWindowHeight()/2);
|
||||
|
||||
for (int i = 0; i < KEY_MAXARRAY; i++)
|
||||
{
|
||||
keys[i] = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1255,6 +1222,10 @@ bool Core::doMouseConstraint()
|
|||
void Core::onEvent(const SDL_Event& event)
|
||||
{
|
||||
const bool focus = window->hasFocus();
|
||||
|
||||
if(focus)
|
||||
InputSystem::handleSDLEvent(&event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
|
@ -1263,37 +1234,12 @@ void Core::onEvent(const SDL_Event& event)
|
|||
{
|
||||
setInputGrab(!grabInput);
|
||||
}
|
||||
else if (focus)
|
||||
{
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
unsigned kidx = event.key.keysym.scancode;
|
||||
#else
|
||||
unsigned kidx = event.key.keysym.sym;
|
||||
#endif
|
||||
if(kidx < KEY_MAXARRAY)
|
||||
keys[kidx] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
if (focus)
|
||||
{
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
unsigned kidx = event.key.keysym.scancode;
|
||||
#else
|
||||
unsigned kidx = event.key.keysym.sym;
|
||||
#endif
|
||||
if(kidx < KEY_MAXARRAY)
|
||||
keys[kidx] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (focus && updateMouse)
|
||||
if (focus)
|
||||
{
|
||||
mouse.lastPosition = mouse.position;
|
||||
|
||||
|
@ -1309,19 +1255,6 @@ void Core::onEvent(const SDL_Event& event)
|
|||
break;
|
||||
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if (focus && updateMouse)
|
||||
{
|
||||
if (event.wheel.y > 0)
|
||||
mouse.scrollWheelChange = 1;
|
||||
else if (event.wheel.y < 0)
|
||||
mouse.scrollWheelChange = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEADDED:
|
||||
onJoystickAdded(event.jdevice.which);
|
||||
break;
|
||||
|
@ -1329,82 +1262,12 @@ void Core::onEvent(const SDL_Event& event)
|
|||
case SDL_JOYDEVICEREMOVED:
|
||||
onJoystickRemoved(event.jdevice.which);
|
||||
break;
|
||||
|
||||
#else
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
if (focus && updateMouse)
|
||||
{
|
||||
switch(event.button.button)
|
||||
{
|
||||
case 4:
|
||||
mouse.scrollWheelChange = 1;
|
||||
break;
|
||||
case 5:
|
||||
mouse.scrollWheelChange = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
if (focus && updateMouse)
|
||||
{
|
||||
switch(event.button.button)
|
||||
{
|
||||
case 4:
|
||||
mouse.scrollWheelChange = 1;
|
||||
break;
|
||||
case 5:
|
||||
mouse.scrollWheelChange = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Core::pollEvents(float dt)
|
||||
{
|
||||
bool warpMouse=false;
|
||||
|
||||
|
||||
|
||||
if (updateMouse)
|
||||
{
|
||||
int x, y;
|
||||
unsigned mousestate = SDL_GetMouseState(&x,&y);
|
||||
|
||||
if (mouse.buttonsEnabled)
|
||||
{
|
||||
mouse.buttons.left = mousestate & SDL_BUTTON(1)?DOWN:UP;
|
||||
mouse.buttons.right = mousestate & SDL_BUTTON(3)?DOWN:UP;
|
||||
mouse.buttons.middle = mousestate & SDL_BUTTON(2)?DOWN:UP;
|
||||
|
||||
for(unsigned i = 0; i < mouseExtraButtons; ++i)
|
||||
mouse.buttons.extra[i] = mousestate & SDL_BUTTON(3+i)?DOWN:UP;
|
||||
|
||||
mouse.pure_buttons = mouse.buttons;
|
||||
mouse.rawButtonMask = mousestate;
|
||||
|
||||
if (flipMouseButtons)
|
||||
{
|
||||
std::swap(mouse.buttons.left, mouse.buttons.right);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse.buttons.left = mouse.buttons.right = mouse.buttons.middle = UP;
|
||||
}
|
||||
|
||||
mouse.scrollWheelChange = 0;
|
||||
mouse.change = Vector(0,0);
|
||||
}
|
||||
|
||||
window->handleInput();
|
||||
|
||||
for(size_t i = 0; i < joysticks.size(); ++i)
|
||||
|
@ -1412,8 +1275,8 @@ void Core::pollEvents(float dt)
|
|||
joysticks[i]->update(dt);
|
||||
|
||||
// all input done; update button states
|
||||
updateActionButtons();
|
||||
|
||||
//updateActionButtons();
|
||||
rawInput.update();
|
||||
}
|
||||
|
||||
#define _VLN(x, y, x2, y2) glVertex2f(x, y); glVertex2f(x2, y2);
|
||||
|
@ -2442,11 +2305,9 @@ void Core::onJoystickAdded(int deviceID)
|
|||
if(!joysticks[i])
|
||||
{
|
||||
joysticks[i] = j;
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
joysticks.push_back(j);
|
||||
done:
|
||||
;
|
||||
}
|
||||
|
||||
void Core::onJoystickRemoved(int instanceID)
|
||||
|
@ -2467,26 +2328,6 @@ Joystick *Core::getJoystick(size_t 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(int sourceID)
|
||||
{
|
||||
if(unsigned(sourceID+1) < (unsigned)actionStatus.size())
|
||||
return getJoystick(actionStatus[sourceID+1]->getJoystickID());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include <png.h>
|
||||
|
||||
bool Core::pngSave(const char *filename, unsigned width, unsigned height, unsigned char *data)
|
||||
|
|
25
BBGE/Core.h
25
BBGE/Core.h
|
@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "DarkLayer.h"
|
||||
|
||||
#include "GameKeys.h"
|
||||
#include "InputMapperRaw.h"
|
||||
|
||||
class ParticleEffect;
|
||||
class Joystick;
|
||||
|
@ -81,7 +82,6 @@ struct MouseButtons
|
|||
}
|
||||
|
||||
ButtonState left, right, middle;
|
||||
ButtonState extra[mouseExtraButtons];
|
||||
};
|
||||
|
||||
struct Mouse
|
||||
|
@ -96,7 +96,7 @@ struct Mouse
|
|||
MouseButtons pure_buttons;
|
||||
unsigned rawButtonMask;
|
||||
Vector change;
|
||||
bool buttonsEnabled;
|
||||
bool buttonsEnabled; //KILL
|
||||
|
||||
int scrollWheelChange;
|
||||
};
|
||||
|
@ -273,7 +273,7 @@ public:
|
|||
void setMouseConstraint(bool on);
|
||||
void setMouseConstraintCircle(const Vector& pos, float mouseCircle);
|
||||
|
||||
virtual void action(int id, int state, int source, InputDevice device){}
|
||||
virtual void action(int id, int state, int playerID, InputDeviceType device) {}
|
||||
|
||||
bool exists(const std::string &file);
|
||||
|
||||
|
@ -372,11 +372,10 @@ public:
|
|||
|
||||
void clearRenderObjects();
|
||||
|
||||
bool getKeyState(int k);
|
||||
bool getMouseButtonState(int m);
|
||||
bool getKeyState(unsigned k) const;
|
||||
bool isKeyChanged(unsigned k) const;
|
||||
|
||||
int currentLayerPass;
|
||||
int keys[KEY_MAXARRAY];
|
||||
virtual void debugLog(const std::string &s);
|
||||
virtual void errorLog(const std::string &s);
|
||||
void messageBox(const std::string &title, const std::string &msg);
|
||||
|
@ -404,12 +403,9 @@ public:
|
|||
int flipMouseButtons;
|
||||
FrameBuffer frameBuffer;
|
||||
void updateRenderObjects(float dt);
|
||||
bool joystickAsMouse;
|
||||
bool joystickAsMouse; //KILL?
|
||||
virtual void prepScreen(bool t){}
|
||||
|
||||
bool updateMouse;
|
||||
bool frameOutputMode;
|
||||
|
||||
int overrideStartLayer, overrideEndLayer;
|
||||
|
||||
ParticleEffect* createParticleEffect(const std::string &name, const Vector &position, int layer, float rotz=0);
|
||||
|
@ -536,20 +532,13 @@ protected:
|
|||
void setupFileAccess();
|
||||
std::string _extraDataDir;
|
||||
|
||||
std::vector<ActionButtonStatus*> actionStatus; // contains at least 1 element (the sentinel)
|
||||
virtual void updateActionButtons();
|
||||
void clearActionButtons();
|
||||
InputMapperRaw rawInput;
|
||||
|
||||
public:
|
||||
// inclusive!
|
||||
inline int getMaxActionStatusIndex() const { return int(actionStatus.size()) - 2; }
|
||||
// pass -1 for is a sentinel that captures all input
|
||||
inline ActionButtonStatus *getActionStatus(size_t idx) { return actionStatus[idx + 1]; }
|
||||
|
||||
Joystick *getJoystick(size_t idx); // warning: may return NULL/contain holes
|
||||
// not the actual number of joysticks!
|
||||
size_t getNumJoysticks() const { return joysticks.size(); }
|
||||
Joystick *getJoystickForSourceID(int sourceID);
|
||||
private:
|
||||
std::vector<Joystick*> joysticks;
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ void EventPtr::call()
|
|||
}
|
||||
if (actionMapperCallback)
|
||||
{
|
||||
actionMapperCallback->action(actionValue, stateToCall, -1, INPUT_NODEVICE);
|
||||
actionMapperCallback->action(actionValue, stateToCall, -1, INP_DEV_NODEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "GameKeyNames.h"
|
||||
#include "ActionStatus.h"
|
||||
#include "GameKeys.h"
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
|
||||
typedef std::map<std::string, int> InputCodeMap;
|
||||
|
||||
InputCodeMap inputCodeMap;
|
||||
static std::string keyNames[ACTION_BUTTON_ENUM_SIZE];
|
||||
static InputCodeMap inputCodeMap;
|
||||
static const char *keyNames[ACTION_BUTTON_ENUM_SIZE];
|
||||
|
||||
static void initInputCodeMap()
|
||||
{
|
||||
|
@ -101,38 +101,31 @@ static void initInputCodeMap()
|
|||
K(KEY_RBRACKET)
|
||||
K(KEY_TILDE)
|
||||
|
||||
|
||||
K(MOUSE_BUTTON_LEFT)
|
||||
K(MOUSE_BUTTON_RIGHT)
|
||||
K(MOUSE_BUTTON_MIDDLE)
|
||||
#undef K
|
||||
|
||||
for (int jb = JOY_BUTTON_0; jb < JOY_BUTTON_END; jb++)
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "JOY_BUTTON_%d", jb - JOY_BUTTON_0);
|
||||
inputCodeMap[buf] = jb;
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
|
||||
for(size_t i = 0; i < ACTION_BUTTON_ENUM_SIZE; ++i)
|
||||
keyNames[i] = NULL;
|
||||
|
||||
// Can just use pointers to the strings in the map; they'll stay where they are in memory
|
||||
for(InputCodeMap::iterator it = inputCodeMap.begin(); it != inputCodeMap.end(); ++it)
|
||||
keyNames[it->second] = it->first;
|
||||
keyNames[it->second] = it->first.c_str();
|
||||
}
|
||||
|
||||
int getInputCodeFromKeyName(const char *name)
|
||||
unsigned getLegacyInputCodeFromKeyName(const std::string& name)
|
||||
{
|
||||
if(inputCodeMap.empty())
|
||||
initInputCodeMap();
|
||||
return inputCodeMap[name];
|
||||
}
|
||||
|
||||
const std::string& getKeyNameFromInputCode(int k)
|
||||
const char *getLegacyKeyNameFromInputCode(unsigned k)
|
||||
{
|
||||
if(inputCodeMap.empty())
|
||||
initInputCodeMap();
|
||||
return keyNames[k];
|
||||
}
|
||||
|
||||
struct KeyNameInitializer
|
||||
{
|
||||
KeyNameInitializer() { initInputCodeMap(); }
|
||||
};
|
||||
static KeyNameInitializer s_kinit;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
int getInputCodeFromKeyName(const char *name);
|
||||
const std::string& getKeyNameFromInputCode(int k);
|
||||
unsigned getLegacyInputCodeFromKeyName(const std::string& name);
|
||||
const char *getLegacyKeyNameFromInputCode(unsigned k);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -241,4 +241,17 @@
|
|||
|
||||
#endif // BBGE_BUILD_SDL2
|
||||
|
||||
|
||||
// Extra symbolic names that the engine may use when referencing keys
|
||||
// For use with ActionMapper::addAction()
|
||||
// (also see GameKeyNames.cpp)
|
||||
enum ActionButtonType
|
||||
{
|
||||
MOUSE_BUTTON_LEFT = KEY_MAXARRAY + 1,
|
||||
MOUSE_BUTTON_RIGHT,
|
||||
MOUSE_BUTTON_MIDDLE,
|
||||
|
||||
ACTION_BUTTON_ENUM_SIZE
|
||||
};
|
||||
|
||||
#endif // BBGE_GAME_KEYS_H
|
||||
|
|
267
BBGE/InputMapper.cpp
Normal file
267
BBGE/InputMapper.cpp
Normal file
|
@ -0,0 +1,267 @@
|
|||
#include "InputMapper.h"
|
||||
#include "InputSystem.h"
|
||||
#include "ActionMapper.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
std::vector<ActionMapper*> IInputMapper::s_actionmappers;
|
||||
|
||||
GameControlState::GameControlState(size_t numbuttons, size_t numaxes)
|
||||
: buttons(numbuttons), axes(numaxes)
|
||||
, mouseX(0), mouseY(0), wheelDelta(0)
|
||||
, lastDevice(INP_DEV_NODEVICE)
|
||||
{
|
||||
}
|
||||
|
||||
void GameControlState::clear()
|
||||
{
|
||||
std::fill(axes.begin(), axes.end(), 0.0f);
|
||||
std::fill(buttons.begin(), buttons.end(), 0);
|
||||
}
|
||||
|
||||
// -----------------
|
||||
|
||||
void IInputMapper::RegisterActionMapper(ActionMapper *mapper)
|
||||
{
|
||||
s_actionmappers.push_back(mapper);
|
||||
}
|
||||
|
||||
void IInputMapper::UnregisterActionMapper(ActionMapper *mapper)
|
||||
{
|
||||
s_actionmappers.erase(std::remove(s_actionmappers.begin(), s_actionmappers.end(), mapper), s_actionmappers.end());
|
||||
}
|
||||
|
||||
void IInputMapper::ForwardAction(unsigned idx, bool state, int playerID, InputDeviceType dev)
|
||||
{
|
||||
const size_t N = s_actionmappers.size();
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
s_actionmappers[i]->recvAction(idx, state, playerID, dev);
|
||||
}
|
||||
|
||||
void IInputMapper::ForwardDirectInput(unsigned k, bool state)
|
||||
{
|
||||
const size_t N = s_actionmappers.size();
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
s_actionmappers[i]->recvDirectInput(k, state);
|
||||
}
|
||||
|
||||
|
||||
// ------------------
|
||||
|
||||
|
||||
IInputMapper::IInputMapper()
|
||||
{
|
||||
InputSystem::addMapper(this);
|
||||
}
|
||||
|
||||
IInputMapper::~IInputMapper()
|
||||
{
|
||||
InputSystem::addMapper(this);
|
||||
}
|
||||
|
||||
// ------------------
|
||||
|
||||
InputMapper::InputMapper(int playerID)
|
||||
: acceptMouse(true), acceptMouseID(-1), playerID(playerID)
|
||||
{
|
||||
}
|
||||
|
||||
InputMapper::~InputMapper()
|
||||
{
|
||||
InputSystem::removeMapper(this);
|
||||
}
|
||||
|
||||
static float rescale(float t, float lower, float upper, float rangeMin, float rangeMax)
|
||||
{
|
||||
if(upper == lower)
|
||||
return rangeMin;
|
||||
|
||||
return (((t - lower) / (upper - lower)) * (rangeMax - rangeMin)) + rangeMin;
|
||||
}
|
||||
|
||||
static float clamp(float x, float a, float b)
|
||||
{
|
||||
return std::max(a, std::min(x, b));
|
||||
}
|
||||
|
||||
static float rescaleClamp(float t, float lower, float upper, float rangeMin, float rangeMax)
|
||||
{
|
||||
return clamp(rescale(t, lower, upper, rangeMin, rangeMax), std::min(rangeMin, rangeMax), std::max(rangeMin, rangeMax));
|
||||
}
|
||||
|
||||
unsigned char InputMapper::MapToButton(const Mapping& m)
|
||||
{
|
||||
assert(m.buttonOrAxis > 0);
|
||||
|
||||
switch(m.raw.src.ctrlType)
|
||||
{
|
||||
case INP_CTRL_BUTTON:
|
||||
return m.raw.u.pressed;
|
||||
|
||||
case INP_CTRL_AXIS: // when axis is beyond threshold, register as button press
|
||||
return m.val.axis > 0
|
||||
? m.raw.u.axis > m.val.axis
|
||||
: m.raw.u.axis < m.val.axis;
|
||||
|
||||
case INP_CTRL_HAT:
|
||||
return !memcmp(&m.raw.u.ivec, &m.val.ivec, sizeof(m.raw.u.ivec));
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float InputMapper::MapToAxis(const Mapping& m)
|
||||
{
|
||||
assert(m.buttonOrAxis < 0);
|
||||
|
||||
switch(m.raw.src.ctrlType)
|
||||
{
|
||||
case INP_CTRL_BUTTON:
|
||||
return m.raw.u.pressed ? m.val.axis : 0.0f;
|
||||
|
||||
case INP_CTRL_WHEEL:
|
||||
return m.raw.u.axis * m.val.axis;
|
||||
|
||||
case INP_CTRL_AXIS:
|
||||
return m.raw.u.axis < 0
|
||||
? rescaleClamp(m.raw.u.axis, m.val.axis, 1.0f, 0.0f, 1.0f)
|
||||
: rescaleClamp(m.raw.u.axis, -m.val.axis, -1.0f, 0.0f, -1.0f);
|
||||
|
||||
case INP_CTRL_HAT: // hat to axis; one hat direction should be 0
|
||||
return m.val.axis * m.raw.u.ivec.x + m.val.axis * m.raw.u.ivec.y;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void InputMapper::accumulate(GameControlState *ctrl)
|
||||
{
|
||||
ctrl->wheelDelta = wheelDelta;
|
||||
ctrl->mouseX = mouseX;
|
||||
ctrl->mouseY = mouseY;
|
||||
|
||||
// walk over all inputs, check the values, apply to state
|
||||
const size_t N = mappings.size();
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
{
|
||||
const Mapping& m = mappings[i];
|
||||
if(m.buttonOrAxis > 0)
|
||||
ctrl->buttons[m.buttonOrAxis - 1] += MapToButton(m);
|
||||
if(m.buttonOrAxis < 0)
|
||||
ctrl->axes[-m.buttonOrAxis - 1] += MapToAxis(m);
|
||||
|
||||
ctrl->lastDevice = m.raw.src.deviceType;
|
||||
}
|
||||
|
||||
wheelDelta = 0;
|
||||
}
|
||||
|
||||
// TODO controllerfixup: need "follow-up" mapping
|
||||
// means "axis A -> mapped axis 0 ==> if mapped axis 0 > thresh -> trigger action
|
||||
// same for buttons: ACTION_SWIMLEFT -> ACTION_MENULEFT
|
||||
|
||||
void InputMapper::input(const RawInput *inp)
|
||||
{
|
||||
size_t N = mappings.size();
|
||||
if(inp->src.deviceType == INP_DEV_MOUSE && acceptMouse && (acceptMouseID < 0 || inp->src.deviceID == acceptMouseID))
|
||||
{
|
||||
switch(inp->src.ctrlType)
|
||||
{
|
||||
case INP_CTRL_POSITION:
|
||||
mouseX = inp->u.ivec.x;
|
||||
mouseY = inp->u.ivec.y;
|
||||
break;
|
||||
|
||||
case INP_CTRL_WHEEL:
|
||||
wheelDelta += inp->u.axis; // accumulate deltas until fetched
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
{
|
||||
Mapping& m = mappings[i];
|
||||
if(!memcmp(&m.raw.src, &inp->src, sizeof(m.raw.src)))
|
||||
{
|
||||
memcpy(&m.raw.u, &inp->u, sizeof(m.raw.u)); // store raw inputs if source matches
|
||||
|
||||
if(m.buttonOrAxis > 0) // Mapped to an action?
|
||||
{
|
||||
unsigned char state = MapToButton(m); // Does this count as a button press?
|
||||
if(m.buttonState != state) // Did it actually change? (filter Axis movements that don't actually "release" the button)
|
||||
ForwardAction(m.buttonOrAxis - 1, state, playerID, inp->src.deviceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// don't trigger if we just released a button or wiggled an analog stick by 1/10th millimeter.
|
||||
bool InputMapper::CleanupForMapping(InputControlType c, InputMapper::MapType mt, InputValue& val)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case INP_CTRL_BUTTON:
|
||||
if(!val.pressed)
|
||||
return false;
|
||||
val.pressed = 1;
|
||||
return true;
|
||||
|
||||
case INP_CTRL_AXIS:
|
||||
//if(fabsf(val.axis) < 0.6f)
|
||||
// return false;
|
||||
if(mt == TO_AXIS && val.axis < 0)
|
||||
val.axis = -val.axis;
|
||||
return true;
|
||||
|
||||
case INP_CTRL_HAT:
|
||||
if(!!val.ivec.x + !!val.ivec.y != 1) // exactly one hat axis, not centered, not diagonal
|
||||
return false;
|
||||
if(mt == TO_AXIS)
|
||||
{
|
||||
// make sure the axis goes in the right direction
|
||||
if(val.ivec.x < 0)
|
||||
val.ivec.x = -val.ivec.x;
|
||||
if(val.ivec.y < 0)
|
||||
val.ivec.y = -val.ivec.y;
|
||||
}
|
||||
return true;
|
||||
|
||||
case INP_CTRL_POSITION:
|
||||
return false;
|
||||
|
||||
case INP_CTRL_WHEEL:
|
||||
if(!val.axis)
|
||||
return false;
|
||||
if(mt == TO_AXIS && val.axis < 0)
|
||||
val.axis = -val.axis;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool InputMapper::addMapping(MapType mt, const RawInput& inp, unsigned targetID)
|
||||
{
|
||||
Mapping m;
|
||||
m.buttonOrAxis = 1 + (mt == TO_BUTTON ? int(targetID) : -int(targetID));
|
||||
m.raw = inp;
|
||||
m.val = inp.u;
|
||||
|
||||
if(!CleanupForMapping(inp.src.ctrlType, mt, m.val))
|
||||
return false;
|
||||
|
||||
mappings.push_back(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputMapper::clearMapping()
|
||||
{
|
||||
mappings.clear();
|
||||
}
|
89
BBGE/InputMapper.h
Normal file
89
BBGE/InputMapper.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef BBGE_INPUTMAPPER_H
|
||||
#define BBGE_INPUTMAPPER_H
|
||||
|
||||
#include "InputSystem.h"
|
||||
#include <vector>
|
||||
|
||||
class ActionMapper;
|
||||
|
||||
// This is what the engine sees to handle the current state.
|
||||
// Changes are not tracked here!
|
||||
struct GameControlState
|
||||
{
|
||||
GameControlState(size_t numbuttons, size_t numaxes);
|
||||
int mouseX, mouseY;
|
||||
float wheelDelta;
|
||||
InputDeviceType lastDevice;
|
||||
std::vector<unsigned char> buttons; // actually bool
|
||||
std::vector<float> axes; // uncalibrated floats, -1 .. +1
|
||||
|
||||
void clear(); // Call before InputMapper::accumulate()
|
||||
};
|
||||
|
||||
class IInputMapper
|
||||
{
|
||||
public:
|
||||
IInputMapper();
|
||||
virtual void input(const RawInput *inp) = 0;
|
||||
|
||||
// Called by ActionMapper ctor/dtor to register itself
|
||||
static void RegisterActionMapper(ActionMapper *mapper);
|
||||
static void UnregisterActionMapper(ActionMapper *mapper);
|
||||
|
||||
// Forward actions to all registered input mappers
|
||||
static void ForwardAction(unsigned idx, bool state, int playerID, InputDeviceType dev);
|
||||
static void ForwardDirectInput(unsigned k, bool state);
|
||||
|
||||
protected:
|
||||
virtual ~IInputMapper();
|
||||
|
||||
private:
|
||||
// shared between all InputMapper instances
|
||||
static std::vector<ActionMapper*> s_actionmappers;
|
||||
};
|
||||
|
||||
// Maps raw device input to player input.
|
||||
// One mapper per player.
|
||||
class InputMapper : public IInputMapper
|
||||
{
|
||||
public:
|
||||
InputMapper(int playerID);
|
||||
~InputMapper();
|
||||
|
||||
bool acceptMouse;
|
||||
int acceptMouseID; // -1: accept all, otherwise: that id
|
||||
|
||||
// raw data go in
|
||||
virtual void input(const RawInput *inp);
|
||||
|
||||
// output: apply changes to ctrl
|
||||
void accumulate(GameControlState *ctrl);
|
||||
|
||||
enum MapType
|
||||
{
|
||||
TO_BUTTON,
|
||||
TO_AXIS
|
||||
};
|
||||
bool addMapping(MapType mt, const RawInput& inp, unsigned targetID);
|
||||
void clearMapping();
|
||||
|
||||
private:
|
||||
struct Mapping
|
||||
{
|
||||
RawInput raw; // last input that came in, also contains src to check for
|
||||
int buttonOrAxis;
|
||||
InputValue val; // used as min. axis value to trigger, deadzone, hat direction, etc
|
||||
unsigned char buttonState; // for buttons: consider this pressed?
|
||||
};
|
||||
const int playerID;
|
||||
const GameControlState *target;
|
||||
float wheelDelta;
|
||||
int mouseX, mouseY;
|
||||
std::vector<Mapping> mappings;
|
||||
|
||||
static unsigned char MapToButton(const InputMapper::Mapping& m);
|
||||
static float MapToAxis(const InputMapper::Mapping& m);
|
||||
static bool CleanupForMapping(InputControlType c, InputMapper::MapType mt, InputValue& val); // modifies val, returns whether acceptable
|
||||
};
|
||||
|
||||
#endif
|
60
BBGE/InputMapperRaw.cpp
Normal file
60
BBGE/InputMapperRaw.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "InputMapperRaw.h"
|
||||
#include <assert.h>
|
||||
|
||||
InputMapperRaw::InputMapperRaw()
|
||||
{
|
||||
memset(&keyState[0], 0, sizeof(keyState));
|
||||
}
|
||||
|
||||
InputMapperRaw::~InputMapperRaw()
|
||||
{
|
||||
}
|
||||
|
||||
void InputMapperRaw::input(const RawInput *inp)
|
||||
{
|
||||
if(inp->src.ctrlType != INP_CTRL_BUTTON)
|
||||
return;
|
||||
|
||||
unsigned idx = inp->src.ctrlID;
|
||||
switch(inp->src.deviceType)
|
||||
{
|
||||
case INP_DEV_MOUSE:
|
||||
if(idx > 2)
|
||||
return; // only want left, middle, right button
|
||||
idx += MOUSE_BUTTON_LEFT;
|
||||
// fall through
|
||||
case INP_DEV_KEYBOARD:
|
||||
break; // all good
|
||||
default: // not interested in joystick etc buttons, those are only used via InputMapper
|
||||
return;
|
||||
}
|
||||
|
||||
// record change as soon as a change event comes in,
|
||||
// so we don't lose button presses that are shorter than 1 frame.
|
||||
unsigned char ch = !!inp->u.pressed;
|
||||
keyChanged[idx] |= (keyState[idx] != ch) << 1; // bit 1 becomes bit 0 in next frame
|
||||
keyState[idx] |= ch;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void InputMapperRaw::update()
|
||||
{
|
||||
// make sure that the change bit lives for at least 1 frame
|
||||
for(size_t i = 0; i < sizeof(keyChanged); ++i)
|
||||
keyChanged[i] >>= 1;
|
||||
}
|
||||
|
||||
bool InputMapperRaw::isKeyPressed(unsigned k) const
|
||||
{
|
||||
assert(k < sizeof(keyState));
|
||||
return k < sizeof(keyState) ? !!keyState[k] : false;
|
||||
}
|
||||
|
||||
bool InputMapperRaw::isKeyChanged(unsigned k) const
|
||||
{
|
||||
assert(k < sizeof(keyChanged));
|
||||
return k < sizeof(keyChanged) ? !!keyChanged[k] : false;
|
||||
}
|
||||
|
||||
|
27
BBGE/InputMapperRaw.h
Normal file
27
BBGE/InputMapperRaw.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef BBGE_INPUTMAPPERRAW_H
|
||||
#define BBGE_INPUTMAPPERRAW_H
|
||||
|
||||
#include "InputMapper.h"
|
||||
#include "GameKeys.h"
|
||||
|
||||
// Legacy mapper: Raw keys to game actions. Required by e.g. editor.
|
||||
// Used by legacy parts of ActionMapper.
|
||||
class InputMapperRaw : public IInputMapper
|
||||
{
|
||||
public:
|
||||
InputMapperRaw();
|
||||
virtual ~InputMapperRaw();
|
||||
virtual void input(const RawInput *inp);
|
||||
void update();
|
||||
|
||||
bool isKeyPressed(unsigned k) const;
|
||||
bool isKeyChanged(unsigned k) const;
|
||||
|
||||
private:
|
||||
// actually bools
|
||||
unsigned char keyState[ACTION_BUTTON_ENUM_SIZE];
|
||||
unsigned char keyChanged[ACTION_BUTTON_ENUM_SIZE];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
28
BBGE/InputSystem.cpp
Normal file
28
BBGE/InputSystem.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "InputSystem.h"
|
||||
#include "InputMapper.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace InputSystem {
|
||||
|
||||
static std::vector<IInputMapper*> s_mappers;
|
||||
|
||||
void handleRawInput(const RawInput *inp)
|
||||
{
|
||||
size_t N = s_mappers.size();
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
s_mappers[i]->input(inp);
|
||||
}
|
||||
|
||||
void addMapper(IInputMapper *mapper)
|
||||
{
|
||||
removeMapper(mapper);
|
||||
s_mappers.push_back(mapper);
|
||||
}
|
||||
|
||||
void removeMapper(IInputMapper *mapper)
|
||||
{
|
||||
s_mappers.erase(std::remove(s_mappers.begin(), s_mappers.end(), mapper), s_mappers.end());
|
||||
}
|
||||
|
||||
} // end namespace InputSystem
|
55
BBGE/InputSystem.h
Normal file
55
BBGE/InputSystem.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifndef BBGE_INPUTSYSTEM_H
|
||||
#define BBGE_INPUTSYSTEM_H
|
||||
|
||||
enum InputDeviceType
|
||||
{
|
||||
INP_DEV_NODEVICE,
|
||||
INP_DEV_KEYBOARD,
|
||||
INP_DEV_MOUSE,
|
||||
INP_DEV_JOYSTICK,
|
||||
};
|
||||
|
||||
enum InputControlType
|
||||
{
|
||||
INP_CTRL_BUTTON, // keyboard key or joystick button
|
||||
INP_CTRL_AXIS, // joystick axis
|
||||
INP_CTRL_HAT, // "digital axis"
|
||||
INP_CTRL_WHEEL, // no absolute position, only knows relative changes
|
||||
INP_CTRL_POSITION, // only absolute position
|
||||
};
|
||||
|
||||
struct InputSource
|
||||
{
|
||||
InputDeviceType deviceType;
|
||||
unsigned deviceID;
|
||||
InputControlType ctrlType;
|
||||
unsigned ctrlID;
|
||||
};
|
||||
|
||||
union InputValue
|
||||
{
|
||||
float axis; // abs. axis value or wheel delta
|
||||
unsigned pressed; // used as bool
|
||||
// TODO constrollerfixup: add uchar .hat, SDL uses a bitmask!
|
||||
struct { int x, y; } ivec; // -1, 0, +1 as hat values, window coords, etc
|
||||
};
|
||||
|
||||
struct RawInput
|
||||
{
|
||||
InputSource src;
|
||||
InputValue u;
|
||||
};
|
||||
|
||||
union SDL_Event;
|
||||
class IInputMapper;
|
||||
|
||||
namespace InputSystem
|
||||
{
|
||||
void handleSDLEvent(const SDL_Event *ev);
|
||||
void handleRawInput(const RawInput *inp);
|
||||
|
||||
void addMapper(IInputMapper *mapper);
|
||||
void removeMapper(IInputMapper *mapper);
|
||||
};
|
||||
|
||||
#endif
|
156
BBGE/InputSystemSDL.cpp
Normal file
156
BBGE/InputSystemSDL.cpp
Normal file
|
@ -0,0 +1,156 @@
|
|||
#include "InputSystem.h"
|
||||
#include <SDL.h>
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
#define USESDL2
|
||||
#endif
|
||||
|
||||
void InputSystem::handleSDLEvent(const SDL_Event *ev)
|
||||
{
|
||||
RawInput raw;
|
||||
|
||||
switch(ev->type)
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_MOUSE;
|
||||
raw.src.deviceID = ev->motion.which;
|
||||
raw.src.ctrlType = INP_CTRL_POSITION;
|
||||
raw.src.ctrlID = ev->motion.which;
|
||||
raw.u.ivec.x = ev->motion.x;
|
||||
raw.u.ivec.y = ev->motion.y;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_MOUSE;
|
||||
raw.src.deviceID = ev->button.which;
|
||||
|
||||
#ifndef USESDL2
|
||||
// SDL1 uses buttons 4 and 5 as wheel
|
||||
unsigned b = ev->button.button;
|
||||
if(b == 4 || b == 5)
|
||||
{
|
||||
raw.src.ctrlType = INP_CTRL_WHEEL;
|
||||
raw.src.ctrlID = 0;
|
||||
int dir = b == 4 ? 1 : -1;
|
||||
raw.u.axis = dir;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
raw.src.ctrlType = INP_CTRL_BUTTON;
|
||||
raw.src.ctrlID = ev->button.which;
|
||||
raw.u.pressed = ev->button.state;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef USESDL2
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_MOUSE;
|
||||
raw.src.deviceID = ev->wheel.which;
|
||||
raw.src.ctrlType = INP_CTRL_WHEEL;
|
||||
raw.src.ctrlID = ev->wheel.which;
|
||||
raw.u.axis = ev->button.state;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
#ifdef USESDL2
|
||||
unsigned kidx = ev->key.keysym.scancode;
|
||||
#else
|
||||
unsigned kidx= event.key.keysym.sym;
|
||||
#endif
|
||||
raw.src.deviceType = INP_DEV_KEYBOARD;
|
||||
raw.src.deviceID = 0; // SDL doesn't seem to support multiple keyboards
|
||||
raw.src.ctrlType = INP_CTRL_BUTTON;
|
||||
raw.src.ctrlID = kidx;
|
||||
raw.u.pressed = ev->key.state;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_KEYBOARD;
|
||||
raw.src.deviceID = ev->jbutton.which;
|
||||
raw.src.ctrlType = INP_CTRL_BUTTON;
|
||||
raw.src.ctrlID = ev->jbutton.button;
|
||||
raw.u.pressed = ev->jbutton.state;
|
||||
}
|
||||
|
||||
case SDL_JOYAXISMOTION:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_JOYSTICK;
|
||||
raw.src.deviceID = ev->jaxis.which;
|
||||
raw.src.ctrlType = INP_CTRL_AXIS;
|
||||
raw.src.ctrlID = ev->jaxis.axis;
|
||||
raw.u.axis = ev->jaxis.value / 32768.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_JOYSTICK;
|
||||
raw.src.deviceID = ev->jhat.which;
|
||||
raw.src.ctrlType = INP_CTRL_HAT;
|
||||
raw.src.ctrlID = ev->jhat.hat;
|
||||
int x, y;
|
||||
switch(ev->jhat.value)
|
||||
{
|
||||
case SDL_HAT_CENTERED: x = 0; y = 0; break;
|
||||
case SDL_HAT_UP: x = 0; y = -1; break;
|
||||
case SDL_HAT_DOWN: x = 0; y = +1; break;
|
||||
case SDL_HAT_LEFT: x = -1; y = 0; break;
|
||||
case SDL_HAT_RIGHT: x = +1; y = 0; break;
|
||||
case SDL_HAT_LEFTUP: x = -1; y = -1; break;
|
||||
case SDL_HAT_LEFTDOWN: x = -1; y = +1; break;
|
||||
case SDL_HAT_RIGHTUP: x = +1; y = -1; break;
|
||||
case SDL_HAT_RIGHTDOWN: x = +1; y = +1; break;
|
||||
}
|
||||
raw.u.ivec.x = (signed short)x;
|
||||
raw.u.ivec.y = (signed short)y;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_JOYSTICK;
|
||||
raw.src.deviceID = ev->caxis.which;
|
||||
raw.src.ctrlType = INP_CTRL_AXIS;
|
||||
raw.src.ctrlID = ev->caxis.axis;
|
||||
raw.u.axis = ev->caxis.value / float(0x7fff);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
{
|
||||
raw.src.deviceType = INP_DEV_JOYSTICK;
|
||||
raw.src.deviceID = ev->cbutton.which;
|
||||
raw.src.ctrlType = INP_CTRL_BUTTON;
|
||||
raw.src.ctrlID = ev->cbutton.button;
|
||||
raw.u.pressed = ev->cbutton.state;
|
||||
}
|
||||
break;
|
||||
|
||||
/*case SDL_WINDOWEVENT:
|
||||
switch(ev->window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
s_winSizeXInv = 1.0f / (float)ev->window.data1;
|
||||
s_winSizeYInv = 1.0f / (float)ev->window.data2;
|
||||
break;
|
||||
}*/
|
||||
// fall through
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
handleRawInput(&raw);
|
||||
}
|
|
@ -39,21 +39,7 @@ Joystick::Joystick()
|
|||
debugLog("Failed to init haptic subsystem");
|
||||
# endif
|
||||
sdl_joy = NULL;
|
||||
buttonBitmask = 0;
|
||||
deadZone1 = 0.3f;
|
||||
deadZone2 = 0.3f;
|
||||
|
||||
clearRumbleTime= 0;
|
||||
numJoyAxes = 0;
|
||||
numHats = 0;
|
||||
numButtons = 0;
|
||||
clearAxes();
|
||||
|
||||
s1ax = 0;
|
||||
s1ay = 1;
|
||||
s2ax = 4;
|
||||
s2ay = 3;
|
||||
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
|
@ -80,7 +66,6 @@ const char *Joystick::getGUID() const
|
|||
bool Joystick::init(int stick)
|
||||
{
|
||||
stickIndex = stick;
|
||||
numJoyAxes = 0;
|
||||
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
if (SDL_IsGameController(stick))
|
||||
|
@ -119,10 +104,7 @@ bool Joystick::init(int stick)
|
|||
guid = &guidbuf[0];
|
||||
debugLog(std::string("Initialized Joystick [") + name + "], GUID [" + guid + "]");
|
||||
if (sdl_controller)
|
||||
{
|
||||
debugLog("Joystick is a Game Controller");
|
||||
numJoyAxes = SDL_CONTROLLER_AXIS_MAX;
|
||||
}
|
||||
if (sdl_haptic)
|
||||
debugLog("Joystick has force feedback support");
|
||||
instanceID = SDL_JoystickInstanceID(sdl_joy);
|
||||
|
@ -133,14 +115,11 @@ bool Joystick::init(int stick)
|
|||
instanceID = SDL_JoystickIndex(sdl_joy);
|
||||
#endif
|
||||
|
||||
if(!numJoyAxes)
|
||||
numJoyAxes = SDL_JoystickNumAxes(sdl_joy);
|
||||
if(numJoyAxes > MAX_JOYSTICK_AXIS)
|
||||
numJoyAxes = MAX_JOYSTICK_AXIS;
|
||||
|
||||
numHats = SDL_JoystickNumHats(sdl_joy);
|
||||
numButtons = SDL_JoystickNumButtons(sdl_joy);
|
||||
|
||||
std::ostringstream os;
|
||||
os << "Joystick has " << SDL_JoystickNumAxes(sdl_joy) << " axes, "
|
||||
<< SDL_JoystickNumButtons(sdl_joy) << " buttons, "
|
||||
<< SDL_JoystickNumHats(sdl_joy) << " hats.";
|
||||
debugLog(os.str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -171,14 +150,6 @@ void Joystick::shutdown()
|
|||
SDL_JoystickClose(sdl_joy);
|
||||
sdl_joy = 0;
|
||||
}
|
||||
|
||||
numJoyAxes = 0;
|
||||
clearAxes();
|
||||
}
|
||||
|
||||
void Joystick::clearAxes()
|
||||
{
|
||||
memset(axisRaw, 0, sizeof(axisRaw));
|
||||
}
|
||||
|
||||
void Joystick::rumble(float leftMotor, float rightMotor, float time)
|
||||
|
@ -204,7 +175,7 @@ void Joystick::rumble(float leftMotor, float rightMotor, float time)
|
|||
}
|
||||
}
|
||||
|
||||
void Joystick::calibrate(Vector &calvec, float deadZone)
|
||||
void Joystick::Calibrate(Vector &calvec, float deadZone)
|
||||
{
|
||||
if (calvec.isLength2DIn(deadZone))
|
||||
{
|
||||
|
@ -244,20 +215,6 @@ void Joystick::update(float dt)
|
|||
shutdown();
|
||||
return;
|
||||
}
|
||||
if (sdl_controller)
|
||||
{
|
||||
for(unsigned i = 0; i < numJoyAxes; ++i)
|
||||
{
|
||||
Sint16 ax = SDL_GameControllerGetAxis(sdl_controller, (SDL_GameControllerAxis)i);
|
||||
axisRaw[i] = float(ax)/32768.0f;
|
||||
}
|
||||
|
||||
position.x = axisRaw[SDL_CONTROLLER_AXIS_LEFTX];
|
||||
position.y = axisRaw[SDL_CONTROLLER_AXIS_LEFTY];
|
||||
rightStick.x = axisRaw[SDL_CONTROLLER_AXIS_RIGHTX];
|
||||
rightStick.y = axisRaw[SDL_CONTROLLER_AXIS_RIGHTY];
|
||||
}
|
||||
else
|
||||
#else
|
||||
if (!SDL_JoystickOpened(stickIndex))
|
||||
{
|
||||
|
@ -266,38 +223,6 @@ void Joystick::update(float dt)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
// Note: this connects with the else above when the SDL2 path is compiled!
|
||||
{
|
||||
for(unsigned i = 0; i < numJoyAxes; ++i)
|
||||
{
|
||||
Sint16 ax = SDL_JoystickGetAxis(sdl_joy, i);
|
||||
axisRaw[i] = float(ax)/32768.0f;
|
||||
}
|
||||
position.x = s1ax >= 0 ? axisRaw[s1ax] : 0.0f;
|
||||
position.y = s1ay >= 0 ? axisRaw[s1ay] : 0.0f;
|
||||
rightStick.x = s2ax >= 0 ? axisRaw[s2ax] : 0.0f;
|
||||
rightStick.y = s2ay >= 0 ? axisRaw[s2ay] : 0.0f;
|
||||
}
|
||||
|
||||
calibrate(position, deadZone1);
|
||||
calibrate(rightStick, deadZone2);
|
||||
|
||||
buttonBitmask = 0;
|
||||
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
if (sdl_controller)
|
||||
{
|
||||
for (unsigned i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
|
||||
buttonBitmask |= !!SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)i) << i;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (unsigned i = 0; i < numButtons; i++)
|
||||
buttonBitmask |= !!SDL_JoystickGetButton(sdl_joy, i) << i;
|
||||
|
||||
//for (unsigned i = 0; i < numHats; i++)
|
||||
}
|
||||
}
|
||||
|
||||
if (clearRumbleTime >= 0)
|
||||
|
@ -310,60 +235,8 @@ void Joystick::update(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
bool Joystick::anyButton() const
|
||||
{
|
||||
return !!buttonBitmask;;
|
||||
}
|
||||
|
||||
unsigned Joystick::getNumAxes() const
|
||||
{
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
return sdl_controller ? SDL_CONTROLLER_AXIS_MAX : numJoyAxes;
|
||||
#else
|
||||
return numJoyAxes;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned Joystick::getNumButtons() const
|
||||
{
|
||||
return numButtons;
|
||||
}
|
||||
|
||||
unsigned Joystick::getNumHats() const
|
||||
{
|
||||
return numHats;
|
||||
}
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
#ifdef BBGE_BUILD_SDL2
|
||||
if(sdl_controller)
|
||||
return SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)axis);
|
||||
|
|
|
@ -11,20 +11,6 @@
|
|||
|
||||
#include "Vector.h"
|
||||
|
||||
#define MAX_JOYSTICK_BTN 32
|
||||
#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
|
||||
|
@ -40,19 +26,8 @@ public:
|
|||
//Ranges from 0 to 1 (full speed).
|
||||
void rumble(float leftMotor, float rightMotor, float time);
|
||||
void update(float dt);
|
||||
Vector position;
|
||||
|
||||
float deadZone1, deadZone2;
|
||||
float clearRumbleTime;
|
||||
|
||||
void calibrate(Vector &vec, float dead);
|
||||
bool anyButton() const;
|
||||
bool getButton(size_t id) const { return !!(buttonBitmask & (1u << id)); }
|
||||
float getAxisUncalibrated(unsigned id) const;
|
||||
JoyHatDirection getHat(unsigned id) const;
|
||||
unsigned getNumAxes() const;
|
||||
unsigned getNumButtons() const;
|
||||
unsigned getNumHats() const;
|
||||
static void Calibrate(Vector &vec, float dead);
|
||||
int getIndex() const { return stickIndex; }
|
||||
int getInstanceID() const { return instanceID; }
|
||||
inline bool isEnabled() const { return enabled; }
|
||||
|
@ -63,19 +38,12 @@ public:
|
|||
const char *getName() const;
|
||||
const char *getGUID() const;
|
||||
|
||||
Vector rightStick;
|
||||
|
||||
int s1ax, s1ay, s2ax, s2ay;
|
||||
|
||||
private:
|
||||
void clearAxes();
|
||||
float clearRumbleTime;
|
||||
bool enabled;
|
||||
int stickIndex;
|
||||
int instanceID;
|
||||
unsigned buttonBitmask;
|
||||
unsigned numJoyAxes, numHats, numButtons;
|
||||
SDL_Joystick *sdl_joy;
|
||||
float axisRaw[MAX_JOYSTICK_AXIS];
|
||||
std::string name;
|
||||
std::string guid;
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
void removeRenderObject(RenderObject *renderObject);
|
||||
std::string name;
|
||||
|
||||
virtual void action(int actionID, int state, int source, InputDevice device) {}
|
||||
virtual void action(int actionID, int state, int playerID, InputDeviceType device) {}
|
||||
|
||||
protected:
|
||||
void registerState(StateObject *sb, const std::string &name);
|
||||
|
|
|
@ -4,17 +4,6 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// Some strings used in BBGE
|
||||
enum StringBankIndexBBGE
|
||||
{
|
||||
SB_BBGE_NO_KEY = 2153,
|
||||
SB_BBGE_INVALID_KEY_ID = 2154,
|
||||
SB_BBGE_INVALID_JOY_BTN = 2155,
|
||||
SB_BBGE_INVALID_MOUSE_BTN = 2156,
|
||||
SB_BBGE_INVALID_JOY_AXIS_POS = 2157,
|
||||
SB_BBGE_INVALID_JOY_AXIS_NEG = 2158,
|
||||
};
|
||||
|
||||
class StringBank
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -423,10 +423,6 @@
|
|||
RelativePath="..\..\Aquaria\Damage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Aquaria\Demo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Aquaria\DSQ.cpp"
|
||||
>
|
||||
|
@ -475,6 +471,14 @@
|
|||
RelativePath="..\..\Aquaria\GameEnums.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Aquaria\GameInput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Aquaria\GameInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Aquaria\GameplayVariables.cpp"
|
||||
>
|
||||
|
|
|
@ -333,14 +333,6 @@
|
|||
RelativePath="..\..\BBGE\ActionSet.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\ActionStatus.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\ActionStatus.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\AfterEffect.cpp"
|
||||
>
|
||||
|
@ -461,6 +453,34 @@
|
|||
RelativePath="..\..\BBGE\Gradient.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputMapper.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputMapper.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputMapperRaw.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputMapperRaw.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputSystem.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputSystem.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\InputSystemSDL.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\Joystick.cpp"
|
||||
>
|
||||
|
|
Loading…
Add table
Reference in a new issue