diff --git a/src/nme/ui/GameInput.hx b/src/nme/ui/GameInput.hx index 25bb247d8..4e6b609aa 100644 --- a/src/nme/ui/GameInput.hx +++ b/src/nme/ui/GameInput.hx @@ -16,6 +16,7 @@ class GameInput extends EventDispatcher static var nmeDevices = new Array(); static var nmeInstances = []; static var nmeKeyboardDevices = new Array(); + static var added = false; public function new() @@ -23,6 +24,20 @@ class GameInput extends EventDispatcher super(); nmeInstances.push(this); + #if android + if (!added) + { + var setInputManagerCallback = JNI.createStaticMethod( + "org/haxe/nme/GameActivity", + "setInputManagerCallback", + "(Lorg/haxe/nme/HaxeObject;)[I" ); + added = true; + var existing:Array = setInputManagerCallback(this); + for(device in existing) + nme.app.Application.runOnMainThread( () -> nmeGamepadConnect(device) ); + } + #end + //Called from Stage //if (nmeInstances.length==1) //{ @@ -34,6 +49,22 @@ class GameInput extends EventDispatcher //} } + #if android + // Called from android handler + @keep function onInputDeviceAdded(device:Int) + { + nmeGamepadConnect(device); + } + @keep function onInputDeviceChanged(device:Int) + { + // ? + } + @keep function onInputDeviceRemoved(device:Int) + { + nmeGamepadDisconnect(device); + } + #end + public function addKeyboardDevice0() : GameInputDevice { if (nmeKeyboardDevices[0]!=null) @@ -107,7 +138,11 @@ class GameInput extends EventDispatcher static function getGamepadGuid(index:Int) : String { // TODO + #if android + return ""+index; + #else return "guid"+index; + #end } diff --git a/src/nme/ui/GameInputDevice.hx b/src/nme/ui/GameInputDevice.hx index ae1ce47cb..7452be936 100644 --- a/src/nme/ui/GameInputDevice.hx +++ b/src/nme/ui/GameInputDevice.hx @@ -13,6 +13,9 @@ class GameInputDevice public var name(default, null):String; public var numControls(get, never):Int; public var sampleInterval:Int; + #if android + public var androidDevice:Int; + #end var nmeAxis = new Map (); var nmeButton = new Map (); @@ -25,6 +28,10 @@ class GameInputDevice { this.id = id; this.name = name; + #if android + androidDevice = Std.parseInt(id); + #end + var control; for (i in 0...6) { diff --git a/templates/android/java/org/haxe/nme/GameActivity.java b/templates/android/java/org/haxe/nme/GameActivity.java index e74abaaec..eda1aec3e 100644 --- a/templates/android/java/org/haxe/nme/GameActivity.java +++ b/templates/android/java/org/haxe/nme/GameActivity.java @@ -65,6 +65,8 @@ import org.json.JSONException; import java.io.StringWriter; import java.io.PrintWriter; +import android.hardware.input.InputManager; +import android.view.MotionEvent; import androidx.core.content.ContextCompat; import android.content.pm.PackageManager; @@ -112,6 +114,7 @@ public class GameActivity extends ::GAME_ACTIVITY_BASE:: static HashMap mLoadedClasses = new HashMap(); static SensorManager sensorManager; static android.text.ClipboardManager mClipboard; + static InputManager inputManager; private static List extensions; ::if NME_FIREBASE:: @@ -137,6 +140,13 @@ class NmeText extends EditText if (activity!=null) activity.onSelectionChanged(selStart,selEnd); } + + // The view gets the events if it has focus + @Override public boolean onGenericMotionEvent(MotionEvent event) + { + //Log.v(TAG,"NME Forward MotionEvent" + event); + return activity.mView.onGenericMotionEvent(event); + } } ArrayList mOnDestroyListeners; @@ -374,6 +384,31 @@ public static int billingClientCode() } ::end:: + public static int[] setInputManagerCallback(final HaxeObject inCallback) + { + final HaxeObject callback = inCallback; + inputManager = (InputManager)activity.mContext.getSystemService(Context.INPUT_SERVICE); + inputManager.registerInputDeviceListener( new InputManager.InputDeviceListener() { + @Override public void onInputDeviceAdded(final int deviceId) { + sendHaxe( new Runnable() { + @Override public void run() { + callback.call1("onInputDeviceAdded", deviceId); + } }); } + @Override public void onInputDeviceChanged(final int deviceId) { + sendHaxe( new Runnable() { + @Override public void run() { + callback.call1("onInputDeviceChanged", deviceId); + } }); } + @Override public void onInputDeviceRemoved(final int deviceId) { + sendHaxe( new Runnable() { + @Override public void run() { + callback.call1("onInputDeviceRemoved", deviceId); + } }); } + }, activity.mHandler); + + return inputManager.getInputDeviceIds(); + } + public void createStageVideoSync(HaxeObject inHandler) { diff --git a/templates/android/java/org/haxe/nme/MainView.java b/templates/android/java/org/haxe/nme/MainView.java index f144f0ab9..6d267d772 100644 --- a/templates/android/java/org/haxe/nme/MainView.java +++ b/templates/android/java/org/haxe/nme/MainView.java @@ -321,35 +321,58 @@ static public void renderNow() mRefreshView.requestRender(); } - public boolean onGenericMotionEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { - if (event.getAction() == MotionEvent.ACTION_MOVE) { - //TODO: process the joystick movement... - return true; - } - } - if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { - switch (event.getAction()) { - case MotionEvent.ACTION_HOVER_MOVE: - //TODO process the mouse hover movement... - return true; - case MotionEvent.ACTION_HOVER_EXIT: - //TODO process the mouse exit .. - return true; - case MotionEvent.ACTION_SCROLL: - final MainView me = this; - final float x = event.getRawX(); - final float y = event.getRawY(); - //previous behavior in nme was 3 for down, 4 for up - final int event_dir = event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f ? 4 : 3; - queueEvent(new Runnable(){ - public void run() { me.HandleResult(NME.onMouseWheel(x,y,event_dir) ); } - }); - return true; - } - } - return super.onGenericMotionEvent(event); - } + @Override + public boolean onGenericMotionEvent(MotionEvent event) + { + //Log.e("NME VIEW", "Joystick " + event ); + final MainView me = this; + if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) + { + if (event.getAction() == MotionEvent.ACTION_MOVE) + { + final int deviceId = event.getDeviceId(); + + //Log.e("VIEW", "Joystick " + deviceId ); + queueEvent(new Runnable() { + // This method will be called on the rendering thread: + public void run() { + float [] axisValues = { + event.getAxisValue(MotionEvent.AXIS_X), + event.getAxisValue(MotionEvent.AXIS_Y), + event.getAxisValue(MotionEvent.AXIS_HAT_X), + event.getAxisValue(MotionEvent.AXIS_HAT_Y) + }; + + //Log.e("VIEW", "Joystick axis ->" + axisValues ); + + me.HandleResult(NME.onJoyChange(deviceId,0,false)); + }}); + return true; + } + } + if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) + { + switch (event.getAction()) + { + case MotionEvent.ACTION_HOVER_MOVE: + //TODO process the mouse hover movement... + return true; + case MotionEvent.ACTION_HOVER_EXIT: + //TODO process the mouse exit .. + return true; + case MotionEvent.ACTION_SCROLL: + final float x = event.getRawX(); + final float y = event.getRawY(); + //previous behavior in nme was 3 for down, 4 for up + final int event_dir = event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f ? 4 : 3; + queueEvent(new Runnable(){ + public void run() { me.HandleResult(NME.onMouseWheel(x,y,event_dir) ); } + }); + return true; + } + } + return super.onGenericMotionEvent(event); + } @Override public void onPause () { @@ -512,6 +535,7 @@ public void run() { } + private static class Renderer implements GLSurfaceView.Renderer { MainView mMainView;