aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/psp/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/psp/input.cpp')
-rw-r--r--backends/platform/psp/input.cpp583
1 files changed, 394 insertions, 189 deletions
diff --git a/backends/platform/psp/input.cpp b/backends/platform/psp/input.cpp
index 4fe7cb3f92..3ea2d4365d 100644
--- a/backends/platform/psp/input.cpp
+++ b/backends/platform/psp/input.cpp
@@ -23,238 +23,272 @@
*
*/
-// Todo: handle events that should fire because of shift going off
-// Solution: handle shift on a button-by-button basis, only allowing it when the button is up. Also a inputmap-wide button. At buttonup, shiftstate is inspected per button.
+#include <pspctrl.h>
+#include "gui/message.h"
+#include "backends/platform/psp/input.h"
//#define __PSP_DEBUG_FUNCS__ /* Uncomment for debugging the stack */
//#define __PSP_DEBUG_PRINT__ /* Uncomment for debug prints */
-
#include "backends/platform/psp/trace.h"
-#include "backends/platform/psp/psppixelformat.h"
-#include "backends/platform/psp/input.h"
-
// Defines for working with PSP buttons
-#define CHANGED(x) (_buttonsChanged & (x))
-#define PRESSED(x) ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
-#define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
-#define DOWN(x) (pad.Buttons & (x))
+#define DOWN(x) ((pad.Buttons & (x)) == (x))
#define UP(x) (!(pad.Buttons & (x)))
#define PSP_DPAD (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
#define PSP_TRIGGERS (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER)
+#define PSP_ALL_BUTTONS (PSP_DPAD | PSP_4BUTTONS | PSP_TRIGGERS | PSP_CTRL_START | PSP_CTRL_SELECT)
#define PAD_CHECK_TIME 53
-void InputHandler::init() {
- sceCtrlSetSamplingCycle(0); // set sampling to vsync. n = n usecs
- sceCtrlSetSamplingMode(1); // analog
+Button::Button() {
+ clear();
}
-bool InputHandler::getAllInputs(Common::Event &event) {
- DEBUG_ENTER_FUNC();
-
- uint32 time = g_system->getMillis(); // may not be necessary with read
- if (time - _lastPadCheckTime < PAD_CHECK_TIME) {
- return false;
- }
-
- _lastPadCheckTime = time;
- SceCtrlData pad;
-
- sceCtrlPeekBufferPositive(&pad, 1); // Peek ignores sleep. Read sleeps thread
-
- bool haveEvent;
-
- memset(&event, 0, sizeof(event));
-
- if (_keyboard->isVisible())
- haveEvent = _keyboard->processInput(event, pad);
- else
- haveEvent = getEvent(event, pad);
+inline void Button::clear() {
+ _key = Common::KEYCODE_INVALID;
+ _ascii = 0;
+ _flag = 0;
+ _pspEventDown.clear();
+ _pspEventUp.clear();
+}
- if (haveEvent) {
- PSP_DEBUG_PRINT("Have event[%s]\n", haveEvent ? "true" : "false");
- PSP_DEBUG_PRINT("event.type[%d]\n", event.type);
+inline bool Button::getEvent(Common::Event &event, PspEvent &pspEvent, bool down) {
+ if (down) {
+ if (!_pspEventDown.isEmpty())
+ pspEvent = _pspEventDown;
+ } else { // up
+ if (!_pspEventUp.isEmpty())
+ pspEvent = _pspEventUp;
+ }
+ if (_key != Common::KEYCODE_INVALID) {
+ event.type = down ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
+ event.kbd.keycode = _key;
+ event.kbd.ascii = _ascii;
+ event.kbd.flags |= _flag;
+ return true;
+ } else if (_flag) { // handle flag only events
+ event.type = down ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
+ event.kbd.flags |= down ? _flag : 0;
+ return true;
}
-
- return haveEvent;
+ return false;
}
-bool InputHandler::getEvent(Common::Event &event, SceCtrlData &pad) {
- DEBUG_ENTER_FUNC();
-
- _buttonsChanged = pad.Buttons ^ _prevButtons;
- bool haveEvent = false;
-
- // Collect events from different sources
- haveEvent = getDpadEvent(event, pad);
-
- if (!haveEvent)
- haveEvent = getButtonEvent(event, pad);
-
- if (!haveEvent)
- haveEvent = getNubEvent(event, pad);
-
- _prevButtons = pad.Buttons;
-
- return haveEvent;
+void Button::setPspEvent(PspEventType typeDown, uint32 dataDown, PspEventType typeUp, uint32 dataUp) {
+ _pspEventDown.type = typeDown;
+ _pspEventDown.data = dataDown;
+ _pspEventUp.type = typeUp;
+ _pspEventUp.data = dataUp;
+}
+
+// Translates bitfields to our constants
+// We put combined bitfields first to make sure we pick up diagonals
+const uint32 ButtonPad::_buttonMap[] = {
+ PSP_CTRL_UP | PSP_CTRL_LEFT,
+ PSP_CTRL_UP | PSP_CTRL_RIGHT,
+ PSP_CTRL_DOWN | PSP_CTRL_RIGHT,
+ PSP_CTRL_DOWN | PSP_CTRL_LEFT,
+ PSP_CTRL_RIGHT, PSP_CTRL_DOWN, PSP_CTRL_LEFT, PSP_CTRL_UP,
+ PSP_CTRL_CROSS, PSP_CTRL_CIRCLE, PSP_CTRL_TRIANGLE, PSP_CTRL_SQUARE,
+ PSP_CTRL_LTRIGGER, PSP_CTRL_RTRIGGER, PSP_CTRL_START, PSP_CTRL_SELECT
+};
+
+ButtonPad::ButtonPad() : _prevButtonState(0), _shifted(UNSHIFTED), _padMode(PAD_MODE_NORMAL),
+ _comboMode(false) {
+ for (int i = UNSHIFTED; i < SHIFTED_MODE_LAST; i++)
+ _buttonsChanged[i] = 0;
+ clearButtons();
}
-bool InputHandler::getDpadEvent(Common::Event &event, SceCtrlData &pad) {
- DEBUG_ENTER_FUNC();
-
- int newDpadX = 0, newDpadY = 0;
- bool haveEvent = false;
-
- if (DOWN(PSP_CTRL_UP)) {
- newDpadY++;
- if (DOWN(PSP_CTRL_RTRIGGER)) // Shifting causes diagonals
- newDpadX++;
- }
- if (DOWN(PSP_CTRL_RIGHT)) {
- newDpadX++;
- if (DOWN(PSP_CTRL_RTRIGGER))
- newDpadY--;
+void ButtonPad::clearButtons() {
+ for (int i = BTN_UP_LEFT; i < BTN_LAST; i++) {
+ _button[i][UNSHIFTED].clear();
+ _button[i][SHIFTED].clear();
}
- if (DOWN(PSP_CTRL_DOWN)) {
- newDpadY--;
- if (DOWN(PSP_CTRL_RTRIGGER))
- newDpadX--;
- }
- if (DOWN(PSP_CTRL_LEFT)) {
- newDpadX--;
- if (DOWN(PSP_CTRL_RTRIGGER))
- newDpadY++;
- }
-
- if (newDpadX != _dpadX || newDpadY != _dpadY) {
- if (_dpadX == 0 && _dpadY == 0) { // We were in the middle so we pressed dpad
- event.type = Common::EVENT_KEYDOWN;
- event.kbd.keycode = translateDpad(newDpadX, newDpadY);
- event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0'; // Get ascii
- _dpadX = newDpadX;
- _dpadY = newDpadY;
- } else if (newDpadX == 0 && newDpadY == 0) {// We're now centered so we unpressed dpad
- event.type = Common::EVENT_KEYUP;
- event.kbd.keycode = translateDpad(_dpadX, _dpadY);
- event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
- _dpadX = newDpadX;
- _dpadY = newDpadY;
- } else { // we moved from one pressed dpad direction to another one
- event.type = Common::EVENT_KEYUP; // first release the last dpad direction
- event.kbd.keycode = translateDpad(_dpadX, _dpadY);
- event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
- _dpadX = 0; // so that we'll pick up a new dpad movement the next round
- _dpadY = 0;
- }
+}
- PSP_DEBUG_PRINT("Keypad event. DpadX[%d], DpadY[%d]\n", _dpadX, _dpadY);
- haveEvent = true;
+void ButtonPad::initButtons() {
+ switch (_padMode) {
+ case PAD_MODE_NORMAL:
+ initButtonsNormalMode();
+ break;
+ case PAD_MODE_LOL:
+ initButtonsLolMode();
+ break;
+ default:
+ break;
}
-
- return haveEvent;
}
-inline Common::KeyCode InputHandler::translateDpad(int x, int y) {
+void ButtonPad::initButtonsNormalMode() {
DEBUG_ENTER_FUNC();
- Common::KeyCode key;
-
- if (x == -1) {
- if (y == -1)
- key = Common::KEYCODE_KP1;
- else if (y == 0)
- key = Common::KEYCODE_KP4;
- else /* y == 1 */
- key = Common::KEYCODE_KP7;
- } else if (x == 0) {
- if (y == -1)
- key = Common::KEYCODE_KP2;
- else /* y == 1 */
- key = Common::KEYCODE_KP8;
- } else {/* x == 1 */
- if (y == -1)
- key = Common::KEYCODE_KP3;
- else if (y == 0)
- key = Common::KEYCODE_KP6;
- else /* y == 1 */
- key = Common::KEYCODE_KP9;
- }
-
- return key;
+ PSP_DEBUG_PRINT("initializing buttons for normal mode\n");
+ clearButtons();
+
+ // Dpad
+ _button[BTN_UP_LEFT][UNSHIFTED].setKey(Common::KEYCODE_KP7, '7');
+ _button[BTN_LEFT][SHIFTED].setKey(Common::KEYCODE_KP7, '7'); // same as up_left
+ _button[BTN_UP][UNSHIFTED].setKey(Common::KEYCODE_KP8, '8');
+ _button[BTN_UP_RIGHT][UNSHIFTED].setKey(Common::KEYCODE_KP9, '9');
+ _button[BTN_UP][SHIFTED].setKey(Common::KEYCODE_KP9, '9'); // same as up_right
+ _button[BTN_LEFT][UNSHIFTED].setKey(Common::KEYCODE_KP4, '4');
+ _button[BTN_RIGHT][UNSHIFTED].setKey(Common::KEYCODE_KP6, '6');
+ _button[BTN_DOWN_LEFT][UNSHIFTED].setKey(Common::KEYCODE_KP1, '1');
+ _button[BTN_DOWN][SHIFTED].setKey(Common::KEYCODE_KP1, '1'); // same as down_left
+ _button[BTN_DOWN][UNSHIFTED].setKey(Common::KEYCODE_KP2, '2');
+ _button[BTN_DOWN_RIGHT][UNSHIFTED].setKey(Common::KEYCODE_KP3, '3');
+ _button[BTN_RIGHT][SHIFTED].setKey(Common::KEYCODE_KP3, '3'); // same as down_right
+
+ // Other buttons
+ _button[BTN_CROSS][UNSHIFTED].setPspEvent(PSP_EVENT_LBUTTON, true, PSP_EVENT_LBUTTON, false);
+ _button[BTN_CIRCLE][UNSHIFTED].setPspEvent(PSP_EVENT_RBUTTON, true, PSP_EVENT_RBUTTON, false);
+ _button[BTN_TRIANGLE][UNSHIFTED].setKey(Common::KEYCODE_RETURN, '\r');
+ _button[BTN_SQUARE][UNSHIFTED].setKey(Common::KEYCODE_PERIOD, '.');
+ _button[BTN_SQUARE][SHIFTED].setKey(Common::KEYCODE_SPACE, ' ');
+ _button[BTN_LTRIGGER][UNSHIFTED].setKey(Common::KEYCODE_ESCAPE, 27);
+ _button[BTN_RTRIGGER][SHIFTED].setPspEvent(PSP_EVENT_SHIFT, true, PSP_EVENT_SHIFT, false);
+ _button[BTN_RTRIGGER][UNSHIFTED].setPspEvent(PSP_EVENT_SHIFT, true, PSP_EVENT_SHIFT, false);
+ _button[BTN_RTRIGGER][SHIFTED].setKey(Common::KEYCODE_INVALID, 0, Common::KBD_SHIFT);
+ _button[BTN_RTRIGGER][UNSHIFTED].setKey(Common::KEYCODE_INVALID, 0, Common::KBD_SHIFT);
+ _button[BTN_START][SHIFTED].setKey(Common::KEYCODE_F5, Common::ASCII_F5);
+ _button[BTN_START][UNSHIFTED].setKey(Common::KEYCODE_F5, Common::ASCII_F5, Common::KBD_CTRL);
+ _button[BTN_SELECT][UNSHIFTED].setPspEvent(PSP_EVENT_SHOW_VIRTUAL_KB, true, PSP_EVENT_NONE, 0);
+}
+
+void ButtonPad::initButtonsLolMode() {
+ DEBUG_ENTER_FUNC();
+ initButtonsNormalMode(); // set normal button configuration
+ PSP_DEBUG_PRINT("initializing buttons for LOL mode\n");
+
+ // Square is our new shift button
+ _button[BTN_SQUARE][UNSHIFTED].clear();
+ _button[BTN_SQUARE][UNSHIFTED].setPspEvent(PSP_EVENT_SHIFT, true, PSP_EVENT_SHIFT, false);
+ _button[BTN_SQUARE][SHIFTED].clear();
+ _button[BTN_SQUARE][SHIFTED].setPspEvent(PSP_EVENT_SHIFT, true, PSP_EVENT_SHIFT, false);
+
+ // Dpad
+ _button[BTN_LEFT][UNSHIFTED].clear();
+ _button[BTN_LEFT][UNSHIFTED].setKey(Common::KEYCODE_KP7, '7');
+ _button[BTN_LEFT][SHIFTED].clear();
+ _button[BTN_LEFT][SHIFTED].setKey(Common::KEYCODE_F1, Common::ASCII_F1);
+ _button[BTN_UP][SHIFTED].clear();
+ _button[BTN_UP][SHIFTED].setKey(Common::KEYCODE_F2, Common::ASCII_F2);
+ _button[BTN_RIGHT][UNSHIFTED].clear();
+ _button[BTN_RIGHT][UNSHIFTED].setKey(Common::KEYCODE_KP9, '9');
+ _button[BTN_RIGHT][SHIFTED].clear();
+ _button[BTN_RIGHT][SHIFTED].setKey(Common::KEYCODE_F3, Common::ASCII_F3);
+ _button[BTN_DOWN][SHIFTED].clear();
+ _button[BTN_DOWN][SHIFTED].setKey(Common::KEYCODE_F4, Common::ASCII_F4);
+
+ // Buttons
+ _button[BTN_LTRIGGER][UNSHIFTED].clear();
+ _button[BTN_LTRIGGER][SHIFTED].clear();
+ _button[BTN_LTRIGGER][UNSHIFTED].setKey(Common::KEYCODE_KP4, '4'); // Triggers turn
+ _button[BTN_RTRIGGER][UNSHIFTED].clear();
+ _button[BTN_RTRIGGER][SHIFTED].clear();
+ _button[BTN_RTRIGGER][UNSHIFTED].setKey(Common::KEYCODE_KP6, '6');
+ _button[BTN_START][SHIFTED].clear();
+ _button[BTN_START][SHIFTED].setKey(Common::KEYCODE_ESCAPE, 27);
}
-
-bool InputHandler::getButtonEvent(Common::Event &event, SceCtrlData &pad) {
+bool ButtonPad::getEvent(Common::Event &event, PspEvent &pspEvent, SceCtrlData &pad) {
DEBUG_ENTER_FUNC();
- bool haveEvent = false;
+
+ //PSP_DEBUG_PRINT("buttons[%x]\n", pad.Buttons);
+
+ uint32 curButtonState = PSP_ALL_BUTTONS & pad.Buttons; // we only care about these
+
+ modifyButtonsForCombos(pad); // change buttons for combos
+
+ return getEventFromButtonState(event, pspEvent, curButtonState);
+}
- if (PRESSED(PSP_CTRL_SELECT))
- _keyboard->setVisible(true);
-
- else if (CHANGED(PSP_4BUTTONS | PSP_TRIGGERS | PSP_CTRL_START)) {
- if (CHANGED(PSP_CTRL_CROSS)) {
- event.type = DOWN(PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
- event.mouse.x = _cursor->getX(); // Could this have to do with SCI enter problem?
- event.mouse.y = _cursor->getY();
- PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "LButtonDown" : "LButtonUp");
- } else if (CHANGED(PSP_CTRL_CIRCLE)) {
- event.type = DOWN(PSP_CTRL_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP;
- event.mouse.x = _cursor->getX();
- event.mouse.y = _cursor->getY();
- PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "RButtonDown" : "RButtonUp");
- } else {
- //any of the other buttons.
- event.type = _buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
- event.kbd.ascii = 0;
- event.kbd.flags = 0;
-
- if (CHANGED(PSP_CTRL_LTRIGGER)) {
- event.kbd.keycode = Common::KEYCODE_ESCAPE;
- event.kbd.ascii = 27;
- } else if (CHANGED(PSP_CTRL_START)) {
- event.kbd.keycode = Common::KEYCODE_F5;
- event.kbd.ascii = Common::ASCII_F5;
- if (DOWN(PSP_CTRL_RTRIGGER)) {
- event.kbd.flags |= Common::KBD_CTRL; // Main menu to allow RTL
+bool ButtonPad::getEventFromButtonState(Common::Event &event, PspEvent &pspEvent, uint32 buttonState) {
+ DEBUG_ENTER_FUNC();
+ _buttonsChanged[_shifted] |= buttonState ^ _prevButtonState; // add any buttons that changed
+ _prevButtonState = buttonState;
+
+ for (int shiftState = UNSHIFTED; shiftState < SHIFTED_MODE_LAST; shiftState++) {
+ if (_buttonsChanged[shiftState]) { // any button to address?
+ PSP_DEBUG_PRINT("found changed buttons\n");
+ ButtonType buttonType = BTN_LAST;
+ bool buttonDown = false; // normally we release a button (as in when we're in a different shiftmode)
+
+ for (int i = BTN_UP_LEFT; i < BTN_LAST; i++) {
+ uint32 buttonCode = _buttonMap[i];
+ if ((_buttonsChanged[shiftState] & buttonCode) == buttonCode) { // check for this changed button
+ buttonType = (ButtonType)i; // we know which button changed
+ _buttonsChanged[shiftState] &= ~buttonCode; // save the fact that we treated this button
+ if (shiftState == _shifted)
+ buttonDown = buttonState & buttonCode ? true : false; // pressed or released?
+
+ PSP_DEBUG_PRINT("button[%i] pressed\n", i);
+ break;
}
- } else if (CHANGED(PSP_CTRL_SQUARE)) {
- event.kbd.keycode = Common::KEYCODE_PERIOD;
- event.kbd.ascii = '.';
- } else if (CHANGED(PSP_CTRL_TRIANGLE)) {
- event.kbd.keycode = Common::KEYCODE_RETURN;
- event.kbd.ascii = '\r';
- } else if (DOWN(PSP_CTRL_RTRIGGER)) { // An event
- event.kbd.flags |= Common::KBD_SHIFT;
}
- PSP_DEBUG_PRINT("Ascii[%d]. Key %s.\n", event.kbd.ascii, event.type == Common::EVENT_KEYDOWN ? "down" : "up");
+
+ assert (buttonType < BTN_LAST);
+ bool haveEvent = _button[buttonType][shiftState].getEvent(event, pspEvent, buttonDown);
+ if (haveEvent)
+ PSP_DEBUG_PRINT("have event. key[%d] flag[%x] %s\n", event.kbd.ascii, event.kbd.flags, buttonDown ? "down" : "up");
+ return haveEvent;
}
-
- haveEvent = true;
- }
-
- return haveEvent;
+ }
+
+ return false;
}
-
-bool InputHandler::getNubEvent(Common::Event &event, SceCtrlData &pad) {
+
+void ButtonPad::modifyButtonsForCombos(SceCtrlData &pad) {
+ if (DOWN(PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) {
+ if (!_comboMode) { // we're entering combo mode
+ PSP_DEBUG_PRINT("entering combo mode\n");
+ _button[BTN_SQUARE][UNSHIFTED].clear();
+ _button[BTN_SQUARE][SHIFTED].clear();
+ _button[BTN_DOWN][SHIFTED].clear();
+ _button[BTN_DOWN][UNSHIFTED].clear();
+ _button[BTN_UP][SHIFTED].clear();
+ _button[BTN_UP][UNSHIFTED].clear();
+ _button[BTN_SQUARE][UNSHIFTED].setPspEvent(PSP_EVENT_MODE_SWITCH, true, PSP_EVENT_NONE, true);
+ _button[BTN_SQUARE][SHIFTED].setPspEvent(PSP_EVENT_MODE_SWITCH, true, PSP_EVENT_NONE, true);
+ _button[BTN_DOWN][UNSHIFTED].setPspEvent(PSP_EVENT_CHANGE_SPEED, false, PSP_EVENT_NONE, true);
+ _button[BTN_DOWN][SHIFTED].setPspEvent(PSP_EVENT_CHANGE_SPEED, false, PSP_EVENT_NONE, true);
+ _button[BTN_UP][UNSHIFTED].setPspEvent(PSP_EVENT_CHANGE_SPEED, true, PSP_EVENT_NONE, true);
+ _button[BTN_UP][SHIFTED].setPspEvent(PSP_EVENT_CHANGE_SPEED, true, PSP_EVENT_NONE, true);
+ _comboMode = true;
+ }
+ } else { // no combo buttons are pressed now
+ if (_comboMode) { // we have been running in combo mode
+ initButtons(); // reset the button configuration
+ _comboMode = false;
+ }
+ }
+}
+
+bool Nub::getEvent(Common::Event &event, PspEvent &pspEvent, SceCtrlData &pad) {
DEBUG_ENTER_FUNC();
-
- bool haveEvent = false;
+
+ if (_dpadMode) { // Convert the nub to a D-Pad
+ uint32 buttonState;
+ translateToDpadState(pad.Lx, pad.Ly, buttonState);
+ return _buttonPad.getEventFromButtonState(event, pspEvent, buttonState);
+ }
+
int32 analogStepX = pad.Lx; // Goes up to 255.
int32 analogStepY = pad.Ly;
- int32 oldX = _cursor->getX();
- int32 oldY = _cursor->getY();
-
analogStepX = modifyNubAxisMotion(analogStepX);
analogStepY = modifyNubAxisMotion(analogStepY);
+
+ int32 oldX = _cursor->getX();
+ int32 oldY = _cursor->getY();
if (analogStepX != 0 || analogStepY != 0) {
PSP_DEBUG_PRINT("raw x[%d], y[%d]\n", analogStepX, analogStepY);
// If no movement then this has no effect
- if (DOWN(PSP_CTRL_RTRIGGER)) {
+ if (_shifted) {
// Fine control mode for analog
if (analogStepX != 0) {
if (analogStepX > 0)
@@ -281,15 +315,29 @@ bool InputHandler::getNubEvent(Common::Event &event, SceCtrlData &pad) {
event.type = Common::EVENT_MOUSEMOVE;
event.mouse.x = newX;
event.mouse.y = newY;
- haveEvent = true;
-
PSP_DEBUG_PRINT("Nub event. X[%d], Y[%d]\n", newX, newY);
+ return true;
}
}
- return haveEvent;
+ return false;
+}
+
+void Nub::translateToDpadState(int dpadX, int dpadY, uint32 &buttonState) {
+ #define MIN_NUB_POSITION 70
+ buttonState = 0;
+
+ if (dpadX > 127 + MIN_NUB_POSITION)
+ buttonState |= PSP_CTRL_RIGHT;
+ else if (dpadX < 127 - MIN_NUB_POSITION)
+ buttonState |= PSP_CTRL_LEFT;
+
+ if (dpadY > 127 + MIN_NUB_POSITION)
+ buttonState |= PSP_CTRL_DOWN;
+ else if (dpadY < 127 - MIN_NUB_POSITION)
+ buttonState |= PSP_CTRL_UP;
}
-inline int32 InputHandler::modifyNubAxisMotion(int32 input) {
+inline int32 Nub::modifyNubAxisMotion(int32 input) {
DEBUG_ENTER_FUNC();
const int MIN_NUB_MOTION = 30;
@@ -304,3 +352,160 @@ inline int32 InputHandler::modifyNubAxisMotion(int32 input) {
return input;
}
+
+inline bool Nub::isButtonDown() {
+ if (_dpadMode) // only relevant in dpad mode
+ return _buttonPad.isButtonDown();
+ return false;
+}
+
+const char *InputHandler::_padModeText[] = {
+ "Normal Button Mode",
+ "1st Person RPG Button Mode"
+};
+
+void InputHandler::init() {
+ sceCtrlSetSamplingCycle(0); // set sampling to vsync. n = n usecs
+ sceCtrlSetSamplingMode(1); // analog
+
+ _buttonPad.initButtons();
+}
+
+bool InputHandler::getAllInputs(Common::Event &event) {
+ DEBUG_ENTER_FUNC();
+
+ uint32 time = g_system->getMillis(); // may not be necessary with read
+ if (time - _lastPadCheckTime < PAD_CHECK_TIME) {
+ return false;
+ }
+
+ _lastPadCheckTime = time;
+ SceCtrlData pad;
+
+ sceCtrlPeekBufferPositive(&pad, 1); // Peek doesn't sleep. Read sleeps the thread
+
+ bool haveEvent;
+ //memset(&event, 0, sizeof(event));
+
+ haveEvent = getEvent(event, pad);
+
+ if (haveEvent) {
+ PSP_DEBUG_PRINT("Have event[%s]. Type[%d]\n", haveEvent ? "true" : "false", event.type);
+ }
+
+ return haveEvent;
+}
+
+bool InputHandler::getEvent(Common::Event &event, SceCtrlData &pad) {
+ DEBUG_ENTER_FUNC();
+
+ PspEvent pspEvent;
+ bool haveEvent = false;
+
+ if (_keyboard->isVisible()) {
+ haveEvent = _keyboard->processInput(event, pspEvent, pad);
+ } else { // only process buttonpad if keyboard invisible
+ haveEvent = _buttonPad.getEvent(event, pspEvent, pad);
+ }
+
+ if (!haveEvent && pspEvent.isEmpty())
+ haveEvent = _nub.getEvent(event, pspEvent, pad);
+
+ // handle any pending PSP events
+ if (!haveEvent && pspEvent.isEmpty()) {
+ if (!_pendingPspEvent.isEmpty()) {
+ pspEvent = _pendingPspEvent;
+ _pendingPspEvent.clear();
+ }
+ }
+
+ // handle any PSP events we might have
+ if (!pspEvent.isEmpty())
+ haveEvent |= handlePspEvent(event, pspEvent); // overrides any event we might have
+
+ return haveEvent;
+}
+
+bool InputHandler::handlePspEvent(Common::Event &event, PspEvent &pspEvent) {
+ bool haveEvent = false;
+
+ PSP_DEBUG_PRINT("have pspEvent[%d] data[%d]\n", pspEvent.type, pspEvent.data);
+
+ switch (pspEvent.type) {
+ case PSP_EVENT_SHIFT:
+ handleShiftEvent((ShiftMode)pspEvent.data);
+ break;
+ case PSP_EVENT_SHOW_VIRTUAL_KB:
+ _keyboard->setVisible((bool)pspEvent.data);
+ if ((pspEvent.data && _keyboard->isVisible()) || !pspEvent.data) // don't change mode if keyboard didn't load
+ _nub.setDpadMode((bool)pspEvent.data); // set nub to keypad/regular mode
+ break;
+ case PSP_EVENT_LBUTTON:
+ haveEvent = true;
+ if (pspEvent.data) // down
+ handleMouseEvent(event, Common::EVENT_LBUTTONDOWN, "LButtonDown");
+ else
+ handleMouseEvent(event, Common::EVENT_LBUTTONUP, "LButtonUp");
+ break;
+ case PSP_EVENT_RBUTTON:
+ haveEvent = true;
+ if (pspEvent.data) // down
+ handleMouseEvent(event, Common::EVENT_RBUTTONDOWN, "RButtonDown");
+ else
+ handleMouseEvent(event, Common::EVENT_RBUTTONUP, "RButtonUp");
+ break;
+ case PSP_EVENT_MODE_SWITCH:
+ handleModeSwitchEvent();
+ break;
+ /*case PSP_EVENT_CHANGE_SPEED:
+ handleSpeedChange(pspEvent.data);
+ break;*/
+ default:
+ PSP_ERROR("Unhandled PSP Event[%d]\n", pspEvent.type);
+ break;
+ }
+
+ return haveEvent;
+}
+
+void InputHandler::handleMouseEvent(Common::Event &event, Common::EventType type, const char *string) {
+ event.type = type;
+ event.mouse.x = _cursor->getX();
+ event.mouse.y = _cursor->getY();
+ PSP_DEBUG_PRINT("%s event, x[%d], y[%d]\n", string, event.mouse.x, event.mouse.y);
+}
+
+void InputHandler::handleShiftEvent(ShiftMode shifted) {
+ _buttonPad.setShifted(shifted);
+ _nub.setShifted(shifted);
+}
+
+void InputHandler::handleModeSwitchEvent() {
+ // check if we can't switch modes right now
+ if (_buttonPad.isButtonDown() || _nub.isButtonDown()) { // can't switch yet
+ PSP_DEBUG_PRINT("postponing mode switch event\n");
+ _pendingPspEvent.type = PSP_EVENT_MODE_SWITCH; // queue it to be done later
+ } else { // we can switch
+ PSP_DEBUG_PRINT("mode switch event\n");
+ _padMode = (PspPadMode)(_padMode + 1);
+ if (_padMode >= PAD_MODE_LAST)
+ _padMode = PAD_MODE_NORMAL;
+
+ GUI::TimedMessageDialog dialog(_padModeText[_padMode], 1500);
+ dialog.runModal();
+
+ _buttonPad.setPadMode(_padMode);
+ _buttonPad.initButtons();
+ }
+}
+
+/*
+void InputHandler::handleSpeedChange(bool up) {
+ char *dialogMsg;
+
+ if (up) {
+ dialogMsg = "
+
+ GUI::TimedMessageDialog dialog(_padModeText[_padMode], 1500);
+ dialog.runModal();
+}*/