Răsfoiți Sursa

1. add environment callback
2. add set input descriptor

ZengGengSen 2 ani în urmă
părinte
comite
3adf1902c2

+ 95 - 0
app/src/main/cpp/frontend/drivers/platform_unix.c

@@ -305,6 +305,63 @@ static void android_app_free(struct android_app* android_app)
    free(android_app);
 }
 
+void android_environment_cb_native(unsigned cmd, void *data) {
+   struct android_app *app = g_android;
+   JNIEnv *env = NULL;
+   int i = 0;
+   if (!(env = jni_thread_getenv()))
+      return;
+
+   switch (cmd) {
+      case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS: {
+         struct retro_input_descriptor *desc = (struct retro_input_descriptor *) data;
+         jobject bean = NULL;
+         jobjectArray array = NULL;
+         jstring description = NULL;
+
+         for (; desc->description; ++desc) { ++i; }
+
+         if (app->beans.input_descriptor_bean.clazz == NULL
+             || app->beans.input_descriptor_bean.constructor == NULL)
+            return;
+
+         array = (*env)->NewObjectArray(
+                 env, i,
+                 app->beans.input_descriptor_bean.clazz,
+                 NULL
+         );
+
+         desc = (struct retro_input_descriptor *) data;
+         i = 0;
+         for (; desc->description; ++desc, ++i) {
+            description = (*env)->NewStringUTF(env, desc->description);
+
+            bean = (*env)->NewObject(
+                    env,
+                    app->beans.input_descriptor_bean.clazz,
+                    app->beans.input_descriptor_bean.constructor,
+                    desc->port,
+                    desc->device,
+                    desc->index,
+                    desc->id,
+                    description
+            );
+
+            (*env)->SetObjectArrayElement(env, array, i, bean);
+            (*env)->DeleteLocalRef(env, description);
+         }
+
+         CALL_VOID_METHOD_PARAM(
+                 env, app->activity->clazz,
+                 app->environmentCallback,
+                 cmd, array
+         );
+         (*env)->DeleteLocalRef(env, array);
+      }
+           break;
+   }
+}
+
 static void onDestroy(ANativeActivity* activity)
 {
    android_app_free((struct android_app*)activity->instance);
@@ -509,6 +566,40 @@ JNIEXPORT void JNICALL Java_com_retroarch_browser_retroactivity_RetroActivityCom
     android_app_write_cmd(android_app, APP_CMD_GAME_DIALOG_CLOSED);
 }
 
+JNIEXPORT void JNICALL
+Java_com_retroarch_browser_retroactivity_RetroActivityCommon_registerBeans(
+        JNIEnv *env,
+        jobject thiz) {
+    struct android_app *android_app = g_android;
+    if (android_app == NULL)
+        return;
+
+    FIND_CLASS(
+            env,
+            android_app->beans.input_descriptor_bean.clazz,
+            "com/xugame/bean/InputDescriptorBean"
+    );
+    android_app->beans.input_descriptor_bean.clazz =
+            (*env)->NewGlobalRef(env, android_app->beans.input_descriptor_bean.clazz);
+
+    GET_METHOD_ID(
+            env,
+            android_app->beans.input_descriptor_bean.constructor,
+            android_app->beans.input_descriptor_bean.clazz,
+            "<init>", "(IIIILjava/lang/String;)V"
+    );
+}
+
+JNIEXPORT void JNICALL
+Java_com_retroarch_browser_retroactivity_RetroActivityCommon_unregisterBeans(
+        JNIEnv *env,
+        jobject thiz) {
+   struct android_app *android_app = g_android;
+   if (android_app == NULL)
+      return;
+
+   (*env)->DeleteGlobalRef(env, android_app->beans.input_descriptor_bean.clazz);
+}
 /*
  * Native activity interaction (called from main thread)
  **/
@@ -2109,6 +2200,8 @@ static void frontend_unix_init(void *data)
          "getVolumePath", "(Ljava/lang/String;)Ljava/lang/String;");
    GET_METHOD_ID(env, android_app->openGameDialog, class,
                  "openGameDialog", "()V");
+   GET_METHOD_ID(env, android_app->environmentCallback, class,
+                 "environmentCallback", "(ILjava/lang/Object;)V");
 
    GET_OBJECT_CLASS(env, class, obj);
    GET_METHOD_ID(env, android_app->getStringExtra, class,
@@ -2949,3 +3042,5 @@ frontend_ctx_driver_t frontend_ctx_unix = {
 #endif
    NULL                          /* get_video_driver    */
 };
+
+

+ 10 - 0
app/src/main/cpp/frontend/drivers/platform_unix.h

@@ -182,6 +182,7 @@ struct android_app
    jmethodID getVolumePath;
 
    jmethodID openGameDialog;
+    jmethodID environmentCallback;
 
    struct
    {
@@ -192,6 +193,13 @@ struct android_app
    uint16_t rumble_last_strength_weak[MAX_USERS];
    uint16_t rumble_last_strength[MAX_USERS];
    int id[MAX_USERS];
+
+   struct {
+       struct {
+           jclass clazz;
+           jmethodID constructor;
+       } input_descriptor_bean;
+   } beans;
 };
 
 enum
@@ -370,6 +378,8 @@ void android_app_write_cmd(struct android_app *android_app, int8_t cmd);
 
 void android_dpi_get_density(char *s, size_t len);
 
+void android_environment_cb_native(unsigned cmd, void *desc);
+
 extern struct android_app *g_android;
 #endif
 

+ 1 - 0
app/src/main/cpp/runloop.c

@@ -2058,6 +2058,7 @@ bool runloop_environment_cb(unsigned cmd, void *data)
             "A (right)", "X (up)",
             "L", "R", "L2", "R2", "L3", "R3",
          };
+         android_environment_cb_native(cmd, data);
 
          if (system)
          {

+ 28 - 0
app/src/main/java/com/retroarch/browser/retroactivity/RetroActivityCommon.java

@@ -1,6 +1,9 @@
 package com.retroarch.browser.retroactivity;
 
 import com.xugame.BuildConfig;
+import com.xugame.app.EnvironmentCallback;
+import com.xugame.app.EnvironmentCallbackCmd;
+import com.xugame.bean.InputDescriptorBean;
 import com.xugame.gameconsole.playcore.PlayCoreManager;
 import com.xugame.gameconsole.preferences.UserPreferences;
 import com.xugame.gameconsole.util.DebugUtil;
@@ -65,9 +68,18 @@ public abstract class RetroActivityCommon extends NativeActivity
   public static int RETRO_RUMBLE_WEAK = 1;
   public boolean sustainedPerformanceMode = true;
   public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+  protected EnvironmentCallback callback = null;
 
   public abstract void showExitDialog();
 
+  public void environmentCallback(int cmd, Object data) {
+    if (callback == null) return;
+    Log.i(TAG, "environmentCallback");
+    if (cmd == EnvironmentCallbackCmd.SET_INPUT_DESCRIPTORS) {
+      callback.setInputDescriptors((InputDescriptorBean[]) data);
+    }
+  }
+
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     cleanupSymlinks();
@@ -78,6 +90,22 @@ public abstract class RetroActivityCommon extends NativeActivity
 //    startCuntDown();
   }
 
+  private native void registerBeans();
+  private native void unregisterBeans();
+
+  @Override
+  protected void onStart() {
+    super.onStart();
+
+    registerBeans();
+  }
+
+  @Override
+  protected void onStop() {
+    super.onStop();
+    unregisterBeans();
+  }
+
   private CountDownTimer mDownTimer;
   private void startCuntDown(){
     mDownTimer=new CountDownTimer(4000,1000) {

+ 44 - 0
app/src/main/java/com/xugame/app/AppSystem.java

@@ -0,0 +1,44 @@
+package com.xugame.app;
+
+import com.xugame.bean.InputCode;
+import com.xugame.bean.InputDescriptorBean;
+
+public class AppSystem {
+    public static final int MAX_USERS = 16;
+
+    public static final int DEVICE_NONE = 0;
+    public static final int DEVICE_JOYPAD = 1;
+    public static final int DEVICE_ANALOG = 5;
+
+    public static final int DEVICE_ID_JOYPAD_B = 0;
+    public static final int DEVICE_ID_JOYPAD_Y = 1;
+    public static final int DEVICE_ID_JOYPAD_SELECT = 2;
+    public static final int DEVICE_ID_JOYPAD_START = 3;
+    public static final int DEVICE_ID_JOYPAD_UP = 4;
+    public static final int DEVICE_ID_JOYPAD_DOWN = 5;
+    public static final int DEVICE_ID_JOYPAD_LEFT = 6;
+    public static final int DEVICE_ID_JOYPAD_RIGHT = 7;
+    public static final int DEVICE_ID_JOYPAD_A = 8;
+    public static final int DEVICE_ID_JOYPAD_X = 9;
+    public static final int DEVICE_ID_JOYPAD_L = 10;
+    public static final int DEVICE_ID_JOYPAD_R = 11;
+    public static final int DEVICE_ID_JOYPAD_L2 = 12;
+    public static final int DEVICE_ID_JOYPAD_R2 = 13;
+    public static final int DEVICE_ID_JOYPAD_L3 = 14;
+    public static final int DEVICE_ID_JOYPAD_R3 = 15;
+
+    public static final int DEVICE_ID_ANALOG_X = 0;
+    public static final int DEVICE_ID_ANALOG_Y = 1;
+
+    public static final int DEVICE_INDEX_ANALOG_LEFT = 0;
+    public static final int DEVICE_INDEX_ANALOG_RIGHT = 1;
+    public static final int DEVICE_INDEX_ANALOG_BUTTON = 2;
+
+    public String[][] inputDescriptors;
+    public boolean hasInputDescriptors;
+
+    public AppSystem() {
+        this.inputDescriptors = new String[MAX_USERS][InputCode.INPUT_CODE_END];
+        this.hasInputDescriptors = false;
+    }
+}

+ 11 - 0
app/src/main/java/com/xugame/app/EnvironmentCallback.java

@@ -0,0 +1,11 @@
+package com.xugame.app;
+
+import android.util.Log;
+
+import com.xugame.bean.InputDescriptorBean;
+
+import java.util.Arrays;
+
+public interface EnvironmentCallback {
+    public void setInputDescriptors(InputDescriptorBean[] descriptors);
+}

+ 4 - 0
app/src/main/java/com/xugame/app/EnvironmentCallbackCmd.java

@@ -0,0 +1,4 @@
+package com.xugame.app;
+public class EnvironmentCallbackCmd {
+    public static final int SET_INPUT_DESCRIPTORS = 11;
+}

+ 31 - 0
app/src/main/java/com/xugame/bean/InputCode.java

@@ -0,0 +1,31 @@
+package com.xugame.bean;
+
+public class InputCode {
+    public static final int JOYPAD_B = 0;
+    public static final int JOYPAD_Y = 1;
+    public static final int JOYPAD_SELECT = 2;
+    public static final int JOYPAD_START = 3;
+    public static final int JOYPAD_UP = 4;
+    public static final int JOYPAD_DOWN = 5;     
+    public static final int JOYPAD_LEFT = 6;     
+    public static final int JOYPAD_RIGHT = 7;
+    public static final int JOYPAD_A = 8;        
+    public static final int JOYPAD_X = 9;        
+    public static final int JOYPAD_L = 10;       
+    public static final int JOYPAD_R = 11;
+    public static final int JOYPAD_L2 = 12;      
+    public static final int JOYPAD_R2 = 13;      
+    public static final int JOYPAD_L3 = 14;      
+    public static final int JOYPAD_R3 = 15;
+
+    public static final int ANALOG_LEFT_X_PLUS = 16;
+    public static final int ANALOG_LEFT_X_MINUS = 17;
+    public static final int ANALOG_LEFT_Y_PLUS = 18;
+    public static final int ANALOG_LEFT_Y_MINUS = 19;
+    public static final int ANALOG_RIGHT_X_PLUS = 20;
+    public static final int ANALOG_RIGHT_X_MINUS = 21;
+    public static final int ANALOG_RIGHT_Y_PLUS = 22;
+    public static final int ANALOG_RIGHT_Y_MINUS = 23;
+
+    public static final int INPUT_CODE_END = 24;
+}

+ 66 - 0
app/src/main/java/com/xugame/bean/InputDescriptorBean.java

@@ -0,0 +1,66 @@
+package com.xugame.bean;
+
+public class InputDescriptorBean {
+    // 玩家的输入端口
+    private int port;
+
+    // 设备 类型:None, JoyPad, Keyboard ...
+    private int device;
+
+    // 索引,Analog 设备的选择
+    private int index;
+
+    // 映射的按键 ID
+    private int id;
+
+    // 按键的用法描述
+    private String description;
+
+    public InputDescriptorBean(int port, int device, int index, int id, String description) {
+        this.port = port;
+        this.device = device;
+        this.index = index;
+        this.id = id;
+        this.description = description;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public int getDevice() {
+        return device;
+    }
+
+    public void setDevice(int device) {
+        this.device = device;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}

+ 85 - 8
app/src/main/java/com/xugame/gameconsole/emulator/RetroArchEmulatorActivity.java

@@ -5,12 +5,17 @@ import android.content.Context;
 import android.content.Intent;
 import android.hardware.input.InputManager;
 import android.os.Build;
+import android.os.Bundle;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.WindowManager;
 
 import com.retroarch.browser.retroactivity.AspectRatio;
+import com.xugame.app.AppSystem;
+import com.xugame.app.EnvironmentCallback;
+import com.xugame.bean.InputCode;
+import com.xugame.bean.InputDescriptorBean;
 import com.xugame.gameconsole.dialog.gamemenu.GameMenuDialog;
 import com.xugame.gameconsole.dialog.gamemenu.GameMenuDialogListener;
 import com.xugame.gameconsole.preferences.ConfigFile;
@@ -35,6 +40,78 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
     // If set to true then Retroarch will completely exit when it loses focus
     private boolean quitfocus = false;
 
+    private AppSystem system = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        system = new AppSystem();
+
+        callback = new EnvironmentCallback() {
+            @Override
+            public void setInputDescriptors(InputDescriptorBean[] descriptors) {
+                for (int i = 0; i < descriptors.length; i++) {
+                    Log.i(
+                            "EnvironmentCallback",
+                            "i: " + i
+                                    + ", port: " + descriptors[i].getPort()
+                                    + ", device: " + descriptors[i].getDevice()
+                                    + ", index: " + descriptors[i].getIndex()
+                                    + ", id: " + descriptors[i].getId()
+                                    + ", desc: " + descriptors[i].getDescription()
+                    );
+
+                    if (descriptors[i].getPort() >= AppSystem.MAX_USERS)
+                        continue;
+
+                    if (descriptors[i].getId() >= 16)
+                        continue;
+
+                    if (descriptors[i].getDevice() == AppSystem.DEVICE_JOYPAD) {
+                        system.inputDescriptors[descriptors[i].getPort()]
+                                [descriptors[i].getId()] = descriptors[i].getDescription();
+                    } else if (descriptors[i].getDevice() == AppSystem.DEVICE_ANALOG) {
+                        if (descriptors[i].getId() == AppSystem.DEVICE_ID_ANALOG_X) {
+                            if (descriptors[i].getIndex() == AppSystem.DEVICE_INDEX_ANALOG_LEFT) {
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_LEFT_X_PLUS] = descriptors[i].getDescription();
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_LEFT_X_MINUS] = descriptors[i].getDescription();
+                            } else if (descriptors[i].getIndex() == AppSystem.DEVICE_INDEX_ANALOG_RIGHT) {
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_RIGHT_X_PLUS] = descriptors[i].getDescription();
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_RIGHT_X_MINUS] = descriptors[i].getDescription();
+                            }
+                        } else if (descriptors[i].getId() == AppSystem.DEVICE_ID_ANALOG_Y) {
+                            if (descriptors[i].getIndex() == AppSystem.DEVICE_INDEX_ANALOG_LEFT) {
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_LEFT_Y_PLUS] = descriptors[i].getDescription();
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_LEFT_Y_MINUS] = descriptors[i].getDescription();
+                            } else if (descriptors[i].getIndex() == AppSystem.DEVICE_INDEX_ANALOG_RIGHT) {
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_RIGHT_Y_PLUS] = descriptors[i].getDescription();
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [InputCode.ANALOG_RIGHT_Y_MINUS] = descriptors[i].getDescription();
+                            }
+                        } else if (descriptors[i].getId() == AppSystem.DEVICE_ID_JOYPAD_L2
+                                || descriptors[i].getId() == AppSystem.DEVICE_ID_JOYPAD_R2
+                        ) {
+                            if (descriptors[i].getIndex() == AppSystem.DEVICE_INDEX_ANALOG_BUTTON) {
+                                system.inputDescriptors[descriptors[i].getPort()]
+                                        [descriptors[i].getId()] = descriptors[i].getDescription();
+                            }
+                        }
+                    }
+                }
+
+                system.hasInputDescriptors = true;
+            }
+        };
+    }
+
     @Override
     public void showLocalExitDialog() {
         runOnUiThread(new Runnable() {
@@ -44,7 +121,7 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
             }
         });
 
-        DebugUtil.i(TAG,"showLocalExitDialog");
+        DebugUtil.i(TAG, "showLocalExitDialog");
     }
 
     @Override
@@ -92,8 +169,8 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
             // This requires NVIDIA Android extensions (available on NVIDIA Shield), if they are not
             // available then nothing will be done
             if (retro.hasExtra("HIDEMOUSE")) hideMouseCursor();
-            int screenMode=retro.getIntExtra("screenMode",0);
-            if(screenMode>=0&&screenMode<3){
+            int screenMode = retro.getIntExtra("screenMode", 0);
+            if (screenMode >= 0 && screenMode < 3) {
                 switch (screenMode) {
                     case 0:
                         setAspectRatio(AspectRatio.ASPECT_RATIO_CORE.getValue());
@@ -158,11 +235,11 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
         if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
                 && event.getAction() == KeyEvent.ACTION_DOWN) {
 //            showDialog();
-            Intent intent=new Intent();//调出主菜单UI
-            ComponentName componentName=new ComponentName("com.xugame.gameconsoleMenu",
+            Intent intent = new Intent();//调出主菜单UI
+            ComponentName componentName = new ComponentName("com.xugame.gameconsoleMenu",
                     "com.xugame.gameconsole.dialog.localgamesetting.LocalGameSettingDialog");
-           intent.setComponent(componentName);
-            startActivityForResult(intent,200);
+            intent.setComponent(componentName);
+            startActivityForResult(intent, 200);
             return super.dispatchKeyEvent(event);
         }
 
@@ -275,7 +352,7 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
                 if (data != null) {
                     int scanLine = data.getIntExtra("scanLine", 0);
                     int screen = data.getIntExtra("screen", 0);
-                    DebugUtil.i(TAG,"scanline="+scanLine+"screen="+screen);
+                    DebugUtil.i(TAG, "scanline=" + scanLine + "screen=" + screen);
 
                     if (screen >= 0 && screen < 3) {
                         switch (screen) {