Update the fallback input mapping for the Oculus mobile devices.

This commit is contained in:
fhuya 2019-08-26 17:47:13 -07:00
parent be99e7b68f
commit 5eaaabceaf
8 changed files with 195 additions and 48 deletions

View File

@ -58,6 +58,7 @@ import android.os.Environment;
import android.os.Messenger; import android.os.Messenger;
import android.os.Vibrator; import android.os.Vibrator;
import android.provider.Settings.Secure; import android.provider.Settings.Secure;
import android.support.annotation.Keep;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.view.Display; import android.view.Display;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -101,7 +102,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
static final int REQUEST_CAMERA_PERMISSION = 2; static final int REQUEST_CAMERA_PERMISSION = 2;
static final int REQUEST_VIBRATE_PERMISSION = 3; static final int REQUEST_VIBRATE_PERMISSION = 3;
private IStub mDownloaderClientStub; private IStub mDownloaderClientStub;
private IDownloaderService mRemoteService;
private TextView mStatusText; private TextView mStatusText;
private TextView mProgressFraction; private TextView mProgressFraction;
private TextView mProgressPercent; private TextView mProgressPercent;
@ -224,15 +224,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private Sensor mMagnetometer; private Sensor mMagnetometer;
private Sensor mGyroscope; private Sensor mGyroscope;
public FrameLayout layout;
public static GodotIO io; public static GodotIO io;
public static void setWindowTitle(String title) { static SingletonBase[] singletons = new SingletonBase[MAX_SINGLETONS];
//setTitle(title);
}
static SingletonBase singletons[] = new SingletonBase[MAX_SINGLETONS];
static int singleton_count = 0; static int singleton_count = 0;
public interface ResultCallback { public interface ResultCallback {
@ -268,13 +262,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
} }
}; };
public void onVideoInit() { /**
* Used by the native code (java_godot_lib_jni.cpp) to complete initialization of the GLSurfaceView view and renderer.
*/
@Keep
private void onVideoInit() {
boolean use_gl3 = getGLESVersionCode() >= 0x00030000; boolean use_gl3 = getGLESVersionCode() >= 0x00030000;
//mView = new GodotView(getApplication(),io,use_gl3); final FrameLayout layout = new FrameLayout(this);
//setContentView(mView);
layout = new FrameLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setContentView(layout); setContentView(layout);
@ -326,11 +321,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}); });
} }
public void vibrate(int p_duration_ms) { /**
* Used by the native code (java_godot_wrapper.h) to vibrate the device.
* @param durationMs
*/
@Keep
private void vibrate(int durationMs) {
if (requestPermission("VIBRATE")) { if (requestPermission("VIBRATE")) {
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) { if (v != null) {
v.vibrate(p_duration_ms); v.vibrate(durationMs);
} }
} }
} }
@ -416,6 +416,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
/** /**
* Used by the native code (java_godot_wrapper.h) to check whether the activity is resumed or paused. * Used by the native code (java_godot_wrapper.h) to check whether the activity is resumed or paused.
*/ */
@Keep
private boolean isActivityResumed() { private boolean isActivityResumed() {
return activityResumed; return activityResumed;
} }
@ -423,10 +424,20 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
/** /**
* Used by the native code (java_godot_wrapper.h) to access the Android surface. * Used by the native code (java_godot_wrapper.h) to access the Android surface.
*/ */
@Keep
private Surface getSurface() { private Surface getSurface() {
return mView.getHolder().getSurface(); return mView.getHolder().getSurface();
} }
/**
* Used by the native code (java_godot_wrapper.h) to access the input fallback mapping.
* @return The input fallback mapping for the current XR mode.
*/
@Keep
private String getInputFallbackMapping() {
return xrMode.inputFallbackMapping;
}
String expansion_pack_path; String expansion_pack_path;
private void initializeGodot() { private void initializeGodot() {
@ -474,8 +485,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override @Override
public void onServiceConnected(Messenger m) { public void onServiceConnected(Messenger m) {
mRemoteService = DownloaderServiceMarshaller.CreateProxy(m); IDownloaderService remoteService = DownloaderServiceMarshaller.CreateProxy(m);
mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger()); remoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
} }
@Override @Override
@ -483,7 +494,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
super.onCreate(icicle); super.onCreate(icicle);
Window window = getWindow(); Window window = getWindow();
//window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
@ -609,7 +619,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mWiFiSettingsButton = (Button)findViewById(com.godot.game.R.id.wifiSettingsButton); mWiFiSettingsButton = (Button)findViewById(com.godot.game.R.id.wifiSettingsButton);
return; return;
} else {
} }
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
@ -621,8 +630,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mCurrentIntent = getIntent(); mCurrentIntent = getIntent();
initializeGodot(); initializeGodot();
//instanceSingleton( new GodotFacebook(this) );
} }
@Override @Override
@ -831,8 +838,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
} }
} }
public void forceQuit() { private void forceQuit() {
System.exit(0); System.exit(0);
} }
@ -879,7 +885,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
} }
} }
//@Override public boolean dispatchTouchEvent (MotionEvent event) {
public boolean gotTouchEvent(final MotionEvent event) { public boolean gotTouchEvent(final MotionEvent event) {
final int evcount = event.getPointerCount(); final int evcount = event.getPointerCount();
@ -950,8 +955,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0) for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
; ;
if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event); if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
final Activity me = this; mView.queueEvent(new Runnable() {
queueEvent(new Runnable() {
// This method will be called on the rendering thread: // This method will be called on the rendering thread:
public void run() { public void run() {
for (int i = 0, n = cc.length; i < n; i++) { for (int i = 0, n = cc.length; i < n; i++) {
@ -967,20 +971,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return true; return true;
} }
private void queueEvent(Runnable runnable) {
// TODO Auto-generated method stub
}
public PaymentsManager getPaymentsManager() { public PaymentsManager getPaymentsManager() {
return mPaymentsManager; return mPaymentsManager;
} }
/*
public void setPaymentsManager(PaymentsManager mPaymentsManager) {
this.mPaymentsManager = mPaymentsManager;
}
*/
public boolean requestPermission(String p_name) { public boolean requestPermission(String p_name) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Not necessary, asked on install already // Not necessary, asked on install already
@ -1025,7 +1019,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
switch (newState) { switch (newState) {
case IDownloaderClient.STATE_IDLE: case IDownloaderClient.STATE_IDLE:
// STATE_IDLE means the service is listening, so it's // STATE_IDLE means the service is listening, so it's
// safe to start making calls via mRemoteService. // safe to start making remote service calls.
paused = false; paused = false;
indeterminate = true; indeterminate = true;
break; break;

View File

@ -30,8 +30,14 @@
package org.godotengine.godot; package org.godotengine.godot;
// Wrapper for native library import android.app.Activity;
import android.hardware.SensorEvent;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Wrapper for native library
*/
public class GodotLib { public class GodotLib {
public static GodotIO io; public static GodotIO io;
@ -41,36 +47,168 @@ public class GodotLib {
} }
/** /**
* @param width the current view width * Invoked on the main thread to initialize Godot native layer.
* @param height the current view height */
*/
public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion); public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
/**
* Invoked on the main thread to clean up Godot native layer.
* @see Activity#onDestroy()
*/
public static native void ondestroy(Godot p_instance); public static native void ondestroy(Godot p_instance);
/**
* Invoked on the GL thread to complete setup for the Godot native layer logic.
* @param p_cmdline Command line arguments used to configure Godot native layer components.
*/
public static native void setup(String[] p_cmdline); public static native void setup(String[] p_cmdline);
/**
* Invoked on the GL thread when the underlying Android surface has changed size.
* @param width
* @param height
* @see android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(GL10, int, int)
*/
public static native void resize(int width, int height); public static native void resize(int width, int height);
/**
* Invoked on the GL thread when the underlying Android surface is created or recreated.
* @param p_32_bits
* @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)
*/
public static native void newcontext(boolean p_32_bits); public static native void newcontext(boolean p_32_bits);
/**
* Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
*/
public static native void back(); public static native void back();
/**
* Invoked on the GL thread to draw the current frame.
* @see android.opengl.GLSurfaceView.Renderer#onDrawFrame(GL10)
*/
public static native void step(); public static native void step();
/**
* Forward touch events from the main thread to the GL thread.
*/
public static native void touch(int what, int pointer, int howmany, int[] arr); public static native void touch(int what, int pointer, int howmany, int[] arr);
/**
* Forward accelerometer sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
public static native void accelerometer(float x, float y, float z); public static native void accelerometer(float x, float y, float z);
/**
* Forward gravity sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
public static native void gravity(float x, float y, float z); public static native void gravity(float x, float y, float z);
/**
* Forward magnetometer sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
public static native void magnetometer(float x, float y, float z); public static native void magnetometer(float x, float y, float z);
/**
* Forward gyroscope sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
public static native void gyroscope(float x, float y, float z); public static native void gyroscope(float x, float y, float z);
/**
* Forward regular key events from the main thread to the GL thread.
*/
public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed); public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
/**
* Forward game device's key events from the main thread to the GL thread.
*/
public static native void joybutton(int p_device, int p_but, boolean p_pressed); public static native void joybutton(int p_device, int p_but, boolean p_pressed);
/**
* Forward joystick devices axis motion events from the main thread to the GL thread.
*/
public static native void joyaxis(int p_device, int p_axis, float p_value); public static native void joyaxis(int p_device, int p_axis, float p_value);
/**
* Forward joystick devices hat motion events from the main thread to the GL thread.
*/
public static native void joyhat(int p_device, int p_hat_x, int p_hat_y); public static native void joyhat(int p_device, int p_hat_x, int p_hat_y);
/**
* Fires when a joystick device is added or removed.
*/
public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name); public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
/**
* Invoked when the Android activity resumes.
* @see Activity#onResume()
*/
public static native void focusin(); public static native void focusin();
/**
* Invoked when the Android activity pauses.
* @see Activity#onPause()
*/
public static native void focusout(); public static native void focusout();
/**
* Invoked when the audio thread is started.
*/
public static native void audio(); public static native void audio();
/**
* Used to setup a {@link org.godotengine.godot.Godot.SingletonBase} instance.
* @param p_name Name of the instance.
* @param p_object Reference to the singleton instance.
*/
public static native void singleton(String p_name, Object p_object); public static native void singleton(String p_name, Object p_object);
/**
* Used to complete registration of the {@link org.godotengine.godot.Godot.SingletonBase} instance's methods.
* @param p_sname Name of the instance
* @param p_name Name of the method to register
* @param p_ret Return type of the registered method
* @param p_params Method parameters types
*/
public static native void method(String p_sname, String p_name, String p_ret, String[] p_params); public static native void method(String p_sname, String p_name, String p_ret, String[] p_params);
/**
* Used to access Godot global properties.
* @param p_key Property key
* @return String value of the property
*/
public static native String getGlobal(String p_key); public static native String getGlobal(String p_key);
/**
* Invoke method |p_method| on the Godot object specified by |p_id|
* @param p_id Id of the Godot object to invoke
* @param p_method Name of the method to invoke
* @param p_params Parameters to use for method invocation
*/
public static native void callobject(int p_id, String p_method, Object[] p_params); public static native void callobject(int p_id, String p_method, Object[] p_params);
/**
* Invoke method |p_method| on the Godot object specified by |p_id| during idle time.
* @param p_id Id of the Godot object to invoke
* @param p_method Name of the method to invoke
* @param p_params Parameters to use for method invocation
*/
public static native void calldeferred(int p_id, String p_method, Object[] p_params); public static native void calldeferred(int p_id, String p_method, Object[] p_params);
/**
* Forward the results from a permission request.
* @see Activity#onRequestPermissionsResult(int, String[], int[])
* @param p_permission Request permission
* @param p_result True if the permission was granted, false otherwise
*/
public static native void requestPermissionResult(String p_permission, boolean p_result); public static native void requestPermissionResult(String p_permission, boolean p_result);
/**
* Invoked on the GL thread to configure the height of the virtual keyboard.
*/
public static native void setVirtualKeyboardHeight(int p_height); public static native void setVirtualKeyboardHeight(int p_height);
} }

View File

@ -34,16 +34,18 @@ package org.godotengine.godot.xr;
* Godot available XR modes. * Godot available XR modes.
*/ */
public enum XRMode { public enum XRMode {
REGULAR(0, "Regular", "--xr_mode_regular"), // Regular/flatscreen REGULAR(0, "Regular", "--xr_mode_regular", "Default Android Gamepad"), // Regular/flatscreen
OVR(1, "Oculus Mobile VR", "--xr_mode_ovr"); OVR(1, "Oculus Mobile VR", "--xr_mode_ovr", "");
final int index; final int index;
final String label; final String label;
public final String cmdLineArg; public final String cmdLineArg;
public final String inputFallbackMapping;
XRMode(int index, String label, String cmdLineArg) { XRMode(int index, String label, String cmdLineArg, String inputFallbackMapping) {
this.index = index; this.index = index;
this.label = label; this.label = label;
this.cmdLineArg = cmdLineArg; this.cmdLineArg = cmdLineArg;
this.inputFallbackMapping = inputFallbackMapping;
} }
} }

View File

@ -644,7 +644,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
godot_java->on_video_init(env); godot_java->on_video_init(env);
} }
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env) { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jobject obj, jobject activity) {
// lets cleanup // lets cleanup
if (godot_io_java) { if (godot_io_java) {
delete godot_io_java; delete godot_io_java;

View File

@ -38,7 +38,7 @@
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names) // See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
extern "C" { extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jobject obj, jobject activity);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits);

View File

@ -63,6 +63,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;"); _get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z"); _is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
_vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V"); _vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V");
_get_input_fallback_mapping = p_env->GetMethodID(cls, "getInputFallbackMapping", "()Ljava/lang/String;");
} }
GodotJavaWrapper::~GodotJavaWrapper() { GodotJavaWrapper::~GodotJavaWrapper() {
@ -166,6 +167,16 @@ String GodotJavaWrapper::get_clipboard() {
} }
} }
String GodotJavaWrapper::get_input_fallback_mapping() {
if (_get_input_fallback_mapping) {
JNIEnv *env = ThreadAndroid::get_env();
jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_instance, _get_input_fallback_mapping);
return jstring_to_string(fallback_mapping, env);
} else {
return String();
}
}
bool GodotJavaWrapper::has_set_clipboard() { bool GodotJavaWrapper::has_set_clipboard() {
return _set_clipboard != 0; return _set_clipboard != 0;
} }

View File

@ -58,6 +58,7 @@ private:
jmethodID _get_surface = 0; jmethodID _get_surface = 0;
jmethodID _is_activity_resumed = 0; jmethodID _is_activity_resumed = 0;
jmethodID _vibrate = 0; jmethodID _vibrate = 0;
jmethodID _get_input_fallback_mapping = 0;
public: public:
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance); GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
@ -84,6 +85,7 @@ public:
jobject get_surface(); jobject get_surface();
bool is_activity_resumed(); bool is_activity_resumed();
void vibrate(int p_duration_ms); void vibrate(int p_duration_ms);
String get_input_fallback_mapping();
}; };
#endif /* !JAVA_GODOT_WRAPPER_H */ #endif /* !JAVA_GODOT_WRAPPER_H */

View File

@ -173,7 +173,7 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
AudioDriverManager::initialize(p_audio_driver); AudioDriverManager::initialize(p_audio_driver);
input = memnew(InputDefault); input = memnew(InputDefault);
input->set_fallback_mapping("Default Android Gamepad"); input->set_fallback_mapping(godot_java->get_input_fallback_mapping());
///@TODO implement a subclass for Android and instantiate that instead ///@TODO implement a subclass for Android and instantiate that instead
camera_server = memnew(CameraServer); camera_server = memnew(CameraServer);