diff --git a/bugs.txt b/bugs.txt index 9b8e7566c..4c20d5301 100644 --- a/bugs.txt +++ b/bugs.txt @@ -16,9 +16,6 @@ Requested features, might never get implemented, see todo.txt for features that - Show/hide screen controls with longpress on Text Edit button. -- Floating on-screen joystick - initially invisible, it appears when you touch the screen, - centered on your finger, then it slides with your finger if you bump the joystick edge. - - Export phone vibrator to SDL - interface is available in SDL 1.3. - Control screen brightness with SDL_SetGamma(). diff --git a/changeAppSettings.sh b/changeAppSettings.sh index fd4d7bcf7..a500564a3 100755 --- a/changeAppSettings.sh +++ b/changeAppSettings.sh @@ -229,13 +229,18 @@ echo >> AndroidAppSettings.cfg echo "# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)" >> AndroidAppSettings.cfg echo ForceRelativeMouseMode=$ForceRelativeMouseMode >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg -echo "# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)" >> AndroidAppSettings.cfg +echo "# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n)" >> AndroidAppSettings.cfg echo AppNeedsArrowKeys=$AppNeedsArrowKeys >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg +echo "# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n)" >> AndroidAppSettings.cfg +echo "# Joystick always follows finger, so moving mouse requires touching the screen with other finger" >> AndroidAppSettings.cfg +echo FloatingScreenJoystick=$FloatingScreenJoystick >> AndroidAppSettings.cfg +echo >> AndroidAppSettings.cfg echo "# Application needs text input (y) or (n), enables button for text input on screen" >> AndroidAppSettings.cfg echo AppNeedsTextInput=$AppNeedsTextInput >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg echo "# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1" >> AndroidAppSettings.cfg +echo "# This will disable AppNeedsArrowKeys option" >> AndroidAppSettings.cfg echo AppUsesJoystick=$AppUsesJoystick >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg echo "# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)" >> AndroidAppSettings.cfg @@ -532,6 +537,12 @@ else AppNeedsArrowKeys=false fi +if [ "$FloatingScreenJoystick" = "y" ] ; then + FloatingScreenJoystick=true +else + FloatingScreenJoystick=false +fi + if [ "$AppNeedsTextInput" = "y" ] ; then AppNeedsTextInput=true else @@ -767,6 +778,7 @@ $SEDI "s/public static boolean ForceRelativeMouseMode = .*;/public static boolea $SEDI "s/public static boolean ShowMouseCursor = .*;/public static boolean ShowMouseCursor = $ShowMouseCursor;/" project/src/Globals.java $SEDI "s/public static boolean GenerateSubframeTouchEvents = .*;/public static boolean GenerateSubframeTouchEvents = $GenerateSubframeTouchEvents;/" project/src/Globals.java $SEDI "s/public static boolean AppNeedsArrowKeys = .*;/public static boolean AppNeedsArrowKeys = $AppNeedsArrowKeys;/" project/src/Globals.java +$SEDI "s/public static boolean FloatingScreenJoystick = .*;/public static boolean FloatingScreenJoystick = $FloatingScreenJoystick;/" project/src/Globals.java $SEDI "s/public static boolean AppNeedsTextInput = .*;/public static boolean AppNeedsTextInput = $AppNeedsTextInput;/" project/src/Globals.java $SEDI "s/public static boolean AppUsesJoystick = .*;/public static boolean AppUsesJoystick = $AppUsesJoystick;/" project/src/Globals.java $SEDI "s/public static boolean AppUsesSecondJoystick = .*;/public static boolean AppUsesSecondJoystick = $AppUsesSecondJoystick;/" project/src/Globals.java diff --git a/project/java/Globals.java b/project/java/Globals.java index 6fd1b09df..a24ca4e7d 100644 --- a/project/java/Globals.java +++ b/project/java/Globals.java @@ -89,6 +89,7 @@ class Globals public static int TouchscreenKeyboardDrawSize = 1; public static int TouchscreenKeyboardTheme = 2; public static int TouchscreenKeyboardTransparency = 2; + public static boolean FloatingScreenJoystick = false; public static int AccelerometerSensitivity = 2; public static int AccelerometerCenterPos = 2; public static int TrackballDampening = 0; @@ -130,7 +131,6 @@ class Globals public static String DataDir = new String(""); public static boolean VideoLinearFilter = true; public static boolean MultiThreadedVideo = false; - public static boolean BrokenLibCMessageShown = false; public static boolean OuyaEmulation = false; // For debugging public static boolean RedirectStdout = false; // For debugging diff --git a/project/java/Settings.java b/project/java/Settings.java index 1bd1cd98e..c1336b540 100644 --- a/project/java/Settings.java +++ b/project/java/Settings.java @@ -159,7 +159,7 @@ class Settings out.writeInt(Globals.OptionalDataDownload.length); for(int i = 0; i < Globals.OptionalDataDownload.length; i++) out.writeBoolean(Globals.OptionalDataDownload[i]); - out.writeBoolean(Globals.BrokenLibCMessageShown); + out.writeBoolean(false); // Unused out.writeInt(Globals.TouchscreenKeyboardDrawSize); out.writeInt(p.getApplicationVersion()); out.writeFloat(AccelerometerReader.gyro.x1); @@ -177,6 +177,7 @@ class Settings out.writeBoolean(Globals.MoveMouseWithGyroscope); out.writeInt(Globals.MoveMouseWithGyroscopeSpeed); out.writeBoolean(Globals.FingerHover); + out.writeBoolean(Globals.FloatingScreenJoystick); out.close(); settingsLoaded = true; @@ -346,7 +347,7 @@ class Settings Globals.OptionalDataDownload = new boolean[settingsFile.readInt()]; for(int i = 0; i < Globals.OptionalDataDownload.length; i++) Globals.OptionalDataDownload[i] = settingsFile.readBoolean(); - Globals.BrokenLibCMessageShown = settingsFile.readBoolean(); + settingsFile.readBoolean(); // Unused Globals.TouchscreenKeyboardDrawSize = settingsFile.readInt(); int cfgVersion = settingsFile.readInt(); AccelerometerReader.gyro.x1 = settingsFile.readFloat(); @@ -364,6 +365,7 @@ class Settings Globals.MoveMouseWithGyroscope = settingsFile.readBoolean(); Globals.MoveMouseWithGyroscopeSpeed = settingsFile.readInt(); Globals.FingerHover = settingsFile.readBoolean(); + Globals.FloatingScreenJoystick = settingsFile.readBoolean(); settingsLoaded = true; @@ -560,7 +562,8 @@ class Settings nativeSetupScreenKeyboard( Globals.TouchscreenKeyboardSize, Globals.TouchscreenKeyboardDrawSize, Globals.TouchscreenKeyboardTheme, - Globals.TouchscreenKeyboardTransparency ); + Globals.TouchscreenKeyboardTransparency, + Globals.FloatingScreenJoystick ? 1 : 0 ); SetupTouchscreenKeyboardGraphics(p); for( int i = 0; i < Globals.RemapScreenKbKeycode.length; i++ ) nativeSetKeymapKeyScreenKb(i, SDL_Keys.values[Globals.RemapScreenKbKeycode[i]]); @@ -844,7 +847,7 @@ class Settings private static native void nativeSetCompatibilityHacks(); private static native void nativeSetVideoMultithreaded(); private static native void nativeSetVideoForceSoftwareMode(); - private static native void nativeSetupScreenKeyboard(int size, int drawsize, int theme, int transparency); + private static native void nativeSetupScreenKeyboard(int size, int drawsize, int theme, int transparency, int floatingScreenJoystick); private static native void nativeSetupScreenKeyboardButtons(byte[] img); private static native void nativeInitKeymap(); private static native int nativeGetKeymapKey(int key); diff --git a/project/jni/application/ballfield/AndroidAppSettings.cfg b/project/jni/application/ballfield/AndroidAppSettings.cfg index 685dd710b..7b1849984 100644 --- a/project/jni/application/ballfield/AndroidAppSettings.cfg +++ b/project/jni/application/ballfield/AndroidAppSettings.cfg @@ -119,13 +119,18 @@ GenerateSubframeTouchEvents=n # Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n) ForceRelativeMouseMode=n -# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n) +# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n) AppNeedsArrowKeys=y +# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n) +# Joystick always follows finger, so moving mouse requires touching the screen with other finger +FloatingScreenJoystick=y + # Application needs text input (y) or (n), enables button for text input on screen AppNeedsTextInput=y # Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1 +# This will disable AppNeedsArrowKeys option AppUsesJoystick=y # Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n) @@ -208,7 +213,7 @@ FirstStartMenuOptions='SettingsMenu.DummyMenu' # Specify architectures to compile, 'all' or 'y' to compile for all architectures. # Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips -MultiABI='armeabi-v7a-hard x86 mips armeabi' +MultiABI='armeabi-v7a' # Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower AppMinimumRAM=0 diff --git a/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c b/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c index ebbd23b47..94a1922b1 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c @@ -88,6 +88,7 @@ enum { MOUSE_POINTER_W = 32, MOUSE_POINTER_H = 32, MOUSE_POINTER_X = 5, MOUSE_PO static int sunTheme = 0; static int joystickTouchPoints[MAX_JOYSTICKS*2]; +static int floatingScreenJoystick = 0; static void R_DumpOpenGlState(void); @@ -96,6 +97,39 @@ static inline int InsideRect(const SDL_Rect * r, int x, int y) return ( x >= r->x && x <= r->x + r->w ) && ( y >= r->y && y <= r->y + r->h ); } +// Find the intersection of a line and a rectangle, +// where on of the line points and the center of rectangle +// are both at the coordinate [0,0]. +// It returns the remaining line segment outside of the rectangle. +// Do not check for border condition, we check that the line point +// is outside of the rectangle in another function. +static inline void LineAndRectangleIntersection( + int lx, int ly, // Line point, that is outside of rectangle + int rw, int rh, // Rectangle dimensions + int *x, int *y) +{ + if( abs(lx) * rh > abs(ly) * rw ) + { + rw /= 2; + // Intersection at the left side + if( lx < -rw ) + *x = lx + rw; // lx is negative + else //if( lx > rw ) // At the right side + *x = lx - rw; // lx is positive + *y = *x * ly / lx; + } + else + { + rh /= 2; + // At the top + if( ly < -rh ) + *y = ly + rh; // ly is negative + else //if( ly > rh ) // At the right side + *y = ly - rh; // ly is positive + *x = *y * lx / ly; + } +} + static struct ScreenKbGlState_t { GLboolean texture2d; @@ -360,7 +394,7 @@ unsigned SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int po int i, j; unsigned processed = 0; int joyAmount = SDL_ANDROID_joysticksAmount; - if( joyAmount == 0 && arrows[0].w > 0 ) + if( joyAmount == 0 && (arrows[0].w > 0 || floatingScreenJoystick) ) joyAmount = 1; if( !touchscreenKeyboardShown ) @@ -424,6 +458,19 @@ unsigned SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int po } } } + + if( floatingScreenJoystick && !processed && pointerInButtonRect[BUTTON_ARROWS] == -1 ) + { + // Center joystick under finger, do not send any events yet + SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, 1); + arrows[0].x = x - arrows[0].w / 2; + arrows[0].y = y - arrows[0].h / 2; + arrowsDraw[0] = arrowsExtended[0] = arrows[0]; + processed |= 1<