diff options
-rw-r--r-- | backends/platform/android/android.cpp | 179 | ||||
-rw-r--r-- | backends/platform/android/android.h | 23 | ||||
-rw-r--r-- | backends/platform/android/android.mk | 1 | ||||
-rw-r--r-- | backends/platform/android/events.cpp | 661 | ||||
-rw-r--r-- | backends/platform/android/gfx.cpp | 48 | ||||
-rw-r--r-- | backends/platform/android/jni.cpp | 96 | ||||
-rw-r--r-- | backends/platform/android/jni.h | 13 | ||||
-rw-r--r-- | backends/platform/android/module.mk | 3 | ||||
-rw-r--r-- | backends/platform/android/org/inodes/gus/scummvm/Event.java | 330 | ||||
-rw-r--r-- | backends/platform/android/org/inodes/gus/scummvm/ScummVM.java | 5 | ||||
-rw-r--r-- | backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java | 295 | ||||
-rw-r--r-- | backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java | 201 |
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; + } +} + |