From 1ef531ec9cb74e9490dcff8ba7c427588eff0b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 16 Dec 2013 16:19:40 +0100 Subject: [PATCH] Add some infrastructure to handle screen resizes that don't lose the device --- android/app-android.cpp | 50 +++++++++++++++++------------------------ base/NativeApp.h | 10 ++++++--- ui/screen.cpp | 7 ++++++ ui/screen.h | 2 ++ 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/android/app-android.cpp b/android/app-android.cpp index 11a51bfe8..975ac96b7 100644 --- a/android/app-android.cpp +++ b/android/app-android.cpp @@ -52,11 +52,6 @@ void SystemToast(const char *text) { frameCommandParam = text; } -// TODO: need a Hide or bool show; -void ShowAd(int x, int y, bool center_x) { - ELOG("TODO! ShowAd!"); -} - void ShowKeyboard() { frameCommand = "showKeyboard"; frameCommandParam = ""; @@ -103,8 +98,8 @@ std::string System_GetProperty(SystemProperty prop) { // Remember that all of these need initialization on init! The process // may be reused when restarting the game. Globals are DANGEROUS. -float dp_xscale = 1; -float dp_yscale = 1; +float dp_xscale = 1.0f; +float dp_yscale = 1.0f; InputState input_state; @@ -113,16 +108,14 @@ static bool first_lost = true; static bool use_opensl_audio = false; static std::string library_path; -std::string GetJavaString(JNIEnv *env, jstring jstr) -{ +std::string GetJavaString(JNIEnv *env, jstring jstr) { const char *str = env->GetStringUTFChars(jstr, 0); std::string cpp_string = std::string(str); env->ReleaseStringUTFChars(jstr, str); return cpp_string; } -extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_isLandscape(JNIEnv *env, jclass) -{ +extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_isLandscape(JNIEnv *env, jclass) { std::string app_name, app_nice_name; bool landscape; NativeGetAppInfo(&app_name, &app_nice_name, &landscape); @@ -240,7 +233,7 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeApp_shutdown(JNIEnv *, jc static jmethodID postCommand; extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { - ILOG("NativeApp.displayInit()"); + ILOG("NativeApp.displayInit(pixel_xres = %i, pixel_yres = %i)", pixel_xres, pixel_yres); if (!renderer_inited) { // We default to 240 dpi and all UI code is written to assume it. (DENSITY_HIGH, like Nexus S). // Note that we don't compute dp_xscale and dp_yscale until later! This is so that NativeGetAppInfo @@ -265,6 +258,7 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayInit(JNIE extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayResize(JNIEnv *, jobject clazz, jint w, jint h) { ILOG("NativeApp.displayResize(%i, %i)", w, h); + // TODO: Move some of the logic from displayInit here? pixel_xres = w; pixel_yres = h; @@ -272,6 +266,8 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayResize(JN dp_yres = pixel_yres * g_dpi_scale; dp_xscale = (float)dp_xres / pixel_xres; dp_yscale = (float)dp_yres / pixel_yres; + + NativeResized(); } extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayRender(JNIEnv *env, jobject obj) { @@ -332,9 +328,6 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayShutdown( // This path is not used if OpenSL ES is available. extern "C" jint Java_com_henrikrydgard_libnative_NativeApp_audioRender(JNIEnv* env, jclass clazz, jshortArray array) { - // Too spammy - // ILOG("NativeApp.audioRender"); - // The audio thread can pretty safely enable Flush-to-Zero mode on the FPU. EnableFZ(); @@ -356,8 +349,6 @@ extern "C" jint Java_com_henrikrydgard_libnative_NativeApp_audioRender(JNIEnv* e extern "C" void JNICALL Java_com_henrikrydgard_libnative_NativeApp_touch (JNIEnv *, jclass, float x, float y, int code, int pointerId) { - // ELOG("Touch Enter %i", pointerId); - float scaledX = (int)(x * dp_xscale); // why the (int) cast? float scaledY = (int)(y * dp_yscale); @@ -376,21 +367,18 @@ extern "C" void JNICALL Java_com_henrikrydgard_libnative_NativeApp_touch } NativeTouch(touch); - - lock_guard guard(input_state.lock); - - if (pointerId >= MAX_POINTERS) { - ELOG("Too many pointers: %i", pointerId); - return; // We ignore 8+ pointers entirely. + { + lock_guard guard(input_state.lock); + if (pointerId >= MAX_POINTERS) { + ELOG("Too many pointers: %i", pointerId); + return; // We ignore 8+ pointers entirely. + } + input_state.pointer_x[pointerId] = scaledX; + input_state.pointer_y[pointerId] = scaledY; + input_state.mouse_valid = true; } - input_state.pointer_x[pointerId] = scaledX; - input_state.pointer_y[pointerId] = scaledY; - input_state.mouse_valid = true; - - // ELOG("Touch Exit %i", pointerId); } - extern "C" void Java_com_henrikrydgard_libnative_NativeApp_keyDown(JNIEnv *, jclass, jint deviceId, jint key) { KeyInput keyInput; keyInput.deviceId = deviceId; @@ -414,6 +402,8 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeApp_beginJoystickEvent( extern "C" void Java_com_henrikrydgard_libnative_NativeApp_joystickAxis( JNIEnv *env, jclass, jint deviceId, jint axisId, jfloat value) { + if (!renderer_inited) + return; switch (axisId) { case JOYSTICK_AXIS_X: left_joystick_x_async = value; @@ -454,6 +444,8 @@ extern "C" void Java_com_henrikrydgard_libnative_NativeApp_mouseWheelEvent( } extern "C" void JNICALL Java_com_henrikrydgard_libnative_NativeApp_accelerometer(JNIEnv *, jclass, float x, float y, float z) { + if (!renderer_inited) + return; // Theoretically this needs locking but I doubt it matters. Worst case, the X // from one "sensor frame" will be used together with Y from the next. // Should look into quantization though, for compressed movement storage. diff --git a/base/NativeApp.h b/base/NativeApp.h index c81ffe830..0b1ba00f0 100644 --- a/base/NativeApp.h +++ b/base/NativeApp.h @@ -35,11 +35,15 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co // Runs after NativeInit() at some point. May (and probably should) call OpenGL. void NativeInitGraphics(); -// Signals that you need to recreate all buffered OpenGL resources, -// like textures, vbo etc. Also, if you have modified dp_xres and dp_yres, you have to -// do it again here. Main thread. +// Signals that you need to destroy and recreate all buffered OpenGL resources, +// like textures, vbo etc. void NativeDeviceLost(); +// If you want to change DPI stuff (such as modifying dp_xres and dp_yres), this is the +// place to do it. You should only read g_dpi_scale and pixel_xres and pixel_yres in this, +// and only write dp_xres and dp_yres. +void NativeResized(); + // Called ~sixty times a second, delivers the current input state. // Main thread. void NativeUpdate(InputState &input); diff --git a/ui/screen.cpp b/ui/screen.cpp index 27a0c6ffe..7219f2a7a 100644 --- a/ui/screen.cpp +++ b/ui/screen.cpp @@ -79,6 +79,13 @@ void ScreenManager::axis(const AxisInput &axis) { stack_.back().screen->axis(axis); } +void ScreenManager::resized() { + // Have to notify the whole stack, otherwise there will be problems when going back + // to non-top screens. + for (auto iter = stack_.begin(); iter != stack_.end(); ++iter) { + iter->screen->resized(); + } +} void ScreenManager::render() { if (!stack_.empty()) { diff --git a/ui/screen.h b/ui/screen.h index 4a4e13778..4df96d1c8 100644 --- a/ui/screen.h +++ b/ui/screen.h @@ -48,6 +48,7 @@ public: virtual void update(InputState &input) {} virtual void render() {} virtual void deviceLost() {} + virtual void resized() {} virtual void dialogFinished(const Screen *dialog, DialogResult result) {} virtual void touch(const TouchInput &touch) {} virtual void key(const KeyInput &key) {} @@ -95,6 +96,7 @@ public: UIContext *getUIContext() { return uiContext_; } void render(); + void resized(); void deviceLost(); void shutdown();