Initial work to make android STK use SDL2 completely

This commit is contained in:
Benau
2020-07-12 08:25:06 +08:00
parent ddd4b8b9c9
commit 8cc4dd3383
36 changed files with 554 additions and 3669 deletions

View File

@@ -175,8 +175,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := irrlicht
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/irrlicht/source/Irrlicht/*.cpp) \
../lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c
LOCAL_SRC_FILES := $(wildcard ../lib/irrlicht/source/Irrlicht/*.cpp)
LOCAL_CFLAGS := -I../lib/irrlicht/source/Irrlicht/ \
-I../lib/irrlicht/include/ \
-I../src \
@@ -184,6 +183,7 @@ LOCAL_CFLAGS := -I../lib/irrlicht/source/Irrlicht/ \
-Iobj/libpng/ \
-Iobj/zlib/ \
-I../lib/sdl2/include/ \
-DMOBILE_STK \
-DANDROID_PACKAGE_CALLBACK_NAME=$(PACKAGE_CALLBACK_NAME)
LOCAL_CPPFLAGS := -std=gnu++0x
LOCAL_STATIC_LIBRARIES := libjpeg png zlib

View File

@@ -10,7 +10,7 @@
android:banner="@drawable/banner"
android:hasCode="true"
android:isGame="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true"
android:resizeableActivity="false">
@@ -20,10 +20,6 @@
android:configChanges="fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|uiMode"
android:screenOrientation="sensorLandscape">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="main" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@@ -668,11 +668,15 @@ if [ $RUN_OPTIMIZE_SCRIPT -gt 0 ]; then
fi
# Generate directories list
echo "Generate directories list"
find "$OUTPUT_PATH"/* -type d | sort > "$OUTPUT_PATH/directories.txt"
sed -i s/".\/$OUTPUT_PATH\/"// "$OUTPUT_PATH/directories.txt"
sed -i s/"$OUTPUT_PATH\/"// "$OUTPUT_PATH/directories.txt"
# Generate files list
echo "Generate files list"
find "$OUTPUT_PATH"/* -type d| sort > tmp1.txt
sed -i 's/$/\//' tmp1.txt
find "$OUTPUT_PATH"/* -type f| sort > tmp2.txt
cat tmp1.txt tmp2.txt | sort > "$OUTPUT_PATH/files.txt"
rm tmp1.txt tmp2.txt
sed -i s/".\/$OUTPUT_PATH\/"// "$OUTPUT_PATH/files.txt"
sed -i s/"$OUTPUT_PATH\/"// "$OUTPUT_PATH/files.txt"
# A file that can be used to check if apk has assets
echo "has_assets" > "$OUTPUT_PATH/has_assets.txt"

View File

@@ -568,11 +568,14 @@ cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/HID
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java" \
"$DIRNAME/src/main/java/"
sed -i "s/import org.supertuxkart.*.SuperTuxKartActivity;/import $PACKAGE_NAME.SuperTuxKartActivity;/g" \
"$DIRNAME/src/main/java/SDLControllerManager.java"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDL.java" \
"$DIRNAME/src/main/java/"
cp "banner.png" "$DIRNAME/res/drawable/banner.png"
cp "$APP_ICON" "$DIRNAME/res/drawable/icon.png"

View File

@@ -1,5 +1,6 @@
package org.supertuxkart.stk_dbg;
import org.libsdl.app.SDLActivity;
import org.supertuxkart.stk_dbg.STKInputConnection;
import android.content.Context;
@@ -37,6 +38,8 @@ public class STKEditText extends EditText
// ------------------------------------------------------------------------
private native static void handleActionNext(int widget_id);
// ------------------------------------------------------------------------
private native static void handleLeftRight(boolean left, int widget_id);
// ------------------------------------------------------------------------
public STKEditText(Context context)
{
super(context);
@@ -62,6 +65,61 @@ public class STKEditText extends EditText
return false;
}
});
setOnKeyListener(new EditText.OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
// Up or down pressed, leave focus
if (keyCode == KeyEvent.KEYCODE_DPAD_UP ||
keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
beforeHideKeyboard(true/*clear_text*/);
SDLActivity.onNativeKeyDown(keyCode);
SDLActivity.onNativeKeyUp(keyCode);
}
return true;
}
// For left or right let STK decides
else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT &&
getSelectionStart() == 0)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
beforeHideKeyboard(true/*clear_text*/);
handleLeftRight(true, m_stk_widget_id);
}
else
updateSTKEditBox();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT &&
getSelectionEnd() == getText().length())
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
beforeHideKeyboard(true/*clear_text*/);
handleLeftRight(false, m_stk_widget_id);
}
else
updateSTKEditBox();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_ENTER)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
handleActionNext(m_stk_widget_id);
return true;
}
// Requires for hardware key like "Ctrl-a" so it will select
// all text in stk edit box
updateSTKEditBox();
return false;
}
});
}
// ------------------------------------------------------------------------
@Override
@@ -88,7 +146,8 @@ public class STKEditText extends EditText
{
// Always remove the focus on STKEdit when pressing back button in
// phone, which hideSoftInputFromWindow is called by java itself
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_UP)
beforeHideKeyboard(false/*clear_text*/);
return false;
}
@@ -134,6 +193,7 @@ public class STKEditText extends EditText
}
clearFocus();
setVisibility(View.GONE);
SDLActivity.reFocusAfterSTKEditText();
}
catch (Exception e)
{

View File

@@ -1,11 +1,8 @@
package org.supertuxkart.stk_dbg;
import org.supertuxkart.stk_dbg.STKEditText;
import org.libsdl.app.SDLActivity;
import org.libsdl.app.SDLControllerManager;
import org.libsdl.app.HIDDeviceManager;
import android.app.NativeActivity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -32,45 +29,13 @@ import org.minidns.hla.ResolverResult;
import org.minidns.record.SRV;
import org.minidns.record.TXT;
public class SuperTuxKartActivity extends NativeActivity
public class SuperTuxKartActivity extends SDLActivity
{
// Same as irrlicht
enum TouchInputEvent
{
ETIE_PRESSED_DOWN,
ETIE_LEFT_UP,
ETIE_MOVED,
ETIE_COUNT
}
class TouchEventData
{
public TouchInputEvent event_type;
public int x;
public int y;
TouchEventData()
{
event_type = TouchInputEvent.ETIE_PRESSED_DOWN;
x = 0;
y = 0;
}
};
private TouchEventData[] m_touch_event_data;
private STKEditText m_stk_edittext;
private static Context m_context;
private static HIDDeviceManager m_hid_device_manager;
private int m_bottom_y;
// ------------------------------------------------------------------------
private native void saveKeyboardHeight(int height);
// ------------------------------------------------------------------------
private native void startSTK();
// ------------------------------------------------------------------------
private native static void addKey(int key_code, int action, int meta_state,
int scan_code, int unichar);
// ------------------------------------------------------------------------
private native static void addTouch(int id, int x, int y, int event_type);
// ------------------------------------------------------------------------
private native static void addDNSSrvRecords(String name, int weight);
// ------------------------------------------------------------------------
private void hideKeyboardNative(final boolean clear_text)
@@ -88,24 +53,14 @@ public class SuperTuxKartActivity extends NativeActivity
imm.hideSoftInputFromWindow(m_stk_edittext.getWindowToken(), 0);
}
// ------------------------------------------------------------------------
private void hideNavBar(View decor_view)
{
if (Build.VERSION.SDK_INT < 19)
return;
decor_view.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
}
// ------------------------------------------------------------------------
private void createSTKEditText()
{
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
// We move the dummy edittext out of the android screen because we draw
// our own manually
params.setMargins(0, -100000, 1, -100010);
m_stk_edittext = new STKEditText(this);
// For some copy-and-paste text are not done by commitText in
// STKInputConnection, so we need an extra watcher
@@ -120,7 +75,7 @@ public class SuperTuxKartActivity extends NativeActivity
@Override
public void afterTextChanged(Editable edit)
{
if (!isHardwareKeyboardConnected() && m_stk_edittext != null)
if (m_stk_edittext != null)
m_stk_edittext.updateSTKEditBox();
}
});
@@ -133,15 +88,7 @@ public class SuperTuxKartActivity extends NativeActivity
public void onCreate(Bundle instance)
{
super.onCreate(instance);
// We don't use native activity input event queue
getWindow().takeInputQueue(null);
System.loadLibrary("main");
m_touch_event_data = new TouchEventData[32];
for (int i = 0; i < 32; i++)
m_touch_event_data[i] = new TouchEventData();
m_context = this;
m_stk_edittext = null;
m_bottom_y = 0;
final View root = getWindow().getDecorView().findViewById(
android.R.id.content);
root.getViewTreeObserver().addOnGlobalLayoutListener(new
@@ -155,26 +102,13 @@ public class SuperTuxKartActivity extends NativeActivity
int screen_height = root.getRootView().getHeight();
int keyboard_height = screen_height - (r.bottom);
saveKeyboardHeight(keyboard_height);
int moved_height = 0;
int margin = screen_height - m_bottom_y;
if (keyboard_height > margin)
moved_height = -keyboard_height + margin;
SDLActivity.moveView(moved_height);
}
});
final View decor_view = getWindow().getDecorView();
decor_view.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener()
{
@Override
public void onSystemUiVisibilityChange(int visibility)
{
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
hideNavBar(decor_view);
}
});
SDLControllerManager.nativeSetupJNI();
SDLControllerManager.initialize();
m_hid_device_manager = HIDDeviceManager.acquire(this);
// We only start stk main thread after JNI_OnLoad (for initializing the
// java environment)
startSTK();
}
// ------------------------------------------------------------------------
@Override
@@ -182,194 +116,16 @@ public class SuperTuxKartActivity extends NativeActivity
{
super.onPause();
hideKeyboardNative(false/*clear_text*/);
if (m_hid_device_manager != null)
m_hid_device_manager.setFrozen(true);
}
// ------------------------------------------------------------------------
@Override
public void onResume()
/* STK statically link SDL2. */
protected String[] getLibraries()
{
super.onResume();
if (m_hid_device_manager != null)
m_hid_device_manager.setFrozen(false);
return new String[]{ "main" };
}
// ------------------------------------------------------------------------
@Override
protected void onDestroy()
{
if (m_hid_device_manager != null)
{
HIDDeviceManager.release(m_hid_device_manager);
m_hid_device_manager = null;
}
super.onDestroy();
}
// ------------------------------------------------------------------------
@Override
public void onWindowFocusChanged(boolean has_focus)
{
super.onWindowFocusChanged(has_focus);
if (has_focus)
hideNavBar(getWindow().getDecorView());
}
// ------------------------------------------------------------------------
@Override
public boolean dispatchKeyEvent(KeyEvent event)
{
int key_code = event.getKeyCode();
int action = event.getAction();
int device_id = event.getDeviceId();
int source = event.getSource();
int meta_state = event.getMetaState();
int scan_code = event.getScanCode();
// KeyCharacterMap.COMBINING_ACCENT is not handled at the moment
int unichar = event.getUnicodeChar(meta_state);
int repeat_count = event.getRepeatCount();
// Dispatch the different events depending on where they come from
// Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
// So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD
//
// Furthermore, it's possible a game controller has SOURCE_KEYBOARD and
// SOURCE_JOYSTICK, while its key events arrive from the keyboard source
// So, retrieve the device itself and check all of its sources
if (SDLControllerManager.isDeviceSDLJoystick(device_id))
{
// Note that we process events with specific key codes here
if (action == KeyEvent.ACTION_DOWN)
{
if (SDLControllerManager.onNativePadDown(device_id, key_code, meta_state, scan_code, unichar, repeat_count) == 0)
return true;
}
else if (action == KeyEvent.ACTION_UP)
{
if (SDLControllerManager.onNativePadUp(device_id, key_code, meta_state, scan_code, unichar) == 0)
return true;
}
}
// User pressed back button
if (key_code == KeyEvent.KEYCODE_BACK &&
action == KeyEvent.ACTION_DOWN)
{
// Avoid repeating the event which leads to some strange behaviour
// For ACTION_UP it's always zero
if (repeat_count == 0)
addKey(key_code, action, meta_state, scan_code, 0);
return true;
}
boolean has_hardware_keyboard = isHardwareKeyboardConnected();
// Allow hacker keyboard (one of the native android keyboard)
// to close itself when pressing the esc button
if (key_code == KeyEvent.KEYCODE_ESCAPE &&
action == KeyEvent.ACTION_DOWN && !has_hardware_keyboard &&
m_stk_edittext != null && m_stk_edittext.isFocused())
{
hideKeyboardNative(/*clear_text*/false);
return true;
}
// Called when user change cursor / select all text in native android
// keyboard
boolean ret = super.dispatchKeyEvent(event);
if (!has_hardware_keyboard && m_stk_edittext != null)
m_stk_edittext.updateSTKEditBox();
// Allow sending navigation key event found in native android keyboard
// so user can using up or down to toggle multiple textfield
boolean send_navigation = key_code == KeyEvent.KEYCODE_DPAD_UP ||
key_code == KeyEvent.KEYCODE_DPAD_DOWN ||
key_code == KeyEvent.KEYCODE_DPAD_LEFT ||
key_code == KeyEvent.KEYCODE_DPAD_RIGHT;
// We don't send navigation event if it's consumed by input method
send_navigation = send_navigation && !ret;
if (has_hardware_keyboard || send_navigation)
{
if (has_hardware_keyboard &&
m_stk_edittext != null && m_stk_edittext.isFocused())
m_stk_edittext.beforeHideKeyboard(/*clear_text*/true);
addKey(key_code, action, meta_state, scan_code, unichar);
// We use only java to handle key for hardware keyboard
return true;
}
else
return ret;
}
// ------------------------------------------------------------------------
@Override
public boolean dispatchGenericMotionEvent(MotionEvent ev)
{
if (SDLControllerManager.useGenericMotionListener(ev))
return true;
return super.dispatchGenericMotionEvent(ev);
}
// ------------------------------------------------------------------------
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
boolean ret = super.dispatchTouchEvent(ev);
if (!ret)
{
TouchInputEvent event_type;
int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
event_type = TouchInputEvent.ETIE_PRESSED_DOWN;
break;
case MotionEvent.ACTION_MOVE:
event_type = TouchInputEvent.ETIE_MOVED;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
event_type = TouchInputEvent.ETIE_LEFT_UP;
break;
default:
return false;
}
int count = 1;
int idx = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
// Process all touches for move action.
if (event_type == TouchInputEvent.ETIE_MOVED)
{
count = ev.getPointerCount();
idx = 0;
}
for (int i = 0; i < count; i++)
{
int id = ev.getPointerId(i + idx);
int x = (int)ev.getX(i + idx);
int y = (int)ev.getY(i + idx);
if (id >= 32)
continue;
// Don't send move event when nothing changed
if (m_touch_event_data[id].event_type == event_type &&
m_touch_event_data[id].x == x &&
m_touch_event_data[id].y == y)
continue;
m_touch_event_data[id].event_type = event_type;
m_touch_event_data[id].x = x;
m_touch_event_data[id].y = y;
addTouch(id, x, y, event_type.ordinal());
}
return true;
}
return false;
}
// ------------------------------------------------------------------------
public void showKeyboard(final int type)
public void showKeyboard(final int type, final int y)
{
final Context context = this;
// Need to run in ui thread as it access the view m_stk_edittext
@@ -378,6 +134,7 @@ public class SuperTuxKartActivity extends NativeActivity
@Override
public void run()
{
m_bottom_y = y;
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null)
@@ -404,6 +161,7 @@ public class SuperTuxKartActivity extends NativeActivity
@Override
public void run()
{
m_bottom_y = 0;
hideKeyboardNative(clear_text);
}
});
@@ -486,5 +244,9 @@ public class SuperTuxKartActivity extends NativeActivity
.keyboard == Configuration.KEYBOARD_QWERTY;
}
// ------------------------------------------------------------------------
public static Context getContext() { return m_context; }
public int getScreenSize()
{
return getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
}
}