Floating on-screen joystick, which can be enabled in .cfg file
This commit is contained in:
3
bugs.txt
3
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().
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<<BUTTON_ARROWS;
|
||||
pointerInButtonRect[BUTTON_ARROWS] = pointerId;
|
||||
joystickTouchPoints[0] = x;
|
||||
joystickTouchPoints[1] = y;
|
||||
}
|
||||
}
|
||||
else
|
||||
if( action == MOUSE_UP )
|
||||
@@ -449,6 +496,8 @@ unsigned SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int po
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT), 0 );
|
||||
oldArrows = 0;
|
||||
}
|
||||
if( floatingScreenJoystick && j == 0 )
|
||||
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, 0);
|
||||
}
|
||||
}
|
||||
for( i = 0; i < MAX_BUTTONS; i++ )
|
||||
@@ -489,6 +538,16 @@ unsigned SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int po
|
||||
if( pointerInButtonRect[BUTTON_ARROWS+j] == pointerId )
|
||||
{
|
||||
processed |= 1<<(BUTTON_ARROWS+j);
|
||||
if( floatingScreenJoystick && j == 0 && ! InsideRect( &arrows[j], x, y ) )
|
||||
{
|
||||
int xx = 0, yy = 0;
|
||||
// Move joystick back under finger
|
||||
LineAndRectangleIntersection(x - (arrows[0].x + arrows[0].w / 2), y - (arrows[0].y + arrows[0].h / 2), arrows[0].w, arrows[0].h, &xx, &yy);
|
||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Touch %4d:%4d dpad %4d:%4d:%4d:%4d move by %4d:%4d", x, y, pointerId, action);
|
||||
arrows[0].x += xx;
|
||||
arrows[0].y += yy;
|
||||
arrowsDraw[0] = arrowsExtended[0] = arrows[0];
|
||||
}
|
||||
if( ! InsideRect( &arrowsExtended[j], x, y ) )
|
||||
{
|
||||
pointerInButtonRect[BUTTON_ARROWS+j] = -1;
|
||||
@@ -584,7 +643,8 @@ void shrinkButtonRect(SDL_Rect s, SDL_Rect * d)
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thiz, jint size, jint drawsize, jint theme, jint _transparency )
|
||||
JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thiz,
|
||||
jint size, jint drawsize, jint theme, jint _transparency, jint _floatingScreenJoystick )
|
||||
{
|
||||
int i, ii;
|
||||
int nbuttons1row, nbuttons2row;
|
||||
@@ -675,6 +735,13 @@ JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thi
|
||||
shrinkButtonRect(buttons[i], &buttonsDraw[i]);
|
||||
for( i = 0; i < SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM; i++ )
|
||||
SDL_ANDROID_GetScreenKeyboardButtonPos(i, &hiddenButtons[i]);
|
||||
|
||||
floatingScreenJoystick = _floatingScreenJoystick;
|
||||
if( floatingScreenJoystick )
|
||||
{
|
||||
arrowsExtended[0] = arrows[0] = arrowsDraw[0];
|
||||
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, 0);
|
||||
}
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
|
||||
7
todo.txt
7
todo.txt
@@ -19,7 +19,12 @@ TODO, which will get actually done
|
||||
|
||||
- SDL: control mouse with right analog gamepad stick.
|
||||
|
||||
- SDL: user-configurable option to set screen orientation.
|
||||
- SDL: user-configurable option to set screen orientation and BPP.
|
||||
|
||||
- SDL: 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.
|
||||
|
||||
- SDL: option to disable immersive mode.
|
||||
|
||||
- OpenTTD: All menus in the scenario editor are out of the screen.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user