Files
minecraft-pe-0.6.1/src/main_android_java.cpp
2026-03-11 11:01:29 +02:00

252 lines
7.9 KiB
C++
Executable File

#include "App.h"
#include "AppPlatform_android.h"
// JNI keycode constants
#include <android/keycodes.h>
//#include "main_android_java.h"
#include "platform/input/Multitouch.h"
#include <unistd.h>
#include <sys/syscall.h>
#define gettid() ((int)syscall(SYS_gettid))
// Horrible, I know. / A
#ifndef MAIN_CLASS
#include "main.cpp"
#endif
// References for JNI
static jobject g_pActivity = 0;
static AppPlatform_android appPlatform;
static void setupExternalPath(JNIEnv* env, MAIN_CLASS* app)
{
//JVMAttacher ta(vm);
//JNIEnv* env = ta.getEnv();
LOGI("setupExternalPath");
if (env)
{
LOGI("Environment exists");
}
jclass clazz = env->FindClass("android/os/Environment");
jmethodID method = env->GetStaticMethodID(clazz, "getExternalStorageDirectory", "()Ljava/io/File;");
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
jobject file = env->CallStaticObjectMethod(clazz, method);
jclass fileClass = env->GetObjectClass(file);
jmethodID fileMethod = env->GetMethodID(fileClass, "getAbsolutePath", "()Ljava/lang/String;");
jobject pathString = env->CallObjectMethod(file, fileMethod);
const char* str = env->GetStringUTFChars((jstring) pathString, NULL);
app->externalStoragePath = str;
app->externalCacheStoragePath = str;
LOGI("%s", str);
// same fix as the native entry point: make sure cwd is writable
if (chdir(str) != 0) {
LOGI("chdir to %s failed: %s", str, strerror(errno));
}
env->ReleaseStringUTFChars((jstring)pathString, str);
}
static void pointerDown(int pointerId, int x, int y) {
Multitouch::feed(1, 1, x, y, pointerId);
}
static void pointerUp(int pointerId, int x, int y) {
Multitouch::feed(1, 0, x, y, pointerId);
}
static void pointerMove(int pointerId, int x, int y) {
Multitouch::feed(0, 0, x, y, pointerId);
}
static App* gApp = 0;
static AppContext gContext;
static bool g_inNativeOnCreate = false;
extern "C" {
JNIEXPORT jint JNICALL
JNI_OnLoad( JavaVM * vm, void * reserved )
{
LOGI("Entering OnLoad\n");
return appPlatform.init(vm);
}
// Register/save a reference to the java main activity instance
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeRegisterThis(JNIEnv* env, jobject clazz) {
LOGI("@RegisterThis\n");
g_pActivity = (jobject)env->NewGlobalRef( clazz );
}
// Unregister/delete the reference to the java main activity instance
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeUnregisterThis(JNIEnv* env, jobject clazz) {
LOGI("@UnregisterThis\n");
env->DeleteGlobalRef( g_pActivity );
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeOnCreate(JNIEnv* env, jobject thiz, jint screenWidth, jint screenHeight) {
LOGI("@nativeOnCreate w=%d h=%d\n", (int)screenWidth, (int)screenHeight);
g_inNativeOnCreate = true;
appPlatform.instance = g_pActivity;
appPlatform.setScreenDimensions((int)screenWidth, (int)screenHeight);
LOGI("nativeOnCreate: screen set, no initConsts needed\n");
gContext.doRender = false;
gContext.platform = &appPlatform;
LOGI("nativeOnCreate: creating gApp\n");
gApp = new MAIN_CLASS();
LOGI("nativeOnCreate: gApp=%p\n", gApp);
setupExternalPath(env, (MAIN_CLASS*)gApp);
if (env->ExceptionOccurred()) {
LOGI("nativeOnCreate: exception after setupExternalPath!\n");
env->ExceptionDescribe();
env->ExceptionClear();
}
LOGI("nativeOnCreate: done\n");
g_inNativeOnCreate = false;
//gApp->init(gContext);
}
static int s_surfaceCreatedCount = 0;
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_GLRenderer_nativeOnSurfaceCreated(JNIEnv* env) {
s_surfaceCreatedCount++;
if (g_inNativeOnCreate) {
// Skip re-entrant surface callbacks that fire during nativeOnCreate
return;
}
LOGI("@nativeOnSurfaceCreated #%d tid=%d\n", s_surfaceCreatedCount, (int)gettid());
if (gApp) {
// Don't call onGraphicsReset the first time
if (gApp->isInited()) {
LOGI("nativeOnSurfaceCreated: calling onGraphicsReset\n");
gApp->onGraphicsReset(gContext);
}
if (!gApp->isInited()) {
LOGI("nativeOnSurfaceCreated: calling init\n");
gApp->init(gContext);
LOGI("nativeOnSurfaceCreated: init done, isInited=%d\n", (int)gApp->isInited());
}
}
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_GLRenderer_nativeOnSurfaceChanged(JNIEnv* env, jclass cls, jint w, jint h) {
LOGI("@nativeOnSurfaceChanged: %p\n", pthread_self());
if (gApp) {
gApp->setSize(w, h);
if (!gApp->isInited())
gApp->init(gContext);
if (!gApp->isInited())
LOGI("nativeOnSurfaceChanged: NOT INITED!\n");
}
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeOnDestroy(JNIEnv* env) {
LOGI("@nativeOnDestroy\n");
delete gApp;
gApp = 0;
//gApp->onGraphicsReset(gContext);
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_GLRenderer_nativeUpdate(JNIEnv* env) {
//LOGI("@nativeUpdate: %p\n", pthread_self());
if (gApp) {
if (!gApp->isInited())
gApp->init(gContext);
gApp->update();
if (gApp->wantToQuit())
appPlatform.finish();
}
}
//
// Keyboard events
//
// helper to convert Android keycodes to our internal Keyboard constants
static int androidKeyToInternal(int androidKey) {
switch(androidKey) {
case AKEYCODE_DEL: return Keyboard::KEY_BACKSPACE;
case AKEYCODE_ENTER:
case AKEYCODE_NUMPAD_ENTER:
return Keyboard::KEY_RETURN;
// letters are delivered via nativeTextChar so no need to map here
default:
return androidKey; // fall back to raw code
}
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeOnKeyDown(JNIEnv* env, jclass cls, jint keyCode) {
LOGI("@nativeOnKeyDown: %d\n", keyCode);
int mapped = androidKeyToInternal(keyCode);
Keyboard::feed(mapped, true);
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeTextChar(JNIEnv* env, jclass cls, jint unicodeChar) {
// soft-keyboards may send a backspace as a character code
if (unicodeChar == 8) {
Keyboard::feed(Keyboard::KEY_BACKSPACE, true);
Keyboard::feed(Keyboard::KEY_BACKSPACE, false);
} else if (unicodeChar > 0 && unicodeChar < 128) {
Keyboard::feedText((char)unicodeChar);
}
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeOnKeyUp(JNIEnv* env, jclass cls, jint keyCode) {
LOGI("@nativeOnKeyUp: %d\n", (int)keyCode);
int mapped = androidKeyToInternal(keyCode);
Keyboard::feed(mapped, false);
}
JNIEXPORT jboolean JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeHandleBack(JNIEnv* env, jclass cls, jboolean isDown) {
LOGI("@nativeHandleBack: %d\n", isDown);
if (gApp) return gApp->handleBack(isDown)? JNI_TRUE : JNI_FALSE;
return JNI_FALSE;
}
//
// Mouse events
//
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeMouseDown(JNIEnv* env, jclass cls, jint pointerId, jint buttonId, jfloat x, jfloat y) {
//LOGI("@nativeMouseDown: %f %f\n", x, y);
mouseDown(1, x, y);
pointerDown(pointerId, x, y);
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeMouseUp(JNIEnv* env, jclass cls, jint pointerId, jint buttonId, jfloat x, jfloat y) {
//LOGI("@nativeMouseUp: %f %f\n", x, y);
mouseUp(1, x, y);
pointerUp(pointerId, x, y);
}
JNIEXPORT void JNICALL
Java_com_mojang_minecraftpe_MainActivity_nativeMouseMove(JNIEnv* env, jclass cls, jint pointerId, jfloat x, jfloat y) {
//LOGI("@nativeMouseMove: %f %f\n", x, y);
mouseMove(x, y);
pointerMove(pointerId, x, y);
}
}