aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordhewg2011-03-15 23:30:17 +0100
committerdhewg2011-03-16 20:54:49 +0100
commitadef4c3f4256a690b374b9801279952c39ccf7a4 (patch)
tree691f0ac0f5e42708ec1620629592703acff7f7ae
parente71c2cf850388b2a25200d544d2fb422525b4c88 (diff)
downloadscummvm-rg350-adef4c3f4256a690b374b9801279952c39ccf7a4.tar.gz
scummvm-rg350-adef4c3f4256a690b374b9801279952c39ccf7a4.tar.bz2
scummvm-rg350-adef4c3f4256a690b374b9801279952c39ccf7a4.zip
ANDROID: Input system overhaul
Rewritten input system with many new feature. Fixed related bugs and shortcomings on the way.
-rw-r--r--backends/platform/android/android.cpp179
-rw-r--r--backends/platform/android/android.h23
-rw-r--r--backends/platform/android/android.mk1
-rw-r--r--backends/platform/android/events.cpp661
-rw-r--r--backends/platform/android/gfx.cpp48
-rw-r--r--backends/platform/android/jni.cpp96
-rw-r--r--backends/platform/android/jni.h13
-rw-r--r--backends/platform/android/module.mk3
-rw-r--r--backends/platform/android/org/inodes/gus/scummvm/Event.java330
-rw-r--r--backends/platform/android/org/inodes/gus/scummvm/ScummVM.java5
-rw-r--r--backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java295
-rw-r--r--backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java201
12 files changed, 940 insertions, 915 deletions
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index ddef4275a4..4e1373a1b1 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -94,12 +94,6 @@ void checkGlError(const char *expr, const char *file, int line) {
}
#endif
-// floating point. use sparingly
-template <class T>
-static inline T scalef(T in, float numerator, float denominator) {
- return static_cast<float>(in) * numerator / denominator;
-}
-
OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
_audio_sample_rate(audio_sample_rate),
_audio_buffer_size(audio_buffer_size),
@@ -126,7 +120,16 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
_timer(0),
_fsFactory(new POSIXFilesystemFactory()),
_shake_offset(0),
- _event_queue_lock(createMutex()) {
+ _event_queue_lock(createMutex()),
+ _touch_pt_down(),
+ _touch_pt_dt(),
+ _eventScaleX(100),
+ _eventScaleY(100),
+ // TODO put these values in some option dlg?
+ _touchpad_mode(true),
+ _touchpad_scale(50),
+ _dpad_scale(4),
+ _trackball_scale(2) {
}
OSystem_Android::~OSystem_Android() {
@@ -310,6 +313,10 @@ void OSystem_Android::initBackend() {
ConfMan.setBool("FM_high_quality", false);
ConfMan.setBool("FM_medium_quality", true);
+ // TODO hackity hack
+ if (ConfMan.hasKey("multi_midi"))
+ _touchpad_mode = !ConfMan.getBool("multi_midi");
+
// must happen before creating TimerManager to avoid race in
// creating EventManager
setupKeymapper();
@@ -396,164 +403,6 @@ bool OSystem_Android::getFeatureState(Feature f) {
}
}
-void OSystem_Android::setupKeymapper() {
-#ifdef ENABLE_KEYMAPPER
- using namespace Common;
-
- Keymapper *mapper = getEventManager()->getKeymapper();
-
- HardwareKeySet *keySet = new HardwareKeySet();
-
- keySet->addHardwareKey(
- new HardwareKey("n", KeyState(KEYCODE_n), "n (vk)",
- kTriggerLeftKeyType,
- kVirtualKeyboardActionType));
-
- mapper->registerHardwareKeySet(keySet);
-
- Keymap *globalMap = new Keymap("global");
- Action *act;
-
- act = new Action(globalMap, "VIRT", "Display keyboard",
- kVirtualKeyboardActionType);
- act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
-
- mapper->addGlobalKeymap(globalMap);
-
- mapper->pushKeymap("global");
-#endif
-}
-
-bool OSystem_Android::pollEvent(Common::Event &event) {
- //ENTER();
-
- if (pthread_self() == _main_thread) {
- if (_screen_changeid != JNI::surface_changeid) {
- if (JNI::egl_surface_width > 0 && JNI::egl_surface_height > 0) {
- if (_egl_surface_width > 0 && _egl_surface_height > 0) {
- // surface still alive but changed
- _screen_changeid = JNI::surface_changeid;
- _egl_surface_width = JNI::egl_surface_width;
- _egl_surface_height = JNI::egl_surface_height;
-
- initViewport();
- updateScreenRect();
-
- // double buffered, flip twice
- clearScreen(kClearUpdate, 2);
-
- event.type = Common::EVENT_SCREEN_CHANGED;
-
- return true;
- } else {
- // new surface
- initSurface();
- updateScreenRect();
-
- // double buffered, flip twice
- clearScreen(kClearUpdate, 2);
-
- event.type = Common::EVENT_SCREEN_CHANGED;
-
- return true;
- }
- } else {
- // surface lost
- deinitSurface();
- }
- }
-
- if (JNI::pause) {
- deinitSurface();
-
- LOGD("main thread going to sleep");
- sem_wait(&JNI::pause_sem);
- LOGD("main thread woke up");
- }
- }
-
- lockMutex(_event_queue_lock);
-
- if (_event_queue.empty()) {
- unlockMutex(_event_queue_lock);
- return false;
- }
-
- event = _event_queue.pop();
- unlockMutex(_event_queue_lock);
-
- switch (event.type) {
- case Common::EVENT_MOUSEMOVE:
- _force_redraw = true;
- // fallthrough
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- case Common::EVENT_MBUTTONDOWN:
- case Common::EVENT_MBUTTONUP: {
- // relative mouse hack
- if (event.kbd.flags == 1) {
- // Relative (trackball) mouse hack.
- const Common::Point& mouse_pos =
- getEventManager()->getMousePos();
- event.mouse.x += mouse_pos.x;
- event.mouse.y += mouse_pos.y;
- event.mouse.x = CLIP(event.mouse.x, (int16)0, _show_overlay ?
- getOverlayWidth() : getWidth());
- event.mouse.y = CLIP(event.mouse.y, (int16)0, _show_overlay ?
- getOverlayHeight() : getHeight());
- } else {
- // Touchscreen events need to be converted
- // from device to game coords first.
- if (_show_overlay) {
- event.mouse.x = scalef(event.mouse.x,
- _overlay_texture->width(),
- _egl_surface_width);
- event.mouse.y = scalef(event.mouse.y,
- _overlay_texture->height(),
- _egl_surface_height);
- } else {
- const Common::Rect &r = _game_texture->getDrawRect();
-
- event.mouse.x -= r.left;
- event.mouse.y -= r.top;
-
- event.mouse.x = scalef(event.mouse.x,
- _game_texture->width(),
- r.width());
- event.mouse.y = scalef(event.mouse.y,
- _game_texture->height(),
- r.height());
-
- event.mouse.x -= _shake_offset;
-
- event.mouse.x = CLIP(event.mouse.x, int16(0),
- int16(_game_texture->width()));
- event.mouse.y = CLIP(event.mouse.y, int16(0),
- int16(_game_texture->height()));
- }
- }
- break;
- }
-
- default:
- break;
- }
-
- return true;
-}
-
-void OSystem_Android::pushEvent(const Common::Event& event) {
- lockMutex(_event_queue_lock);
-
- _event_queue.push(event);
-
- unlockMutex(_event_queue_lock);
-}
-
uint32 OSystem_Android::getMillis() {
timeval curTime;
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index dc45f06cb6..7ff96186f9 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -125,9 +125,6 @@ private:
bool _fullscreen;
bool _ar_correction;
- Common::Queue<Common::Event> _event_queue;
- MutexRef _event_queue_lock;
-
pthread_t _main_thread;
bool _timer_thread_exit;
@@ -205,6 +202,25 @@ public:
return this;
}
+public:
+ void pushEvent(int type, int arg1, int arg2, int arg3, int arg4, int arg5);
+
+private:
+ Common::Queue<Common::Event> _event_queue;
+ MutexRef _event_queue_lock;
+
+ Common::Point _touch_pt_down, _touch_pt_dt;
+ int _eventScaleX;
+ int _eventScaleY;
+ bool _touchpad_mode;
+ int _touchpad_scale;
+ int _trackball_scale;
+ int _dpad_scale;
+
+ void clipMouse(Common::Point &p);
+ void scaleMouse(Common::Point &p, int x, int y, bool deductDrawRect = true);
+ void updateEventScale();
+
protected:
// PaletteManager API
virtual void setPalette(const byte *colors, uint start, uint num);
@@ -242,7 +258,6 @@ public:
virtual void disableCursorPalette(bool disable);
virtual bool pollEvent(Common::Event &event);
- void pushEvent(const Common::Event& event);
virtual uint32 getMillis();
virtual void delayMillis(uint msecs);
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index eb58089376..cb39f8acfe 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -6,6 +6,7 @@ ANDROID_PLUGIN_VERSIONCODE = 6
JAVA_FILES = \
ScummVM.java \
+ ScummVMEvents.java \
ScummVMApplication.java \
ScummVMActivity.java \
EditableSurfaceView.java \
diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
new file mode 100644
index 0000000000..1715e6a8a7
--- /dev/null
+++ b/backends/platform/android/events.cpp
@@ -0,0 +1,661 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#if defined(__ANDROID__)
+
+#include "common/events.h"
+
+#include "backends/platform/android/android.h"
+#include "backends/platform/android/jni.h"
+
+// $ANDROID_NDK/platforms/android-9/arch-arm/usr/include/android/keycodes.h
+// http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=libs/ui/Input.cpp
+// http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/view/KeyEvent.java
+
+// event type
+enum {
+ JE_SYS_KEY = 0,
+ JE_KEY = 1,
+ JE_DOWN = 2,
+ JE_SCROLL = 3,
+ JE_TAP = 4,
+ JE_DOUBLE_TAP = 5,
+ JE_BALL = 6,
+ JE_QUIT = 0x1000
+};
+
+// action type
+enum {
+ JACTION_DOWN = 0,
+ JACTION_UP = 1,
+ JACTION_MULTIPLE = 2
+};
+
+// system keys
+enum {
+ JKEYCODE_SOFT_RIGHT = 2,
+ JKEYCODE_HOME = 3,
+ JKEYCODE_BACK = 4,
+ JKEYCODE_CALL = 5,
+ JKEYCODE_ENDCALL = 6,
+ JKEYCODE_VOLUME_UP = 24,
+ JKEYCODE_VOLUME_DOWN = 25,
+ JKEYCODE_POWER = 26,
+ JKEYCODE_CAMERA = 27,
+ JKEYCODE_HEADSETHOOK = 79,
+ JKEYCODE_FOCUS = 80,
+ JKEYCODE_MENU = 82,
+ JKEYCODE_SEARCH = 84,
+ JKEYCODE_MUTE = 91,
+ JKEYCODE_MEDIA_PLAY_PAUSE = 85,
+ JKEYCODE_MEDIA_STOP = 86,
+ JKEYCODE_MEDIA_NEXT = 87,
+ JKEYCODE_MEDIA_PREVIOUS = 88,
+ JKEYCODE_MEDIA_REWIND = 89,
+ JKEYCODE_MEDIA_FAST_FORWARD = 90
+};
+
+// five-way navigation control
+enum {
+ JKEYCODE_DPAD_UP = 19,
+ JKEYCODE_DPAD_DOWN = 20,
+ JKEYCODE_DPAD_LEFT = 21,
+ JKEYCODE_DPAD_RIGHT = 22,
+ JKEYCODE_DPAD_CENTER = 23
+};
+
+// meta modifier
+enum {
+ JMETA_SHIFT = 0x01,
+ JMETA_ALT = 0x02,
+ JMETA_SYM = 0x04,
+ JMETA_CTRL = 0x1000
+};
+
+// map android key codes to our kbd codes
+static const Common::KeyCode jkeymap[] = {
+ Common::KEYCODE_INVALID, // KEYCODE_UNKNOWN
+ Common::KEYCODE_INVALID, // KEYCODE_SOFT_LEFT
+ Common::KEYCODE_INVALID, // KEYCODE_SOFT_RIGHT
+ Common::KEYCODE_INVALID, // KEYCODE_HOME
+ Common::KEYCODE_INVALID, // KEYCODE_BACK
+ Common::KEYCODE_INVALID, // KEYCODE_CALL
+ Common::KEYCODE_INVALID, // KEYCODE_ENDCALL
+ Common::KEYCODE_0, // KEYCODE_0
+ Common::KEYCODE_1, // KEYCODE_1
+ Common::KEYCODE_2, // KEYCODE_2
+ Common::KEYCODE_3, // KEYCODE_3
+ Common::KEYCODE_4, // KEYCODE_4
+ Common::KEYCODE_5, // KEYCODE_5
+ Common::KEYCODE_6, // KEYCODE_6
+ Common::KEYCODE_7, // KEYCODE_7
+ Common::KEYCODE_8, // KEYCODE_8
+ Common::KEYCODE_9, // KEYCODE_9
+ Common::KEYCODE_ASTERISK, // KEYCODE_STAR
+ Common::KEYCODE_HASH, // KEYCODE_POUND
+ Common::KEYCODE_INVALID, // KEYCODE_DPAD_UP
+ Common::KEYCODE_INVALID, // KEYCODE_DPAD_DOWN
+ Common::KEYCODE_INVALID, // KEYCODE_DPAD_LEFT
+ Common::KEYCODE_INVALID, // KEYCODE_DPAD_RIGHT
+ Common::KEYCODE_INVALID, // KEYCODE_DPAD_CENTER
+ Common::KEYCODE_INVALID, // KEYCODE_VOLUME_UP
+ Common::KEYCODE_INVALID, // KEYCODE_VOLUME_DOWN
+ Common::KEYCODE_INVALID, // KEYCODE_POWER
+ Common::KEYCODE_INVALID, // KEYCODE_CAMERA
+ Common::KEYCODE_INVALID, // KEYCODE_CLEAR
+ Common::KEYCODE_a, // KEYCODE_A
+ Common::KEYCODE_b, // KEYCODE_B
+ Common::KEYCODE_c, // KEYCODE_C
+ Common::KEYCODE_d, // KEYCODE_D
+ Common::KEYCODE_e, // KEYCODE_E
+ Common::KEYCODE_f, // KEYCODE_F
+ Common::KEYCODE_g, // KEYCODE_G
+ Common::KEYCODE_h, // KEYCODE_H
+ Common::KEYCODE_i, // KEYCODE_I
+ Common::KEYCODE_j, // KEYCODE_J
+ Common::KEYCODE_k, // KEYCODE_K
+ Common::KEYCODE_l, // KEYCODE_L
+ Common::KEYCODE_m, // KEYCODE_M
+ Common::KEYCODE_n, // KEYCODE_N
+ Common::KEYCODE_o, // KEYCODE_O
+ Common::KEYCODE_p, // KEYCODE_P
+ Common::KEYCODE_q, // KEYCODE_Q
+ Common::KEYCODE_r, // KEYCODE_R
+ Common::KEYCODE_s, // KEYCODE_S
+ Common::KEYCODE_t, // KEYCODE_T
+ Common::KEYCODE_u, // KEYCODE_U
+ Common::KEYCODE_v, // KEYCODE_V
+ Common::KEYCODE_w, // KEYCODE_W
+ Common::KEYCODE_x, // KEYCODE_X
+ Common::KEYCODE_y, // KEYCODE_Y
+ Common::KEYCODE_z, // KEYCODE_Z
+ Common::KEYCODE_COMMA, // KEYCODE_COMMA
+ Common::KEYCODE_PERIOD, // KEYCODE_PERIOD
+ Common::KEYCODE_LALT, // KEYCODE_ALT_LEFT
+ Common::KEYCODE_RALT, // KEYCODE_ALT_RIGHT
+ Common::KEYCODE_LSHIFT, // KEYCODE_SHIFT_LEFT
+ Common::KEYCODE_RSHIFT, // KEYCODE_SHIFT_RIGHT
+ Common::KEYCODE_TAB, // KEYCODE_TAB
+ Common::KEYCODE_SPACE, // KEYCODE_SPACE
+ Common::KEYCODE_LCTRL, // KEYCODE_SYM
+ Common::KEYCODE_INVALID, // KEYCODE_EXPLORER
+ Common::KEYCODE_INVALID, // KEYCODE_ENVELOPE
+ Common::KEYCODE_RETURN, // KEYCODE_ENTER
+ Common::KEYCODE_BACKSPACE, // KEYCODE_DEL
+ Common::KEYCODE_BACKQUOTE, // KEYCODE_GRAVE
+ Common::KEYCODE_MINUS, // KEYCODE_MINUS
+ Common::KEYCODE_EQUALS, // KEYCODE_EQUALS
+ Common::KEYCODE_LEFTPAREN, // KEYCODE_LEFT_BRACKET
+ Common::KEYCODE_RIGHTPAREN, // KEYCODE_RIGHT_BRACKET
+ Common::KEYCODE_BACKSLASH, // KEYCODE_BACKSLASH
+ Common::KEYCODE_SEMICOLON, // KEYCODE_SEMICOLON
+ Common::KEYCODE_QUOTE, // KEYCODE_APOSTROPHE
+ Common::KEYCODE_SLASH, // KEYCODE_SLASH
+ Common::KEYCODE_AT, // KEYCODE_AT
+ Common::KEYCODE_INVALID, // KEYCODE_NUM
+ Common::KEYCODE_INVALID, // KEYCODE_HEADSETHOOK
+ Common::KEYCODE_INVALID, // KEYCODE_FOCUS
+ Common::KEYCODE_PLUS, // KEYCODE_PLUS
+ Common::KEYCODE_INVALID, // KEYCODE_MENU
+ Common::KEYCODE_INVALID, // KEYCODE_NOTIFICATION
+ Common::KEYCODE_INVALID, // KEYCODE_SEARCH
+ Common::KEYCODE_INVALID, // KEYCODE_MEDIA_PLAY_PAUSE
+ Common::KEYCODE_INVALID, // KEYCODE_MEDIA_STOP
+ Common::KEYCODE_INVALID, // KEYCODE_MEDIA_NEXT
+ Common::KEYCODE_INVALID, // KEYCODE_MEDIA_PREVIOUS
+ Common::KEYCODE_INVALID, // KEYCODE_MEDIA_REWIND
+ Common::KEYCODE_INVALID, // KEYCODE_MEDIA_FAST_FORWARD
+ Common::KEYCODE_INVALID, // KEYCODE_MUTE
+ Common::KEYCODE_PAGEUP, // KEYCODE_PAGE_UP
+ Common::KEYCODE_PAGEDOWN // KEYCODE_PAGE_DOWN
+};
+
+// floating point. use sparingly
+template <class T>
+static inline T scalef(T in, float numerator, float denominator) {
+ return static_cast<float>(in) * numerator / denominator;
+}
+
+void OSystem_Android::setupKeymapper() {
+#ifdef ENABLE_KEYMAPPER
+ using namespace Common;
+
+ Keymapper *mapper = getEventManager()->getKeymapper();
+
+ HardwareKeySet *keySet = new HardwareKeySet();
+
+ keySet->addHardwareKey(
+ new HardwareKey("n", KeyState(KEYCODE_n), "n (vk)",
+ kTriggerLeftKeyType,
+ kVirtualKeyboardActionType));
+
+ mapper->registerHardwareKeySet(keySet);
+
+ Keymap *globalMap = new Keymap("global");
+ Action *act;
+
+ act = new Action(globalMap, "VIRT", "Display keyboard",
+ kVirtualKeyboardActionType);
+ act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+
+ mapper->addGlobalKeymap(globalMap);
+
+ mapper->pushKeymap("global");
+#endif
+}
+
+void OSystem_Android::warpMouse(int x, int y) {
+ ENTER("%d, %d", x, y);
+
+ Common::Event e;
+
+ e.type = Common::EVENT_MOUSEMOVE;
+ e.mouse.x = x;
+ e.mouse.y = y;
+
+ clipMouse(e.mouse);
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+}
+
+void OSystem_Android::clipMouse(Common::Point &p) {
+ const GLESBaseTexture *tex;
+
+ if (_show_overlay)
+ tex = _overlay_texture;
+ else
+ tex = _game_texture;
+
+ p.x = CLIP(p.x, int16(0), int16(tex->width()));
+ p.y = CLIP(p.y, int16(0), int16(tex->height()));
+}
+
+void OSystem_Android::scaleMouse(Common::Point &p, int x, int y,
+ bool deductDrawRect) {
+ const GLESBaseTexture *tex;
+
+ if (_show_overlay)
+ tex = _overlay_texture;
+ else
+ tex = _game_texture;
+
+ const Common::Rect &r = tex->getDrawRect();
+
+ if (_touchpad_mode) {
+ x = x * 100 / _touchpad_scale;
+ y = y * 100 / _touchpad_scale;
+ }
+
+ if (deductDrawRect) {
+ x -= r.left;
+ y -= r.top;
+ }
+
+ p.x = scalef(x, tex->width(), r.width());
+ p.y = scalef(y, tex->height(), r.height());
+}
+
+void OSystem_Android::updateEventScale() {
+ const GLESBaseTexture *tex;
+
+ if (_show_overlay)
+ tex = _overlay_texture;
+ else
+ tex = _game_texture;
+
+ _eventScaleY = 100 * 480 / tex->height();
+ _eventScaleX = 100 * 640 / tex->width();
+}
+
+void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
+ int arg4, int arg5) {
+ Common::Event e;
+
+ switch (type) {
+ case JE_SYS_KEY:
+ switch (arg1) {
+ case JACTION_DOWN:
+ e.type = Common::EVENT_KEYDOWN;
+ break;
+ case JACTION_UP:
+ e.type = Common::EVENT_KEYUP;
+ break;
+ default:
+ LOGE("unhandled jaction on system key: %d", arg1);
+ return;
+ }
+
+ switch (arg2) {
+ case JKEYCODE_BACK:
+ e.kbd.keycode = Common::KEYCODE_ESCAPE;
+ e.kbd.ascii = Common::ASCII_ESCAPE;
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ // special case. we'll only get it's up event
+ case JKEYCODE_MENU:
+ e.type = Common::EVENT_MAINMENU;
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ default:
+ LOGW("unmapped system key: %d", arg2);
+ return;
+ }
+
+ break;
+
+ case JE_KEY:
+ // five-way first
+ switch (arg2) {
+ case JKEYCODE_DPAD_UP:
+ case JKEYCODE_DPAD_DOWN:
+ case JKEYCODE_DPAD_LEFT:
+ case JKEYCODE_DPAD_RIGHT:
+ {
+ if (arg1 != JACTION_DOWN)
+ return;
+
+ e.type = Common::EVENT_MOUSEMOVE;
+ e.synthetic = true;
+
+ e.mouse = getEventManager()->getMousePos();
+
+ int16 *c;
+ int s;
+
+ if (arg2 == JKEYCODE_DPAD_UP || arg2 == JKEYCODE_DPAD_DOWN) {
+ c = &e.mouse.y;
+ s = _eventScaleY;
+ } else {
+ c = &e.mouse.x;
+ s = _eventScaleX;
+ }
+
+ // the longer the button held, the faster the pointer is
+ // TODO put these values in some option dlg?
+ int f = CLIP(arg5, 1, 8) * _dpad_scale * 100 / s;
+
+ *c += ((arg2 == JKEYCODE_DPAD_UP ||
+ arg2 == JKEYCODE_DPAD_LEFT) ? -1 : 1) * f;
+
+ clipMouse(e.mouse);
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+ }
+
+ return;
+
+ case JKEYCODE_DPAD_CENTER:
+ switch (arg1) {
+ case JACTION_DOWN:
+ e.type = Common::EVENT_LBUTTONDOWN;
+ break;
+ case JACTION_UP:
+ e.type = Common::EVENT_LBUTTONUP;
+ break;
+ default:
+ LOGE("unhandled jaction on dpad key: %d", arg1);
+ return;
+ }
+
+ {
+ const Common::Point &m = getEventManager()->getMousePos();
+
+ e.mouse = m;
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+ }
+
+ return;
+ }
+
+ switch (arg1) {
+ case JACTION_DOWN:
+ e.type = Common::EVENT_KEYDOWN;
+ break;
+ case JACTION_UP:
+ e.type = Common::EVENT_KEYUP;
+ break;
+ default:
+ LOGE("unhandled jaction on key: %d", arg1);
+ return;
+ }
+
+ if (arg2 < 1 || arg2 > ARRAYSIZE(jkeymap)) {
+ LOGE("received invalid keycode: %d", arg2);
+ return;
+ }
+
+ if (arg5 > 0)
+ e.synthetic = true;
+
+ e.kbd.keycode = jkeymap[arg2];
+ e.kbd.ascii = arg3;
+
+ if (arg4 & JMETA_SHIFT)
+ e.kbd.flags |= Common::KBD_SHIFT;
+ if (arg4 & JMETA_ALT)
+ e.kbd.flags |= Common::KBD_ALT;
+ if (arg4 & (JMETA_SYM | JMETA_CTRL))
+ e.kbd.flags |= Common::KBD_CTRL;
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ case JE_DOWN:
+ _touch_pt_down = getEventManager()->getMousePos();
+ break;
+
+ case JE_SCROLL:
+ e.type = Common::EVENT_MOUSEMOVE;
+
+ if (_touchpad_mode) {
+ scaleMouse(e.mouse, arg3 - arg1, arg4 - arg2, false);
+ e.mouse += _touch_pt_down;
+ clipMouse(e.mouse);
+ } else {
+ scaleMouse(e.mouse, arg3, arg4);
+ clipMouse(e.mouse);
+ }
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ case JE_TAP:
+ e.type = Common::EVENT_MOUSEMOVE;
+
+ if (_touchpad_mode) {
+ e.mouse = getEventManager()->getMousePos();
+ } else {
+ scaleMouse(e.mouse, arg1, arg2);
+ clipMouse(e.mouse);
+ }
+
+ {
+ Common::EventType down, up;
+
+ // TODO put these values in some option dlg?
+ if (arg3 > 1000) {
+ down = Common::EVENT_MBUTTONDOWN;
+ up = Common::EVENT_MBUTTONUP;
+ } else if (arg3 > 500) {
+ down = Common::EVENT_RBUTTONDOWN;
+ up = Common::EVENT_RBUTTONUP;
+ } else {
+ down = Common::EVENT_LBUTTONDOWN;
+ up = Common::EVENT_LBUTTONUP;
+ }
+
+ lockMutex(_event_queue_lock);
+
+ if (!_touchpad_mode)
+ _event_queue.push(e);
+
+ e.type = down;
+ _event_queue.push(e);
+ e.type = up;
+ _event_queue.push(e);
+
+ unlockMutex(_event_queue_lock);
+ }
+
+ return;
+
+ case JE_DOUBLE_TAP:
+ e.type = Common::EVENT_MOUSEMOVE;
+
+ if (_touchpad_mode) {
+ e.mouse = getEventManager()->getMousePos();
+ } else {
+ scaleMouse(e.mouse, arg1, arg2);
+ clipMouse(e.mouse);
+ }
+
+ {
+ Common::EventType dptype = Common::EVENT_INVALID;
+
+ switch (arg3) {
+ case JACTION_DOWN:
+ dptype = Common::EVENT_LBUTTONDOWN;
+ _touch_pt_dt.x = arg1;
+ _touch_pt_dt.y = arg2;
+ break;
+ case JACTION_UP:
+ dptype = Common::EVENT_LBUTTONUP;
+ break;
+ case JACTION_MULTIPLE:
+ // held and moved
+ dptype = Common::EVENT_MOUSEMOVE;
+
+ if (_touchpad_mode) {
+ scaleMouse(e.mouse, arg1 - _touch_pt_dt.x,
+ arg2 - _touch_pt_dt.y, false);
+ e.mouse += _touch_pt_down;
+
+ clipMouse(e.mouse);
+ }
+
+ break;
+ default:
+ LOGE("unhandled jaction on double tap: %d", arg3);
+ return;
+ }
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ e.type = dptype;
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+ }
+
+ return;
+
+ case JE_BALL:
+ e.type = Common::EVENT_MOUSEMOVE;
+
+ e.mouse = getEventManager()->getMousePos();
+
+ // already multiplied by 100
+ e.mouse.x += arg1 * _trackball_scale / _eventScaleX;
+ e.mouse.y += arg2 * _trackball_scale / _eventScaleY;
+
+ clipMouse(e.mouse);
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ case JE_QUIT:
+ e.type = Common::EVENT_QUIT;
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ default:
+ LOGE("unknown jevent type: %d", type);
+
+ break;
+ }
+}
+
+bool OSystem_Android::pollEvent(Common::Event &event) {
+ //ENTER();
+
+ if (pthread_self() == _main_thread) {
+ if (_screen_changeid != JNI::surface_changeid) {
+ if (JNI::egl_surface_width > 0 && JNI::egl_surface_height > 0) {
+ if (_egl_surface_width > 0 && _egl_surface_height > 0) {
+ // surface still alive but changed
+ _screen_changeid = JNI::surface_changeid;
+ _egl_surface_width = JNI::egl_surface_width;
+ _egl_surface_height = JNI::egl_surface_height;
+
+ initViewport();
+ updateScreenRect();
+ updateEventScale();
+
+ // double buffered, flip twice
+ clearScreen(kClearUpdate, 2);
+
+ event.type = Common::EVENT_SCREEN_CHANGED;
+
+ return true;
+ } else {
+ // new surface
+ initSurface();
+ updateScreenRect();
+ updateEventScale();
+
+ // double buffered, flip twice
+ clearScreen(kClearUpdate, 2);
+
+ event.type = Common::EVENT_SCREEN_CHANGED;
+
+ return true;
+ }
+ } else {
+ // surface lost
+ deinitSurface();
+ }
+ }
+
+ if (JNI::pause) {
+ deinitSurface();
+
+ LOGD("main thread going to sleep");
+ sem_wait(&JNI::pause_sem);
+ LOGD("main thread woke up");
+ }
+ }
+
+ lockMutex(_event_queue_lock);
+
+ if (_event_queue.empty()) {
+ unlockMutex(_event_queue_lock);
+ return false;
+ }
+
+ event = _event_queue.pop();
+
+ unlockMutex(_event_queue_lock);
+
+ if (event.type == Common::EVENT_MOUSEMOVE) {
+ const Common::Point &m = getEventManager()->getMousePos();
+
+ if (m != event.mouse)
+ _force_redraw = true;
+ }
+
+ return true;
+}
+
+#endif
+
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index 65f98d5094..fc45f4c9e1 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -272,6 +272,7 @@ void OSystem_Android::initSize(uint width, uint height,
#endif
updateScreenRect();
+ updateEventScale();
// Don't know mouse size yet - it gets reallocated in
// setMouseCursor. We need the palette allocated before
@@ -285,17 +286,13 @@ void OSystem_Android::initSize(uint width, uint height,
void OSystem_Android::clearScreen(FixupType type, byte count) {
assert(count > 0);
- for (byte i = 0; i < count; ++i) {
- if (!_show_overlay)
- GLCALL(glDisable(GL_SCISSOR_TEST));
+ GLCALL(glDisable(GL_SCISSOR_TEST));
+ for (byte i = 0; i < count; ++i) {
// clear screen
GLCALL(glClearColorx(0, 0, 0, 1 << 16));
GLCALL(glClear(GL_COLOR_BUFFER_BIT));
- if (!_show_overlay)
- GLCALL(glEnable(GL_SCISSOR_TEST));
-
switch (type) {
case kClear:
break;
@@ -310,6 +307,9 @@ void OSystem_Android::clearScreen(FixupType type, byte count) {
break;
}
}
+
+ if (!_show_overlay)
+ GLCALL(glEnable(GL_SCISSOR_TEST));
}
void OSystem_Android::updateScreenRect() {
@@ -577,34 +577,27 @@ void OSystem_Android::clearFocusRectangle() {
void OSystem_Android::showOverlay() {
ENTER();
- Common::Event e;
- e.type = Common::EVENT_MOUSEMOVE;
- e.mouse.x = _egl_surface_width / 2;
- e.mouse.y = _egl_surface_height / 2;
-
- pushEvent(e);
-
_show_overlay = true;
_force_redraw = true;
+ updateEventScale();
+
+ warpMouse(_overlay_texture->width() / 2, _overlay_texture->height() / 2);
+
GLCALL(glDisable(GL_SCISSOR_TEST));
}
void OSystem_Android::hideOverlay() {
ENTER();
- Common::Event e;
- e.type = Common::EVENT_MOUSEMOVE;
- e.mouse.x = _egl_surface_width / 2;
- e.mouse.y = _egl_surface_height / 2;
-
- pushEvent(e);
+ clearScreen(kClear);
_show_overlay = false;
_force_redraw = true;
- // double buffered, flip twice
- clearScreen(kClearUpdate, 2);
+ updateEventScale();
+
+ warpMouse(_game_texture->width() / 2, _game_texture->height() / 2);
GLCALL(glEnable(GL_SCISSOR_TEST));
}
@@ -673,13 +666,6 @@ bool OSystem_Android::showMouse(bool visible) {
return true;
}
-void OSystem_Android::warpMouse(int x, int y) {
- ENTER("%d, %d", x, y);
-
- // We use only the eventmanager's idea of the current mouse
- // position, so there is nothing extra to do here.
-}
-
void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
int hotspotX, int hotspotY,
uint32 keycolor, int cursorTargetScale,
@@ -719,8 +705,10 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
WRITE_UINT16(_mouse_texture_palette->palette() + keycolor * 2, 0);
}
- if (w == 0 || h == 0)
+ if (w == 0 || h == 0) {
+ _show_mouse = false;
return;
+ }
if (_mouse_texture == _mouse_texture_palette) {
_mouse_texture->updateBuffer(0, 0, w, h, buf, w);
@@ -737,7 +725,7 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
delete[] tmp;
- _mouse_texture->fillBuffer(0);
+ _show_mouse = false;
return;
}
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index 0628d92a2f..92cb04904c 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -56,15 +56,6 @@ int JNI::egl_surface_width = 0;
int JNI::egl_surface_height = 0;
bool JNI::_ready_for_events = 0;
-jfieldID JNI::_FID_Event_type = 0;
-jfieldID JNI::_FID_Event_synthetic = 0;
-jfieldID JNI::_FID_Event_kbd_keycode = 0;
-jfieldID JNI::_FID_Event_kbd_ascii = 0;
-jfieldID JNI::_FID_Event_kbd_flags = 0;
-jfieldID JNI::_FID_Event_mouse_x = 0;
-jfieldID JNI::_FID_Event_mouse_y = 0;
-jfieldID JNI::_FID_Event_mouse_relative = 0;
-
jmethodID JNI::_MID_getDPI = 0;
jmethodID JNI::_MID_displayMessageOnOSD = 0;
jmethodID JNI::_MID_setWindowCaption = 0;
@@ -94,7 +85,7 @@ const JNINativeMethod JNI::_natives[] = {
(void *)JNI::setSurface },
{ "main", "([Ljava/lang/String;)I",
(void *)JNI::main },
- { "pushEvent", "(Lorg/inodes/gus/scummvm/Event;)V",
+ { "pushEvent", "(IIIIII)V",
(void *)JNI::pushEvent },
{ "enableZoning", "(Z)V",
(void *)JNI::enableZoning },
@@ -123,42 +114,6 @@ jint JNI::onLoad(JavaVM *vm) {
if (env->RegisterNatives(cls, _natives, ARRAYSIZE(_natives)) < 0)
return JNI_ERR;
- jclass event = env->FindClass("org/inodes/gus/scummvm/Event");
- if (event == 0)
- return JNI_ERR;
-
- _FID_Event_type = env->GetFieldID(event, "type", "I");
- if (_FID_Event_type == 0)
- return JNI_ERR;
-
- _FID_Event_synthetic = env->GetFieldID(event, "synthetic", "Z");
- if (_FID_Event_synthetic == 0)
- return JNI_ERR;
-
- _FID_Event_kbd_keycode = env->GetFieldID(event, "kbd_keycode", "I");
- if (_FID_Event_kbd_keycode == 0)
- return JNI_ERR;
-
- _FID_Event_kbd_ascii = env->GetFieldID(event, "kbd_ascii", "I");
- if (_FID_Event_kbd_ascii == 0)
- return JNI_ERR;
-
- _FID_Event_kbd_flags = env->GetFieldID(event, "kbd_flags", "I");
- if (_FID_Event_kbd_flags == 0)
- return JNI_ERR;
-
- _FID_Event_mouse_x = env->GetFieldID(event, "mouse_x", "I");
- if (_FID_Event_mouse_x == 0)
- return JNI_ERR;
-
- _FID_Event_mouse_y = env->GetFieldID(event, "mouse_y", "I");
- if (_FID_Event_mouse_y == 0)
- return JNI_ERR;
-
- _FID_Event_mouse_relative = env->GetFieldID(event, "mouse_relative", "Z");
- if (_FID_Event_mouse_relative == 0)
- return JNI_ERR;
-
return JNI_VERSION_1_2;
}
@@ -600,54 +555,17 @@ cleanup:
return res;
}
-void JNI::pushEvent(JNIEnv *env, jobject self, jobject java_event) {
+void JNI::pushEvent(JNIEnv *env, jobject self, int type, int arg1, int arg2,
+ int arg3, int arg4, int arg5) {
// drop events until we're ready and after we quit
- if (!_ready_for_events)
+ if (!_ready_for_events) {
+ LOGW("dropping event");
return;
+ }
assert(_system);
- Common::Event event;
- event.type = (Common::EventType)env->GetIntField(java_event,
- _FID_Event_type);
-
- event.synthetic =
- env->GetBooleanField(java_event, _FID_Event_synthetic);
-
- switch (event.type) {
- case Common::EVENT_KEYDOWN:
- case Common::EVENT_KEYUP:
- event.kbd.keycode = (Common::KeyCode)env->GetIntField(
- java_event, _FID_Event_kbd_keycode);
- event.kbd.ascii = static_cast<int>(env->GetIntField(
- java_event, _FID_Event_kbd_ascii));
- event.kbd.flags = static_cast<int>(env->GetIntField(
- java_event, _FID_Event_kbd_flags));
- break;
- case Common::EVENT_MOUSEMOVE:
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- case Common::EVENT_MBUTTONDOWN:
- case Common::EVENT_MBUTTONUP:
- event.mouse.x =
- env->GetIntField(java_event, _FID_Event_mouse_x);
- event.mouse.y =
- env->GetIntField(java_event, _FID_Event_mouse_y);
- // This is a terrible hack. We stash "relativeness"
- // in the kbd.flags field until pollEvent() can work
- // it out.
- event.kbd.flags = env->GetBooleanField(
- java_event, _FID_Event_mouse_relative) ? 1 : 0;
- break;
- default:
- break;
- }
-
- _system->pushEvent(event);
+ _system->pushEvent(type, arg1, arg2, arg3, arg4, arg5);
}
void JNI::enableZoning(JNIEnv *env, jobject self, jboolean enable) {
diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h
index 5746c01afd..d029f1a2a8 100644
--- a/backends/platform/android/jni.h
+++ b/backends/platform/android/jni.h
@@ -91,16 +91,6 @@ private:
static bool _ready_for_events;
- static jfieldID _FID_Event_type;
- static jfieldID _FID_Event_synthetic;
- static jfieldID _FID_Event_kbd_keycode;
- static jfieldID _FID_Event_kbd_ascii;
- static jfieldID _FID_Event_kbd_flags;
- static jfieldID _FID_Event_mouse_x;
- static jfieldID _FID_Event_mouse_y;
- static jfieldID _FID_Event_mouse_relative;
- static jfieldID _FID_ScummVM_nativeScummVM;
-
static jmethodID _MID_getDPI;
static jmethodID _MID_displayMessageOnOSD;
static jmethodID _MID_setWindowCaption;
@@ -133,7 +123,8 @@ private:
static void setSurface(JNIEnv *env, jobject self, jint width, jint height);
static jint main(JNIEnv *env, jobject self, jobjectArray args);
- static void pushEvent(JNIEnv *env, jobject self, jobject java_event);
+ static void pushEvent(JNIEnv *env, jobject self, int type, int arg1,
+ int arg2, int arg3, int arg4, int arg5);
static void enableZoning(JNIEnv *env, jobject self, jboolean enable);
static void setPause(JNIEnv *env, jobject self, jboolean value);
diff --git a/backends/platform/android/module.mk b/backends/platform/android/module.mk
index 3bcfa7ad87..2fe4b40585 100644
--- a/backends/platform/android/module.mk
+++ b/backends/platform/android/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS := \
texture.o \
asset-archive.o \
android.o \
- gfx.o
+ gfx.o \
+ events.o
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/backends/platform/android/org/inodes/gus/scummvm/Event.java b/backends/platform/android/org/inodes/gus/scummvm/Event.java
deleted file mode 100644
index f9c7aba93b..0000000000
--- a/backends/platform/android/org/inodes/gus/scummvm/Event.java
+++ /dev/null
@@ -1,330 +0,0 @@
-package org.inodes.gus.scummvm;
-
-import android.view.KeyEvent;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Event {
- // Common::EventType enum.
- // Must be kept in sync with common/events.h
- public final static int EVENT_INVALID = 0;
- public final static int EVENT_KEYDOWN = 1;
- public final static int EVENT_KEYUP = 2;
- public final static int EVENT_MOUSEMOVE = 3;
- public final static int EVENT_LBUTTONDOWN = 4;
- public final static int EVENT_LBUTTONUP = 5;
- public final static int EVENT_RBUTTONDOWN = 6;
- public final static int EVENT_RBUTTONUP = 7;
- public final static int EVENT_WHEELUP = 8;
- public final static int EVENT_WHEELDOWN = 9;
- public final static int EVENT_QUIT = 10;
- public final static int EVENT_SCREEN_CHANGED = 11;
- public final static int EVENT_PREDICTIVE_DIALOG = 12;
- public final static int EVENT_MBUTTONDOWN = 13;
- public final static int EVENT_MBUTTONUP = 14;
- public final static int EVENT_MAINMENU = 15;
- public final static int EVENT_RTL = 16;
-
- // common/keyboard.h
- public final static int ASCII_F1 = 315;
- public final static int ASCII_F2 = 316;
- public final static int ASCII_F3 = 317;
- public final static int ASCII_F4 = 318;
- public final static int ASCII_F5 = 319;
- public final static int ASCII_F6 = 320;
- public final static int ASCII_F7 = 321;
- public final static int ASCII_F8 = 322;
- public final static int ASCII_F9 = 323;
- public final static int ASCII_F10 = 324;
- public final static int ASCII_F11 = 325;
- public final static int ASCII_F12 = 326;
- public final static int KBD_CTRL = 1 << 0;
- public final static int KBD_ALT = 1 << 1;
- public final static int KBD_SHIFT = 1 << 2;
-
- public final static int KEYCODE_INVALID = 0;
- public final static int KEYCODE_BACKSPACE = 8;
- public final static int KEYCODE_TAB = 9;
- public final static int KEYCODE_CLEAR = 12;
- public final static int KEYCODE_RETURN = 13;
- public final static int KEYCODE_PAUSE = 19;
- public final static int KEYCODE_ESCAPE = 27;
- public final static int KEYCODE_SPACE = 32;
- public final static int KEYCODE_EXCLAIM = 33;
- public final static int KEYCODE_QUOTEDBL = 34;
- public final static int KEYCODE_HASH = 35;
- public final static int KEYCODE_DOLLAR = 36;
- public final static int KEYCODE_AMPERSAND = 38;
- public final static int KEYCODE_QUOTE = 39;
- public final static int KEYCODE_LEFTPAREN = 40;
- public final static int KEYCODE_RIGHTPAREN = 41;
- public final static int KEYCODE_ASTERISK = 42;
- public final static int KEYCODE_PLUS = 43;
- public final static int KEYCODE_COMMA = 44;
- public final static int KEYCODE_MINUS = 45;
- public final static int KEYCODE_PERIOD = 46;
- public final static int KEYCODE_SLASH = 47;
- public final static int KEYCODE_0 = 48;
- public final static int KEYCODE_1 = 49;
- public final static int KEYCODE_2 = 50;
- public final static int KEYCODE_3 = 51;
- public final static int KEYCODE_4 = 52;
- public final static int KEYCODE_5 = 53;
- public final static int KEYCODE_6 = 54;
- public final static int KEYCODE_7 = 55;
- public final static int KEYCODE_8 = 56;
- public final static int KEYCODE_9 = 57;
- public final static int KEYCODE_COLON = 58;
- public final static int KEYCODE_SEMICOLON = 59;
- public final static int KEYCODE_LESS = 60;
- public final static int KEYCODE_EQUALS = 61;
- public final static int KEYCODE_GREATER = 62;
- public final static int KEYCODE_QUESTION = 63;
- public final static int KEYCODE_AT = 64;
- public final static int KEYCODE_LEFTBRACKET = 91;
- public final static int KEYCODE_BACKSLASH = 92;
- public final static int KEYCODE_RIGHTBRACKET = 93;
- public final static int KEYCODE_CARET = 94;
- public final static int KEYCODE_UNDERSCORE = 95;
- public final static int KEYCODE_BACKQUOTE = 96;
- public final static int KEYCODE_a = 97;
- public final static int KEYCODE_b = 98;
- public final static int KEYCODE_c = 99;
- public final static int KEYCODE_d = 100;
- public final static int KEYCODE_e = 101;
- public final static int KEYCODE_f = 102;
- public final static int KEYCODE_g = 103;
- public final static int KEYCODE_h = 104;
- public final static int KEYCODE_i = 105;
- public final static int KEYCODE_j = 106;
- public final static int KEYCODE_k = 107;
- public final static int KEYCODE_l = 108;
- public final static int KEYCODE_m = 109;
- public final static int KEYCODE_n = 110;
- public final static int KEYCODE_o = 111;
- public final static int KEYCODE_p = 112;
- public final static int KEYCODE_q = 113;
- public final static int KEYCODE_r = 114;
- public final static int KEYCODE_s = 115;
- public final static int KEYCODE_t = 116;
- public final static int KEYCODE_u = 117;
- public final static int KEYCODE_v = 118;
- public final static int KEYCODE_w = 119;
- public final static int KEYCODE_x = 120;
- public final static int KEYCODE_y = 121;
- public final static int KEYCODE_z = 122;
- public final static int KEYCODE_DELETE = 127;
- // Numeric keypad
- public final static int KEYCODE_KP0 = 256;
- public final static int KEYCODE_KP1 = 257;
- public final static int KEYCODE_KP2 = 258;
- public final static int KEYCODE_KP3 = 259;
- public final static int KEYCODE_KP4 = 260;
- public final static int KEYCODE_KP5 = 261;
- public final static int KEYCODE_KP6 = 262;
- public final static int KEYCODE_KP7 = 263;
- public final static int KEYCODE_KP8 = 264;
- public final static int KEYCODE_KP9 = 265;
- public final static int KEYCODE_KP_PERIOD = 266;
- public final static int KEYCODE_KP_DIVIDE = 267;
- public final static int KEYCODE_KP_MULTIPLY = 268;
- public final static int KEYCODE_KP_MINUS = 269;
- public final static int KEYCODE_KP_PLUS = 270;
- public final static int KEYCODE_KP_ENTER = 271;
- public final static int KEYCODE_KP_EQUALS = 272;
- // Arrows + Home/End pad
- public final static int KEYCODE_UP = 273;
- public final static int KEYCODE_DOWN = 274;
- public final static int KEYCODE_RIGHT = 275;
- public final static int KEYCODE_LEFT = 276;
- public final static int KEYCODE_INSERT = 277;
- public final static int KEYCODE_HOME = 278;
- public final static int KEYCODE_END = 279;
- public final static int KEYCODE_PAGEUP = 280;
- public final static int KEYCODE_PAGEDOWN = 281;
- // Function keys
- public final static int KEYCODE_F1 = 282;
- public final static int KEYCODE_F2 = 283;
- public final static int KEYCODE_F3 = 284;
- public final static int KEYCODE_F4 = 285;
- public final static int KEYCODE_F5 = 286;
- public final static int KEYCODE_F6 = 287;
- public final static int KEYCODE_F7 = 288;
- public final static int KEYCODE_F8 = 289;
- public final static int KEYCODE_F9 = 290;
- public final static int KEYCODE_F10 = 291;
- public final static int KEYCODE_F11 = 292;
- public final static int KEYCODE_F12 = 293;
- public final static int KEYCODE_F13 = 294;
- public final static int KEYCODE_F14 = 295;
- public final static int KEYCODE_F15 = 296;
- // Key state modifier keys
- public final static int KEYCODE_NUMLOCK = 300;
- public final static int KEYCODE_CAPSLOCK = 301;
- public final static int KEYCODE_SCROLLOCK = 302;
- public final static int KEYCODE_RSHIFT = 303;
- public final static int KEYCODE_LSHIFT = 304;
- public final static int KEYCODE_RCTRL = 305;
- public final static int KEYCODE_LCTRL = 306;
- public final static int KEYCODE_RALT = 307;
- public final static int KEYCODE_LALT = 308;
- public final static int KEYCODE_RMETA = 309;
- public final static int KEYCODE_LMETA = 310;
- public final static int KEYCODE_LSUPER = 311; // Left "Windows" key
- public final static int KEYCODE_RSUPER = 312; // Right "Windows" key
- public final static int KEYCODE_MODE = 313; // "Alt Gr" key
- public final static int KEYCODE_COMPOSE = 314; // Multi-key compose key
- // Miscellaneous function keys
- public final static int KEYCODE_HELP = 315;
- public final static int KEYCODE_PRINT = 316;
- public final static int KEYCODE_SYSREQ = 317;
- public final static int KEYCODE_BREAK = 318;
- public final static int KEYCODE_MENU = 319;
- public final static int KEYCODE_POWER = 320; // Power Macintosh power key
- public final static int KEYCODE_EURO = 321; // Some european keyboards
- public final static int KEYCODE_UNDO = 322; // Atari keyboard has Undo
-
- // Android KeyEvent keycode -> ScummVM keycode
- public final static Map<Integer, Integer> androidKeyMap;
- static {
- Map<Integer, Integer> map = new HashMap<Integer, Integer>();
-
- map.put(KeyEvent.KEYCODE_DEL, KEYCODE_BACKSPACE);
- map.put(KeyEvent.KEYCODE_TAB, KEYCODE_TAB);
- map.put(KeyEvent.KEYCODE_CLEAR, KEYCODE_CLEAR);
- map.put(KeyEvent.KEYCODE_ENTER, KEYCODE_RETURN);
- //map.put(??, KEYCODE_PAUSE);
- map.put(KeyEvent.KEYCODE_BACK, KEYCODE_ESCAPE);
- map.put(KeyEvent.KEYCODE_SPACE, KEYCODE_SPACE);
- //map.put(??, KEYCODE_EXCLAIM);
- //map.put(??, KEYCODE_QUOTEDBL);
- map.put(KeyEvent.KEYCODE_POUND, KEYCODE_HASH);
- //map.put(??, KEYCODE_DOLLAR);
- //map.put(??, KEYCODE_AMPERSAND);
- map.put(KeyEvent.KEYCODE_APOSTROPHE, KEYCODE_QUOTE);
- //map.put(??, KEYCODE_LEFTPAREN);
- //map.put(??, KEYCODE_RIGHTPAREN);
- //map.put(??, KEYCODE_ASTERISK);
- map.put(KeyEvent.KEYCODE_PLUS, KEYCODE_PLUS);
- map.put(KeyEvent.KEYCODE_COMMA, KEYCODE_COMMA);
- map.put(KeyEvent.KEYCODE_MINUS, KEYCODE_MINUS);
- map.put(KeyEvent.KEYCODE_PERIOD, KEYCODE_PERIOD);
- map.put(KeyEvent.KEYCODE_SLASH, KEYCODE_SLASH);
- map.put(KeyEvent.KEYCODE_0, KEYCODE_0);
- map.put(KeyEvent.KEYCODE_1, KEYCODE_1);
- map.put(KeyEvent.KEYCODE_2, KEYCODE_2);
- map.put(KeyEvent.KEYCODE_3, KEYCODE_3);
- map.put(KeyEvent.KEYCODE_4, KEYCODE_4);
- map.put(KeyEvent.KEYCODE_5, KEYCODE_5);
- map.put(KeyEvent.KEYCODE_6, KEYCODE_6);
- map.put(KeyEvent.KEYCODE_7, KEYCODE_7);
- map.put(KeyEvent.KEYCODE_8, KEYCODE_8);
- map.put(KeyEvent.KEYCODE_9, KEYCODE_9);
- //map.put(??, KEYCODE_COLON);
- map.put(KeyEvent.KEYCODE_SEMICOLON, KEYCODE_SEMICOLON);
- //map.put(??, KEYCODE_LESS);
- map.put(KeyEvent.KEYCODE_EQUALS, KEYCODE_EQUALS);
- //map.put(??, KEYCODE_GREATER);
- //map.put(??, KEYCODE_QUESTION);
- map.put(KeyEvent.KEYCODE_AT, KEYCODE_AT);
- map.put(KeyEvent.KEYCODE_LEFT_BRACKET, KEYCODE_LEFTBRACKET);
- map.put(KeyEvent.KEYCODE_BACKSLASH, KEYCODE_BACKSLASH);
- map.put(KeyEvent.KEYCODE_RIGHT_BRACKET, KEYCODE_RIGHTBRACKET);
- //map.put(??, KEYCODE_CARET);
- //map.put(??, KEYCODE_UNDERSCORE);
- //map.put(??, KEYCODE_BACKQUOTE);
- map.put(KeyEvent.KEYCODE_A, KEYCODE_a);
- map.put(KeyEvent.KEYCODE_B, KEYCODE_b);
- map.put(KeyEvent.KEYCODE_C, KEYCODE_c);
- map.put(KeyEvent.KEYCODE_D, KEYCODE_d);
- map.put(KeyEvent.KEYCODE_E, KEYCODE_e);
- map.put(KeyEvent.KEYCODE_F, KEYCODE_f);
- map.put(KeyEvent.KEYCODE_G, KEYCODE_g);
- map.put(KeyEvent.KEYCODE_H, KEYCODE_h);
- map.put(KeyEvent.KEYCODE_I, KEYCODE_i);
- map.put(KeyEvent.KEYCODE_J, KEYCODE_j);
- map.put(KeyEvent.KEYCODE_K, KEYCODE_k);
- map.put(KeyEvent.KEYCODE_L, KEYCODE_l);
- map.put(KeyEvent.KEYCODE_M, KEYCODE_m);
- map.put(KeyEvent.KEYCODE_N, KEYCODE_n);
- map.put(KeyEvent.KEYCODE_O, KEYCODE_o);
- map.put(KeyEvent.KEYCODE_P, KEYCODE_p);
- map.put(KeyEvent.KEYCODE_Q, KEYCODE_q);
- map.put(KeyEvent.KEYCODE_R, KEYCODE_r);
- map.put(KeyEvent.KEYCODE_S, KEYCODE_s);
- map.put(KeyEvent.KEYCODE_T, KEYCODE_t);
- map.put(KeyEvent.KEYCODE_U, KEYCODE_u);
- map.put(KeyEvent.KEYCODE_V, KEYCODE_v);
- map.put(KeyEvent.KEYCODE_W, KEYCODE_w);
- map.put(KeyEvent.KEYCODE_X, KEYCODE_x);
- map.put(KeyEvent.KEYCODE_Y, KEYCODE_y);
- map.put(KeyEvent.KEYCODE_Z, KEYCODE_z);
- //map.put(KeyEvent.KEYCODE_DEL, KEYCODE_DELETE); use BACKSPACE instead
- //map.put(??, KEYCODE_KP_*);
- map.put(KeyEvent.KEYCODE_DPAD_UP, KEYCODE_UP);
- map.put(KeyEvent.KEYCODE_DPAD_DOWN, KEYCODE_DOWN);
- map.put(KeyEvent.KEYCODE_DPAD_RIGHT, KEYCODE_RIGHT);
- map.put(KeyEvent.KEYCODE_DPAD_LEFT, KEYCODE_LEFT);
- //map.put(??, KEYCODE_INSERT);
- //map.put(??, KEYCODE_HOME);
- //map.put(??, KEYCODE_END);
- //map.put(??, KEYCODE_PAGEUP);
- //map.put(??, KEYCODE_PAGEDOWN);
- //map.put(??, KEYCODE_F{1-15});
- map.put(KeyEvent.KEYCODE_NUM, KEYCODE_NUMLOCK);
- //map.put(??, KEYCODE_CAPSLOCK);
- //map.put(??, KEYCODE_SCROLLLOCK);
- map.put(KeyEvent.KEYCODE_SHIFT_RIGHT, KEYCODE_RSHIFT);
- map.put(KeyEvent.KEYCODE_SHIFT_LEFT, KEYCODE_LSHIFT);
- //map.put(??, KEYCODE_RCTRL);
- //map.put(??, KEYCODE_LCTRL);
- map.put(KeyEvent.KEYCODE_ALT_RIGHT, KEYCODE_RALT);
- map.put(KeyEvent.KEYCODE_ALT_LEFT, KEYCODE_LALT);
- // ?? META, SUPER
- // ?? MODE, COMPOSE
- // ?? HELP, PRINT, SYSREQ, BREAK, EURO, UNDO
- map.put(KeyEvent.KEYCODE_MENU, KEYCODE_MENU);
- map.put(KeyEvent.KEYCODE_POWER, KEYCODE_POWER);
-
- androidKeyMap = Collections.unmodifiableMap(map);
- }
-
- public int type;
- public boolean synthetic;
- public int kbd_keycode;
- public int kbd_ascii;
- public int kbd_flags;
- public int mouse_x;
- public int mouse_y;
- public boolean mouse_relative; // Used for trackball events
-
- public Event() {
- type = EVENT_INVALID;
- synthetic = false;
- }
-
- public Event(int type) {
- this.type = type;
- synthetic = false;
- }
-
- public static Event KeyboardEvent(int type, int keycode, int ascii,
- int flags) {
- Event e = new Event();
- e.type = type;
- e.kbd_keycode = keycode;
- e.kbd_ascii = ascii;
- e.kbd_flags = flags;
- return e;
- }
-
- public static Event MouseEvent(int type, int x, int y) {
- Event e = new Event();
- e.type = type;
- e.mouse_x = x;
- e.mouse_y = y;
- return e;
- }
-}
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
index ed4e00d769..fe225af48b 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
@@ -9,14 +9,12 @@ import android.media.AudioTrack;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import java.io.File;
-import java.util.Map;
import java.util.LinkedHashMap;
public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
@@ -49,7 +47,8 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
final public native void setPause(boolean pause);
final public native void enableZoning(boolean enable);
// Feed an event to ScummVM. Safe to call from other threads.
- final public native void pushEvent(Event e);
+ final public native void pushEvent(int type, int arg1, int arg2, int arg3,
+ int arg4, int arg5);
// Callbacks from C++ peer instance
abstract protected void getDPI(float[] values);
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
index 2cf6f58941..1978b690d0 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
@@ -3,33 +3,18 @@ package org.inodes.gus.scummvm;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
-import android.view.View;
-import android.view.ViewConfiguration;
+import android.view.MotionEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
-import java.io.IOException;
-
public class ScummVMActivity extends Activity {
- private boolean _do_right_click;
- private boolean _last_click_was_right;
-
- // game pixels to move per trackball/dpad event.
- // FIXME: replace this with proper mouse acceleration
- private final static int TRACKBALL_SCALE = 2;
private class MyScummVM extends ScummVM {
private boolean usingSmallScreen() {
@@ -106,13 +91,13 @@ public class ScummVMActivity extends Activity {
}
private MyScummVM _scummvm;
+ private ScummVMEvents _events;
private Thread _scummvm_thread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- _do_right_click = false;
setVolumeControlStream(AudioManager.STREAM_MUSIC);
setContentView(R.layout.main);
@@ -139,18 +124,6 @@ public class ScummVMActivity extends Activity {
SurfaceView main_surface = (SurfaceView)findViewById(R.id.main_surface);
- main_surface.setOnTouchListener(new View.OnTouchListener() {
- public boolean onTouch(View v, MotionEvent event) {
- return onTouchEvent(event);
- }
- });
-
- main_surface.setOnKeyListener(new View.OnKeyListener() {
- public boolean onKey(View v, int code, KeyEvent ev) {
- return onKeyDown(code, ev);
- }
- });
-
main_surface.requestFocus();
getFilesDir().mkdirs();
@@ -166,6 +139,11 @@ public class ScummVMActivity extends Activity {
"--savepath=" + getDir("saves", 0).getPath()
});
+ _events = new ScummVMEvents(this, _scummvm);
+
+ main_surface.setOnKeyListener(_events);
+ main_surface.setOnTouchListener(_events);
+
_scummvm_thread = new Thread(_scummvm, "ScummVM");
_scummvm_thread.start();
}
@@ -210,8 +188,8 @@ public class ScummVMActivity extends Activity {
super.onDestroy();
- if (_scummvm != null) {
- _scummvm.pushEvent(new Event(Event.EVENT_QUIT));
+ if (_events != null) {
+ _events.sendQuitEvent();
try {
// 1s timeout
@@ -224,259 +202,12 @@ public class ScummVMActivity extends Activity {
}
}
- static final int MSG_MENU_LONG_PRESS = 1;
-
- private final Handler keycodeMenuTimeoutHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_MENU_LONG_PRESS) {
- InputMethodManager imm = (InputMethodManager)
- getSystemService(INPUT_METHOD_SERVICE);
- if (imm != null)
- imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
- }
- }
- };
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent kevent) {
- return onKeyDown(keyCode, kevent);
- }
-
- @Override
- public boolean onKeyMultiple(int keyCode, int repeatCount,
- KeyEvent kevent) {
- return onKeyDown(keyCode, kevent);
- }
-
@Override
- public boolean onKeyDown(int keyCode, KeyEvent kevent) {
- // Filter out "special" keys
- switch (keyCode) {
- case KeyEvent.KEYCODE_MENU:
- // Have to reimplement hold-down-menu-brings-up-softkeybd
- // ourselves, since we are otherwise hijacking the menu key :(
- // See com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel()
- // for the usual Android implementation of this feature.
-
- // Ignore keyrepeat for menu
- if (kevent.getRepeatCount() > 0)
- return false;
-
- boolean timeout_fired = !keycodeMenuTimeoutHandler.hasMessages(MSG_MENU_LONG_PRESS);
- keycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
-
- if (kevent.getAction() == KeyEvent.ACTION_DOWN) {
- keycodeMenuTimeoutHandler.sendMessageDelayed(keycodeMenuTimeoutHandler.obtainMessage(MSG_MENU_LONG_PRESS),
- ViewConfiguration.getLongPressTimeout());
- return true;
- }
-
- if (kevent.getAction() == KeyEvent.ACTION_UP) {
- if (!timeout_fired)
- _scummvm.pushEvent(new Event(Event.EVENT_MAINMENU));
-
- return true;
- }
-
- return false;
-
- case KeyEvent.KEYCODE_CAMERA:
- case KeyEvent.KEYCODE_SEARCH:
- _do_right_click = (kevent.getAction() == KeyEvent.ACTION_DOWN);
- return true;
-
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT: {
- // HTC Hero doesn't seem to generate
- // MotionEvent.ACTION_DOWN events on trackball press :(
- // We'll have to just fake one here.
- // Some other handsets lack a trackball, so the DPAD is
- // the only way of moving the cursor.
- int motion_action;
-
- // FIXME: this logic is a mess.
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- switch (kevent.getAction()) {
- case KeyEvent.ACTION_DOWN:
- motion_action = MotionEvent.ACTION_DOWN;
- break;
-
- case KeyEvent.ACTION_UP:
- motion_action = MotionEvent.ACTION_UP;
- break;
-
- // ACTION_MULTIPLE
- default:
- return false;
- }
- } else {
- motion_action = MotionEvent.ACTION_MOVE;
- }
-
- Event e = new Event(getEventType(motion_action));
-
- e.mouse_x = 0;
- e.mouse_y = 0;
- e.mouse_relative = true;
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:
- e.mouse_y = -TRACKBALL_SCALE;
- break;
-
- case KeyEvent.KEYCODE_DPAD_DOWN:
- e.mouse_y = TRACKBALL_SCALE;
- break;
-
- case KeyEvent.KEYCODE_DPAD_LEFT:
- e.mouse_x = -TRACKBALL_SCALE;
- break;
-
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- e.mouse_x = TRACKBALL_SCALE;
- break;
- }
-
- _scummvm.pushEvent(e);
-
- return true;
- }
-
- case KeyEvent.KEYCODE_BACK:
- // skip isSystem() check and fall through to main code
- break;
-
- default:
- if (kevent.isSystem())
- return false;
- }
-
- // FIXME: what do I need to do for composed characters?
-
- Event e = new Event();
-
- switch (kevent.getAction()) {
- case KeyEvent.ACTION_DOWN:
- e.type = Event.EVENT_KEYDOWN;
- e.synthetic = false;
- break;
-
- case KeyEvent.ACTION_UP:
- e.type = Event.EVENT_KEYUP;
- e.synthetic = false;
- break;
-
- case KeyEvent.ACTION_MULTIPLE:
- // e.type is handled below
- e.synthetic = true;
- break;
-
- default:
- return false;
- }
-
- e.kbd_keycode = Event.androidKeyMap.containsKey(keyCode) ?
- Event.androidKeyMap.get(keyCode) : Event.KEYCODE_INVALID;
-
- e.kbd_ascii = kevent.getUnicodeChar();
-
- if (e.kbd_ascii == 0)
- e.kbd_ascii = e.kbd_keycode; // scummvm keycodes are mostly ascii
-
- e.kbd_flags = 0;
-
- if (kevent.isAltPressed())
- e.kbd_flags |= Event.KBD_ALT;
-
- // no ctrl key in android, so use sym (?)
- if (kevent.isSymPressed())
- e.kbd_flags |= Event.KBD_CTRL;
-
- if (kevent.isShiftPressed()) {
- if (keyCode >= KeyEvent.KEYCODE_0 &&
- keyCode <= KeyEvent.KEYCODE_9) {
- // Shift+number -> convert to F* key
- int offset = keyCode == KeyEvent.KEYCODE_0 ?
- 10 : keyCode - KeyEvent.KEYCODE_1; // turn 0 into 10
-
- e.kbd_keycode = Event.KEYCODE_F1 + offset;
- e.kbd_ascii = Event.ASCII_F1 + offset;
- } else {
- e.kbd_flags |= Event.KBD_SHIFT;
- }
- }
-
- if (kevent.getAction() == KeyEvent.ACTION_MULTIPLE) {
- for (int i = 0; i <= kevent.getRepeatCount(); i++) {
- e.type = Event.EVENT_KEYDOWN;
- _scummvm.pushEvent(e);
-
- e.type = Event.EVENT_KEYUP;
- _scummvm.pushEvent(e);
- }
- } else {
- _scummvm.pushEvent(e);
- }
-
- return true;
- }
-
- private int getEventType(int action) {
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- _last_click_was_right = _do_right_click;
- return _last_click_was_right ?
- Event.EVENT_RBUTTONDOWN : Event.EVENT_LBUTTONDOWN;
-
- case MotionEvent.ACTION_UP:
- return _last_click_was_right ?
- Event.EVENT_RBUTTONUP : Event.EVENT_LBUTTONUP;
-
- case MotionEvent.ACTION_MOVE:
- return Event.EVENT_MOUSEMOVE;
-
- default:
- return Event.EVENT_INVALID;
- }
- }
-
- @Override
- public boolean onTrackballEvent(MotionEvent event) {
- int type = getEventType(event.getAction());
- if (type == Event.EVENT_INVALID)
- return false;
-
- Event e = new Event(type);
- e.mouse_x =
- (int)(event.getX() * event.getXPrecision()) * TRACKBALL_SCALE;
- e.mouse_y =
- (int)(event.getY() * event.getYPrecision()) * TRACKBALL_SCALE;
- e.mouse_relative = true;
-
- _scummvm.pushEvent(e);
-
- return true;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- int type = getEventType(event.getAction());
-
- if (type == Event.EVENT_INVALID)
- return false;
-
- Event e = new Event(type);
- e.mouse_x = (int)event.getX();
- e.mouse_y = (int)event.getY();
- e.mouse_relative = false;
-
- _scummvm.pushEvent(e);
+ public boolean onTrackballEvent(MotionEvent e) {
+ if (_events != null)
+ return _events.onTrackballEvent(e);
- return true;
+ return false;
}
private void showKeyboard(boolean show) {
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java
new file mode 100644
index 0000000000..3d3fdeece4
--- /dev/null
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java
@@ -0,0 +1,201 @@
+package org.inodes.gus.scummvm;
+
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.content.Context;
+import android.view.KeyEvent;
+import android.view.KeyCharacterMap;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.GestureDetector;
+import android.view.inputmethod.InputMethodManager;
+
+public class ScummVMEvents implements
+ android.view.View.OnKeyListener,
+ android.view.View.OnTouchListener,
+ android.view.GestureDetector.OnGestureListener,
+ android.view.GestureDetector.OnDoubleTapListener {
+
+ public static final int JE_SYS_KEY = 0;
+ public static final int JE_KEY = 1;
+ public static final int JE_DOWN = 2;
+ public static final int JE_SCROLL = 3;
+ public static final int JE_TAP = 4;
+ public static final int JE_DOUBLE_TAP = 5;
+ public static final int JE_BALL = 6;
+ public static final int JE_QUIT = 0x1000;
+
+ final protected Context _context;
+ final protected ScummVM _scummvm;
+ final protected GestureDetector _gd;
+ final protected int _longPress;
+ final protected int _slop;
+
+ public ScummVMEvents(Context context, ScummVM scummvm) {
+ _context = context;
+ _scummvm = scummvm;
+
+ _gd = new GestureDetector(context, this);
+ _gd.setOnDoubleTapListener(this);
+ _gd.setIsLongpressEnabled(false);
+
+ _longPress = ViewConfiguration.getLongPressTimeout();
+ _slop = ViewConfiguration.get(context).getScaledTouchSlop();
+
+ }
+
+ final public void sendQuitEvent() {
+ _scummvm.pushEvent(JE_QUIT, 0, 0, 0, 0, 0);
+ }
+
+ public boolean onTrackballEvent(MotionEvent e) {
+ _scummvm.pushEvent(JE_BALL, (int)(e.getX() * e.getXPrecision() * 100),
+ (int)(e.getY() * e.getYPrecision() * 100), 0, 0, 0);
+ return true;
+ }
+
+ final static int MSG_MENU_LONG_PRESS = 1;
+
+ final private Handler keyHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_MENU_LONG_PRESS) {
+ InputMethodManager imm = (InputMethodManager)
+ _context.getSystemService(_context.INPUT_METHOD_SERVICE);
+
+ if (imm != null)
+ imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
+ }
+ }
+ };
+
+ // OnKeyListener
+ final public boolean onKey(View v, int keyCode, KeyEvent e) {
+ final int action = e.getAction();
+
+ if (e.isSystem()) {
+ // filter what we handle
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ case KeyEvent.KEYCODE_MENU:
+ break;
+
+ default:
+ return false;
+ }
+
+ // no repeats for system keys
+ if (e.getRepeatCount() > 0)
+ return false;
+
+ // Have to reimplement hold-down-menu-brings-up-softkeybd
+ // ourselves, since we are otherwise hijacking the menu key :(
+ // See com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel()
+ // for the usual Android implementation of this feature.
+ if (keyCode == KeyEvent.KEYCODE_MENU) {
+ final boolean fired =
+ !keyHandler.hasMessages(MSG_MENU_LONG_PRESS);
+
+ keyHandler.removeMessages(MSG_MENU_LONG_PRESS);
+
+ if (action == KeyEvent.ACTION_DOWN) {
+ keyHandler.sendMessageDelayed(keyHandler.obtainMessage(
+ MSG_MENU_LONG_PRESS), _longPress);
+ return true;
+ }
+
+ if (fired)
+ return true;
+
+ // only send up events of the menu button to the native side
+ if (action != KeyEvent.ACTION_UP)
+ return true;
+ }
+
+ _scummvm.pushEvent(JE_SYS_KEY, action, keyCode, 0, 0, 0);
+
+ return true;
+ }
+
+ // sequence of characters
+ if (action == KeyEvent.ACTION_MULTIPLE &&
+ keyCode == KeyEvent.KEYCODE_UNKNOWN) {
+ KeyCharacterMap m = KeyCharacterMap.load(e.getDeviceId());
+
+ for (KeyEvent s : m.getEvents(e.getCharacters().toCharArray())) {
+ _scummvm.pushEvent(JE_KEY, s.getAction(), s.getKeyCode(),
+ s.getUnicodeChar() & KeyCharacterMap.COMBINING_ACCENT_MASK,
+ s.getMetaState(), s.getRepeatCount());
+ }
+
+ return true;
+ }
+
+ _scummvm.pushEvent(JE_KEY, action, keyCode,
+ e.getUnicodeChar() & KeyCharacterMap.COMBINING_ACCENT_MASK,
+ e.getMetaState(), e.getRepeatCount());
+
+ return true;
+ }
+
+ // OnTouchListener
+ final public boolean onTouch(View v, MotionEvent e) {
+ return _gd.onTouchEvent(e);
+ }
+
+ // OnGestureListener
+ final public boolean onDown(MotionEvent e) {
+ _scummvm.pushEvent(JE_DOWN, (int)e.getX(), (int)e.getY(), 0, 0, 0);
+ return true;
+ }
+
+ final public boolean onFling(MotionEvent e1, MotionEvent e2,
+ float velocityX, float velocityY) {
+ //Log.d(ScummVM.LOG_TAG, String.format("onFling: %s -> %s (%.3f %.3f)",
+ // e1.toString(), e2.toString(),
+ // velocityX, velocityY));
+
+ return true;
+ }
+
+ final public void onLongPress(MotionEvent e) {
+ // disabled, interferes with drag&drop
+ }
+
+ final public boolean onScroll(MotionEvent e1, MotionEvent e2,
+ float distanceX, float distanceY) {
+ _scummvm.pushEvent(JE_SCROLL, (int)e1.getX(), (int)e1.getY(),
+ (int)e2.getX(), (int)e2.getY(), _slop);
+
+ return true;
+ }
+
+ final public void onShowPress(MotionEvent e) {
+ }
+
+ final public boolean onSingleTapUp(MotionEvent e) {
+ _scummvm.pushEvent(JE_TAP, (int)e.getX(), (int)e.getY(),
+ (int)(e.getEventTime() - e.getDownTime()), 0, 0);
+
+ return true;
+ }
+
+ // OnDoubleTapListener
+ final public boolean onDoubleTap(MotionEvent e) {
+ return true;
+ }
+
+ final public boolean onDoubleTapEvent(MotionEvent e) {
+ _scummvm.pushEvent(JE_DOUBLE_TAP, (int)e.getX(), (int)e.getY(),
+ e.getAction(), _slop, 0);
+
+ return true;
+ }
+
+ final public boolean onSingleTapConfirmed(MotionEvent e) {
+ return true;
+ }
+}
+