From d195789abdf88ccc56780797be4db06793f92c2b Mon Sep 17 00:00:00 2001 From: "Reed A. Cartwright" Date: Sun, 11 Apr 2021 22:05:48 -0700 Subject: [PATCH] Implement MainActivity::getImageData (merged from feature-jnivm branch) --- src/jni/jni_descriptors.cpp | 1 + src/jni/jni_support.cpp | 6 +++++- src/jni/jni_support.h | 3 ++- src/jni/main_activity.cpp | 23 +++++++++++++++++++++++ src/jni/main_activity.h | 7 ++++++- src/main.cpp | 4 +++- 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/jni/jni_descriptors.cpp b/src/jni/jni_descriptors.cpp index 83a57f2b..31c15b90 100644 --- a/src/jni/jni_descriptors.cpp +++ b/src/jni/jni_descriptors.cpp @@ -106,6 +106,7 @@ BEGIN_NATIVE_DESCRIPTOR(MainActivity) // {Function<&MainActivity::getSecureStorageKey> {}, "getSecureStorageKey"}, {Function<&MainActivity::lockCursor> {}, "lockCursor"}, {Function<&MainActivity::unlockCursor> {}, "unlockCursor"}, +{Function<&MainActivity::getImageData> {}, "getImageData"}, END_NATIVE_DESCRIPTOR BEGIN_NATIVE_DESCRIPTOR(AccountManager) diff --git a/src/jni/jni_support.cpp b/src/jni/jni_support.cpp index 820df4a7..e90766aa 100644 --- a/src/jni/jni_support.cpp +++ b/src/jni/jni_support.cpp @@ -148,7 +148,8 @@ void JniSupport::registerNatives(std::shared_ptr clazz, throw std::runtime_error("RegisterNatives failed"); } -void JniSupport::startGame(ANativeActivity_createFunc *activityOnCreate) { +void JniSupport::startGame(ANativeActivity_createFunc *activityOnCreate, + void *stbiLoadFromMemory, void *stbiImageFree) { FakeJni::LocalFrame frame (vm); vm.attachLibrary("libfmod.so", "", {linker::dlopen, linker::dlsym, linker::dlclose_unlocked}); @@ -167,6 +168,9 @@ void JniSupport::startGame(ANativeActivity_createFunc *activityOnCreate) { activity->textInput = &textInput; activity->quitCallback = [this]() { requestExitGame(); }; activity->storageDirectory = PathHelper::getPrimaryDataDirectory(); + activity->stbi_load_from_memory = (decltype(activity->stbi_load_from_memory)) stbiLoadFromMemory; + activity->stbi_image_free = (decltype(activity->stbi_image_free)) stbiImageFree; + assetManager = std::make_unique(PathHelper::getGameDir() + "/assets"); XboxLiveHelper::getInstance().setJvm(&vm); diff --git a/src/jni/jni_support.h b/src/jni/jni_support.h index 2a12b840..d61d4b34 100644 --- a/src/jni/jni_support.h +++ b/src/jni/jni_support.h @@ -41,7 +41,8 @@ struct JniSupport { void registerMinecraftNatives(void *(*symResolver)(const char *)); - void startGame(ANativeActivity_createFunc *activityOnCreate); + void startGame(ANativeActivity_createFunc *activityOnCreate, + void *stbiLoadFromMemory, void *stbiImageFree); void stopGame(); diff --git a/src/jni/main_activity.cpp b/src/jni/main_activity.cpp index 74466613..640e3f97 100644 --- a/src/jni/main_activity.cpp +++ b/src/jni/main_activity.cpp @@ -10,6 +10,8 @@ #include #include #include "uuid.h" +#include +#include FakeJni::JInt BuildVersion::SDK_INT = 27; std::shared_ptr BuildVersion::RELEASE = std::make_shared("AndroidX"); @@ -113,3 +115,24 @@ void MainActivity::initializeXboxLive(FakeJni::JLong xalinit, FakeJni::JLong xbl FakeJni::LocalFrame frame; method->invoke(frame.getJniEnv(), this, xalinit, xblinit); } + +std::shared_ptr MainActivity::getImageData(std::shared_ptr filename) { + if(!stbi_load_from_memory || !stbi_image_free) return 0; + int width, height, channels; + std::ifstream f(filename->asStdString().data()); + if(!f.is_open()) return 0; + std::stringstream s; + s << f.rdbuf(); + auto buf = s.str(); + auto image = stbi_load_from_memory((unsigned char*)buf.data(), buf.length(), &width, &height, &channels, 4); + if(!image) return 0; + auto ret = std::make_shared(2 + width * height); + (*ret)[0] = width; + (*ret)[1] = height; + + for(int x = 0; x < width * height; x++) { + (*ret)[2 + x] = (image[x * 4 + 2]) | (image[x * 4 + 1] << 8) | (image[x * 4 + 0] << 16) | (image[x * 4 + 3] << 24); + } + stbi_image_free(image); + return ret; +} \ No newline at end of file diff --git a/src/jni/main_activity.h b/src/jni/main_activity.h index 65f53eaf..858fefa6 100644 --- a/src/jni/main_activity.h +++ b/src/jni/main_activity.h @@ -99,13 +99,16 @@ class HardwareInfo : public FakeJni::JObject { } }; - +#include class MainActivity : public NativeActivity { private: bool ignoreNextHideKeyboard = false; public: + unsigned char* (*stbi_load_from_memory)(unsigned char const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + void (*stbi_image_free)(void *retval_from_stbi_load); + DEFINE_CLASS_NAME("com/mojang/minecraftpe/MainActivity", NativeActivity) std::string storageDirectory; @@ -213,6 +216,8 @@ class MainActivity : public NativeActivity { void pickImage(FakeJni::JLong callback); void initializeXboxLive(FakeJni::JLong xalinit, FakeJni::JLong xblinit); + + std::shared_ptr getImageData(std::shared_ptr filename); }; class JellyBeanDeviceManager : public FakeJni::JObject { diff --git a/src/main.cpp b/src/main.cpp index bd129d91..93856973 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -171,7 +171,9 @@ int main(int argc, char *argv[]) { return linker::dlsym(handle, sym); }); std::thread startThread([&support]() { - support.startGame((ANativeActivity_createFunc *) linker::dlsym(handle, "ANativeActivity_onCreate")); + support.startGame((ANativeActivity_createFunc *) linker::dlsym(handle, "ANativeActivity_onCreate"), + linker::dlsym(handle, "stbi_load_from_memory"), + linker::dlsym(handle, "stbi_image_free")); linker::dlclose(handle); }); startThread.detach();