Skip to content

Commit

Permalink
Merge branch 'feature-getImageData', to fix a rare crash
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherHX committed Apr 12, 2021
2 parents d6f0455 + d195789 commit 67b8976
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/jni/jni_descriptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion src/jni/jni_support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ void JniSupport::registerNatives(std::shared_ptr<FakeJni::JClass const> 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});
Expand All @@ -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<FakeAssetManager>(PathHelper::getGameDir() + "/assets");

XboxLiveHelper::getInstance().setJvm(&vm);
Expand Down
3 changes: 2 additions & 1 deletion src/jni/jni_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
23 changes: 23 additions & 0 deletions src/jni/main_activity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <file_picker_factory.h>
#include <game_window_manager.h>
#include "uuid.h"
#include <climits>
#include <sstream>

FakeJni::JInt BuildVersion::SDK_INT = 27;
std::shared_ptr<FakeJni::JString> BuildVersion::RELEASE = std::make_shared<FakeJni::JString>("AndroidX");
Expand Down Expand Up @@ -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<FakeJni::JIntArray> MainActivity::getImageData(std::shared_ptr<FakeJni::JString> 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<FakeJni::JIntArray>(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;
}
7 changes: 6 additions & 1 deletion src/jni/main_activity.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,16 @@ class HardwareInfo : public FakeJni::JObject {
}

};

#include <fstream>
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;
Expand Down Expand Up @@ -213,6 +216,8 @@ class MainActivity : public NativeActivity {
void pickImage(FakeJni::JLong callback);

void initializeXboxLive(FakeJni::JLong xalinit, FakeJni::JLong xblinit);

std::shared_ptr<FakeJni::JIntArray> getImageData(std::shared_ptr<FakeJni::JString> filename);
};

class JellyBeanDeviceManager : public FakeJni::JObject {
Expand Down
4 changes: 3 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,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();
Expand Down

0 comments on commit 67b8976

Please sign in to comment.