ANDROID: Move rest of everything JNI
This commit is contained in:
parent
f80d993860
commit
53b5808d4f
6 changed files with 274 additions and 195 deletions
|
@ -40,8 +40,8 @@
|
||||||
#include "backends/saves/default/default-saves.h"
|
#include "backends/saves/default/default-saves.h"
|
||||||
#include "backends/timer/default/default-timer.h"
|
#include "backends/timer/default/default-timer.h"
|
||||||
|
|
||||||
|
#include "backends/platform/android/jni.h"
|
||||||
#include "backends/platform/android/android.h"
|
#include "backends/platform/android/android.h"
|
||||||
#include "backends/platform/android/asset-archive.h"
|
|
||||||
|
|
||||||
const char *android_log_tag = "ScummVM";
|
const char *android_log_tag = "ScummVM";
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ static inline T scalef(T in, float numerator, float denominator) {
|
||||||
return static_cast<float>(in) * numerator / denominator;
|
return static_cast<float>(in) * numerator / denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSystem_Android::OSystem_Android(jobject am) :
|
OSystem_Android::OSystem_Android() :
|
||||||
_screen_changeid(0),
|
_screen_changeid(0),
|
||||||
_force_redraw(false),
|
_force_redraw(false),
|
||||||
_game_texture(0),
|
_game_texture(0),
|
||||||
|
@ -112,7 +112,6 @@ OSystem_Android::OSystem_Android(jobject am) :
|
||||||
_mixer(0),
|
_mixer(0),
|
||||||
_timer(0),
|
_timer(0),
|
||||||
_fsFactory(new POSIXFilesystemFactory()),
|
_fsFactory(new POSIXFilesystemFactory()),
|
||||||
_asset_archive(new AndroidAssetArchive(am)),
|
|
||||||
_shake_offset(0),
|
_shake_offset(0),
|
||||||
_event_queue_lock(createMutex()) {
|
_event_queue_lock(createMutex()) {
|
||||||
}
|
}
|
||||||
|
@ -124,42 +123,16 @@ OSystem_Android::~OSystem_Android() {
|
||||||
delete _overlay_texture;
|
delete _overlay_texture;
|
||||||
delete _mouse_texture;
|
delete _mouse_texture;
|
||||||
|
|
||||||
destroyScummVMSurface();
|
JNI::destroySurface();
|
||||||
|
|
||||||
delete _savefile;
|
delete _savefile;
|
||||||
delete _mixer;
|
delete _mixer;
|
||||||
delete _timer;
|
delete _timer;
|
||||||
delete _fsFactory;
|
delete _fsFactory;
|
||||||
delete _asset_archive;
|
|
||||||
|
|
||||||
deleteMutex(_event_queue_lock);
|
deleteMutex(_event_queue_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSystem_Android::initJavaHooks(JNIEnv *env) {
|
|
||||||
jclass cls = env->GetObjectClass(back_ptr);
|
|
||||||
|
|
||||||
#define FIND_METHOD(name, signature) do { \
|
|
||||||
MID_ ## name = env->GetMethodID(cls, #name, signature); \
|
|
||||||
if (MID_ ## name == 0) \
|
|
||||||
return false; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
FIND_METHOD(setWindowCaption, "(Ljava/lang/String;)V");
|
|
||||||
FIND_METHOD(displayMessageOnOSD, "(Ljava/lang/String;)V");
|
|
||||||
FIND_METHOD(initBackend, "()V");
|
|
||||||
FIND_METHOD(audioSampleRate, "()I");
|
|
||||||
FIND_METHOD(showVirtualKeyboard, "(Z)V");
|
|
||||||
FIND_METHOD(getSysArchives, "()[Ljava/lang/String;");
|
|
||||||
FIND_METHOD(getPluginDirectories, "()[Ljava/lang/String;");
|
|
||||||
FIND_METHOD(setupScummVMSurface, "()V");
|
|
||||||
FIND_METHOD(destroyScummVMSurface, "()V");
|
|
||||||
FIND_METHOD(swapBuffers, "()Z");
|
|
||||||
|
|
||||||
#undef FIND_METHOD
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *OSystem_Android::timerThreadFunc(void *arg) {
|
void *OSystem_Android::timerThreadFunc(void *arg) {
|
||||||
OSystem_Android *system = (OSystem_Android *)arg;
|
OSystem_Android *system = (OSystem_Android *)arg;
|
||||||
DefaultTimerManager *timer = (DefaultTimerManager *)(system->_timer);
|
DefaultTimerManager *timer = (DefaultTimerManager *)(system->_timer);
|
||||||
|
@ -183,8 +156,6 @@ void *OSystem_Android::timerThreadFunc(void *arg) {
|
||||||
void OSystem_Android::initBackend() {
|
void OSystem_Android::initBackend() {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
|
||||||
|
|
||||||
ConfMan.setInt("autosave_period", 0);
|
ConfMan.setInt("autosave_period", 0);
|
||||||
ConfMan.setInt("FM_medium_quality", true);
|
ConfMan.setInt("FM_medium_quality", true);
|
||||||
|
|
||||||
|
@ -200,74 +171,23 @@ void OSystem_Android::initBackend() {
|
||||||
|
|
||||||
gettimeofday(&_startTime, 0);
|
gettimeofday(&_startTime, 0);
|
||||||
|
|
||||||
jint sample_rate = env->CallIntMethod(back_ptr, MID_audioSampleRate);
|
_mixer = new Audio::MixerImpl(this, JNI::getAudioSampleRate());
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
warning("Error finding audio sample rate - assuming 11025HZ");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
|
|
||||||
sample_rate = 11025;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mixer = new Audio::MixerImpl(this, sample_rate);
|
|
||||||
_mixer->setReady(true);
|
_mixer->setReady(true);
|
||||||
|
|
||||||
env->CallVoidMethod(back_ptr, MID_initBackend);
|
JNI::initBackend();
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
error("Error in Java initBackend");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
_timer_thread_exit = false;
|
_timer_thread_exit = false;
|
||||||
pthread_create(&_timer_thread, 0, timerThreadFunc, this);
|
pthread_create(&_timer_thread, 0, timerThreadFunc, this);
|
||||||
|
|
||||||
OSystem::initBackend();
|
OSystem::initBackend();
|
||||||
|
|
||||||
setupScummVMSurface();
|
setupSurface();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
|
void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNI::getPluginDirectories(dirs);
|
||||||
jobjectArray array =
|
|
||||||
(jobjectArray)env->CallObjectMethod(back_ptr, MID_getPluginDirectories);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
warning("Error finding plugin directories");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsize size = env->GetArrayLength(array);
|
|
||||||
for (jsize i = 0; i < size; ++i) {
|
|
||||||
jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
|
|
||||||
|
|
||||||
if (path_obj == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *path = env->GetStringUTFChars(path_obj, 0);
|
|
||||||
if (path == 0) {
|
|
||||||
warning("Error getting string characters from plugin directory");
|
|
||||||
|
|
||||||
env->ExceptionClear();
|
|
||||||
env->DeleteLocalRef(path_obj);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs.push_back(Common::FSNode(path));
|
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(path_obj, path);
|
|
||||||
env->DeleteLocalRef(path_obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSystem_Android::hasFeature(Feature f) {
|
bool OSystem_Android::hasFeature(Feature f) {
|
||||||
|
@ -380,8 +300,8 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
|
||||||
case Common::EVENT_SCREEN_CHANGED:
|
case Common::EVENT_SCREEN_CHANGED:
|
||||||
debug("EVENT_SCREEN_CHANGED");
|
debug("EVENT_SCREEN_CHANGED");
|
||||||
_screen_changeid++;
|
_screen_changeid++;
|
||||||
destroyScummVMSurface();
|
JNI::destroySurface();
|
||||||
setupScummVMSurface();
|
setupSurface();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -475,49 +395,19 @@ void OSystem_Android::quit() {
|
||||||
void OSystem_Android::setWindowCaption(const char *caption) {
|
void OSystem_Android::setWindowCaption(const char *caption) {
|
||||||
ENTER("%s", caption);
|
ENTER("%s", caption);
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNI::setWindowCaption(caption);
|
||||||
jstring java_caption = env->NewStringUTF(caption);
|
|
||||||
env->CallVoidMethod(back_ptr, MID_setWindowCaption, java_caption);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
warning("Failed to set window caption");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
env->DeleteLocalRef(java_caption);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::displayMessageOnOSD(const char *msg) {
|
void OSystem_Android::displayMessageOnOSD(const char *msg) {
|
||||||
ENTER("%s", msg);
|
ENTER("%s", msg);
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNI::displayMessageOnOSD(msg);
|
||||||
jstring java_msg = env->NewStringUTF(msg);
|
|
||||||
env->CallVoidMethod(back_ptr, MID_displayMessageOnOSD, java_msg);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
warning("Failed to display OSD message");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
env->DeleteLocalRef(java_msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::showVirtualKeyboard(bool enable) {
|
void OSystem_Android::showVirtualKeyboard(bool enable) {
|
||||||
ENTER("%d", enable);
|
ENTER("%d", enable);
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNI::showVirtualKeyboard(enable);
|
||||||
env->CallVoidMethod(back_ptr, MID_showVirtualKeyboard, enable);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
error("Error trying to show virtual keyboard");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::SaveFileManager *OSystem_Android::getSavefileManager() {
|
Common::SaveFileManager *OSystem_Android::getSavefileManager() {
|
||||||
|
@ -554,33 +444,9 @@ FilesystemFactory *OSystem_Android::getFilesystemFactory() {
|
||||||
|
|
||||||
void OSystem_Android::addSysArchivesToSearchSet(Common::SearchSet &s,
|
void OSystem_Android::addSysArchivesToSearchSet(Common::SearchSet &s,
|
||||||
int priority) {
|
int priority) {
|
||||||
s.add("ASSET", _asset_archive, priority, false);
|
ENTER("");
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNI::addSysArchivesToSearchSet(s, priority);
|
||||||
jobjectArray array =
|
|
||||||
(jobjectArray)env->CallObjectMethod(back_ptr, MID_getSysArchives);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
warning("Error finding system archive path");
|
|
||||||
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsize size = env->GetArrayLength(array);
|
|
||||||
for (jsize i = 0; i < size; ++i) {
|
|
||||||
jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
|
|
||||||
const char *path = env->GetStringUTFChars(path_obj, 0);
|
|
||||||
|
|
||||||
if (path != 0) {
|
|
||||||
s.addDirectory(path, path, priority);
|
|
||||||
env->ReleaseStringUTFChars(path_obj, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
env->DeleteLocalRef(path_obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::logMessage(LogMessageType::Type type, const char *message) {
|
void OSystem_Android::logMessage(LogMessageType::Type type, const char *message) {
|
||||||
|
|
|
@ -36,12 +36,10 @@
|
||||||
#include "backends/plugins/posix/posix-provider.h"
|
#include "backends/plugins/posix/posix-provider.h"
|
||||||
#include "backends/fs/posix/posix-fs-factory.h"
|
#include "backends/fs/posix/posix-fs-factory.h"
|
||||||
|
|
||||||
#include "backends/platform/android/jni.h"
|
|
||||||
#include "backends/platform/android/texture.h"
|
#include "backends/platform/android/texture.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
|
||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
|
@ -79,9 +77,6 @@ extern void checkGlError(const char *expr, const char *file, int line);
|
||||||
#define GLCALL(x) do { (x); } while (false)
|
#define GLCALL(x) do { (x); } while (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// back pointer to (java) peer instance
|
|
||||||
extern jobject back_ptr;
|
|
||||||
|
|
||||||
#ifdef DYNAMIC_MODULES
|
#ifdef DYNAMIC_MODULES
|
||||||
class AndroidPluginProvider : public POSIXPluginProvider {
|
class AndroidPluginProvider : public POSIXPluginProvider {
|
||||||
protected:
|
protected:
|
||||||
|
@ -91,17 +86,6 @@ protected:
|
||||||
|
|
||||||
class OSystem_Android : public BaseBackend, public PaletteManager {
|
class OSystem_Android : public BaseBackend, public PaletteManager {
|
||||||
private:
|
private:
|
||||||
jmethodID MID_displayMessageOnOSD;
|
|
||||||
jmethodID MID_setWindowCaption;
|
|
||||||
jmethodID MID_initBackend;
|
|
||||||
jmethodID MID_audioSampleRate;
|
|
||||||
jmethodID MID_showVirtualKeyboard;
|
|
||||||
jmethodID MID_getSysArchives;
|
|
||||||
jmethodID MID_getPluginDirectories;
|
|
||||||
jmethodID MID_setupScummVMSurface;
|
|
||||||
jmethodID MID_destroyScummVMSurface;
|
|
||||||
jmethodID MID_swapBuffers;
|
|
||||||
|
|
||||||
int _screen_changeid;
|
int _screen_changeid;
|
||||||
int _egl_surface_width;
|
int _egl_surface_width;
|
||||||
int _egl_surface_height;
|
int _egl_surface_height;
|
||||||
|
@ -138,18 +122,15 @@ private:
|
||||||
Audio::MixerImpl *_mixer;
|
Audio::MixerImpl *_mixer;
|
||||||
Common::TimerManager *_timer;
|
Common::TimerManager *_timer;
|
||||||
FilesystemFactory *_fsFactory;
|
FilesystemFactory *_fsFactory;
|
||||||
Common::Archive *_asset_archive;
|
|
||||||
timeval _startTime;
|
timeval _startTime;
|
||||||
|
|
||||||
void setupScummVMSurface();
|
void setupSurface();
|
||||||
void destroyScummVMSurface();
|
|
||||||
void setupKeymapper();
|
void setupKeymapper();
|
||||||
void _setCursorPalette(const byte *colors, uint start, uint num);
|
void _setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSystem_Android(jobject am);
|
OSystem_Android();
|
||||||
virtual ~OSystem_Android();
|
virtual ~OSystem_Android();
|
||||||
bool initJavaHooks(JNIEnv *env);
|
|
||||||
|
|
||||||
virtual void initBackend();
|
virtual void initBackend();
|
||||||
void addPluginDirectories(Common::FSList &dirs) const;
|
void addPluginDirectories(Common::FSList &dirs) const;
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _ANDROID_ASSET_H_
|
||||||
|
#define _ANDROID_ASSET_H_
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
@ -51,3 +54,5 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
|
||||||
#include "backends/platform/android/android.h"
|
#include "backends/platform/android/android.h"
|
||||||
|
#include "backends/platform/android/jni.h"
|
||||||
|
|
||||||
static inline GLfixed xdiv(int numerator, int denominator) {
|
static inline GLfixed xdiv(int numerator, int denominator) {
|
||||||
assert(numerator < (1 << 16));
|
assert(numerator < (1 << 16));
|
||||||
|
@ -47,11 +48,13 @@ int OSystem_Android::getDefaultGraphicsMode() const {
|
||||||
|
|
||||||
bool OSystem_Android::setGraphicsMode(const char *mode) {
|
bool OSystem_Android::setGraphicsMode(const char *mode) {
|
||||||
ENTER("%s", mode);
|
ENTER("%s", mode);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSystem_Android::setGraphicsMode(int mode) {
|
bool OSystem_Android::setGraphicsMode(int mode) {
|
||||||
ENTER("%d", mode);
|
ENTER("%d", mode);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +62,10 @@ int OSystem_Android::getGraphicsMode() const {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::setupScummVMSurface() {
|
void OSystem_Android::setupSurface() {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
if (!JNI::setupSurface())
|
||||||
env->CallVoidMethod(back_ptr, MID_setupScummVMSurface);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// EGL set up with a new surface. Initialise OpenGLES context.
|
// EGL set up with a new surface. Initialise OpenGLES context.
|
||||||
|
@ -115,12 +115,6 @@ void OSystem_Android::setupScummVMSurface() {
|
||||||
clearFocusRectangle();
|
clearFocusRectangle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::destroyScummVMSurface() {
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
|
||||||
env->CallVoidMethod(back_ptr, MID_destroyScummVMSurface);
|
|
||||||
// Can't use OpenGLES functions after this
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSystem_Android::initSize(uint width, uint height,
|
void OSystem_Android::initSize(uint width, uint height,
|
||||||
const Graphics::PixelFormat *format) {
|
const Graphics::PixelFormat *format) {
|
||||||
ENTER("%d, %d, %p", width, height, format);
|
ENTER("%d, %d, %p", width, height, format);
|
||||||
|
@ -158,6 +152,7 @@ void OSystem_Android::setPalette(const byte *colors, uint start, uint num) {
|
||||||
|
|
||||||
void OSystem_Android::grabPalette(byte *colors, uint start, uint num) {
|
void OSystem_Android::grabPalette(byte *colors, uint start, uint num) {
|
||||||
ENTER("%p, %u, %u", colors, start, num);
|
ENTER("%p, %u, %u", colors, start, num);
|
||||||
|
|
||||||
memcpy(colors, _game_texture->palette_const() + start * 3, num * 3);
|
memcpy(colors, _game_texture->palette_const() + start * 3, num * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,11 +256,10 @@ void OSystem_Android::updateScreen() {
|
||||||
|
|
||||||
GLCALL(glPopMatrix());
|
GLCALL(glPopMatrix());
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
if (!JNI::swapBuffers()) {
|
||||||
if (!env->CallBooleanMethod(back_ptr, MID_swapBuffers)) {
|
|
||||||
// Context lost -> need to reinit GL
|
// Context lost -> need to reinit GL
|
||||||
destroyScummVMSurface();
|
JNI::destroySurface();
|
||||||
setupScummVMSurface();
|
setupSurface();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
|
|
||||||
#include "backends/platform/android/android.h"
|
#include "backends/platform/android/android.h"
|
||||||
|
#include "backends/platform/android/asset-archive.h"
|
||||||
jobject back_ptr;
|
#include "backends/platform/android/jni.h"
|
||||||
|
|
||||||
__attribute__ ((visibility("default")))
|
__attribute__ ((visibility("default")))
|
||||||
jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
|
@ -39,6 +39,8 @@ jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
|
|
||||||
JavaVM *JNI::_vm = 0;
|
JavaVM *JNI::_vm = 0;
|
||||||
jobject JNI::_jobj = 0;
|
jobject JNI::_jobj = 0;
|
||||||
|
|
||||||
|
Common::Archive *JNI::_asset_archive = 0;
|
||||||
OSystem_Android *JNI::_system = 0;
|
OSystem_Android *JNI::_system = 0;
|
||||||
|
|
||||||
jfieldID JNI::_FID_Event_type = 0;
|
jfieldID JNI::_FID_Event_type = 0;
|
||||||
|
@ -51,6 +53,17 @@ jfieldID JNI::_FID_Event_mouse_y = 0;
|
||||||
jfieldID JNI::_FID_Event_mouse_relative = 0;
|
jfieldID JNI::_FID_Event_mouse_relative = 0;
|
||||||
jfieldID JNI::_FID_ScummVM_nativeScummVM = 0;
|
jfieldID JNI::_FID_ScummVM_nativeScummVM = 0;
|
||||||
|
|
||||||
|
jmethodID JNI::_MID_displayMessageOnOSD = 0;
|
||||||
|
jmethodID JNI::_MID_setWindowCaption = 0;
|
||||||
|
jmethodID JNI::_MID_initBackend = 0;
|
||||||
|
jmethodID JNI::_MID_audioSampleRate = 0;
|
||||||
|
jmethodID JNI::_MID_showVirtualKeyboard = 0;
|
||||||
|
jmethodID JNI::_MID_getSysArchives = 0;
|
||||||
|
jmethodID JNI::_MID_getPluginDirectories = 0;
|
||||||
|
jmethodID JNI::_MID_setupScummVMSurface = 0;
|
||||||
|
jmethodID JNI::_MID_destroyScummVMSurface = 0;
|
||||||
|
jmethodID JNI::_MID_swapBuffers = 0;
|
||||||
|
|
||||||
const JNINativeMethod JNI::_natives[] = {
|
const JNINativeMethod JNI::_natives[] = {
|
||||||
{ "create", "(Landroid/content/res/AssetManager;)V",
|
{ "create", "(Landroid/content/res/AssetManager;)V",
|
||||||
(void *)JNI::create },
|
(void *)JNI::create },
|
||||||
|
@ -179,21 +192,192 @@ void JNI::throwByName(JNIEnv *env, const char *name, const char *msg) {
|
||||||
env->DeleteLocalRef(cls);
|
env->DeleteLocalRef(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calls to the dark side
|
||||||
|
|
||||||
|
int JNI::getAudioSampleRate() {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
jint sample_rate = env->CallIntMethod(_jobj, _MID_audioSampleRate);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
warning("Error finding audio sample rate - assuming 11025HZ");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
|
||||||
|
return 11025;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JNI::initBackend() {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
env->CallVoidMethod(_jobj, _MID_initBackend);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
error("Error in Java initBackend");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
|
||||||
|
// TODO now what?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JNI::getPluginDirectories(Common::FSList &dirs) {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
jobjectArray array =
|
||||||
|
(jobjectArray)env->CallObjectMethod(_jobj, _MID_getPluginDirectories);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
warning("Error finding plugin directories");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsize size = env->GetArrayLength(array);
|
||||||
|
for (jsize i = 0; i < size; ++i) {
|
||||||
|
jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
|
||||||
|
|
||||||
|
if (path_obj == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *path = env->GetStringUTFChars(path_obj, 0);
|
||||||
|
|
||||||
|
if (path == 0) {
|
||||||
|
warning("Error getting string characters from plugin directory");
|
||||||
|
|
||||||
|
env->ExceptionClear();
|
||||||
|
env->DeleteLocalRef(path_obj);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirs.push_back(Common::FSNode(path));
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(path_obj, path);
|
||||||
|
env->DeleteLocalRef(path_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JNI::setWindowCaption(const char *caption) {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
jstring java_caption = env->NewStringUTF(caption);
|
||||||
|
|
||||||
|
env->CallVoidMethod(_jobj, _MID_setWindowCaption, java_caption);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
warning("Failed to set window caption");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteLocalRef(java_caption);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JNI::displayMessageOnOSD(const char *msg) {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
jstring java_msg = env->NewStringUTF(msg);
|
||||||
|
|
||||||
|
env->CallVoidMethod(_jobj, _MID_displayMessageOnOSD, java_msg);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
warning("Failed to display OSD message");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteLocalRef(java_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JNI::showVirtualKeyboard(bool enable) {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
env->CallVoidMethod(_jobj, _MID_showVirtualKeyboard, enable);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
error("Error trying to show virtual keyboard");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
s.add("ASSET", _asset_archive, priority, false);
|
||||||
|
|
||||||
|
jobjectArray array =
|
||||||
|
(jobjectArray)env->CallObjectMethod(_jobj, _MID_getSysArchives);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
warning("Error finding system archive path");
|
||||||
|
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsize size = env->GetArrayLength(array);
|
||||||
|
for (jsize i = 0; i < size; ++i) {
|
||||||
|
jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
|
||||||
|
const char *path = env->GetStringUTFChars(path_obj, 0);
|
||||||
|
|
||||||
|
if (path != 0) {
|
||||||
|
s.addDirectory(path, path, priority);
|
||||||
|
env->ReleaseStringUTFChars(path_obj, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteLocalRef(path_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// natives for the dark side
|
||||||
|
|
||||||
void JNI::create(JNIEnv *env, jobject self, jobject am) {
|
void JNI::create(JNIEnv *env, jobject self, jobject am) {
|
||||||
assert(!_system);
|
assert(!_system);
|
||||||
|
|
||||||
_system = new OSystem_Android(am);
|
_asset_archive = new AndroidAssetArchive(am);
|
||||||
|
assert(_asset_archive);
|
||||||
|
|
||||||
|
_system = new OSystem_Android();
|
||||||
assert(_system);
|
assert(_system);
|
||||||
|
|
||||||
// weak global ref to allow class to be unloaded
|
// weak global ref to allow class to be unloaded
|
||||||
// ... except dalvik implements NewWeakGlobalRef only on froyo
|
// ... except dalvik implements NewWeakGlobalRef only on froyo
|
||||||
//_jobj = env->NewWeakGlobalRef(self);
|
//_jobj = env->NewWeakGlobalRef(self);
|
||||||
_jobj = env->NewGlobalRef(self);
|
_jobj = env->NewGlobalRef(self);
|
||||||
back_ptr = _jobj;
|
|
||||||
|
|
||||||
// Exception already thrown by initJavaHooks?
|
jclass cls = env->GetObjectClass(_jobj);
|
||||||
if (!_system->initJavaHooks(env))
|
|
||||||
return;
|
#define FIND_METHOD(name, signature) do { \
|
||||||
|
_MID_ ## name = env->GetMethodID(cls, #name, signature); \
|
||||||
|
if (_MID_ ## name == 0) \
|
||||||
|
return; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
FIND_METHOD(setWindowCaption, "(Ljava/lang/String;)V");
|
||||||
|
FIND_METHOD(displayMessageOnOSD, "(Ljava/lang/String;)V");
|
||||||
|
FIND_METHOD(initBackend, "()V");
|
||||||
|
FIND_METHOD(audioSampleRate, "()I");
|
||||||
|
FIND_METHOD(showVirtualKeyboard, "(Z)V");
|
||||||
|
FIND_METHOD(getSysArchives, "()[Ljava/lang/String;");
|
||||||
|
FIND_METHOD(getPluginDirectories, "()[Ljava/lang/String;");
|
||||||
|
FIND_METHOD(setupScummVMSurface, "()V");
|
||||||
|
FIND_METHOD(destroyScummVMSurface, "()V");
|
||||||
|
FIND_METHOD(swapBuffers, "()Z");
|
||||||
|
|
||||||
|
#undef FIND_METHOD
|
||||||
|
|
||||||
env->SetLongField(self, _FID_ScummVM_nativeScummVM, (jlong)_system);
|
env->SetLongField(self, _FID_ScummVM_nativeScummVM, (jlong)_system);
|
||||||
|
|
||||||
|
@ -208,6 +392,9 @@ void JNI::destroy(JNIEnv *env, jobject self) {
|
||||||
_system = 0;
|
_system = 0;
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
|
delete _asset_archive;
|
||||||
|
_asset_archive = 0;
|
||||||
|
|
||||||
// see above
|
// see above
|
||||||
//JNI::getEnv()->DeleteWeakGlobalRef(_jobj);
|
//JNI::getEnv()->DeleteWeakGlobalRef(_jobj);
|
||||||
JNI::getEnv()->DeleteGlobalRef(_jobj);
|
JNI::getEnv()->DeleteGlobalRef(_jobj);
|
||||||
|
|
|
@ -30,11 +30,16 @@
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
extern jobject back_ptr;
|
#include "common/fs.h"
|
||||||
|
#include "common/archive.h"
|
||||||
|
|
||||||
class OSystem_Android;
|
class OSystem_Android;
|
||||||
|
|
||||||
class JNI {
|
class JNI {
|
||||||
|
private:
|
||||||
|
JNI();
|
||||||
|
virtual ~JNI();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static jint onLoad(JavaVM *vm);
|
static jint onLoad(JavaVM *vm);
|
||||||
|
|
||||||
|
@ -43,14 +48,24 @@ public:
|
||||||
static void attachThread();
|
static void attachThread();
|
||||||
static void detachThread();
|
static void detachThread();
|
||||||
|
|
||||||
private:
|
static int getAudioSampleRate();
|
||||||
JNI();
|
static void initBackend();
|
||||||
virtual ~JNI();
|
static void getPluginDirectories(Common::FSList &dirs);
|
||||||
|
static void setWindowCaption(const char *caption);
|
||||||
|
static void displayMessageOnOSD(const char *msg);
|
||||||
|
static void showVirtualKeyboard(bool enable);
|
||||||
|
static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
|
||||||
|
|
||||||
|
static inline bool setupSurface();
|
||||||
|
static inline void destroySurface();
|
||||||
|
static inline bool swapBuffers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static JavaVM *_vm;
|
static JavaVM *_vm;
|
||||||
// back pointer to (java) peer instance
|
// back pointer to (java) peer instance
|
||||||
static jobject _jobj;
|
static jobject _jobj;
|
||||||
|
|
||||||
|
static Common::Archive *_asset_archive;
|
||||||
static OSystem_Android *_system;
|
static OSystem_Android *_system;
|
||||||
|
|
||||||
static jfieldID _FID_Event_type;
|
static jfieldID _FID_Event_type;
|
||||||
|
@ -63,6 +78,17 @@ private:
|
||||||
static jfieldID _FID_Event_mouse_relative;
|
static jfieldID _FID_Event_mouse_relative;
|
||||||
static jfieldID _FID_ScummVM_nativeScummVM;
|
static jfieldID _FID_ScummVM_nativeScummVM;
|
||||||
|
|
||||||
|
static jmethodID _MID_displayMessageOnOSD;
|
||||||
|
static jmethodID _MID_setWindowCaption;
|
||||||
|
static jmethodID _MID_initBackend;
|
||||||
|
static jmethodID _MID_audioSampleRate;
|
||||||
|
static jmethodID _MID_showVirtualKeyboard;
|
||||||
|
static jmethodID _MID_getSysArchives;
|
||||||
|
static jmethodID _MID_getPluginDirectories;
|
||||||
|
static jmethodID _MID_setupScummVMSurface;
|
||||||
|
static jmethodID _MID_destroyScummVMSurface;
|
||||||
|
static jmethodID _MID_swapBuffers;
|
||||||
|
|
||||||
static const JNINativeMethod _natives[];
|
static const JNINativeMethod _natives[];
|
||||||
|
|
||||||
static void throwByName(JNIEnv *env, const char *name, const char *msg);
|
static void throwByName(JNIEnv *env, const char *name, const char *msg);
|
||||||
|
@ -82,6 +108,26 @@ private:
|
||||||
jint height);
|
jint height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool JNI::setupSurface() {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
env->CallVoidMethod(_jobj, _MID_setupScummVMSurface);
|
||||||
|
|
||||||
|
return !env->ExceptionCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void JNI::destroySurface() {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
env->CallVoidMethod(_jobj, _MID_destroyScummVMSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool JNI::swapBuffers() {
|
||||||
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
return env->CallBooleanMethod(_jobj, _MID_swapBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue