ANDROID: Input system overhaul
Rewritten input system with many new feature. Fixed related bugs and shortcomings on the way.
This commit is contained in:
parent
e71c2cf850
commit
adef4c3f42
12 changed files with 940 additions and 915 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ ANDROID_PLUGIN_VERSIONCODE = 6
|
|||
|
||||
JAVA_FILES = \
|
||||
ScummVM.java \
|
||||
ScummVMEvents.java \
|
||||
ScummVMApplication.java \
|
||||
ScummVMActivity.java \
|
||||
EditableSurfaceView.java \
|
||||
|
|
661
backends/platform/android/events.cpp
Normal file
661
backends/platform/android/events.cpp
Normal file
|
@ -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
|
||||
|
|
@ -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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
public boolean onTrackballEvent(MotionEvent e) {
|
||||
if (_events != null)
|
||||
return _events.onTrackballEvent(e);
|
||||
|
||||
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);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showKeyboard(boolean show) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue