summaryrefslogtreecommitdiff
path: root/examples/android/app/src/main/jni/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/android/app/src/main/jni/main.cpp')
-rw-r--r--examples/android/app/src/main/jni/main.cpp175
1 files changed, 175 insertions, 0 deletions
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 <SFML/System.hpp>
+#include <SFML/Window.hpp>
+#include <SFML/Graphics.hpp>
+#include <SFML/Audio.hpp>
+#include <SFML/Network.hpp>
+
+// 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 <jni.h>
+#include <android/native_activity.h>
+
+// Since we want to get the native activity from SFML, we'll have to use an
+// extra header here:
+#include <SFML/System/NativeActivity.hpp>
+
+// 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));
+ }
+ }
+}