From b175eed3ca950204c9b52fdcebc897f337b7bf19 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Tue, 15 May 2018 13:58:15 +0100 Subject: New upstream version 2.5.0+dfsg --- examples/android/app/src/main/jni/main.cpp | 175 +++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 examples/android/app/src/main/jni/main.cpp (limited to 'examples/android/app/src/main/jni/main.cpp') diff --git a/examples/android/app/src/main/jni/main.cpp b/examples/android/app/src/main/jni/main.cpp new file mode 100644 index 0000000..e5445b5 --- /dev/null +++ b/examples/android/app/src/main/jni/main.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include + +// Do we want to showcase direct JNI/NDK interaction? +// Undefine this to get real cross-platform code. +#define USE_JNI + +#if defined(USE_JNI) +// These headers are only needed for direct NDK/JDK interaction +#include +#include + +// Since we want to get the native activity from SFML, we'll have to use an +// extra header here: +#include + +// NDK/JNI sub example - call Java code from native code +int vibrate(sf::Time duration) +{ + // First we'll need the native activity handle + ANativeActivity *activity = sf::getNativeActivity(); + + // Retrieve the JVM and JNI environment + JavaVM* vm = activity->vm; + JNIEnv* env = activity->env; + + // First, attach this thread to the main thread + JavaVMAttachArgs attachargs; + attachargs.version = JNI_VERSION_1_6; + attachargs.name = "NativeThread"; + attachargs.group = NULL; + jint res = vm->AttachCurrentThread(&env, &attachargs); + + if (res == JNI_ERR) + return EXIT_FAILURE; + + // Retrieve class information + jclass natact = env->FindClass("android/app/NativeActivity"); + jclass context = env->FindClass("android/content/Context"); + + // Get the value of a constant + jfieldID fid = env->GetStaticFieldID(context, "VIBRATOR_SERVICE", "Ljava/lang/String;"); + jobject svcstr = env->GetStaticObjectField(context, fid); + + // Get the method 'getSystemService' and call it + jmethodID getss = env->GetMethodID(natact, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); + jobject vib_obj = env->CallObjectMethod(activity->clazz, getss, svcstr); + + // Get the object's class and retrieve the member name + jclass vib_cls = env->GetObjectClass(vib_obj); + jmethodID vibrate = env->GetMethodID(vib_cls, "vibrate", "(J)V"); + + // Determine the timeframe + jlong length = duration.asMilliseconds(); + + // Bzzz! + env->CallVoidMethod(vib_obj, vibrate, length); + + // Free references + env->DeleteLocalRef(vib_obj); + env->DeleteLocalRef(vib_cls); + env->DeleteLocalRef(svcstr); + env->DeleteLocalRef(context); + env->DeleteLocalRef(natact); + + // Detach thread again + vm->DetachCurrentThread(); +} +#endif + +// This is the actual Android example. You don't have to write any platform +// specific code, unless you want to use things not directly exposed. +// ('vibrate()' in this example; undefine 'USE_JNI' above to disable it) +int main(int argc, char *argv[]) +{ + sf::VideoMode screen(sf::VideoMode::getDesktopMode()); + + sf::RenderWindow window(screen, ""); + window.setFramerateLimit(30); + + sf::Texture texture; + if(!texture.loadFromFile("image.png")) + return EXIT_FAILURE; + + sf::Sprite image(texture); + image.setPosition(screen.width / 2, screen.height / 2); + image.setOrigin(texture.getSize().x/2, texture.getSize().y/2); + + sf::Font font; + if (!font.loadFromFile("sansation.ttf")) + return EXIT_FAILURE; + + sf::Text text("Tap anywhere to move the logo.", font, 64); + text.setFillColor(sf::Color::Black); + text.setPosition(10, 10); + + // Loading canary.wav fails for me for now; haven't had time to test why + + /*sf::Music music; + if(!music.openFromFile("canary.wav")) + return EXIT_FAILURE; + + music.play();*/ + + sf::View view = window.getDefaultView(); + + sf::Color background = sf::Color::White; + + // We shouldn't try drawing to the screen while in background + // so we'll have to track that. You can do minor background + // work, but keep battery life in mind. + bool active = true; + + while (window.isOpen()) + { + sf::Event event; + + while (active ? window.pollEvent(event) : window.waitEvent(event)) + { + switch (event.type) + { + case sf::Event::Closed: + window.close(); + break; + case sf::Event::KeyPressed: + if (event.key.code == sf::Keyboard::Escape) + window.close(); + break; + case sf::Event::Resized: + view.setSize(event.size.width, event.size.height); + view.setCenter(event.size.width/2, event.size.height/2); + window.setView(view); + break; + case sf::Event::LostFocus: + background = sf::Color::Black; + break; + case sf::Event::GainedFocus: + background = sf::Color::White; + break; + + // On Android MouseLeft/MouseEntered are (for now) triggered, + // whenever the app loses or gains focus. + case sf::Event::MouseLeft: + active = false; + break; + case sf::Event::MouseEntered: + active = true; + break; + case sf::Event::TouchBegan: + if (event.touch.finger == 0) + { + image.setPosition(event.touch.x, event.touch.y); +#if defined(USE_JNI) + vibrate(sf::milliseconds(10)); +#endif + } + break; + } + } + + if (active) + { + window.clear(background); + window.draw(image); + window.draw(text); + window.display(); + } + else { + sf::sleep(sf::milliseconds(100)); + } + } +} -- cgit v1.2.3