浏览代码

add screen and scanline result

wangyongj 2 年之前
父节点
当前提交
86e8930cef

+ 553 - 561
app/src/main/java/com/retroarch/browser/retroactivity/RetroActivityCommon.java

@@ -46,244 +46,236 @@ import java.util.Locale;
  * Class which provides common methods for RetroActivity related classes.
  */
 //public class RetroActivityCommon extends NativeActivity
-public class RetroActivityCommon extends NativeActivity
-{
-  private static final String TAG = "RetroActivityCommonTAG";
-
-  static { System.loadLibrary("retroarch-activity"); }
-
-  public static int FRONTEND_POWERSTATE_NONE = 0;
-  public static int FRONTEND_POWERSTATE_NO_SOURCE = 1;
-  public static int FRONTEND_POWERSTATE_CHARGING = 2;
-  public static int FRONTEND_POWERSTATE_CHARGED = 3;
-  public static int FRONTEND_POWERSTATE_ON_POWER_SOURCE = 4;
-  public static int FRONTEND_ORIENTATION_0 = 0;
-  public static int FRONTEND_ORIENTATION_90 = 1;
-  public static int FRONTEND_ORIENTATION_180 = 2;
-  public static int FRONTEND_ORIENTATION_270 = 3;
-  public static int RETRO_RUMBLE_STRONG = 0;
-  public static int RETRO_RUMBLE_WEAK = 1;
-  public boolean sustainedPerformanceMode = true;
-  public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
-  @Override
-  protected void onCreate(Bundle savedInstanceState) {
-    cleanupSymlinks();
-    updateSymlinks();
-
-    PlayCoreManager.getInstance().onCreate(this);
-    super.onCreate(savedInstanceState);
+public class RetroActivityCommon extends NativeActivity {
+    private static final String TAG = "RetroActivityCommonTAG";
+
+    static {
+        System.loadLibrary("retroarch-activity");
+    }
+
+    public static int FRONTEND_POWERSTATE_NONE = 0;
+    public static int FRONTEND_POWERSTATE_NO_SOURCE = 1;
+    public static int FRONTEND_POWERSTATE_CHARGING = 2;
+    public static int FRONTEND_POWERSTATE_CHARGED = 3;
+    public static int FRONTEND_POWERSTATE_ON_POWER_SOURCE = 4;
+    public static int FRONTEND_ORIENTATION_0 = 0;
+    public static int FRONTEND_ORIENTATION_90 = 1;
+    public static int FRONTEND_ORIENTATION_180 = 2;
+    public static int FRONTEND_ORIENTATION_270 = 3;
+    public static int RETRO_RUMBLE_STRONG = 0;
+    public static int RETRO_RUMBLE_WEAK = 1;
+    public boolean sustainedPerformanceMode = true;
+    public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        cleanupSymlinks();
+        updateSymlinks();
+
+        PlayCoreManager.getInstance().onCreate(this);
+        super.onCreate(savedInstanceState);
 //    startCuntDown();
-  }
-
-  private CountDownTimer mDownTimer;
-  private void startCuntDown(){
-    mDownTimer=new CountDownTimer(4000,1000) {
-      @Override
-      public void onTick(long millisUntilFinished) {
-DebugUtil.i(TAG,"onTick"+millisUntilFinished);
-      }
-
-      @Override
-      public void onFinish() {
-      finish();
-      }
-    };
-    mDownTimer.start();
-  }
-
-  @Override
-  protected void onDestroy() {
-    PlayCoreManager.getInstance().onDestroy();
-    super.onDestroy();
-  }
-
-  public void doVibrate(int id, int effect, int strength, int oneShot)
-  {
-    Vibrator vibrator = null;
-    int repeat = 0;
-    long[] pattern = {0, 16};
-    int[] strengths = {0, strength};
-
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-      if (id == -1)
-        vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
-      else
-      {
-        InputDevice dev = InputDevice.getDevice(id);
-
-        if (dev != null)
-          vibrator = dev.getVibrator();
-      }
     }
 
-    if (vibrator == null)
-      return;
+    private CountDownTimer mDownTimer;
+
+    private void startCuntDown() {
+        mDownTimer = new CountDownTimer(4000, 1000) {
+            @Override
+            public void onTick(long millisUntilFinished) {
+                DebugUtil.i(TAG, "onTick" + millisUntilFinished);
+            }
+
+            @Override
+            public void onFinish() {
+                finish();
+            }
+        };
+        mDownTimer.start();
+    }
 
-    if (strength == 0) {
-      vibrator.cancel();
-      return;
+    @Override
+    protected void onDestroy() {
+        PlayCoreManager.getInstance().onDestroy();
+        super.onDestroy();
     }
 
-    if (oneShot > 0)
-      repeat = -1;
-    else
-      pattern[1] = 1000;
+    public void doVibrate(int id, int effect, int strength, int oneShot) {
+        Vibrator vibrator = null;
+        int repeat = 0;
+        long[] pattern = {0, 16};
+        int[] strengths = {0, strength};
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            if (id == -1)
+                vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+            else {
+                InputDevice dev = InputDevice.getDevice(id);
+
+                if (dev != null)
+                    vibrator = dev.getVibrator();
+            }
+        }
 
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-      if (id >= 0)
-        Log.i("RetroActivity", "Vibrate id " + id + ": strength " + strength);
+        if (vibrator == null)
+            return;
 
-      vibrator.vibrate(VibrationEffect.createWaveform(pattern, strengths, repeat), new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME).setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build());
-    }else{
-      vibrator.vibrate(pattern, repeat);
+        if (strength == 0) {
+            vibrator.cancel();
+            return;
+        }
+
+        if (oneShot > 0)
+            repeat = -1;
+        else
+            pattern[1] = 1000;
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            if (id >= 0)
+                Log.i("RetroActivity", "Vibrate id " + id + ": strength " + strength);
+
+            vibrator.vibrate(VibrationEffect.createWaveform(pattern, strengths, repeat), new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME).setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build());
+        } else {
+            vibrator.vibrate(pattern, repeat);
+        }
     }
-  }
-
-  public void doHapticFeedback(int effect)
-  {
-    getWindow().getDecorView().performHapticFeedback(effect,
-        HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING | HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-    Log.i("RetroActivity", "Haptic Feedback effect " + effect);
-  }
-
-  // Exiting cleanly from NDK seems to be nearly impossible.
-  // Have to use exit(0) to avoid weird things happening, even with runOnUiThread() approaches.
-  // Use a separate JNI function to explicitly trigger the readback.
-  public void onRetroArchExit()
-  {
-
-      DebugUtil.i(TAG,"onRetroArchExit");
-      finish();
-  }
-
-  public int getVolumeCount()
-  {
-    int ret = 0;
-
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-      StorageManager storageManager = (StorageManager) getApplicationContext().getSystemService(Context.STORAGE_SERVICE);
-      List<StorageVolume> storageVolumeList = storageManager.getStorageVolumes();
-
-      for (int i = 0; i < storageVolumeList.size(); i++) {
-        ret++;
-      }
-      Log.i("RetroActivity", "volume count: " + ret);
+
+    public void doHapticFeedback(int effect) {
+        getWindow().getDecorView().performHapticFeedback(effect,
+                HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING | HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+        Log.i("RetroActivity", "Haptic Feedback effect " + effect);
     }
 
-    return (int)ret;
-  }
+    // Exiting cleanly from NDK seems to be nearly impossible.
+    // Have to use exit(0) to avoid weird things happening, even with runOnUiThread() approaches.
+    // Use a separate JNI function to explicitly trigger the readback.
+    public void onRetroArchExit() {
+        android.os.Process.killProcess(android.os.Process.myPid());
+        DebugUtil.i(TAG, "onRetroArchExit");
+        finish();
+    }
+
+    public int getVolumeCount() {
+        int ret = 0;
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            StorageManager storageManager = (StorageManager) getApplicationContext().getSystemService(Context.STORAGE_SERVICE);
+            List<StorageVolume> storageVolumeList = storageManager.getStorageVolumes();
+
+            for (int i = 0; i < storageVolumeList.size(); i++) {
+                ret++;
+            }
+            Log.i("RetroActivity", "volume count: " + ret);
+        }
+
+        return (int) ret;
+    }
 
-  public String getVolumePath(String input)
-  {
-    String ret = "";
+    public String getVolumePath(String input) {
+        String ret = "";
 
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-      int index = Integer.valueOf(input);
-      int j = 0;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            int index = Integer.valueOf(input);
+            int j = 0;
 
-      StorageManager storageManager = (StorageManager) getApplicationContext().getSystemService(Context.STORAGE_SERVICE);
-      List<StorageVolume> storageVolumeList = storageManager.getStorageVolumes();
+            StorageManager storageManager = (StorageManager) getApplicationContext().getSystemService(Context.STORAGE_SERVICE);
+            List<StorageVolume> storageVolumeList = storageManager.getStorageVolumes();
 
-      for (int i = 0; i < storageVolumeList.size(); i++) {
-        if (i == j) {
-          ret = String.valueOf(storageVolumeList.get(index).getDirectory());
+            for (int i = 0; i < storageVolumeList.size(); i++) {
+                if (i == j) {
+                    ret = String.valueOf(storageVolumeList.get(index).getDirectory());
+                }
+            }
+            Log.i("RetroActivity", "volume path: " + ret);
         }
-      }
-      Log.i("RetroActivity", "volume path: " + ret);
+
+        return ret;
     }
 
-    return ret;
-  }
-  public void FinishMe(int index) {
-    this.runOnUiThread(new Runnable() {
-      public void run() {
-        DebugUtil.i(TAG,"FinishMe");
-        finish();
-      }
-    });
-  }
-// https://stackoverflow.com/questions/4553650/how-to-check-device-natural-default-orientation-on-android-i-e-get-landscape/4555528#4555528
-  public int getDeviceDefaultOrientation() {
-    WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
-    Configuration config = getResources().getConfiguration();
-    int rotation = windowManager.getDefaultDisplay().getRotation();
-
-    if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
-        config.orientation == Configuration.ORIENTATION_LANDSCAPE)
-        || ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
-        config.orientation == Configuration.ORIENTATION_PORTRAIT))
-    {
-      return Configuration.ORIENTATION_LANDSCAPE;
-    }else{
-      return Configuration.ORIENTATION_PORTRAIT;
+    public void FinishMe(int index) {
+        this.runOnUiThread(new Runnable() {
+            public void run() {
+                DebugUtil.i(TAG, "FinishMe");
+                finish();
+            }
+        });
     }
-  }
-
-  public void setScreenOrientation(int orientation)
-  {
-    int naturalOrientation = getDeviceDefaultOrientation();
-    int newOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
-    // We assume no device has a natural orientation that is reversed
-    switch (naturalOrientation) {
-      case Configuration.ORIENTATION_PORTRAIT:
-      {
-        if (orientation == FRONTEND_ORIENTATION_0) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-        }else if (orientation == FRONTEND_ORIENTATION_90) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-        }else if (orientation == FRONTEND_ORIENTATION_180) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
-        }else if (orientation == FRONTEND_ORIENTATION_270) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-        }
-        break;
-      }
-      case Configuration.ORIENTATION_LANDSCAPE:
-      {
-        if (orientation == FRONTEND_ORIENTATION_0) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-        }else if (orientation == FRONTEND_ORIENTATION_90) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
-        }else if (orientation == FRONTEND_ORIENTATION_180) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-        }else if (orientation == FRONTEND_ORIENTATION_270) {
-          newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+
+    // https://stackoverflow.com/questions/4553650/how-to-check-device-natural-default-orientation-on-android-i-e-get-landscape/4555528#4555528
+    public int getDeviceDefaultOrientation() {
+        WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+        Configuration config = getResources().getConfiguration();
+        int rotation = windowManager.getDefaultDisplay().getRotation();
+
+        if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
+                config.orientation == Configuration.ORIENTATION_LANDSCAPE)
+                || ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
+                config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
+            return Configuration.ORIENTATION_LANDSCAPE;
+        } else {
+            return Configuration.ORIENTATION_PORTRAIT;
         }
-        break;
-      }
     }
 
-    screenOrientation = newOrientation;
+    public void setScreenOrientation(int orientation) {
+        int naturalOrientation = getDeviceDefaultOrientation();
+        int newOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+        // We assume no device has a natural orientation that is reversed
+        switch (naturalOrientation) {
+            case Configuration.ORIENTATION_PORTRAIT: {
+                if (orientation == FRONTEND_ORIENTATION_0) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+                } else if (orientation == FRONTEND_ORIENTATION_90) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+                } else if (orientation == FRONTEND_ORIENTATION_180) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+                } else if (orientation == FRONTEND_ORIENTATION_270) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+                }
+                break;
+            }
+            case Configuration.ORIENTATION_LANDSCAPE: {
+                if (orientation == FRONTEND_ORIENTATION_0) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+                } else if (orientation == FRONTEND_ORIENTATION_90) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+                } else if (orientation == FRONTEND_ORIENTATION_180) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+                } else if (orientation == FRONTEND_ORIENTATION_270) {
+                    newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+                }
+                break;
+            }
+        }
 
-    Log.i("RetroActivity", "setting new orientation to " + screenOrientation);
+        screenOrientation = newOrientation;
 
-    runOnUiThread(new Runnable() {
-      @Override
-      public void run() {
-        setRequestedOrientation(screenOrientation);
-      }
-    });
-  }
+        Log.i("RetroActivity", "setting new orientation to " + screenOrientation);
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                setRequestedOrientation(screenOrientation);
+            }
+        });
+    }
 
-  public String getUserLanguageString()
-  {
-    String lang = Locale.getDefault().getLanguage();
-    String country = Locale.getDefault().getCountry();
+    public String getUserLanguageString() {
+        String lang = Locale.getDefault().getLanguage();
+        String country = Locale.getDefault().getCountry();
 
-    if (lang.length() == 0)
-      return "en";
+        if (lang.length() == 0)
+            return "en";
 
-    if (country.length() == 0)
-      return lang;
+        if (country.length() == 0)
+            return lang;
 
-    return lang + '_' + country;
-  }
+        return lang + '_' + country;
+    }
 
-  @TargetApi(24)
-  public void setSustainedPerformanceMode(boolean on)
-  {
+    @TargetApi(24)
+    public void setSustainedPerformanceMode(boolean on) {
 //    sustainedPerformanceMode = on;
 //
 //    if (Build.VERSION.SDK_INT >= 24) {
@@ -308,372 +300,372 @@ DebugUtil.i(TAG,"onTick"+millisUntilFinished);
 //        }
 //      }
 //    }
-  }
+    }
+
+    @TargetApi(24)
+    public boolean isSustainedPerformanceModeSupported() {
+        boolean supported = false;
 
-  @TargetApi(24)
-  public boolean isSustainedPerformanceModeSupported()
-  {
-    boolean supported = false;
+        if (Build.VERSION.SDK_INT >= 24) {
+            PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+
+            if (powerManager.isSustainedPerformanceModeSupported())
+                supported = true;
+        }
 
-    if (Build.VERSION.SDK_INT >= 24)
-    {
-      PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
+        Log.i("RetroActivity", "isSustainedPerformanceModeSupported? " + supported);
 
-      if (powerManager.isSustainedPerformanceModeSupported())
-        supported = true;
+        return supported;
     }
 
-    Log.i("RetroActivity", "isSustainedPerformanceModeSupported? " + supported);
-
-    return supported;
-  }
-
-  public int getBatteryLevel()
-  {
-    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-    // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway
-    Intent batteryStatus = registerReceiver(null, ifilter);
-    int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
-    int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
-
-    float percent = ((float)level / (float)scale) * 100.0f;
-
-    Log.i("RetroActivity", "battery: level = " + level + ", scale = " + scale + ", percent = " + percent);
-
-    return (int)percent;
-  }
-
-  public int getPowerstate()
-  {
-    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-    // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway
-    Intent batteryStatus = registerReceiver(null, ifilter);
-    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
-    boolean hasBattery = batteryStatus.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
-    boolean isCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING);
-    boolean isCharged = (status == BatteryManager.BATTERY_STATUS_FULL);
-    int powerstate = FRONTEND_POWERSTATE_NONE;
-
-    if (isCharged)
-      powerstate = FRONTEND_POWERSTATE_CHARGED;
-    else if (isCharging)
-      powerstate = FRONTEND_POWERSTATE_CHARGING;
-    else if (!hasBattery)
-      powerstate = FRONTEND_POWERSTATE_NO_SOURCE;
-    else
-      powerstate = FRONTEND_POWERSTATE_ON_POWER_SOURCE;
-
-    Log.i("RetroActivity", "power state = " + powerstate);
-
-    return powerstate;
-  }
-
-  public boolean isAndroidTV()
-  {
-    Configuration config = getResources().getConfiguration();
-    UiModeManager uiModeManager = (UiModeManager)getSystemService(UI_MODE_SERVICE);
-
-    if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION)
-    {
-      Log.i("RetroActivity", "isAndroidTV == true");
-      return true;
+    public int getBatteryLevel() {
+        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway
+        Intent batteryStatus = registerReceiver(null, ifilter);
+        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
+
+        float percent = ((float) level / (float) scale) * 100.0f;
+
+        Log.i("RetroActivity", "battery: level = " + level + ", scale = " + scale + ", percent = " + percent);
+
+        return (int) percent;
     }
-    else
-    {
-      Log.i("RetroActivity", "isAndroidTV == false");
-      return false;
+
+    public int getPowerstate() {
+        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway
+        Intent batteryStatus = registerReceiver(null, ifilter);
+        int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+        boolean hasBattery = batteryStatus.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
+        boolean isCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING);
+        boolean isCharged = (status == BatteryManager.BATTERY_STATUS_FULL);
+        int powerstate = FRONTEND_POWERSTATE_NONE;
+
+        if (isCharged)
+            powerstate = FRONTEND_POWERSTATE_CHARGED;
+        else if (isCharging)
+            powerstate = FRONTEND_POWERSTATE_CHARGING;
+        else if (!hasBattery)
+            powerstate = FRONTEND_POWERSTATE_NO_SOURCE;
+        else
+            powerstate = FRONTEND_POWERSTATE_ON_POWER_SOURCE;
+
+        Log.i("RetroActivity", "power state = " + powerstate);
+
+        return powerstate;
     }
-  }
-
-  @Override
-  public void onConfigurationChanged(Configuration newConfig) {
-    int oldOrientation = 0;
-    boolean hasOldOrientation = false;
-
-    super.onConfigurationChanged(newConfig);
-
-    Log.i("RetroActivity", "onConfigurationChanged: orientation is now " + newConfig.orientation);
-
-    SharedPreferences prefs = UserPreferences.getPreferences(this);
-    SharedPreferences.Editor edit = prefs.edit();
-
-    hasOldOrientation = prefs.contains("ORIENTATION");
-
-    if (hasOldOrientation)
-      oldOrientation = prefs.getInt("ORIENTATION", 0);
-
-    edit.putInt("ORIENTATION", newConfig.orientation);
-    edit.apply();
-
-    Log.i("RetroActivity", "hasOldOrientation? " + hasOldOrientation + " newOrientation: " + newConfig.orientation + " oldOrientation: " + oldOrientation);
-  }
-
-  /**
-   * Checks if this version of RetroArch is a Play Store build.
-   *
-   * @return true if this is a Play Store build, false otherwise
-   */
-  public boolean isPlayStoreBuild() {
-    Log.i("RetroActivity", "isPlayStoreBuild: " + BuildConfig.PLAY_STORE_BUILD);
-
-    return BuildConfig.PLAY_STORE_BUILD;
-  }
-
-  /**
-   * Gets the list of available cores that can be downloaded as Dynamic Feature Modules.
-   *
-   * @return the list of available cores
-   */
-  public String[] getAvailableCores() {
-    int id = getResources().getIdentifier("module_names_" + Build.CPU_ABI.replace('-', '_'), "array", getPackageName());
-
-    String[] returnVal = getResources().getStringArray(id);
-    Log.i("RetroActivity", "getAvailableCores: " + Arrays.toString(returnVal));
-    return returnVal;
-  }
-
-  /**
-   * Gets the list of cores that are currently installed as Dynamic Feature Modules.
-   *
-   * @return the list of installed cores
-   */
-  public String[] getInstalledCores() {
-    String[] modules = PlayCoreManager.getInstance().getInstalledModules();
-    List<String> cores = new ArrayList<>();
-    List<String> availableCores = Arrays.asList(getAvailableCores());
-
-    SharedPreferences prefs = UserPreferences.getPreferences(this);
-
-    for(int i = 0; i < modules.length; i++) {
-      String coreName = unsanitizeCoreName(modules[i]);
-      if(!prefs.getBoolean("core_deleted_" + coreName, false)
-              && availableCores.contains(coreName)) {
-        cores.add(coreName);
-      }
+
+    public boolean isAndroidTV() {
+        Configuration config = getResources().getConfiguration();
+        UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
+
+        if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
+            Log.i("RetroActivity", "isAndroidTV == true");
+            return true;
+        } else {
+            Log.i("RetroActivity", "isAndroidTV == false");
+            return false;
+        }
     }
 
-    String[] returnVal = cores.toArray(new String[0]);
-    Log.i("RetroActivity", "getInstalledCores: " + Arrays.toString(returnVal));
-    return returnVal;
-  }
-
-  /**
-   * Asks the system to download a core.
-   *
-   * @param coreName Name of the core to install
-   */
-  public void downloadCore(final String coreName) {
-    Log.i("RetroActivity", "downloadCore: " + coreName);
-
-    SharedPreferences prefs = UserPreferences.getPreferences(this);
-    prefs.edit().remove("core_deleted_" + coreName).apply();
-
-    PlayCoreManager.getInstance().downloadCore(coreName);
-  }
-
-  /**
-   * Asks the system to delete a core.
-   *
-   * Note that the actual module deletion will not happen immediately (the OS will delete
-   * it whenever it feels like it), but the symlink will still be immediately removed.
-   *
-   * @param coreName Name of the core to delete
-   */
-  public void deleteCore(String coreName) {
-    Log.i("RetroActivity", "deleteCore: " + coreName);
-
-    String newFilename = getCorePath() + coreName + "_libretro_android.so";
-    new File(newFilename).delete();
-
-    SharedPreferences prefs = UserPreferences.getPreferences(this);
-    prefs.edit().putBoolean("core_deleted_" + coreName, true).apply();
-
-    PlayCoreManager.getInstance().deleteCore(coreName);
-  }
-
-  /////////////// JNI methods ///////////////
-  /**
-   * 点击返回时,退出库
-   */
-  public native void exitLocalGame();
-
-  /**
-   * 保存状态
-   * @param stateIndex 状态索引
-   * @return 成功返回true,失败返回false
-   */
-  public native boolean saveState(int stateIndex);
-
-  /**
-   * 加载状态
-   * @param stateIndex 状态索引
-   * @return 成功返回true,失败返回false
-   */
-  public native boolean loadState(int stateIndex);
-
-  /**
-   * 设置分辨率
-   */
-  public native void setAspectRatio(int aspectRatioIndex);
-
-  /**
-   * 设置分辨率自定义时,的位置和大小
-   */
-  public native void setCustomX(int x);
-  public native void setCustomY(int y);
-  public native void setCustomWidth(int width);
-  public native void setCustomHeight(int height);
-  public native void setCustomViewPort(int x, int y, int width, int height);
-
-  /**
-   * 切换渲染路径
-   */
-  public native void switchFilter(String path);
-
-  /**
-   * 切换渲染路径
-   */
-  public native void setInputKeys(int port, int keyBindId, int key);
-
-  /**
-   * 保存配置
-   */
-  public native void saveOverrideConfig();
-
-  /**
-   * Called when a core install is initiated.
-   *
-   * @param coreName Name of the core that the install is initiated for.
-   * @param successful true if success, false if failure
-   */
-  public native void coreInstallInitiated(String coreName, boolean successful);
-
-  /**
-   * Called when the status of a core install has changed.
-   *
-   * @param coreNames Names of all cores that are currently being downloaded.
-   * @param status One of INSTALL_STATUS_DOWNLOADING, INSTALL_STATUS_INSTALLING,
-   *               INSTALL_STATUS_INSTALLED, or INSTALL_STATUS_FAILED
-   * @param bytesDownloaded Number of bytes downloaded.
-   * @param totalBytesToDownload Total number of bytes to download.
-   */
-  public native void coreInstallStatusChanged(String[] coreNames, int status, long bytesDownloaded, long totalBytesToDownload);
-
-  /////////////// Private methods ///////////////
-  /**
-   * Sanitizes a core name so that it can be used when dealing with
-   * Dynamic Feature Modules. Needed because Gradle modules cannot use
-   * dashes, but we have at least one core name ("mesen-s") that uses them.
-   *
-   * @param coreName Name of the core to sanitize.
-   * @return The sanitized core name.
-   */
-  public String sanitizeCoreName(String coreName) {
-    return "core_" + coreName.replace('-', '_');
-  }
-
-  /**
-   * Unsanitizes a core name from its module name.
-   *
-   * @param coreName Name of the core to unsanitize.
-   * @return The unsanitized core name.
-   */
-  public String unsanitizeCoreName(String coreName) {
-    if(coreName.equals("core_mesen_s")) {
-      return "mesen-s";
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        int oldOrientation = 0;
+        boolean hasOldOrientation = false;
+
+        super.onConfigurationChanged(newConfig);
+
+        Log.i("RetroActivity", "onConfigurationChanged: orientation is now " + newConfig.orientation);
+
+        SharedPreferences prefs = UserPreferences.getPreferences(this);
+        SharedPreferences.Editor edit = prefs.edit();
+
+        hasOldOrientation = prefs.contains("ORIENTATION");
+
+        if (hasOldOrientation)
+            oldOrientation = prefs.getInt("ORIENTATION", 0);
+
+        edit.putInt("ORIENTATION", newConfig.orientation);
+        edit.apply();
+
+        Log.i("RetroActivity", "hasOldOrientation? " + hasOldOrientation + " newOrientation: " + newConfig.orientation + " oldOrientation: " + oldOrientation);
+    }
+
+    /**
+     * Checks if this version of RetroArch is a Play Store build.
+     *
+     * @return true if this is a Play Store build, false otherwise
+     */
+    public boolean isPlayStoreBuild() {
+        Log.i("RetroActivity", "isPlayStoreBuild: " + BuildConfig.PLAY_STORE_BUILD);
+
+        return BuildConfig.PLAY_STORE_BUILD;
+    }
+
+    /**
+     * Gets the list of available cores that can be downloaded as Dynamic Feature Modules.
+     *
+     * @return the list of available cores
+     */
+    public String[] getAvailableCores() {
+        int id = getResources().getIdentifier("module_names_" + Build.CPU_ABI.replace('-', '_'), "array", getPackageName());
+
+        String[] returnVal = getResources().getStringArray(id);
+        Log.i("RetroActivity", "getAvailableCores: " + Arrays.toString(returnVal));
+        return returnVal;
     }
 
-    return coreName.substring(5);
-  }
-
-  /**
-   * Gets the path to the RetroArch cores directory.
-   *
-   * @return The path to the RetroArch cores directory
-   */
-  private String getCorePath() {
-    String path = getApplicationInfo().dataDir + "/cores/";
-    new File(path).mkdirs();
-
-    return path;
-  }
-
-  /**
-   * Cleans up existing symlinks before new ones are created.
-   */
-  private void cleanupSymlinks() {
-    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
-
-    File[] files = new File(getCorePath()).listFiles();
-    for(int i = 0; i < files.length; i++) {
-      try {
-        Os.readlink(files[i].getAbsolutePath());
-        files[i].delete();
-      } catch (Exception e) {
-        // File is not a symlink, so don't delete.
-      }
+    /**
+     * Gets the list of cores that are currently installed as Dynamic Feature Modules.
+     *
+     * @return the list of installed cores
+     */
+    public String[] getInstalledCores() {
+        String[] modules = PlayCoreManager.getInstance().getInstalledModules();
+        List<String> cores = new ArrayList<>();
+        List<String> availableCores = Arrays.asList(getAvailableCores());
+
+        SharedPreferences prefs = UserPreferences.getPreferences(this);
+
+        for (int i = 0; i < modules.length; i++) {
+            String coreName = unsanitizeCoreName(modules[i]);
+            if (!prefs.getBoolean("core_deleted_" + coreName, false)
+                    && availableCores.contains(coreName)) {
+                cores.add(coreName);
+            }
+        }
+
+        String[] returnVal = cores.toArray(new String[0]);
+        Log.i("RetroActivity", "getInstalledCores: " + Arrays.toString(returnVal));
+        return returnVal;
+    }
+
+    /**
+     * Asks the system to download a core.
+     *
+     * @param coreName Name of the core to install
+     */
+    public void downloadCore(final String coreName) {
+        Log.i("RetroActivity", "downloadCore: " + coreName);
+
+        SharedPreferences prefs = UserPreferences.getPreferences(this);
+        prefs.edit().remove("core_deleted_" + coreName).apply();
+
+        PlayCoreManager.getInstance().downloadCore(coreName);
     }
-  }
-
-  /**
-   * Triggers a symlink update in the known places that Dynamic Feature Modules
-   * are installed to.
-   */
-  public void updateSymlinks() {
-    if(!isPlayStoreBuild()) return;
-
-    traverseFilesystem(getFilesDir());
-    traverseFilesystem(new File(getApplicationInfo().nativeLibraryDir));
-  }
-
-  /**
-   * Traverse the filesystem, looking for native libraries.
-   * Symlinks any libraries it finds to the main RetroArch "cores" folder,
-   * updating any existing symlinks with the correct path to the native libraries.
-   *
-   * This is necessary because Dynamic Feature Modules are first downloaded
-   * and installed to a temporary location on disk, before being moved
-   * to a more permanent location by the system at a later point.
-   *
-   * This could probably be done in native code instead, if that's preferred.
-   *
-   * @param file The parent directory of the tree to traverse.
-   */
-  private void traverseFilesystem(File file) {
-    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
-
-    File[] list = file.listFiles();
-    if(list == null) return;
-
-    List<String> availableCores = Arrays.asList(getAvailableCores());
-
-    // Check each file in a directory to see if it's a native library.
-    for(int i = 0; i < list.length; i++) {
-      File child = list[i];
-      String name = child.getName();
-
-      if(name.startsWith("lib") && name.endsWith(".so") && !name.contains("retroarch-activity")) {
-        // Found a native library!
-        String core = name.subSequence(3, name.length() - 3).toString();
-        String filename = child.getAbsolutePath();
+
+    /**
+     * Asks the system to delete a core.
+     * <p>
+     * Note that the actual module deletion will not happen immediately (the OS will delete
+     * it whenever it feels like it), but the symlink will still be immediately removed.
+     *
+     * @param coreName Name of the core to delete
+     */
+    public void deleteCore(String coreName) {
+        Log.i("RetroActivity", "deleteCore: " + coreName);
+
+        String newFilename = getCorePath() + coreName + "_libretro_android.so";
+        new File(newFilename).delete();
 
         SharedPreferences prefs = UserPreferences.getPreferences(this);
-        if(!prefs.getBoolean("core_deleted_" + core, false)
-                && availableCores.contains(core)) {
-          // Generate the destination filename and delete any existing symlinks / cores
-          String newFilename = getCorePath() + core + "_libretro_android.so";
-          new File(newFilename).delete();
-
-          try {
-            Os.symlink(filename, newFilename);
-          } catch (Exception e) {
-            // Symlink failed to be created. Should never happen.
-          }
+        prefs.edit().putBoolean("core_deleted_" + coreName, true).apply();
+
+        PlayCoreManager.getInstance().deleteCore(coreName);
+    }
+
+    /////////////// JNI methods ///////////////
+
+    /**
+     * 点击返回时,退出库
+     */
+    public native void exitLocalGame();
+
+    /**
+     * 保存状态
+     *
+     * @param stateIndex 状态索引
+     * @return 成功返回true,失败返回false
+     */
+    public native boolean saveState(int stateIndex);
+
+    /**
+     * 加载状态
+     *
+     * @param stateIndex 状态索引
+     * @return 成功返回true,失败返回false
+     */
+    public native boolean loadState(int stateIndex);
+
+    /**
+     * 设置分辨率
+     */
+    public native void setAspectRatio(int aspectRatioIndex);
+
+    /**
+     * 设置分辨率自定义时,的位置和大小
+     */
+    public native void setCustomX(int x);
+
+    public native void setCustomY(int y);
+
+    public native void setCustomWidth(int width);
+
+    public native void setCustomHeight(int height);
+
+    public native void setCustomViewPort(int x, int y, int width, int height);
+
+    /**
+     * 切换渲染路径
+     */
+    public native void switchFilter(String path);
+
+    /**
+     * 切换渲染路径
+     */
+    public native void setInputKeys(int port, int keyBindId, int key);
+
+    /**
+     * 保存配置
+     */
+    public native void saveOverrideConfig();
+
+    /**
+     * Called when a core install is initiated.
+     *
+     * @param coreName   Name of the core that the install is initiated for.
+     * @param successful true if success, false if failure
+     */
+    public native void coreInstallInitiated(String coreName, boolean successful);
+
+    /**
+     * Called when the status of a core install has changed.
+     *
+     * @param coreNames            Names of all cores that are currently being downloaded.
+     * @param status               One of INSTALL_STATUS_DOWNLOADING, INSTALL_STATUS_INSTALLING,
+     *                             INSTALL_STATUS_INSTALLED, or INSTALL_STATUS_FAILED
+     * @param bytesDownloaded      Number of bytes downloaded.
+     * @param totalBytesToDownload Total number of bytes to download.
+     */
+    public native void coreInstallStatusChanged(String[] coreNames, int status, long bytesDownloaded, long totalBytesToDownload);
+
+    /////////////// Private methods ///////////////
+
+    /**
+     * Sanitizes a core name so that it can be used when dealing with
+     * Dynamic Feature Modules. Needed because Gradle modules cannot use
+     * dashes, but we have at least one core name ("mesen-s") that uses them.
+     *
+     * @param coreName Name of the core to sanitize.
+     * @return The sanitized core name.
+     */
+    public String sanitizeCoreName(String coreName) {
+        return "core_" + coreName.replace('-', '_');
+    }
+
+    /**
+     * Unsanitizes a core name from its module name.
+     *
+     * @param coreName Name of the core to unsanitize.
+     * @return The unsanitized core name.
+     */
+    public String unsanitizeCoreName(String coreName) {
+        if (coreName.equals("core_mesen_s")) {
+            return "mesen-s";
+        }
+
+        return coreName.substring(5);
+    }
+
+    /**
+     * Gets the path to the RetroArch cores directory.
+     *
+     * @return The path to the RetroArch cores directory
+     */
+    private String getCorePath() {
+        String path = getApplicationInfo().dataDir + "/cores/";
+        new File(path).mkdirs();
+
+        return path;
+    }
+
+    /**
+     * Cleans up existing symlinks before new ones are created.
+     */
+    private void cleanupSymlinks() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
+
+        File[] files = new File(getCorePath()).listFiles();
+        for (int i = 0; i < files.length; i++) {
+            try {
+                Os.readlink(files[i].getAbsolutePath());
+                files[i].delete();
+            } catch (Exception e) {
+                // File is not a symlink, so don't delete.
+            }
+        }
+    }
+
+    /**
+     * Triggers a symlink update in the known places that Dynamic Feature Modules
+     * are installed to.
+     */
+    public void updateSymlinks() {
+        if (!isPlayStoreBuild()) return;
+
+        traverseFilesystem(getFilesDir());
+        traverseFilesystem(new File(getApplicationInfo().nativeLibraryDir));
+    }
+
+    /**
+     * Traverse the filesystem, looking for native libraries.
+     * Symlinks any libraries it finds to the main RetroArch "cores" folder,
+     * updating any existing symlinks with the correct path to the native libraries.
+     * <p>
+     * This is necessary because Dynamic Feature Modules are first downloaded
+     * and installed to a temporary location on disk, before being moved
+     * to a more permanent location by the system at a later point.
+     * <p>
+     * This could probably be done in native code instead, if that's preferred.
+     *
+     * @param file The parent directory of the tree to traverse.
+     */
+    private void traverseFilesystem(File file) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
+
+        File[] list = file.listFiles();
+        if (list == null) return;
+
+        List<String> availableCores = Arrays.asList(getAvailableCores());
+
+        // Check each file in a directory to see if it's a native library.
+        for (int i = 0; i < list.length; i++) {
+            File child = list[i];
+            String name = child.getName();
+
+            if (name.startsWith("lib") && name.endsWith(".so") && !name.contains("retroarch-activity")) {
+                // Found a native library!
+                String core = name.subSequence(3, name.length() - 3).toString();
+                String filename = child.getAbsolutePath();
+
+                SharedPreferences prefs = UserPreferences.getPreferences(this);
+                if (!prefs.getBoolean("core_deleted_" + core, false)
+                        && availableCores.contains(core)) {
+                    // Generate the destination filename and delete any existing symlinks / cores
+                    String newFilename = getCorePath() + core + "_libretro_android.so";
+                    new File(newFilename).delete();
+
+                    try {
+                        Os.symlink(filename, newFilename);
+                    } catch (Exception e) {
+                        // Symlink failed to be created. Should never happen.
+                    }
+                }
+            } else if (file.isDirectory()) {
+                // Found another directory, so traverse it
+                traverseFilesystem(child);
+            }
         }
-      } else if(file.isDirectory()) {
-        // Found another directory, so traverse it
-        traverseFilesystem(child);
-      }
     }
-  }
 }

+ 88 - 2
app/src/main/java/com/xugame/gameconsole/MainActivity.java

@@ -9,19 +9,30 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.media.AudioManager;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.Toast;
 
 import com.xugame.gameconsole.emulator.RetroArchEmulatorActivity;
 import com.xugame.gameconsole.preferences.UserPreferences;
-
+import com.xugame.gameconsole.util.Util;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -154,6 +165,7 @@ public class MainActivity extends PreferenceActivity implements View.OnClickList
                 +"\nDATADIR="+dataDirPath+"\nAPK="+dataSourcePath+
                 "\nSDCARD="+Environment.getExternalStorageDirectory().getAbsolutePath()+"\nEXTERNAL="
                 +external);
+        retro.putExtra("screenMode",screenMode);
     }
 
     @Override
@@ -182,15 +194,89 @@ public class MainActivity extends PreferenceActivity implements View.OnClickList
 
         finalStartup();
     }
-    private String corePath,romPath;
+    private String corePath,romPath,coreName;
+    private static int screenMode=0;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 //        setContentView(R.layout.activity_main);
 //        this.findView();
+        Util.init(this);
         PACKAGE_NAME = getPackageName();
         romPath=getIntent().getStringExtra("romPath");
         corePath=getIntent().getStringExtra("corePath");
+        coreName=getIntent().getStringExtra("coreName");
+        screenMode=getIntent().getIntExtra("screenMode",0);
+
+
+        checkCores();
+
+    }
+    private void checkCores(){
+        if(TextUtils.isEmpty(corePath)){
+            finish();
+        }
+        File file=new File(corePath);
+        if(file.exists()){
+            start();
+        }else {
+            startCopy(coreName,corePath);
+        }
+    }
+
+
+    private void startCopy(final String fileName, final String toPath) {
+        File file = new File(this.getFilesDir().getParent() + File.separator + "cores");
+        if (!file.exists())
+            file.mkdirs();
+        new AsyncTask<String, Integer, String>() {
+            @Override
+            protected String doInBackground(String... strings) {
+                copyFile(getFilesDir().getParent() + File.separator+"cores/" + fileName, fileName);
+                return null;
+            }
+
+            @Override
+            protected void onPostExecute(String s) {
+                start();
+                super.onPostExecute(s);
+            }
+        }.execute("");
+    }
+
+
+    private boolean copyFile(String file_path, String fileName) {
+        File baseFile=new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/arcade/cores/");
+        if(!baseFile.exists())//创建/arcade/cores文件夹
+            baseFile.mkdirs();
+
+        File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/arcade/cores/"+fileName);
+        if(!file.exists())//检测cores文件夹下是否存在.so
+            return false;
+        try {
+            InputStream in = null;
+//            in = this.getResources().getAssets().open("xucores/"+fileName);
+            in= new FileInputStream(file);
+            BufferedOutputStream outStream
+                    = new BufferedOutputStream(new FileOutputStream(file_path, false));
+            byte[] buffer = new byte[1024];
+            int size;
+            while ((size = in.read(buffer)) > 0) {
+                outStream.write(buffer, 0, size);
+            }
+            in.close();
+            outStream.flush();
+            outStream.close();
+
+            return true;
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return false;
+    }
+    private void start(){
         // Bind audio stream to hardware controls.
         setVolumeControlStream(AudioManager.STREAM_MUSIC);
 

+ 75 - 6
app/src/main/java/com/xugame/gameconsole/emulator/RetroArchEmulatorActivity.java

@@ -1,5 +1,6 @@
 package com.xugame.gameconsole.emulator;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.input.InputManager;
@@ -15,6 +16,7 @@ import com.xugame.gameconsole.dialog.gamemenu.GameMenuDialogListener;
 import com.xugame.gameconsole.preferences.ConfigFile;
 import com.xugame.gameconsole.preferences.UserPreferences;
 import com.xugame.gameconsole.util.DebugUtil;
+import com.xugame.gameconsole.util.Util;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -78,6 +80,21 @@ 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){
+                switch (screenMode) {
+                    case 0:
+                        setAspectRatio(AspectRatio.ASPECT_RATIO_CORE.getValue());
+                        break;
+                    case 1:
+                        setAspectRatio(AspectRatio.ASPECT_RATIO_FULL.getValue());
+                        break;
+                    case 2:
+                        setAspectRatio(AspectRatio.ASPECT_RATIO_CUSTOM.getValue());
+                        setCustomViewPort(Util.getSize(420), Util.getSize(87), Util.getSize(1080), Util.getSize(810));
+                        break;
+                }
+            }
         }
 
         //Checks if Android versions is above 9.0 (28) and enable the screen to write over notch if the user desires
@@ -122,14 +139,21 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
         // If QUITFOCUS parameter was set then completely exit Retroarch when focus is lost
         if (quitfocus) System.exit(0);
     }
+
     boolean isSelect = false;
     boolean isStart = false;
+
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         DebugUtil.i(TAG, "" + event.getKeyCode());
         if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
                 && event.getAction() == KeyEvent.ACTION_DOWN) {
-            showDialog();
+//            showDialog();
+            Intent intent=new Intent();//调出主菜单UI
+            ComponentName componentName=new ComponentName("com.xugame.gameconsoleMenu",
+                    "com.xugame.gameconsole.dialog.localgamesetting.LocalGameSettingDialog");
+           intent.setComponent(componentName);
+            startActivityForResult(intent,200);
             return super.dispatchKeyEvent(event);
         }
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
@@ -139,12 +163,13 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
             if (event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_START) {
                 isStart = true;
             }
-            if(isSelect&&isStart){
-                isSelect=false;
-                isStart=false;
-                DebugUtil.i(TAG,"select +start click");
+            if (isSelect && isStart) {
+                isSelect = false;
+                isStart = false;
+                DebugUtil.i(TAG, "select +start click");
             }
-        } if (event.getAction() == KeyEvent.ACTION_UP) {
+        }
+        if (event.getAction() == KeyEvent.ACTION_UP) {
             if (event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_SELECT) {
                 isSelect = false;
             } else if (event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_START) {
@@ -252,4 +277,48 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
 //                .setMessage("退出游戏?");
 //        alertDialog.show();
     }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == 200) {
+            if (resultCode == 201) {//继续游戏
+                if (data != null) {
+                    int scanLine = data.getIntExtra("scanLine", 0);
+                    int screen = data.getIntExtra("screen", 0);
+                    DebugUtil.i(TAG,"scanline="+scanLine+"screen="+screen);
+
+                    if (screen >= 0 && screen < 3) {
+                        switch (screen) {
+                            case 0:
+                                setAspectRatio(AspectRatio.ASPECT_RATIO_CORE.getValue());
+                                break;
+                            case 1:
+                                setAspectRatio(AspectRatio.ASPECT_RATIO_FULL.getValue());
+                                break;
+                            case 2:
+                                setAspectRatio(AspectRatio.ASPECT_RATIO_CUSTOM.getValue());
+                                setCustomViewPort(Util.getSize(420), Util.getSize(87), Util.getSize(1080), Util.getSize(810));
+                                break;
+                        }
+                    }
+                    if (scanLine >= 0 && scanLine < 3) {
+                        switch (ScreenType.values()[scanLine]) {
+                            case NORMAL:
+                                switchFilter(null);
+                                break;
+                            case SAI_2X:
+                                switchFilter("/data/user/0/com.xugame.gameconsole/filters/video/2xSaI.filt");
+                                break;
+                            case SCANLINE:
+                                switchFilter("/data/user/0/com.xugame.gameconsole/filters/video/Scanline2x.filt");
+                                break;
+                        }
+                    }
+                }
+            } else if (resultCode == 0) {
+                exitLocalGame();
+            }
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
 }

+ 1 - 0
app/src/main/java/com/xugame/gameconsole/preferences/UserPreferences.java

@@ -132,6 +132,7 @@ public class UserPreferences {
         //设置没有触摸屏
         config.setString("input_overlay_enable", "false");
         config.setBoolean("log_verbosity", true);
+        config.setBoolean("fps_show", true);
         config.setInt("frontend_log_level", 1);
         config.setInt("libretro_log_level", 1);
 

+ 132 - 0
app/src/main/java/com/xugame/gameconsole/util/ResUtil.java

@@ -0,0 +1,132 @@
+package com.xugame.gameconsole.util;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+
+/**
+ * Created by Frank on 2016/11/23.
+ */
+
+public class ResUtil {
+    public static final String sPackageName = null;
+
+    public static int getStringID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "string", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "string", sPackageName);
+
+    }
+
+    public static int getStringGameID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "string", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "string", sPackageName);
+
+    }
+
+    public static int getDrawableID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "drawable", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "drawable", sPackageName);
+    }
+
+    public static int getColorID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "color", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "color", sPackageName);
+    }
+
+    public static int getLayoutID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "layout", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "layout", sPackageName);
+    }
+
+    public static int getAnimID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "anim", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "anim", sPackageName);
+    }
+
+    public static int getID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "id", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "id", sPackageName);
+    }
+
+    public static int getXmlID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "xml", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "xml", sPackageName);
+    }
+
+    public static int getDimID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "dimen", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "dimen", sPackageName);
+    }
+
+    public static int getStyleID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "style", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "style", sPackageName);
+    }
+
+    public static int getArrayID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "array", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "array", sPackageName);
+    }
+
+    public static int getRawID(Context context, String name) {
+        if (sPackageName == null)
+            return context.getResources().
+                    getIdentifier(name, "raw", context.getPackageName());
+        else
+            return context.getResources().
+                    getIdentifier(name, "raw", sPackageName);
+    }
+
+    public static StateListDrawable createSelector(Drawable normal, Drawable focused) {
+        StateListDrawable stateList = new StateListDrawable();
+        int stateFocused = android.R.attr.state_focused;
+
+        stateList.addState(new int[]{-stateFocused}, normal);
+        stateList.addState(new int[]{stateFocused}, focused);
+        return stateList;
+    }
+}

文件差异内容过多而无法显示
+ 1363 - 0
app/src/main/java/com/xugame/gameconsole/util/Util.java


部分文件因为文件数量过多而无法显示