mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-02 08:55:45 +00:00
ANDROID: Merge few files between android and android3d (#2595)
While unfortunately it doesn't help with existing differences it help to prevent their increase
This commit is contained in:
parent
2dc72c3158
commit
e07fc52767
@ -132,15 +132,23 @@ int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) con
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
AAssetDir *dir = AAssetManager_openDir(_am, "");
|
||||
const char *file = AAssetDir_getNextFileName(dir);
|
||||
Common::List<Common::String> dirs;
|
||||
dirs.push_back("");
|
||||
#ifdef BACKEND_ANDROID3D
|
||||
// ResidualVM specific: multiple directories
|
||||
dirs.push_back("shaders");
|
||||
#endif
|
||||
for (const auto& currentDir : dirs) {
|
||||
AAssetDir *dir = AAssetManager_openDir(_am, "");
|
||||
const char *file = AAssetDir_getNextFileName(dir);
|
||||
|
||||
while (file) {
|
||||
member_list.push_back(getMember(file));
|
||||
++count;
|
||||
file = AAssetDir_getNextFileName(dir);
|
||||
while (file) {
|
||||
member_list.push_back(getMember(currentDir + Common::String(file)));
|
||||
++count;
|
||||
file = AAssetDir_getNextFileName(dir);
|
||||
}
|
||||
AAssetDir_close(dir);
|
||||
}
|
||||
AAssetDir_close(dir);
|
||||
|
||||
_cachedMembers = Common::ArchiveMemberList(member_list);
|
||||
_hasCached = true;
|
||||
|
@ -137,7 +137,11 @@ jint JNI::onLoad(JavaVM *vm) {
|
||||
if (_vm->GetEnv((void **)&env, JNI_VERSION_1_2))
|
||||
return JNI_ERR;
|
||||
|
||||
#ifdef BACKEND_ANDROID3D
|
||||
jclass cls = env->FindClass("org/residualvm/residualvm/ResidualVM");
|
||||
#else
|
||||
jclass cls = env->FindClass("org/scummvm/scummvm/ScummVM");
|
||||
#endif
|
||||
if (cls == 0)
|
||||
return JNI_ERR;
|
||||
|
||||
@ -732,10 +736,12 @@ void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
|
||||
else
|
||||
JNI::_pauseToken.clear();
|
||||
|
||||
/*if (value &&
|
||||
#ifdef BACKEND_ANDROID3D
|
||||
if (value &&
|
||||
g_engine->hasFeature(Engine::kSupportsSavingDuringRuntime) &&
|
||||
g_engine->canSaveGameStateCurrently())
|
||||
g_engine->saveGameState(0, "Android parachute");*/
|
||||
g_engine->saveGameState(0, "Android parachute");
|
||||
#endif
|
||||
}
|
||||
|
||||
pause = value;
|
||||
|
@ -1,168 +1,2 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/util.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "backends/platform/android3d/jni-android.h"
|
||||
#include "backends/platform/android3d/asset-archive.h"
|
||||
|
||||
#include <android/asset_manager.h>
|
||||
#include <android/asset_manager_jni.h>
|
||||
|
||||
class AssetInputStream : public Common::SeekableReadStream {
|
||||
public:
|
||||
AssetInputStream(AAssetManager *as, const Common::String &path);
|
||||
virtual ~AssetInputStream();
|
||||
|
||||
virtual bool eos() const { return _eos; }
|
||||
|
||||
virtual void clearErr() {_eos = false; }
|
||||
|
||||
virtual uint32 read(void *dataPtr, uint32 dataSize);
|
||||
|
||||
virtual int32 pos() const { return _pos; }
|
||||
|
||||
virtual int32 size() const { return _len; }
|
||||
|
||||
virtual bool seek(int32 offset, int whence = SEEK_SET);
|
||||
|
||||
private:
|
||||
void close();
|
||||
AAsset *_asset;
|
||||
|
||||
uint32 _pos;
|
||||
uint32 _len;
|
||||
bool _eos;
|
||||
};
|
||||
|
||||
AssetInputStream::AssetInputStream(AAssetManager *as, const Common::String &path) :
|
||||
_eos(false), _pos(0) {
|
||||
_asset = AAssetManager_open(as, path.c_str(), AASSET_MODE_RANDOM);
|
||||
_len = AAsset_getLength(_asset);
|
||||
}
|
||||
|
||||
AssetInputStream::~AssetInputStream() {
|
||||
if (_asset != NULL) {
|
||||
AAsset_close(_asset);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetInputStream::close() {
|
||||
AAsset_close(_asset);
|
||||
}
|
||||
|
||||
uint32 AssetInputStream::read(void *dataPtr, uint32 dataSize) {
|
||||
uint32 readlen = AAsset_read(_asset, dataPtr, dataSize);
|
||||
_pos += readlen;
|
||||
if (readlen != dataSize) {
|
||||
_eos = true;
|
||||
}
|
||||
return readlen;
|
||||
}
|
||||
|
||||
bool AssetInputStream::seek(int32 offset, int whence) {
|
||||
int res = AAsset_seek(_asset, offset, whence);
|
||||
if (res == -1) {
|
||||
return false;
|
||||
}
|
||||
if (whence == SEEK_CUR) {
|
||||
_pos += offset;
|
||||
} else if (whence == SEEK_SET) {
|
||||
_pos = offset;
|
||||
} else if (whence == SEEK_END) {
|
||||
_pos = _len + offset;
|
||||
}
|
||||
assert(_pos <= _len);
|
||||
_eos = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
AndroidAssetArchive::AndroidAssetArchive(jobject am) : _hasCached(false) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
_am = AAssetManager_fromJava(env, am);
|
||||
}
|
||||
|
||||
AndroidAssetArchive::~AndroidAssetArchive() {
|
||||
}
|
||||
|
||||
bool AndroidAssetArchive::hasFile(const Common::String &name) const {
|
||||
AAsset *asset = AAssetManager_open(_am, name.c_str(), AASSET_MODE_RANDOM);
|
||||
bool exists = false;
|
||||
if (asset != NULL) {
|
||||
exists = true;
|
||||
AAsset_close(asset);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) const {
|
||||
if (_hasCached) {
|
||||
member_list.insert(member_list.end(), _cachedMembers.begin(), _cachedMembers.end());
|
||||
return _cachedMembers.size();
|
||||
}
|
||||
|
||||
// ResidualVM specific: multiple directories
|
||||
Common::List<Common::String> dirs;
|
||||
dirs.push_back("");
|
||||
dirs.push_back("shaders");
|
||||
int count = 0;
|
||||
for (const auto& currentDir : dirs) {
|
||||
AAssetDir *dir = AAssetManager_openDir(_am, "");
|
||||
const char *file = AAssetDir_getNextFileName(dir);
|
||||
|
||||
while (file) {
|
||||
member_list.push_back(getMember(currentDir + Common::String(file)));
|
||||
++count;
|
||||
file = AAssetDir_getNextFileName(dir);
|
||||
}
|
||||
AAssetDir_close(dir);
|
||||
}
|
||||
|
||||
_cachedMembers = Common::ArchiveMemberList(member_list);
|
||||
_hasCached = true;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
const Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &name) const {
|
||||
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *AndroidAssetArchive::createReadStreamForMember(const Common::String &path) const {
|
||||
if (!hasFile(path)) {
|
||||
return nullptr;
|
||||
}
|
||||
return new AssetInputStream(_am, path);
|
||||
}
|
||||
|
||||
#endif
|
||||
#define BACKEND_ANDROID3D
|
||||
#include "../android/asset-archive.cpp"
|
||||
|
@ -1,54 +1 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_ASSET_H_
|
||||
#define _ANDROID_ASSET_H_
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/util.h"
|
||||
#include "common/archive.h"
|
||||
|
||||
#include <android/asset_manager.h>
|
||||
|
||||
class AndroidAssetArchive : public Common::Archive {
|
||||
public:
|
||||
AndroidAssetArchive(jobject am);
|
||||
virtual ~AndroidAssetArchive();
|
||||
|
||||
virtual bool hasFile(const Common::String &name) const;
|
||||
virtual int listMembers(Common::ArchiveMemberList &list) const;
|
||||
virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
|
||||
virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
|
||||
|
||||
private:
|
||||
AAssetManager *_am;
|
||||
mutable Common::ArchiveMemberList _cachedMembers;
|
||||
mutable bool _hasCached;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#include "../android/asset-archive.h"
|
||||
|
@ -1,855 +1,2 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
// Allow use of stuff in <time.h> and abort()
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_abort
|
||||
|
||||
// Disable printf override in common/forbidden.h to avoid
|
||||
// clashes with log.h from the Android SDK.
|
||||
// That header file uses
|
||||
// __attribute__ ((format(printf, 3, 4)))
|
||||
// which gets messed up by our override mechanism; this could
|
||||
// be avoided by either changing the Android SDK to use the equally
|
||||
// legal and valid
|
||||
// __attribute__ ((format(printf, 3, 4)))
|
||||
// or by refining our printf override to use a varadic macro
|
||||
// (which then wouldn't be portable, though).
|
||||
// Anyway, for now we just disable the printf override globally
|
||||
// for the Android port
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
|
||||
|
||||
#include "base/main.h"
|
||||
#include "base/version.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/error.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/translation.h"
|
||||
#include "common/encoding.h"
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "backends/platform/android3d/android.h"
|
||||
#include "backends/platform/android3d/asset-archive.h"
|
||||
#include "backends/platform/android3d/jni-android.h"
|
||||
|
||||
__attribute__ ((visibility("default")))
|
||||
jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return JNI::onLoad(vm);
|
||||
}
|
||||
|
||||
JavaVM *JNI::_vm = 0;
|
||||
jobject JNI::_jobj = 0;
|
||||
jobject JNI::_jobj_audio_track = 0;
|
||||
jobject JNI::_jobj_egl = 0;
|
||||
jobject JNI::_jobj_egl_display = 0;
|
||||
jobject JNI::_jobj_egl_surface = 0;
|
||||
|
||||
Common::Archive *JNI::_asset_archive = 0;
|
||||
OSystem_Android *JNI::_system = 0;
|
||||
|
||||
bool JNI::pause = false;
|
||||
sem_t JNI::pause_sem = { 0 };
|
||||
|
||||
int JNI::surface_changeid = 0;
|
||||
int JNI::egl_surface_width = 0;
|
||||
int JNI::egl_surface_height = 0;
|
||||
bool JNI::_ready_for_events = 0;
|
||||
|
||||
jmethodID JNI::_MID_getDPI = 0;
|
||||
jmethodID JNI::_MID_displayMessageOnOSD = 0;
|
||||
jmethodID JNI::_MID_openUrl = 0;
|
||||
jmethodID JNI::_MID_hasTextInClipboard = 0;
|
||||
jmethodID JNI::_MID_getTextFromClipboard = 0;
|
||||
jmethodID JNI::_MID_setTextInClipboard = 0;
|
||||
jmethodID JNI::_MID_isConnectionLimited = 0;
|
||||
jmethodID JNI::_MID_setWindowCaption = 0;
|
||||
jmethodID JNI::_MID_showVirtualKeyboard = 0;
|
||||
jmethodID JNI::_MID_showKeyboardControl = 0;
|
||||
jmethodID JNI::_MID_getSysArchives = 0;
|
||||
jmethodID JNI::_MID_convertEncoding = 0;
|
||||
jmethodID JNI::_MID_getAllStorageLocations = 0;
|
||||
jmethodID JNI::_MID_initSurface = 0;
|
||||
jmethodID JNI::_MID_deinitSurface = 0;
|
||||
jmethodID JNI::_MID_createDirectoryWithSAF = 0;
|
||||
jmethodID JNI::_MID_createFileWithSAF = 0;
|
||||
jmethodID JNI::_MID_closeFileWithSAF = 0;
|
||||
|
||||
jmethodID JNI::_MID_EGL10_eglSwapBuffers = 0;
|
||||
|
||||
jmethodID JNI::_MID_AudioTrack_flush = 0;
|
||||
jmethodID JNI::_MID_AudioTrack_pause = 0;
|
||||
jmethodID JNI::_MID_AudioTrack_play = 0;
|
||||
jmethodID JNI::_MID_AudioTrack_stop = 0;
|
||||
jmethodID JNI::_MID_AudioTrack_write = 0;
|
||||
|
||||
PauseToken JNI::_pauseToken;
|
||||
|
||||
const JNINativeMethod JNI::_natives[] = {
|
||||
{ "create", "(Landroid/content/res/AssetManager;"
|
||||
"Ljavax/microedition/khronos/egl/EGL10;"
|
||||
"Ljavax/microedition/khronos/egl/EGLDisplay;"
|
||||
"Landroid/media/AudioTrack;II)V",
|
||||
(void *)JNI::create },
|
||||
{ "destroy", "()V",
|
||||
(void *)JNI::destroy },
|
||||
{ "setSurface", "(II)V",
|
||||
(void *)JNI::setSurface },
|
||||
{ "main", "([Ljava/lang/String;)I",
|
||||
(void *)JNI::main },
|
||||
{ "pushEvent", "(IIIIIII)V",
|
||||
(void *)JNI::pushEvent },
|
||||
{ "setPause", "(Z)V",
|
||||
(void *)JNI::setPause }
|
||||
};
|
||||
|
||||
JNI::JNI() {
|
||||
}
|
||||
|
||||
JNI::~JNI() {
|
||||
}
|
||||
|
||||
jint JNI::onLoad(JavaVM *vm) {
|
||||
_vm = vm;
|
||||
|
||||
JNIEnv *env;
|
||||
|
||||
if (_vm->GetEnv((void **)&env, JNI_VERSION_1_2))
|
||||
return JNI_ERR;
|
||||
|
||||
jclass cls = env->FindClass("org/residualvm/residualvm/ResidualVM");
|
||||
if (cls == 0)
|
||||
return JNI_ERR;
|
||||
|
||||
if (env->RegisterNatives(cls, _natives, ARRAYSIZE(_natives)) < 0)
|
||||
return JNI_ERR;
|
||||
|
||||
return JNI_VERSION_1_2;
|
||||
}
|
||||
|
||||
JNIEnv *JNI::getEnv() {
|
||||
JNIEnv *env = 0;
|
||||
|
||||
jint res = _vm->GetEnv((void **)&env, JNI_VERSION_1_2);
|
||||
|
||||
if (res != JNI_OK) {
|
||||
LOGE("GetEnv() failed: %d", res);
|
||||
abort();
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
void JNI::attachThread() {
|
||||
JNIEnv *env = 0;
|
||||
|
||||
jint res = _vm->AttachCurrentThread(&env, 0);
|
||||
|
||||
if (res != JNI_OK) {
|
||||
LOGE("AttachCurrentThread() failed: %d", res);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void JNI::detachThread() {
|
||||
jint res = _vm->DetachCurrentThread();
|
||||
|
||||
if (res != JNI_OK) {
|
||||
LOGE("DetachCurrentThread() failed: %d", res);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void JNI::setReadyForEvents(bool ready) {
|
||||
_ready_for_events = ready;
|
||||
}
|
||||
|
||||
void JNI::throwByName(JNIEnv *env, const char *name, const char *msg) {
|
||||
jclass cls = env->FindClass(name);
|
||||
|
||||
// if cls is 0, an exception has already been thrown
|
||||
if (cls != 0)
|
||||
env->ThrowNew(cls, msg);
|
||||
|
||||
env->DeleteLocalRef(cls);
|
||||
}
|
||||
|
||||
void JNI::throwRuntimeException(JNIEnv *env, const char *msg) {
|
||||
throwByName(env, "java/lang/RuntimeException", msg);
|
||||
}
|
||||
|
||||
// calls to the dark side
|
||||
|
||||
void JNI::getDPI(float *values) {
|
||||
values[0] = 0.0;
|
||||
values[1] = 0.0;
|
||||
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
jfloatArray array = env->NewFloatArray(2);
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_getDPI, array);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to get DPIs");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
} else {
|
||||
jfloat *res = env->GetFloatArrayElements(array, 0);
|
||||
|
||||
if (res) {
|
||||
values[0] = res[0];
|
||||
values[1] = res[1];
|
||||
|
||||
env->ReleaseFloatArrayElements(array, res, 0);
|
||||
}
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(array);
|
||||
}
|
||||
|
||||
void JNI::displayMessageOnOSD(const Common::U32String &msg) {
|
||||
// called from common/osd_message_queue, method: OSDMessageQueue::pollEvent()
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
jstring java_msg = convertToJString(env, msg.encode(), "UTF-8");
|
||||
if (java_msg == nullptr) {
|
||||
// Show a placeholder indicative of the translation error instead of silent failing
|
||||
java_msg = env->NewStringUTF("?");
|
||||
LOGE("Failed to convert message to UTF-8 for OSD!");
|
||||
}
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_displayMessageOnOSD, java_msg);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to display OSD message");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(java_msg);
|
||||
}
|
||||
|
||||
bool JNI::openUrl(const Common::String &url) {
|
||||
bool success = true;
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
jstring javaUrl = env->NewStringUTF(url.c_str());
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_openUrl, javaUrl);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to open URL");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
success = false;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(javaUrl);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool JNI::hasTextInClipboard() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
bool hasText = env->CallBooleanMethod(_jobj, _MID_hasTextInClipboard);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to check the contents of the clipboard");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
hasText = true;
|
||||
}
|
||||
|
||||
return hasText;
|
||||
}
|
||||
|
||||
Common::U32String JNI::getTextFromClipboard() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
jstring javaText = (jstring)env->CallObjectMethod(_jobj, _MID_getTextFromClipboard);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to retrieve text from the clipboard");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
|
||||
return Common::U32String();
|
||||
}
|
||||
|
||||
Common::String text = convertFromJString(env, javaText, "UTF-8");
|
||||
env->DeleteLocalRef(javaText);
|
||||
|
||||
return text.decode();
|
||||
}
|
||||
|
||||
bool JNI::setTextInClipboard(const Common::U32String &text) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
jstring javaText = convertToJString(env, text.encode(), "UTF-8");
|
||||
|
||||
bool success = env->CallBooleanMethod(_jobj, _MID_setTextInClipboard, javaText);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to add text to the clipboard");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
success = false;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(javaText);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool JNI::isConnectionLimited() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
bool limited = env->CallBooleanMethod(_jobj, _MID_isConnectionLimited);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to check whether connection's limited");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
limited = true;
|
||||
}
|
||||
|
||||
return limited;
|
||||
}
|
||||
|
||||
void JNI::setWindowCaption(const Common::String &caption) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
jstring java_caption = convertToJString(env, caption, "ISO-8859-1");
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_setWindowCaption, java_caption);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Failed to set window caption");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(java_caption);
|
||||
}
|
||||
|
||||
void JNI::showVirtualKeyboard(bool enable) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_showVirtualKeyboard, enable);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error trying to show virtual keyboard");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
void JNI::showKeyboardControl(bool enable) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_showKeyboardControl, enable);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error trying to show virtual keyboard control");
|
||||
|
||||
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()) {
|
||||
LOGE("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);
|
||||
}
|
||||
}
|
||||
|
||||
char *JNI::convertEncoding(const char *to, const char *from, const char *string, size_t length) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
jstring javaTo = env->NewStringUTF(to);
|
||||
jstring javaFrom = env->NewStringUTF(from);
|
||||
jbyteArray javaString = env->NewByteArray(length);
|
||||
env->SetByteArrayRegion(javaString, 0, length, reinterpret_cast<const jbyte*>(string));
|
||||
|
||||
jbyteArray javaOut = (jbyteArray)env->CallObjectMethod(_jobj, _MID_convertEncoding, javaTo, javaFrom, javaString);
|
||||
|
||||
if (!javaOut || env->ExceptionCheck()) {
|
||||
LOGE("Failed to convert text from %s to %s", from, to);
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int outLength = env->GetArrayLength(javaOut);
|
||||
char *buf = (char *)malloc(outLength + 1);
|
||||
if (!buf)
|
||||
return nullptr;
|
||||
|
||||
env->GetByteArrayRegion(javaOut, 0, outLength, reinterpret_cast<jbyte *>(buf));
|
||||
buf[outLength] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool JNI::initSurface() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
jobject obj = env->CallObjectMethod(_jobj, _MID_initSurface);
|
||||
|
||||
if (!obj || env->ExceptionCheck()) {
|
||||
LOGE("initSurface failed");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_jobj_egl_surface = env->NewGlobalRef(obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void JNI::deinitSurface() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_deinitSurface);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("deinitSurface failed");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
env->DeleteGlobalRef(_jobj_egl_surface);
|
||||
_jobj_egl_surface = 0;
|
||||
}
|
||||
|
||||
void JNI::setAudioPause() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_flush);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error flushing AudioTrack");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_pause);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error setting AudioTrack: pause");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
void JNI::setAudioPlay() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_play);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error setting AudioTrack: play");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
void JNI::setAudioStop() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_stop);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error setting AudioTrack: stop");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
// natives for the dark side
|
||||
|
||||
void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||
jobject egl, jobject egl_display,
|
||||
jobject at, jint audio_sample_rate, jint audio_buffer_size) {
|
||||
LOGI("%s", gScummVMFullVersion);
|
||||
|
||||
assert(!_system);
|
||||
|
||||
pause = false;
|
||||
// initial value of zero!
|
||||
sem_init(&pause_sem, 0, 0);
|
||||
|
||||
_asset_archive = new AndroidAssetArchive(asset_manager);
|
||||
assert(_asset_archive);
|
||||
|
||||
_system = new OSystem_Android(audio_sample_rate, audio_buffer_size);
|
||||
assert(_system);
|
||||
|
||||
// weak global ref to allow class to be unloaded
|
||||
// ... except dalvik implements NewWeakGlobalRef only on froyo
|
||||
//_jobj = env->NewWeakGlobalRef(self);
|
||||
|
||||
_jobj = env->NewGlobalRef(self);
|
||||
|
||||
jclass cls = env->GetObjectClass(_jobj);
|
||||
|
||||
#define FIND_METHOD(prefix, name, signature) do { \
|
||||
_MID_ ## prefix ## name = env->GetMethodID(cls, #name, signature); \
|
||||
if (_MID_ ## prefix ## name == 0) \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
FIND_METHOD(, setWindowCaption, "(Ljava/lang/String;)V");
|
||||
FIND_METHOD(, getDPI, "([F)V");
|
||||
FIND_METHOD(, displayMessageOnOSD, "(Ljava/lang/String;)V");
|
||||
FIND_METHOD(, openUrl, "(Ljava/lang/String;)V");
|
||||
FIND_METHOD(, hasTextInClipboard, "()Z");
|
||||
FIND_METHOD(, getTextFromClipboard, "()Ljava/lang/String;");
|
||||
FIND_METHOD(, setTextInClipboard, "(Ljava/lang/String;)Z");
|
||||
FIND_METHOD(, isConnectionLimited, "()Z");
|
||||
FIND_METHOD(, showVirtualKeyboard, "(Z)V");
|
||||
FIND_METHOD(, showKeyboardControl, "(Z)V");
|
||||
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
|
||||
FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
|
||||
FIND_METHOD(, convertEncoding, "(Ljava/lang/String;Ljava/lang/String;[B)[B");
|
||||
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
|
||||
FIND_METHOD(, deinitSurface, "()V");
|
||||
FIND_METHOD(, createDirectoryWithSAF, "(Ljava/lang/String;)Z");
|
||||
FIND_METHOD(, createFileWithSAF, "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
FIND_METHOD(, closeFileWithSAF, "(Ljava/lang/String;)V");
|
||||
|
||||
_jobj_egl = env->NewGlobalRef(egl);
|
||||
_jobj_egl_display = env->NewGlobalRef(egl_display);
|
||||
|
||||
cls = env->GetObjectClass(_jobj_egl);
|
||||
|
||||
FIND_METHOD(EGL10_, eglSwapBuffers,
|
||||
"(Ljavax/microedition/khronos/egl/EGLDisplay;"
|
||||
"Ljavax/microedition/khronos/egl/EGLSurface;)Z");
|
||||
|
||||
_jobj_audio_track = env->NewGlobalRef(at);
|
||||
|
||||
cls = env->GetObjectClass(_jobj_audio_track);
|
||||
|
||||
FIND_METHOD(AudioTrack_, flush, "()V");
|
||||
FIND_METHOD(AudioTrack_, pause, "()V");
|
||||
FIND_METHOD(AudioTrack_, play, "()V");
|
||||
FIND_METHOD(AudioTrack_, stop, "()V");
|
||||
FIND_METHOD(AudioTrack_, write, "([BII)I");
|
||||
|
||||
#undef FIND_METHOD
|
||||
|
||||
g_system = _system;
|
||||
}
|
||||
|
||||
void JNI::destroy(JNIEnv *env, jobject self) {
|
||||
delete _asset_archive;
|
||||
_asset_archive = 0;
|
||||
|
||||
// _system is a pointer of OSystem_Android <--- ModularBackend <--- BaseBacked <--- Common::OSystem
|
||||
// It's better to call destroy() rather than just delete here
|
||||
// to avoid mutex issues if a Common::String is used after this point
|
||||
_system->destroy();
|
||||
|
||||
g_system = 0;
|
||||
_system = 0;
|
||||
|
||||
sem_destroy(&pause_sem);
|
||||
|
||||
// see above
|
||||
//JNI::getEnv()->DeleteWeakGlobalRef(_jobj);
|
||||
|
||||
JNI::getEnv()->DeleteGlobalRef(_jobj_egl_display);
|
||||
JNI::getEnv()->DeleteGlobalRef(_jobj_egl);
|
||||
JNI::getEnv()->DeleteGlobalRef(_jobj_audio_track);
|
||||
JNI::getEnv()->DeleteGlobalRef(_jobj);
|
||||
}
|
||||
|
||||
void JNI::setSurface(JNIEnv *env, jobject self, jint width, jint height) {
|
||||
egl_surface_width = width;
|
||||
egl_surface_height = height;
|
||||
surface_changeid++;
|
||||
}
|
||||
|
||||
jint JNI::main(JNIEnv *env, jobject self, jobjectArray args) {
|
||||
assert(_system);
|
||||
|
||||
const int MAX_NARGS = 32;
|
||||
int res = -1;
|
||||
|
||||
int argc = env->GetArrayLength(args);
|
||||
if (argc > MAX_NARGS) {
|
||||
throwByName(env, "java/lang/IllegalArgumentException",
|
||||
"too many arguments");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *argv[MAX_NARGS];
|
||||
|
||||
// note use in cleanup loop below
|
||||
int nargs;
|
||||
|
||||
for (nargs = 0; nargs < argc; ++nargs) {
|
||||
jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);
|
||||
|
||||
if (arg == 0) {
|
||||
argv[nargs] = 0;
|
||||
} else {
|
||||
const char *cstr = env->GetStringUTFChars(arg, 0);
|
||||
|
||||
argv[nargs] = const_cast<char *>(cstr);
|
||||
|
||||
// exception already thrown?
|
||||
if (cstr == 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
|
||||
LOGI("Entering scummvm_main with %d args", argc);
|
||||
|
||||
res = scummvm_main(argc, argv);
|
||||
|
||||
LOGI("scummvm_main exited with code %d", res);
|
||||
|
||||
_system->quit();
|
||||
|
||||
cleanup:
|
||||
nargs--;
|
||||
|
||||
for (int i = 0; i < nargs; ++i) {
|
||||
if (argv[i] == 0)
|
||||
continue;
|
||||
|
||||
jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);
|
||||
|
||||
// Exception already thrown?
|
||||
if (arg == 0)
|
||||
return res;
|
||||
|
||||
env->ReleaseStringUTFChars(arg, argv[i]);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void JNI::pushEvent(JNIEnv *env, jobject self, int type, int arg1, int arg2,
|
||||
int arg3, int arg4, int arg5, int arg6) {
|
||||
// drop events until we're ready and after we quit
|
||||
if (!_ready_for_events) {
|
||||
LOGW("dropping event");
|
||||
return;
|
||||
}
|
||||
|
||||
assert(_system);
|
||||
|
||||
_system->pushEvent(type, arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
|
||||
void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
|
||||
if (!_system)
|
||||
return;
|
||||
|
||||
if (g_engine) {
|
||||
LOGD("pauseEngine: %d", value);
|
||||
|
||||
if (value)
|
||||
JNI::_pauseToken = g_engine->pauseEngine();
|
||||
else
|
||||
JNI::_pauseToken.clear();
|
||||
|
||||
if (value &&
|
||||
g_engine->hasFeature(Engine::kSupportsSavingDuringRuntime) &&
|
||||
g_engine->canSaveGameStateCurrently())
|
||||
g_engine->saveGameState(0, "Android parachute");
|
||||
}
|
||||
|
||||
pause = value;
|
||||
|
||||
if (!pause) {
|
||||
// wake up all threads
|
||||
for (uint i = 0; i < 3; ++i)
|
||||
sem_post(&pause_sem);
|
||||
}
|
||||
}
|
||||
|
||||
jstring JNI::convertToJString(JNIEnv *env, const Common::String &str, const Common::String &from) {
|
||||
Common::Encoding converter("UTF-8", from.c_str());
|
||||
char *utf8Str = converter.convert(str.c_str(), converter.stringLength(str.c_str(), from));
|
||||
if (utf8Str == nullptr)
|
||||
return nullptr;
|
||||
|
||||
jstring jstr = env->NewStringUTF(utf8Str);
|
||||
free(utf8Str);
|
||||
|
||||
return jstr;
|
||||
}
|
||||
|
||||
Common::String JNI::convertFromJString(JNIEnv *env, const jstring &jstr, const Common::String &to) {
|
||||
const char *utf8Str = env->GetStringUTFChars(jstr, 0);
|
||||
if (!utf8Str)
|
||||
return Common::String();
|
||||
|
||||
Common::Encoding converter(to.c_str(), "UTF-8");
|
||||
char *asciiStr = converter.convert(utf8Str, env->GetStringUTFLength(jstr));
|
||||
env->ReleaseStringUTFChars(jstr, utf8Str);
|
||||
|
||||
Common::String str(asciiStr);
|
||||
free(asciiStr);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
Common::Array<Common::String> JNI::getAllStorageLocations() {
|
||||
Common::Array<Common::String> *res = new Common::Array<Common::String>();
|
||||
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
jobjectArray array =
|
||||
(jobjectArray)env->CallObjectMethod(_jobj, _MID_getAllStorageLocations);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("Error finding system archive path");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
|
||||
return *res;
|
||||
}
|
||||
|
||||
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) {
|
||||
res->push_back(path);
|
||||
env->ReleaseStringUTFChars(path_obj, path);
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(path_obj);
|
||||
}
|
||||
|
||||
return *res;
|
||||
}
|
||||
|
||||
bool JNI::createDirectoryWithSAF(const Common::String &dirPath) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
jstring javaDirPath = env->NewStringUTF(dirPath.c_str());
|
||||
|
||||
bool created = env->CallBooleanMethod(_jobj, _MID_createDirectoryWithSAF, javaDirPath);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("JNI - Failed to create directory with SAF enhanced method");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
created = false;
|
||||
}
|
||||
|
||||
return created;
|
||||
|
||||
}
|
||||
|
||||
Common::String JNI::createFileWithSAF(const Common::String &filePath) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
jstring javaFilePath = env->NewStringUTF(filePath.c_str());
|
||||
|
||||
jstring hackyFilenameJSTR = (jstring)env->CallObjectMethod(_jobj, _MID_createFileWithSAF, javaFilePath);
|
||||
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("JNI - Failed to create file with SAF enhanced method");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
hackyFilenameJSTR = env->NewStringUTF("");
|
||||
}
|
||||
|
||||
Common::String hackyFilenameStr = convertFromJString(env, hackyFilenameJSTR, "UTF-8");
|
||||
|
||||
//LOGD("JNI - _MID_createFileWithSAF returned %s", hackyFilenameStr.c_str());
|
||||
env->DeleteLocalRef(hackyFilenameJSTR);
|
||||
|
||||
return hackyFilenameStr;
|
||||
|
||||
}
|
||||
|
||||
void JNI::closeFileWithSAF(const Common::String &hackyFilename) {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
jstring javaHackyFilename = env->NewStringUTF(hackyFilename.c_str());
|
||||
|
||||
env->CallVoidMethod(_jobj, _MID_closeFileWithSAF, javaHackyFilename);
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
LOGE("JNI - Failed to close file with SAF enhanced method");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#define BACKEND_ANDROID3D
|
||||
#include "../android/jni-android.cpp"
|
||||
|
@ -1,175 +1 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_JNI_H_
|
||||
#define _ANDROID_JNI_H_
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include <jni.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "common/fs.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/array.h"
|
||||
#include "common/ustr.h"
|
||||
#include "engines/engine.h"
|
||||
|
||||
class OSystem_Android;
|
||||
|
||||
class JNI {
|
||||
private:
|
||||
JNI();
|
||||
virtual ~JNI();
|
||||
|
||||
public:
|
||||
static bool pause;
|
||||
static sem_t pause_sem;
|
||||
|
||||
static int surface_changeid;
|
||||
static int egl_surface_width;
|
||||
static int egl_surface_height;
|
||||
|
||||
static jint onLoad(JavaVM *vm);
|
||||
|
||||
static JNIEnv *getEnv();
|
||||
|
||||
static void attachThread();
|
||||
static void detachThread();
|
||||
|
||||
static void setReadyForEvents(bool ready);
|
||||
|
||||
static void setWindowCaption(const Common::String &caption);
|
||||
static void getDPI(float *values);
|
||||
static void displayMessageOnOSD(const Common::U32String &msg);
|
||||
static bool openUrl(const Common::String &url);
|
||||
static bool hasTextInClipboard();
|
||||
static Common::U32String getTextFromClipboard();
|
||||
static bool setTextInClipboard(const Common::U32String &text);
|
||||
static bool isConnectionLimited();
|
||||
static void showVirtualKeyboard(bool enable);
|
||||
static void showKeyboardControl(bool enable);
|
||||
static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
|
||||
static char *convertEncoding(const char *to, const char *from, const char *string, size_t length);
|
||||
|
||||
static inline bool haveSurface();
|
||||
static inline bool swapBuffers();
|
||||
static bool initSurface();
|
||||
static void deinitSurface();
|
||||
|
||||
static void setAudioPause();
|
||||
static void setAudioPlay();
|
||||
static void setAudioStop();
|
||||
|
||||
static inline int writeAudio(JNIEnv *env, jbyteArray &data, int offset,
|
||||
int size);
|
||||
|
||||
static Common::Array<Common::String> getAllStorageLocations();
|
||||
|
||||
static bool createDirectoryWithSAF(const Common::String &dirPath);
|
||||
static Common::String createFileWithSAF(const Common::String &filePath);
|
||||
static void closeFileWithSAF(const Common::String &hackyFilename);
|
||||
|
||||
private:
|
||||
static JavaVM *_vm;
|
||||
// back pointer to (java) peer instance
|
||||
static jobject _jobj;
|
||||
static jobject _jobj_audio_track;
|
||||
static jobject _jobj_egl;
|
||||
static jobject _jobj_egl_display;
|
||||
static jobject _jobj_egl_surface;
|
||||
|
||||
static Common::Archive *_asset_archive;
|
||||
static OSystem_Android *_system;
|
||||
|
||||
static bool _ready_for_events;
|
||||
|
||||
static jmethodID _MID_getDPI;
|
||||
static jmethodID _MID_displayMessageOnOSD;
|
||||
static jmethodID _MID_openUrl;
|
||||
static jmethodID _MID_hasTextInClipboard;
|
||||
static jmethodID _MID_getTextFromClipboard;
|
||||
static jmethodID _MID_setTextInClipboard;
|
||||
static jmethodID _MID_isConnectionLimited;
|
||||
static jmethodID _MID_setWindowCaption;
|
||||
static jmethodID _MID_showVirtualKeyboard;
|
||||
static jmethodID _MID_showKeyboardControl;
|
||||
static jmethodID _MID_getSysArchives;
|
||||
static jmethodID _MID_convertEncoding;
|
||||
static jmethodID _MID_getAllStorageLocations;
|
||||
static jmethodID _MID_initSurface;
|
||||
static jmethodID _MID_deinitSurface;
|
||||
static jmethodID _MID_createDirectoryWithSAF;
|
||||
static jmethodID _MID_createFileWithSAF;
|
||||
static jmethodID _MID_closeFileWithSAF;
|
||||
|
||||
static jmethodID _MID_EGL10_eglSwapBuffers;
|
||||
|
||||
static jmethodID _MID_AudioTrack_flush;
|
||||
static jmethodID _MID_AudioTrack_pause;
|
||||
static jmethodID _MID_AudioTrack_play;
|
||||
static jmethodID _MID_AudioTrack_stop;
|
||||
static jmethodID _MID_AudioTrack_write;
|
||||
|
||||
static const JNINativeMethod _natives[];
|
||||
|
||||
static void throwByName(JNIEnv *env, const char *name, const char *msg);
|
||||
static void throwRuntimeException(JNIEnv *env, const char *msg);
|
||||
|
||||
// natives for the dark side
|
||||
static void create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||
jobject egl, jobject egl_display,
|
||||
jobject at, jint audio_sample_rate,
|
||||
jint audio_buffer_size);
|
||||
static void destroy(JNIEnv *env, jobject self);
|
||||
|
||||
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, int type, int arg1,
|
||||
int arg2, int arg3, int arg4, int arg5, int arg6);
|
||||
static void setPause(JNIEnv *env, jobject self, jboolean value);
|
||||
|
||||
static jstring convertToJString(JNIEnv *env, const Common::String &str, const Common::String &from);
|
||||
static Common::String convertFromJString(JNIEnv *env, const jstring &jstr, const Common::String &to);
|
||||
|
||||
static PauseToken _pauseToken;
|
||||
};
|
||||
|
||||
inline bool JNI::haveSurface() {
|
||||
return _jobj_egl_surface != 0;
|
||||
}
|
||||
|
||||
inline bool JNI::swapBuffers() {
|
||||
JNIEnv *env = JNI::getEnv();
|
||||
|
||||
return env->CallBooleanMethod(_jobj_egl, _MID_EGL10_eglSwapBuffers,
|
||||
_jobj_egl_display, _jobj_egl_surface);
|
||||
}
|
||||
|
||||
inline int JNI::writeAudio(JNIEnv *env, jbyteArray &data, int offset, int size) {
|
||||
return env->CallIntMethod(_jobj_audio_track, _MID_AudioTrack_write, data,
|
||||
offset, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#include "../android/jni-android.h"
|
||||
|
@ -1,48 +1,2 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
#include "../android/portdefs.h"
|
||||
|
||||
#ifndef _PORTDEFS_H_
|
||||
#define _PORTDEFS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <new>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
// This is defined in snprintf.c
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int rpl_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define vsnprintf rpl_vsnprintf
|
||||
|
||||
#endif // _PORTDEFS_H_
|
||||
|
Loading…
x
Reference in New Issue
Block a user