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

@@ -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;
}
}