summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/java')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.java197
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/dialogs/MotionAlertDialog.java140
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.java10
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/InputBindingSetting.java382
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumHeader.java12
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumSingleChoiceSetting.java59
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.java11
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.java125
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java198
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java55
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/PremiumViewHolder.java57
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.java14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java102
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.java1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java54
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainPresenter.java11
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/BillingManager.java215
17 files changed, 51 insertions, 1592 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.java
index cd64a3298..f4fca40e4 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.java
@@ -3,17 +3,13 @@ package org.yuzu.yuzu_emu.activities;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
-import android.util.SparseIntArray;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SeekBar;
@@ -31,20 +27,14 @@ import androidx.fragment.app.FragmentManager;
import org.yuzu.yuzu_emu.NativeLibrary;
import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.view.InputBindingSetting;
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity;
-import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile;
import org.yuzu.yuzu_emu.fragments.EmulationFragment;
import org.yuzu.yuzu_emu.fragments.MenuFragment;
import org.yuzu.yuzu_emu.utils.ControllerMappingHelper;
-import org.yuzu.yuzu_emu.utils.EmulationMenuSettings;
import org.yuzu.yuzu_emu.utils.ForegroundService;
import java.lang.annotation.Retention;
import java.util.List;
-import static android.Manifest.permission.CAMERA;
-import static android.Manifest.permission.RECORD_AUDIO;
import static java.lang.annotation.RetentionPolicy.SOURCE;
public final class EmulationActivity extends AppCompatActivity {
@@ -198,77 +188,6 @@ public final class EmulationActivity extends AppCompatActivity {
}
}
- // Gets button presses
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (mMenuVisible || event.getKeyCode() == KeyEvent.KEYCODE_BACK)
- {
- return super.dispatchKeyEvent(event);
- }
-
- int action;
- int button = mPreferences.getInt(InputBindingSetting.getInputButtonKey(event.getKeyCode()), event.getKeyCode());
-
- switch (event.getAction()) {
- case KeyEvent.ACTION_DOWN:
- // Handling the case where the back button is pressed.
- if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- onBackPressed();
- return true;
- }
-
- // Normal key events.
- action = NativeLibrary.ButtonState.PRESSED;
- break;
- case KeyEvent.ACTION_UP:
- action = NativeLibrary.ButtonState.RELEASED;
- break;
- default:
- return false;
- }
- InputDevice input = event.getDevice();
-
- if (input == null) {
- // Controller was disconnected
- return false;
- }
-
- return NativeLibrary.onGamePadEvent(input.getDescriptor(), button, action);
- }
-
- private void toggleControls() {
- final SharedPreferences.Editor editor = mPreferences.edit();
- boolean[] enabledButtons = new boolean[14];
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.emulation_toggle_controls);
-
- for (int i = 0; i < enabledButtons.length; i++) {
- // Buttons that are disabled by default
- boolean defaultValue = true;
- switch (i) {
- case 6: // ZL
- case 7: // ZR
- case 12: // C-stick
- defaultValue = false;
- break;
- }
-
- enabledButtons[i] = mPreferences.getBoolean("buttonToggle" + i, defaultValue);
- }
- builder.setMultiChoiceItems(R.array.n3dsButtons, enabledButtons,
- (dialog, indexSelected, isChecked) -> editor
- .putBoolean("buttonToggle" + indexSelected, isChecked));
- builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) ->
- {
- editor.apply();
-
- mEmulationFragment.refreshInputOverlay();
- });
-
- AlertDialog alertDialog = builder.create();
- alertDialog.show();
- }
-
private void adjustScale() {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.dialog_seekbar, null);
@@ -377,122 +296,6 @@ public final class EmulationActivity extends AppCompatActivity {
return super.dispatchTouchEvent(event);
}
- @Override
- public boolean dispatchGenericMotionEvent(MotionEvent event) {
- if (mMenuVisible)
- {
- return false;
- }
-
- if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)) {
- return super.dispatchGenericMotionEvent(event);
- }
-
- // Don't attempt to do anything if we are disconnecting a device.
- if (event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
- return true;
- }
-
- InputDevice input = event.getDevice();
- List<InputDevice.MotionRange> motions = input.getMotionRanges();
-
- float[] axisValuesCirclePad = {0.0f, 0.0f};
- float[] axisValuesCStick = {0.0f, 0.0f};
- float[] axisValuesDPad = {0.0f, 0.0f};
- boolean isTriggerPressedLMapped = false;
- boolean isTriggerPressedRMapped = false;
- boolean isTriggerPressedZLMapped = false;
- boolean isTriggerPressedZRMapped = false;
- boolean isTriggerPressedL = false;
- boolean isTriggerPressedR = false;
- boolean isTriggerPressedZL = false;
- boolean isTriggerPressedZR = false;
-
- for (InputDevice.MotionRange range : motions) {
- int axis = range.getAxis();
- float origValue = event.getAxisValue(axis);
- float value = mControllerMappingHelper.scaleAxis(input, axis, origValue);
- int nextMapping = mPreferences.getInt(InputBindingSetting.getInputAxisButtonKey(axis), -1);
- int guestOrientation = mPreferences.getInt(InputBindingSetting.getInputAxisOrientationKey(axis), -1);
-
- if (nextMapping == -1 || guestOrientation == -1) {
- // Axis is unmapped
- continue;
- }
-
- if ((value > 0.f && value < 0.1f) || (value < 0.f && value > -0.1f)) {
- // Skip joystick wobble
- value = 0.f;
- }
-
- if (nextMapping == NativeLibrary.ButtonType.STICK_LEFT) {
- axisValuesCirclePad[guestOrientation] = value;
- } else if (nextMapping == NativeLibrary.ButtonType.STICK_C) {
- axisValuesCStick[guestOrientation] = value;
- } else if (nextMapping == NativeLibrary.ButtonType.DPAD) {
- axisValuesDPad[guestOrientation] = value;
- } else if (nextMapping == NativeLibrary.ButtonType.TRIGGER_L) {
- isTriggerPressedLMapped = true;
- isTriggerPressedL = value != 0.f;
- } else if (nextMapping == NativeLibrary.ButtonType.TRIGGER_R) {
- isTriggerPressedRMapped = true;
- isTriggerPressedR = value != 0.f;
- } else if (nextMapping == NativeLibrary.ButtonType.BUTTON_ZL) {
- isTriggerPressedZLMapped = true;
- isTriggerPressedZL = value != 0.f;
- } else if (nextMapping == NativeLibrary.ButtonType.BUTTON_ZR) {
- isTriggerPressedZRMapped = true;
- isTriggerPressedZR = value != 0.f;
- }
- }
-
- // Circle-Pad and C-Stick status
- NativeLibrary.onGamePadMoveEvent(input.getDescriptor(), NativeLibrary.ButtonType.STICK_LEFT, axisValuesCirclePad[0], axisValuesCirclePad[1]);
- NativeLibrary.onGamePadMoveEvent(input.getDescriptor(), NativeLibrary.ButtonType.STICK_C, axisValuesCStick[0], axisValuesCStick[1]);
-
- // Triggers L/R and ZL/ZR
- if (isTriggerPressedLMapped) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.TRIGGER_L, isTriggerPressedL ? NativeLibrary.ButtonState.PRESSED : NativeLibrary.ButtonState.RELEASED);
- }
- if (isTriggerPressedRMapped) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.TRIGGER_R, isTriggerPressedR ? NativeLibrary.ButtonState.PRESSED : NativeLibrary.ButtonState.RELEASED);
- }
- if (isTriggerPressedZLMapped) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.BUTTON_ZL, isTriggerPressedZL ? NativeLibrary.ButtonState.PRESSED : NativeLibrary.ButtonState.RELEASED);
- }
- if (isTriggerPressedZRMapped) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.BUTTON_ZR, isTriggerPressedZR ? NativeLibrary.ButtonState.PRESSED : NativeLibrary.ButtonState.RELEASED);
- }
-
- // Work-around to allow D-pad axis to be bound to emulated buttons
- if (axisValuesDPad[0] == 0.f) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_LEFT, NativeLibrary.ButtonState.RELEASED);
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_RIGHT, NativeLibrary.ButtonState.RELEASED);
- }
- if (axisValuesDPad[0] < 0.f) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_LEFT, NativeLibrary.ButtonState.PRESSED);
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_RIGHT, NativeLibrary.ButtonState.RELEASED);
- }
- if (axisValuesDPad[0] > 0.f) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_LEFT, NativeLibrary.ButtonState.RELEASED);
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_RIGHT, NativeLibrary.ButtonState.PRESSED);
- }
- if (axisValuesDPad[1] == 0.f) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_UP, NativeLibrary.ButtonState.RELEASED);
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_DOWN, NativeLibrary.ButtonState.RELEASED);
- }
- if (axisValuesDPad[1] < 0.f) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_UP, NativeLibrary.ButtonState.PRESSED);
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_DOWN, NativeLibrary.ButtonState.RELEASED);
- }
- if (axisValuesDPad[1] > 0.f) {
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_UP, NativeLibrary.ButtonState.RELEASED);
- NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, NativeLibrary.ButtonType.DPAD_DOWN, NativeLibrary.ButtonState.PRESSED);
- }
-
- return true;
- }
-
public boolean isActivityRecreated() {
return activityRecreated;
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/dialogs/MotionAlertDialog.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/dialogs/MotionAlertDialog.java
deleted file mode 100644
index 874c1acbc..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/dialogs/MotionAlertDialog.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.yuzu.yuzu_emu.dialogs;
-
-import android.content.Context;
-import android.view.InputDevice;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-
-import org.yuzu.yuzu_emu.features.settings.model.view.InputBindingSetting;
-import org.yuzu.yuzu_emu.utils.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@link AlertDialog} derivative that listens for
- * motion events from controllers and joysticks.
- */
-public final class MotionAlertDialog extends AlertDialog {
- // The selected input preference
- private final InputBindingSetting setting;
- private final ArrayList<Float> mPreviousValues = new ArrayList<>();
- private int mPrevDeviceId = 0;
- private boolean mWaitingForEvent = true;
-
- /**
- * Constructor
- *
- * @param context The current {@link Context}.
- * @param setting The Preference to show this dialog for.
- */
- public MotionAlertDialog(Context context, InputBindingSetting setting) {
- super(context);
-
- this.setting = setting;
- }
-
- public boolean onKeyEvent(int keyCode, KeyEvent event) {
- Log.debug("[MotionAlertDialog] Received key event: " + event.getAction());
- switch (event.getAction()) {
- case KeyEvent.ACTION_UP:
- setting.onKeyInput(event);
- dismiss();
- // Even if we ignore the key, we still consume it. Thus return true regardless.
- return true;
-
- default:
- return false;
- }
- }
-
- @Override
- public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event) {
- return super.onKeyLongPress(keyCode, event);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- // Handle this key if we care about it, otherwise pass it down the framework
- return onKeyEvent(event.getKeyCode(), event) || super.dispatchKeyEvent(event);
- }
-
- @Override
- public boolean dispatchGenericMotionEvent(@NonNull MotionEvent event) {
- // Handle this event if we care about it, otherwise pass it down the framework
- return onMotionEvent(event) || super.dispatchGenericMotionEvent(event);
- }
-
- private boolean onMotionEvent(MotionEvent event) {
- if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)
- return false;
- if (event.getAction() != MotionEvent.ACTION_MOVE)
- return false;
-
- InputDevice input = event.getDevice();
-
- List<InputDevice.MotionRange> motionRanges = input.getMotionRanges();
-
- if (input.getId() != mPrevDeviceId) {
- mPreviousValues.clear();
- }
- mPrevDeviceId = input.getId();
- boolean firstEvent = mPreviousValues.isEmpty();
-
- int numMovedAxis = 0;
- float axisMoveValue = 0.0f;
- InputDevice.MotionRange lastMovedRange = null;
- char lastMovedDir = '?';
- if (mWaitingForEvent) {
- for (int i = 0; i < motionRanges.size(); i++) {
- InputDevice.MotionRange range = motionRanges.get(i);
- int axis = range.getAxis();
- float origValue = event.getAxisValue(axis);
- float value = origValue;//ControllerMappingHelper.scaleAxis(input, axis, origValue);
- if (firstEvent) {
- mPreviousValues.add(value);
- } else {
- float previousValue = mPreviousValues.get(i);
-
- // Only handle the axes that are not neutral (more than 0.5)
- // but ignore any axis that has a constant value (e.g. always 1)
- if (Math.abs(value) > 0.5f && value != previousValue) {
- // It is common to have multiple axes with the same physical input. For example,
- // shoulder butters are provided as both AXIS_LTRIGGER and AXIS_BRAKE.
- // To handle this, we ignore an axis motion that's the exact same as a motion
- // we already saw. This way, we ignore axes with two names, but catch the case
- // where a joystick is moved in two directions.
- // ref: bottom of https://developer.android.com/training/game-controllers/controller-input.html
- if (value != axisMoveValue) {
- axisMoveValue = value;
- numMovedAxis++;
- lastMovedRange = range;
- lastMovedDir = value < 0.0f ? '-' : '+';
- }
- }
- // Special case for d-pads (axis value jumps between 0 and 1 without any values
- // in between). Without this, the user would need to press the d-pad twice
- // due to the first press being caught by the "if (firstEvent)" case further up.
- else if (Math.abs(value) < 0.25f && Math.abs(previousValue) > 0.75f) {
- numMovedAxis++;
- lastMovedRange = range;
- lastMovedDir = previousValue < 0.0f ? '-' : '+';
- }
- }
-
- mPreviousValues.set(i, value);
- }
-
- // If only one axis moved, that's the winner.
- if (numMovedAxis == 1) {
- mWaitingForEvent = false;
- setting.onMotionInput(input, lastMovedRange, lastMovedDir);
- dismiss();
- }
- }
- return true;
- }
-} \ No newline at end of file
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.java
index efde45ee9..3126eba73 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.java
@@ -14,22 +14,18 @@ import java.util.Map;
import java.util.TreeMap;
public class Settings {
- public static final String SECTION_PREMIUM = "Premium";
- public static final String SECTION_CORE = "Core";
+ public static final String SECTION_GENERAL = "General";
public static final String SECTION_SYSTEM = "System";
- public static final String SECTION_CONTROLS = "Controls";
public static final String SECTION_RENDERER = "Renderer";
- public static final String SECTION_LAYOUT = "Layout";
- public static final String SECTION_UTILITY = "Utility";
public static final String SECTION_AUDIO = "Audio";
- public static final String SECTION_DEBUG = "Debug";
+ public static final String SECTION_CPU = "Cpu";
private String gameId;
private static final Map<String, List<String>> configFileSectionsMap = new HashMap<>();
static {
- configFileSectionsMap.put(SettingsFile.FILE_NAME_CONFIG, Arrays.asList(SECTION_PREMIUM, SECTION_CORE, SECTION_SYSTEM, SECTION_CONTROLS, SECTION_RENDERER, SECTION_LAYOUT, SECTION_UTILITY, SECTION_AUDIO, SECTION_DEBUG));
+ configFileSectionsMap.put(SettingsFile.FILE_NAME_CONFIG, Arrays.asList(SECTION_GENERAL, SECTION_SYSTEM, SECTION_RENDERER, SECTION_AUDIO, SECTION_CPU));
}
/**
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/InputBindingSetting.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/InputBindingSetting.java
deleted file mode 100644
index 4ad54421e..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/InputBindingSetting.java
+++ /dev/null
@@ -1,382 +0,0 @@
-package org.yuzu.yuzu_emu.features.settings.model.view;
-
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.view.InputDevice;
-import android.view.KeyEvent;
-import android.widget.Toast;
-
-import org.yuzu.yuzu_emu.YuzuApplication;
-import org.yuzu.yuzu_emu.NativeLibrary;
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.Setting;
-import org.yuzu.yuzu_emu.features.settings.model.StringSetting;
-import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile;
-
-public final class InputBindingSetting extends SettingsItem {
- private static final String INPUT_MAPPING_PREFIX = "InputMapping";
-
- public InputBindingSetting(String key, String section, int titleId, Setting setting) {
- super(key, section, setting, titleId, 0);
- }
-
- public String getValue() {
- if (getSetting() == null) {
- return "";
- }
-
- StringSetting setting = (StringSetting) getSetting();
- return setting.getValue();
- }
-
- /**
- * Returns true if this key is for the 3DS Circle Pad
- */
- private boolean IsCirclePad() {
- switch (getKey()) {
- case SettingsFile.KEY_CIRCLEPAD_AXIS_HORIZONTAL:
- case SettingsFile.KEY_CIRCLEPAD_AXIS_VERTICAL:
- return true;
- }
- return false;
- }
-
- /**
- * Returns true if this key is for a horizontal axis for a 3DS analog stick or D-pad
- */
- public boolean IsHorizontalOrientation() {
- switch (getKey()) {
- case SettingsFile.KEY_CIRCLEPAD_AXIS_HORIZONTAL:
- case SettingsFile.KEY_CSTICK_AXIS_HORIZONTAL:
- case SettingsFile.KEY_DPAD_AXIS_HORIZONTAL:
- return true;
- }
- return false;
- }
-
- /**
- * Returns true if this key is for the 3DS C-Stick
- */
- private boolean IsCStick() {
- switch (getKey()) {
- case SettingsFile.KEY_CSTICK_AXIS_HORIZONTAL:
- case SettingsFile.KEY_CSTICK_AXIS_VERTICAL:
- return true;
- }
- return false;
- }
-
- /**
- * Returns true if this key is for the 3DS D-Pad
- */
- private boolean IsDPad() {
- switch (getKey()) {
- case SettingsFile.KEY_DPAD_AXIS_HORIZONTAL:
- case SettingsFile.KEY_DPAD_AXIS_VERTICAL:
- return true;
- }
- return false;
- }
-
- /**
- * Returns true if this key is for the 3DS L/R or ZL/ZR buttons. Note, these are not real
- * triggers on the 3DS, but we support them as such on a physical gamepad.
- */
- public boolean IsTrigger() {
- switch (getKey()) {
- case SettingsFile.KEY_BUTTON_L:
- case SettingsFile.KEY_BUTTON_R:
- case SettingsFile.KEY_BUTTON_ZL:
- case SettingsFile.KEY_BUTTON_ZR:
- return true;
- }
- return false;
- }
-
- /**
- * Returns true if a gamepad axis can be used to map this key.
- */
- public boolean IsAxisMappingSupported() {
- return IsCirclePad() || IsCStick() || IsDPad() || IsTrigger();
- }
-
- /**
- * Returns true if a gamepad button can be used to map this key.
- */
- private boolean IsButtonMappingSupported() {
- return !IsAxisMappingSupported() || IsTrigger();
- }
-
- /**
- * Returns the yuzu button code for the settings key.
- */
- private int getButtonCode() {
- switch (getKey()) {
- case SettingsFile.KEY_BUTTON_A:
- return NativeLibrary.ButtonType.BUTTON_A;
- case SettingsFile.KEY_BUTTON_B:
- return NativeLibrary.ButtonType.BUTTON_B;
- case SettingsFile.KEY_BUTTON_X:
- return NativeLibrary.ButtonType.BUTTON_X;
- case SettingsFile.KEY_BUTTON_Y:
- return NativeLibrary.ButtonType.BUTTON_Y;
- case SettingsFile.KEY_BUTTON_L:
- return NativeLibrary.ButtonType.TRIGGER_L;
- case SettingsFile.KEY_BUTTON_R:
- return NativeLibrary.ButtonType.TRIGGER_R;
- case SettingsFile.KEY_BUTTON_ZL:
- return NativeLibrary.ButtonType.BUTTON_ZL;
- case SettingsFile.KEY_BUTTON_ZR:
- return NativeLibrary.ButtonType.BUTTON_ZR;
- case SettingsFile.KEY_BUTTON_SELECT:
- return NativeLibrary.ButtonType.BUTTON_SELECT;
- case SettingsFile.KEY_BUTTON_START:
- return NativeLibrary.ButtonType.BUTTON_START;
- case SettingsFile.KEY_BUTTON_UP:
- return NativeLibrary.ButtonType.DPAD_UP;
- case SettingsFile.KEY_BUTTON_DOWN:
- return NativeLibrary.ButtonType.DPAD_DOWN;
- case SettingsFile.KEY_BUTTON_LEFT:
- return NativeLibrary.ButtonType.DPAD_LEFT;
- case SettingsFile.KEY_BUTTON_RIGHT:
- return NativeLibrary.ButtonType.DPAD_RIGHT;
- }
- return -1;
- }
-
- /**
- * Returns the settings key for the specified yuzu button code.
- */
- private static String getButtonKey(int buttonCode) {
- switch (buttonCode) {
- case NativeLibrary.ButtonType.BUTTON_A:
- return SettingsFile.KEY_BUTTON_A;
- case NativeLibrary.ButtonType.BUTTON_B:
- return SettingsFile.KEY_BUTTON_B;
- case NativeLibrary.ButtonType.BUTTON_X:
- return SettingsFile.KEY_BUTTON_X;
- case NativeLibrary.ButtonType.BUTTON_Y:
- return SettingsFile.KEY_BUTTON_Y;
- case NativeLibrary.ButtonType.TRIGGER_L:
- return SettingsFile.KEY_BUTTON_L;
- case NativeLibrary.ButtonType.TRIGGER_R:
- return SettingsFile.KEY_BUTTON_R;
- case NativeLibrary.ButtonType.BUTTON_ZL:
- return SettingsFile.KEY_BUTTON_ZL;
- case NativeLibrary.ButtonType.BUTTON_ZR:
- return SettingsFile.KEY_BUTTON_ZR;
- case NativeLibrary.ButtonType.BUTTON_SELECT:
- return SettingsFile.KEY_BUTTON_SELECT;
- case NativeLibrary.ButtonType.BUTTON_START:
- return SettingsFile.KEY_BUTTON_START;
- case NativeLibrary.ButtonType.DPAD_UP:
- return SettingsFile.KEY_BUTTON_UP;
- case NativeLibrary.ButtonType.DPAD_DOWN:
- return SettingsFile.KEY_BUTTON_DOWN;
- case NativeLibrary.ButtonType.DPAD_LEFT:
- return SettingsFile.KEY_BUTTON_LEFT;
- case NativeLibrary.ButtonType.DPAD_RIGHT:
- return SettingsFile.KEY_BUTTON_RIGHT;
- }
- return "";
- }
-
- /**
- * Returns the key used to lookup the reverse mapping for this key, which is used to cleanup old
- * settings on re-mapping or clearing of a setting.
- */
- private String getReverseKey() {
- String reverseKey = INPUT_MAPPING_PREFIX + "_ReverseMapping_" + getKey();
-
- if (IsAxisMappingSupported() && !IsTrigger()) {
- // Triggers are the only axis-supported mappings without orientation
- reverseKey += "_" + (IsHorizontalOrientation() ? 0 : 1);
- }
-
- return reverseKey;
- }
-
- /**
- * Removes the old mapping for this key from the settings, e.g. on user clearing the setting.
- */
- public void removeOldMapping() {
- // Get preferences editor
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
- SharedPreferences.Editor editor = preferences.edit();
-
- // Try remove all possible keys we wrote for this setting
- String oldKey = preferences.getString(getReverseKey(), "");
- if (!oldKey.equals("")) {
- editor.remove(getKey()); // Used for ui text
- editor.remove(oldKey); // Used for button mapping
- editor.remove(oldKey + "_GuestOrientation"); // Used for axis orientation
- editor.remove(oldKey + "_GuestButton"); // Used for axis button
- }
-
- // Apply changes
- editor.apply();
- }
-
- /**
- * Helper function to get the settings key for an gamepad button.
- */
- public static String getInputButtonKey(int keyCode) {
- return INPUT_MAPPING_PREFIX + "_Button_" + keyCode;
- }
-
- /**
- * Helper function to get the settings key for an gamepad axis.
- */
- public static String getInputAxisKey(int axis) {
- return INPUT_MAPPING_PREFIX + "_HostAxis_" + axis;
- }
-
- /**
- * Helper function to get the settings key for an gamepad axis button (stick or trigger).
- */
- public static String getInputAxisButtonKey(int axis) {
- return getInputAxisKey(axis) + "_GuestButton";
- }
-
- /**
- * Helper function to get the settings key for an gamepad axis orientation.
- */
- public static String getInputAxisOrientationKey(int axis) {
- return getInputAxisKey(axis) + "_GuestOrientation";
- }
-
- /**
- * Helper function to write a gamepad button mapping for the setting.
- */
- private void WriteButtonMapping(String key) {
- // Get preferences editor
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
- SharedPreferences.Editor editor = preferences.edit();
-
- // Remove mapping for another setting using this input
- int oldButtonCode = preferences.getInt(key, -1);
- if (oldButtonCode != -1) {
- String oldKey = getButtonKey(oldButtonCode);
- editor.remove(oldKey); // Only need to remove UI text setting, others will be overwritten
- }
-
- // Cleanup old mapping for this setting
- removeOldMapping();
-
- // Write new mapping
- editor.putInt(key, getButtonCode());
-
- // Write next reverse mapping for future cleanup
- editor.putString(getReverseKey(), key);
-
- // Apply changes
- editor.apply();
- }
-
- /**
- * Helper function to write a gamepad axis mapping for the setting.
- */
- private void WriteAxisMapping(int axis, int value) {
- // Get preferences editor
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
- SharedPreferences.Editor editor = preferences.edit();
-
- // Cleanup old mapping
- removeOldMapping();
-
- // Write new mapping
- editor.putInt(getInputAxisOrientationKey(axis), IsHorizontalOrientation() ? 0 : 1);
- editor.putInt(getInputAxisButtonKey(axis), value);
-
- // Write next reverse mapping for future cleanup
- editor.putString(getReverseKey(), getInputAxisKey(axis));
-
- // Apply changes
- editor.apply();
- }
-
- /**
- * Saves the provided key input setting as an Android preference.
- *
- * @param keyEvent KeyEvent of this key press.
- */
- public void onKeyInput(KeyEvent keyEvent) {
- if (!IsButtonMappingSupported()) {
- Toast.makeText(YuzuApplication.getAppContext(), R.string.input_message_analog_only, Toast.LENGTH_LONG).show();
- return;
- }
-
- InputDevice device = keyEvent.getDevice();
-
- WriteButtonMapping(getInputButtonKey(keyEvent.getKeyCode()));
-
- String uiString = device.getName() + ": Button " + keyEvent.getKeyCode();
- setUiString(uiString);
- }
-
- /**
- * Saves the provided motion input setting as an Android preference.
- *
- * @param device InputDevice from which the input event originated.
- * @param motionRange MotionRange of the movement
- * @param axisDir Either '-' or '+' (currently unused)
- */
- public void onMotionInput(InputDevice device, InputDevice.MotionRange motionRange,
- char axisDir) {
- if (!IsAxisMappingSupported()) {
- Toast.makeText(YuzuApplication.getAppContext(), R.string.input_message_button_only, Toast.LENGTH_LONG).show();
- return;
- }
-
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
- SharedPreferences.Editor editor = preferences.edit();
-
- int button;
- if (IsCirclePad()) {
- button = NativeLibrary.ButtonType.STICK_LEFT;
- } else if (IsCStick()) {
- button = NativeLibrary.ButtonType.STICK_C;
- } else if (IsDPad()) {
- button = NativeLibrary.ButtonType.DPAD;
- } else {
- button = getButtonCode();
- }
-
- WriteAxisMapping(motionRange.getAxis(), button);
-
- String uiString = device.getName() + ": Axis " + motionRange.getAxis();
- setUiString(uiString);
-
- editor.apply();
- }
-
- /**
- * Sets the string to use in the configuration UI for the gamepad input.
- */
- private StringSetting setUiString(String ui) {
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
- SharedPreferences.Editor editor = preferences.edit();
-
- if (getSetting() == null) {
- StringSetting setting = new StringSetting(getKey(), getSection(), "");
- setSetting(setting);
-
- editor.putString(setting.getKey(), ui);
- editor.apply();
-
- return setting;
- } else {
- StringSetting setting = (StringSetting) getSetting();
-
- editor.putString(setting.getKey(), ui);
- editor.apply();
-
- return null;
- }
- }
-
- @Override
- public int getType() {
- return TYPE_INPUT_BINDING;
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumHeader.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumHeader.java
deleted file mode 100644
index 9bf95ce51..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumHeader.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.yuzu.yuzu_emu.features.settings.model.view;
-
-public final class PremiumHeader extends SettingsItem {
- public PremiumHeader() {
- super(null, null, null, 0, 0);
- }
-
- @Override
- public int getType() {
- return SettingsItem.TYPE_PREMIUM;
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumSingleChoiceSetting.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumSingleChoiceSetting.java
deleted file mode 100644
index 0c4570c8d..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/PremiumSingleChoiceSetting.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.yuzu.yuzu_emu.features.settings.model.view;
-
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
-import org.yuzu.yuzu_emu.YuzuApplication;
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.Setting;
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsFragmentView;
-
-public final class PremiumSingleChoiceSetting extends SettingsItem {
- private int mDefaultValue;
-
- private int mChoicesId;
- private int mValuesId;
- private SettingsFragmentView mView;
-
- private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
-
- public PremiumSingleChoiceSetting(String key, String section, int titleId, int descriptionId,
- int choicesId, int valuesId, int defaultValue, Setting setting, SettingsFragmentView view) {
- super(key, section, setting, titleId, descriptionId);
- mValuesId = valuesId;
- mChoicesId = choicesId;
- mDefaultValue = defaultValue;
- mView = view;
- }
-
- public int getChoicesId() {
- return mChoicesId;
- }
-
- public int getValuesId() {
- return mValuesId;
- }
-
- public int getSelectedValue() {
- return mPreferences.getInt(getKey(), mDefaultValue);
- }
-
- /**
- * Write a value to the backing int. If that int was previously null,
- * initializes a new one and returns it, so it can be added to the Hashmap.
- *
- * @param selection New value of the int.
- * @return null if overwritten successfully otherwise; a newly created IntSetting.
- */
- public void setSelectedValue(int selection) {
- final SharedPreferences.Editor editor = mPreferences.edit();
- editor.putInt(getKey(), selection);
- editor.apply();
- mView.showToastMessage(YuzuApplication.getAppContext().getString(R.string.design_updated), false);
- }
-
- @Override
- public int getType() {
- return TYPE_SINGLE_CHOICE;
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.java
index db7fb791a..e2ba9014f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.java
@@ -17,10 +17,8 @@ public abstract class SettingsItem {
public static final int TYPE_SINGLE_CHOICE = 2;
public static final int TYPE_SLIDER = 3;
public static final int TYPE_SUBMENU = 4;
- public static final int TYPE_INPUT_BINDING = 5;
- public static final int TYPE_STRING_SINGLE_CHOICE = 6;
- public static final int TYPE_DATETIME_SETTING = 7;
- public static final int TYPE_PREMIUM = 8;
+ public static final int TYPE_STRING_SINGLE_CHOICE = 5;
+ public static final int TYPE_DATETIME_SETTING = 6;
private String mKey;
private String mSection;
@@ -48,7 +46,6 @@ public abstract class SettingsItem {
mSetting = setting;
mNameId = nameId;
mDescriptionId = descriptionId;
- mIsPremium = (section == Settings.SECTION_PREMIUM);
}
/**
@@ -93,10 +90,6 @@ public abstract class SettingsItem {
return mDescriptionId;
}
- public boolean isPremium() {
- return mIsPremium;
- }
-
/**
* Used by {@link SettingsAdapter}'s onCreateViewHolder()
* method to determine which type of ViewHolder should be created.
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.java
index 1102d6af1..47e73bfe2 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.java
@@ -14,14 +14,11 @@ import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.dialogs.MotionAlertDialog;
import org.yuzu.yuzu_emu.features.settings.model.FloatSetting;
import org.yuzu.yuzu_emu.features.settings.model.IntSetting;
import org.yuzu.yuzu_emu.features.settings.model.StringSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.CheckBoxSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting;
-import org.yuzu.yuzu_emu.features.settings.model.view.InputBindingSetting;
-import org.yuzu.yuzu_emu.features.settings.model.view.PremiumSingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem;
import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting;
@@ -30,13 +27,10 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.CheckBoxSettingViewHolder;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.DateTimeViewHolder;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.HeaderViewHolder;
-import org.yuzu.yuzu_emu.features.settings.ui.viewholder.InputBindingSettingViewHolder;
-import org.yuzu.yuzu_emu.features.settings.ui.viewholder.PremiumViewHolder;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.SettingViewHolder;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.SingleChoiceViewHolder;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.SliderViewHolder;
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.SubmenuViewHolder;
-import org.yuzu.yuzu_emu.ui.main.MainActivity;
import org.yuzu.yuzu_emu.utils.Log;
import java.util.ArrayList;
@@ -87,18 +81,10 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
view = inflater.inflate(R.layout.list_item_setting, parent, false);
return new SubmenuViewHolder(view, this);
- case SettingsItem.TYPE_INPUT_BINDING:
- view = inflater.inflate(R.layout.list_item_setting, parent, false);
- return new InputBindingSettingViewHolder(view, this, mContext);
-
case SettingsItem.TYPE_DATETIME_SETTING:
view = inflater.inflate(R.layout.list_item_setting, parent, false);
return new DateTimeViewHolder(view, this);
- case SettingsItem.TYPE_PREMIUM:
- view = inflater.inflate(R.layout.premium_item_setting, parent, false);
- return new PremiumViewHolder(view, this, mView);
-
default:
Log.error("[SettingsAdapter] Invalid view type: " + viewType);
return null;
@@ -144,19 +130,6 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
mView.onSettingChanged();
}
- public void onSingleChoiceClick(PremiumSingleChoiceSetting item) {
- mClickedItem = item;
-
- int value = getSelectionForSingleChoiceValue(item);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(mView.getActivity());
-
- builder.setTitle(item.getNameId());
- builder.setSingleChoiceItems(item.getChoicesId(), value, this);
-
- mDialog = builder.show();
- }
-
public void onSingleChoiceClick(SingleChoiceSetting item) {
mClickedItem = item;
@@ -172,28 +145,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
public void onSingleChoiceClick(SingleChoiceSetting item, int position) {
mClickedPosition = position;
-
- if (!item.isPremium() || MainActivity.isPremiumActive()) {
- // Setting is either not Premium, or the user has Premium
- onSingleChoiceClick(item);
- return;
- }
-
- // User needs Premium, invoke the billing flow
- MainActivity.invokePremiumBilling(() -> onSingleChoiceClick(item));
- }
-
- public void onSingleChoiceClick(PremiumSingleChoiceSetting item, int position) {
- mClickedPosition = position;
-
- if (!item.isPremium() || MainActivity.isPremiumActive()) {
- // Setting is either not Premium, or the user has Premium
- onSingleChoiceClick(item);
- return;
- }
-
- // User needs Premium, invoke the billing flow
- MainActivity.invokePremiumBilling(() -> onSingleChoiceClick(item));
+ onSingleChoiceClick(item);
}
public void onStringSingleChoiceClick(StringSingleChoiceSetting item) {
@@ -209,15 +161,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
public void onStringSingleChoiceClick(StringSingleChoiceSetting item, int position) {
mClickedPosition = position;
-
- if (!item.isPremium() || MainActivity.isPremiumActive()) {
- // Setting is either not Premium, or the user has Premium
- onStringSingleChoiceClick(item);
- return;
- }
-
- // User needs Premium, invoke the billing flow
- MainActivity.invokePremiumBilling(() -> onStringSingleChoiceClick(item));
+ onStringSingleChoiceClick(item);
}
DialogInterface.OnClickListener defaultCancelListener = (dialog, which) -> closeDialog();
@@ -309,37 +253,6 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
mView.loadSubMenu(item.getMenuKey());
}
- public void onInputBindingClick(final InputBindingSetting item, final int position) {
- final MotionAlertDialog dialog = new MotionAlertDialog(mContext, item);
- dialog.setTitle(R.string.input_binding);
-
- int messageResId = R.string.input_binding_description;
- if (item.IsAxisMappingSupported() && !item.IsTrigger()) {
- // Use specialized message for axis left/right or up/down
- if (item.IsHorizontalOrientation()) {
- messageResId = R.string.input_binding_description_horizontal_axis;
- } else {
- messageResId = R.string.input_binding_description_vertical_axis;
- }
- }
-
- dialog.setMessage(String.format(mContext.getString(messageResId), mContext.getString(item.getNameId())));
- dialog.setButton(AlertDialog.BUTTON_NEGATIVE, mContext.getString(android.R.string.cancel), this);
- dialog.setButton(AlertDialog.BUTTON_NEUTRAL, mContext.getString(R.string.clear), (dialogInterface, i) ->
- item.removeOldMapping());
- dialog.setOnDismissListener(dialog1 ->
- {
- StringSetting setting = new StringSetting(item.getKey(), item.getSection(), item.getValue());
- notifyItemChanged(position);
-
- mView.putSetting(setting);
-
- mView.onSettingChanged();
- });
- dialog.setCanceledOnTouchOutside(false);
- dialog.show();
- }
-
@Override
public void onClick(DialogInterface dialog, int which) {
if (mClickedItem instanceof SingleChoiceSetting) {
@@ -357,10 +270,6 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
}
closeDialog();
- } else if (mClickedItem instanceof PremiumSingleChoiceSetting) {
- PremiumSingleChoiceSetting scSetting = (PremiumSingleChoiceSetting) mClickedItem;
- scSetting.setSelectedValue(getValueForSingleChoiceSelection(scSetting, which));
- closeDialog();
} else if (mClickedItem instanceof StringSingleChoiceSetting) {
StringSingleChoiceSetting scSetting = (StringSingleChoiceSetting) mClickedItem;
String value = scSetting.getValueAt(which);
@@ -436,17 +345,6 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
}
}
- private int getValueForSingleChoiceSelection(PremiumSingleChoiceSetting item, int which) {
- int valuesId = item.getValuesId();
-
- if (valuesId > 0) {
- int[] valuesArray = mContext.getResources().getIntArray(valuesId);
- return valuesArray[which];
- } else {
- return which;
- }
- }
-
private int getSelectionForSingleChoiceValue(SingleChoiceSetting item) {
int value = item.getSelectedValue();
int valuesId = item.getValuesId();
@@ -465,23 +363,4 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
return -1;
}
-
- private int getSelectionForSingleChoiceValue(PremiumSingleChoiceSetting item) {
- int value = item.getSelectedValue();
- int valuesId = item.getValuesId();
-
- if (valuesId > 0) {
- int[] valuesArray = mContext.getResources().getIntArray(valuesId);
- for (int index = 0; index < valuesArray.length; index++) {
- int current = valuesArray[index];
- if (current == value) {
- return index;
- }
- }
- } else {
- return value;
- }
-
- return -1;
- }
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java
index 27f0adf29..c84467c16 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java
@@ -1,10 +1,5 @@
package org.yuzu.yuzu_emu.features.settings.ui;
-import android.app.Activity;
-import android.content.Context;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
import android.text.TextUtils;
import org.yuzu.yuzu_emu.R;
@@ -15,20 +10,13 @@ import org.yuzu.yuzu_emu.features.settings.model.StringSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.CheckBoxSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.HeaderSetting;
-import org.yuzu.yuzu_emu.features.settings.model.view.InputBindingSetting;
-import org.yuzu.yuzu_emu.features.settings.model.view.PremiumHeader;
-import org.yuzu.yuzu_emu.features.settings.model.view.PremiumSingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem;
import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting;
-import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting;
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile;
-import org.yuzu.yuzu_emu.utils.Log;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Objects;
public final class SettingsFragmentPresenter {
private SettingsFragmentView mView;
@@ -106,27 +94,18 @@ public final class SettingsFragmentPresenter {
case SettingsFile.FILE_NAME_CONFIG:
addConfigSettings(sl);
break;
- case Settings.SECTION_PREMIUM:
- addPremiumSettings(sl);
- break;
- case Settings.SECTION_CORE:
+ case Settings.SECTION_GENERAL:
addGeneralSettings(sl);
break;
case Settings.SECTION_SYSTEM:
addSystemSettings(sl);
break;
- case Settings.SECTION_CONTROLS:
- addInputSettings(sl);
- break;
case Settings.SECTION_RENDERER:
addGraphicsSettings(sl);
break;
case Settings.SECTION_AUDIO:
addAudioSettings(sl);
break;
- case Settings.SECTION_DEBUG:
- addDebugSettings(sl);
- break;
default:
mView.showToastMessage("Unimplemented menu", false);
return;
@@ -139,184 +118,61 @@ public final class SettingsFragmentPresenter {
private void addConfigSettings(ArrayList<SettingsItem> sl) {
mView.getActivity().setTitle(R.string.preferences_settings);
- sl.add(new SubmenuSetting(null, null, R.string.preferences_premium, 0, Settings.SECTION_PREMIUM));
- sl.add(new SubmenuSetting(null, null, R.string.preferences_general, 0, Settings.SECTION_CORE));
+ sl.add(new SubmenuSetting(null, null, R.string.preferences_general, 0, Settings.SECTION_GENERAL));
sl.add(new SubmenuSetting(null, null, R.string.preferences_system, 0, Settings.SECTION_SYSTEM));
- sl.add(new SubmenuSetting(null, null, R.string.preferences_controls, 0, Settings.SECTION_CONTROLS));
sl.add(new SubmenuSetting(null, null, R.string.preferences_graphics, 0, Settings.SECTION_RENDERER));
sl.add(new SubmenuSetting(null, null, R.string.preferences_audio, 0, Settings.SECTION_AUDIO));
- sl.add(new SubmenuSetting(null, null, R.string.preferences_debug, 0, Settings.SECTION_DEBUG));
- }
-
- private void addPremiumSettings(ArrayList<SettingsItem> sl) {
- mView.getActivity().setTitle(R.string.preferences_premium);
-
- SettingSection premiumSection = mSettings.getSection(Settings.SECTION_PREMIUM);
- Setting design = premiumSection.getSetting(SettingsFile.KEY_DESIGN);
-
- sl.add(new PremiumHeader());
-
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
- sl.add(new PremiumSingleChoiceSetting(SettingsFile.KEY_DESIGN, Settings.SECTION_PREMIUM, R.string.design, 0, R.array.designNames, R.array.designValues, 0, design, mView));
- } else {
- // Pre-Android 10 does not support System Default
- sl.add(new PremiumSingleChoiceSetting(SettingsFile.KEY_DESIGN, Settings.SECTION_PREMIUM, R.string.design, 0, R.array.designNamesOld, R.array.designValuesOld, 0, design, mView));
- }
-
- //Setting textureFilterName = premiumSection.getSetting(SettingsFile.KEY_TEXTURE_FILTER_NAME);
- //sl.add(new StringSingleChoiceSetting(SettingsFile.KEY_TEXTURE_FILTER_NAME, Settings.SECTION_PREMIUM, R.string.texture_filter_name, R.string.texture_filter_description, textureFilterNames, textureFilterNames, "none", textureFilterName));
}
private void addGeneralSettings(ArrayList<SettingsItem> sl) {
mView.getActivity().setTitle(R.string.preferences_general);
SettingSection rendererSection = mSettings.getSection(Settings.SECTION_RENDERER);
- Setting frameLimitEnable = rendererSection.getSetting(SettingsFile.KEY_FRAME_LIMIT_ENABLED);
- Setting frameLimitValue = rendererSection.getSetting(SettingsFile.KEY_FRAME_LIMIT);
+ Setting frameLimitEnable = rendererSection.getSetting(SettingsFile.KEY_RENDERER_USE_SPEED_LIMIT);
+ Setting frameLimitValue = rendererSection.getSetting(SettingsFile.KEY_RENDERER_SPEED_LIMIT);
+
+ sl.add(new CheckBoxSetting(SettingsFile.KEY_RENDERER_USE_SPEED_LIMIT, Settings.SECTION_RENDERER, R.string.frame_limit_enable, R.string.frame_limit_enable_description, true, frameLimitEnable));
+ sl.add(new SliderSetting(SettingsFile.KEY_RENDERER_SPEED_LIMIT, Settings.SECTION_RENDERER, R.string.frame_limit_slider, R.string.frame_limit_slider_description, 1, 200, "%", 100, frameLimitValue));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_FRAME_LIMIT_ENABLED, Settings.SECTION_RENDERER, R.string.frame_limit_enable, R.string.frame_limit_enable_description, true, frameLimitEnable));
- sl.add(new SliderSetting(SettingsFile.KEY_FRAME_LIMIT, Settings.SECTION_RENDERER, R.string.frame_limit_slider, R.string.frame_limit_slider_description, 1, 200, "%", 100, frameLimitValue));
+ SettingSection cpuSection = mSettings.getSection(Settings.SECTION_CPU);
+ Setting cpuAccuracy = cpuSection.getSetting(SettingsFile.KEY_CPU_ACCURACY);
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_CPU_ACCURACY, Settings.SECTION_CPU, R.string.cpu_accuracy, 0, R.array.cpuAccuracyNames, R.array.cpuAccuracyValues, 0, cpuAccuracy));
}
private void addSystemSettings(ArrayList<SettingsItem> sl) {
mView.getActivity().setTitle(R.string.preferences_system);
SettingSection systemSection = mSettings.getSection(Settings.SECTION_SYSTEM);
- Setting region = systemSection.getSetting(SettingsFile.KEY_REGION_VALUE);
- Setting language = systemSection.getSetting(SettingsFile.KEY_LANGUAGE);
- Setting systemClock = systemSection.getSetting(SettingsFile.KEY_INIT_CLOCK);
- Setting dateTime = systemSection.getSetting(SettingsFile.KEY_INIT_TIME);
-
- sl.add(new SingleChoiceSetting(SettingsFile.KEY_REGION_VALUE, Settings.SECTION_SYSTEM, R.string.emulated_region, 0, R.array.regionNames, R.array.regionValues, -1, region));
- sl.add(new SingleChoiceSetting(SettingsFile.KEY_LANGUAGE, Settings.SECTION_SYSTEM, R.string.emulated_language, 0, R.array.languageNames, R.array.languageValues, 1, language));
- sl.add(new SingleChoiceSetting(SettingsFile.KEY_INIT_CLOCK, Settings.SECTION_SYSTEM, R.string.init_clock, R.string.init_clock_description, R.array.systemClockNames, R.array.systemClockValues, 0, systemClock));
- sl.add(new DateTimeSetting(SettingsFile.KEY_INIT_TIME, Settings.SECTION_SYSTEM, R.string.init_time, R.string.init_time_description, "2000-01-01 00:00:01", dateTime));
- }
+ Setting dockedMode = systemSection.getSetting(SettingsFile.KEY_USE_DOCKED_MODE);
+ Setting region = systemSection.getSetting(SettingsFile.KEY_REGION_INDEX);
+ Setting language = systemSection.getSetting(SettingsFile.KEY_LANGUAGE_INDEX);
- private void addInputSettings(ArrayList<SettingsItem> sl) {
- mView.getActivity().setTitle(R.string.preferences_controls);
-
- SettingSection controlsSection = mSettings.getSection(Settings.SECTION_CONTROLS);
- Setting buttonA = controlsSection.getSetting(SettingsFile.KEY_BUTTON_A);
- Setting buttonB = controlsSection.getSetting(SettingsFile.KEY_BUTTON_B);
- Setting buttonX = controlsSection.getSetting(SettingsFile.KEY_BUTTON_X);
- Setting buttonY = controlsSection.getSetting(SettingsFile.KEY_BUTTON_Y);
- Setting buttonSelect = controlsSection.getSetting(SettingsFile.KEY_BUTTON_SELECT);
- Setting buttonStart = controlsSection.getSetting(SettingsFile.KEY_BUTTON_START);
- Setting circlepadAxisVert = controlsSection.getSetting(SettingsFile.KEY_CIRCLEPAD_AXIS_VERTICAL);
- Setting circlepadAxisHoriz = controlsSection.getSetting(SettingsFile.KEY_CIRCLEPAD_AXIS_HORIZONTAL);
- Setting cstickAxisVert = controlsSection.getSetting(SettingsFile.KEY_CSTICK_AXIS_VERTICAL);
- Setting cstickAxisHoriz = controlsSection.getSetting(SettingsFile.KEY_CSTICK_AXIS_HORIZONTAL);
- Setting dpadAxisVert = controlsSection.getSetting(SettingsFile.KEY_DPAD_AXIS_VERTICAL);
- Setting dpadAxisHoriz = controlsSection.getSetting(SettingsFile.KEY_DPAD_AXIS_HORIZONTAL);
- // Setting buttonUp = controlsSection.getSetting(SettingsFile.KEY_BUTTON_UP);
- // Setting buttonDown = controlsSection.getSetting(SettingsFile.KEY_BUTTON_DOWN);
- // Setting buttonLeft = controlsSection.getSetting(SettingsFile.KEY_BUTTON_LEFT);
- // Setting buttonRight = controlsSection.getSetting(SettingsFile.KEY_BUTTON_RIGHT);
- Setting buttonL = controlsSection.getSetting(SettingsFile.KEY_BUTTON_L);
- Setting buttonR = controlsSection.getSetting(SettingsFile.KEY_BUTTON_R);
- Setting buttonZL = controlsSection.getSetting(SettingsFile.KEY_BUTTON_ZL);
- Setting buttonZR = controlsSection.getSetting(SettingsFile.KEY_BUTTON_ZR);
-
- sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_A, Settings.SECTION_CONTROLS, R.string.button_a, buttonA));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_B, Settings.SECTION_CONTROLS, R.string.button_b, buttonB));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_X, Settings.SECTION_CONTROLS, R.string.button_x, buttonX));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_Y, Settings.SECTION_CONTROLS, R.string.button_y, buttonY));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_SELECT, Settings.SECTION_CONTROLS, R.string.button_select, buttonSelect));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_START, Settings.SECTION_CONTROLS, R.string.button_start, buttonStart));
-
- sl.add(new HeaderSetting(null, null, R.string.controller_circlepad, 0));
- sl.add(new InputBindingSetting(SettingsFile.KEY_CIRCLEPAD_AXIS_VERTICAL, Settings.SECTION_CONTROLS, R.string.controller_axis_vertical, circlepadAxisVert));
- sl.add(new InputBindingSetting(SettingsFile.KEY_CIRCLEPAD_AXIS_HORIZONTAL, Settings.SECTION_CONTROLS, R.string.controller_axis_horizontal, circlepadAxisHoriz));
-
- sl.add(new HeaderSetting(null, null, R.string.controller_c, 0));
- sl.add(new InputBindingSetting(SettingsFile.KEY_CSTICK_AXIS_VERTICAL, Settings.SECTION_CONTROLS, R.string.controller_axis_vertical, cstickAxisVert));
- sl.add(new InputBindingSetting(SettingsFile.KEY_CSTICK_AXIS_HORIZONTAL, Settings.SECTION_CONTROLS, R.string.controller_axis_horizontal, cstickAxisHoriz));
-
- sl.add(new HeaderSetting(null, null, R.string.controller_dpad, 0));
- sl.add(new InputBindingSetting(SettingsFile.KEY_DPAD_AXIS_VERTICAL, Settings.SECTION_CONTROLS, R.string.controller_axis_vertical, dpadAxisVert));
- sl.add(new InputBindingSetting(SettingsFile.KEY_DPAD_AXIS_HORIZONTAL, Settings.SECTION_CONTROLS, R.string.controller_axis_horizontal, dpadAxisHoriz));
-
- // TODO(bunnei): Figure out what to do with these. Configuring is functional, but removing for MVP because they are confusing.
- // sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_UP, Settings.SECTION_CONTROLS, R.string.generic_up, buttonUp));
- // sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_DOWN, Settings.SECTION_CONTROLS, R.string.generic_down, buttonDown));
- // sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_LEFT, Settings.SECTION_CONTROLS, R.string.generic_left, buttonLeft));
- // sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_RIGHT, Settings.SECTION_CONTROLS, R.string.generic_right, buttonRight));
-
- sl.add(new HeaderSetting(null, null, R.string.controller_triggers, 0));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_L, Settings.SECTION_CONTROLS, R.string.button_l, buttonL));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_R, Settings.SECTION_CONTROLS, R.string.button_r, buttonR));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_ZL, Settings.SECTION_CONTROLS, R.string.button_zl, buttonZL));
- sl.add(new InputBindingSetting(SettingsFile.KEY_BUTTON_ZR, Settings.SECTION_CONTROLS, R.string.button_zr, buttonZR));
+ sl.add(new CheckBoxSetting(SettingsFile.KEY_USE_DOCKED_MODE, Settings.SECTION_SYSTEM, R.string.use_docked_mode, R.string.use_docked_mode_description, true, dockedMode));
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_REGION_INDEX, Settings.SECTION_SYSTEM, R.string.emulated_region, 0, R.array.regionNames, R.array.regionValues, -1, region));
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_LANGUAGE_INDEX, Settings.SECTION_SYSTEM, R.string.emulated_language, 0, R.array.languageNames, R.array.languageValues, 1, language));
}
private void addGraphicsSettings(ArrayList<SettingsItem> sl) {
mView.getActivity().setTitle(R.string.preferences_graphics);
SettingSection rendererSection = mSettings.getSection(Settings.SECTION_RENDERER);
- Setting resolutionFactor = rendererSection.getSetting(SettingsFile.KEY_RESOLUTION_FACTOR);
- Setting filterMode = rendererSection.getSetting(SettingsFile.KEY_FILTER_MODE);
- Setting shadersAccurateMul = rendererSection.getSetting(SettingsFile.KEY_SHADERS_ACCURATE_MUL);
- Setting render3dMode = rendererSection.getSetting(SettingsFile.KEY_RENDER_3D);
- Setting factor3d = rendererSection.getSetting(SettingsFile.KEY_FACTOR_3D);
- Setting useDiskShaderCache = rendererSection.getSetting(SettingsFile.KEY_USE_DISK_SHADER_CACHE);
- SettingSection layoutSection = mSettings.getSection(Settings.SECTION_LAYOUT);
- Setting cardboardScreenSize = layoutSection.getSetting(SettingsFile.KEY_CARDBOARD_SCREEN_SIZE);
- Setting cardboardXShift = layoutSection.getSetting(SettingsFile.KEY_CARDBOARD_X_SHIFT);
- Setting cardboardYShift = layoutSection.getSetting(SettingsFile.KEY_CARDBOARD_Y_SHIFT);
- SettingSection utilitySection = mSettings.getSection(Settings.SECTION_UTILITY);
- Setting dumpTextures = utilitySection.getSetting(SettingsFile.KEY_DUMP_TEXTURES);
- Setting customTextures = utilitySection.getSetting(SettingsFile.KEY_CUSTOM_TEXTURES);
- //Setting preloadTextures = utilitySection.getSetting(SettingsFile.KEY_PRELOAD_TEXTURES);
-
- sl.add(new HeaderSetting(null, null, R.string.renderer, 0));
- sl.add(new SliderSetting(SettingsFile.KEY_RESOLUTION_FACTOR, Settings.SECTION_RENDERER, R.string.internal_resolution, R.string.internal_resolution_description, 1, 4, "x", 1, resolutionFactor));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_FILTER_MODE, Settings.SECTION_RENDERER, R.string.linear_filtering, R.string.linear_filtering_description, true, filterMode));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_SHADERS_ACCURATE_MUL, Settings.SECTION_RENDERER, R.string.shaders_accurate_mul, R.string.shaders_accurate_mul_description, false, shadersAccurateMul));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_USE_DISK_SHADER_CACHE, Settings.SECTION_RENDERER, R.string.use_disk_shader_cache, R.string.use_disk_shader_cache_description, true, useDiskShaderCache));
-
- sl.add(new HeaderSetting(null, null, R.string.stereoscopy, 0));
- sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDER_3D, Settings.SECTION_RENDERER, R.string.render3d, 0, R.array.render3dModes, R.array.render3dValues, 0, render3dMode));
- sl.add(new SliderSetting(SettingsFile.KEY_FACTOR_3D, Settings.SECTION_RENDERER, R.string.factor3d, R.string.factor3d_description, 0, 100, "%", 0, factor3d));
-
- sl.add(new HeaderSetting(null, null, R.string.cardboard_vr, 0));
- sl.add(new SliderSetting(SettingsFile.KEY_CARDBOARD_SCREEN_SIZE, Settings.SECTION_LAYOUT, R.string.cardboard_screen_size, R.string.cardboard_screen_size_description, 30, 100, "%", 85, cardboardScreenSize));
- sl.add(new SliderSetting(SettingsFile.KEY_CARDBOARD_X_SHIFT, Settings.SECTION_LAYOUT, R.string.cardboard_x_shift, R.string.cardboard_x_shift_description, -100, 100, "%", 0, cardboardXShift));
- sl.add(new SliderSetting(SettingsFile.KEY_CARDBOARD_Y_SHIFT, Settings.SECTION_LAYOUT, R.string.cardboard_y_shift, R.string.cardboard_y_shift_description, -100, 100, "%", 0, cardboardYShift));
-
- sl.add(new HeaderSetting(null, null, R.string.utility, 0));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_DUMP_TEXTURES, Settings.SECTION_UTILITY, R.string.dump_textures, R.string.dump_textures_description, false, dumpTextures));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_CUSTOM_TEXTURES, Settings.SECTION_UTILITY, R.string.custom_textures, R.string.custom_textures_description, false, customTextures));
- //Disabled until custom texture implementation gets rewrite, current one overloads RAM and crashes yuzu.
- //sl.add(new CheckBoxSetting(SettingsFile.KEY_PRELOAD_TEXTURES, Settings.SECTION_UTILITY, R.string.preload_textures, R.string.preload_textures_description, false, preloadTextures));
+ Setting rendererBackend = rendererSection.getSetting(SettingsFile.KEY_RENDERER_BACKEND);
+ Setting rendererAccuracy = rendererSection.getSetting(SettingsFile.KEY_RENDERER_ACCURACY);
+ Setting rendererReolution = rendererSection.getSetting(SettingsFile.KEY_RENDERER_RESOLUTION);
+ Setting rendererAsynchronousShaders = rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASYNCHRONOUS_SHADERS);
+
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_BACKEND, Settings.SECTION_RENDERER, R.string.renderer_api, 0, R.array.rendererApiNames, R.array.rendererApiValues, 0, rendererBackend));
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_ACCURACY, Settings.SECTION_RENDERER, R.string.renderer_accuracy, 0, R.array.rendererAccuracyNames, R.array.rendererAccuracyValues, 1, rendererAccuracy));
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_RESOLUTION, Settings.SECTION_RENDERER, R.string.renderer_resolution, 0, R.array.rendererResolutionNames, R.array.rendererResolutionValues, 2, rendererReolution));
+ sl.add(new CheckBoxSetting(SettingsFile.KEY_RENDERER_ASYNCHRONOUS_SHADERS, Settings.SECTION_RENDERER, R.string.renderer_asynchronous_shaders, R.string.renderer_asynchronous_shaders_description, false, rendererAsynchronousShaders));
}
private void addAudioSettings(ArrayList<SettingsItem> sl) {
mView.getActivity().setTitle(R.string.preferences_audio);
SettingSection audioSection = mSettings.getSection(Settings.SECTION_AUDIO);
- Setting audioStretch = audioSection.getSetting(SettingsFile.KEY_ENABLE_AUDIO_STRETCHING);
- Setting micInputType = audioSection.getSetting(SettingsFile.KEY_MIC_INPUT_TYPE);
+ Setting audioVolume = audioSection.getSetting(SettingsFile.KEY_AUDIO_VOLUME);
- sl.add(new CheckBoxSetting(SettingsFile.KEY_ENABLE_AUDIO_STRETCHING, Settings.SECTION_AUDIO, R.string.audio_stretch, R.string.audio_stretch_description, true, audioStretch));
- sl.add(new SingleChoiceSetting(SettingsFile.KEY_MIC_INPUT_TYPE, Settings.SECTION_AUDIO, R.string.audio_input_type, 0, R.array.audioInputTypeNames, R.array.audioInputTypeValues, 1, micInputType));
- }
-
- private void addDebugSettings(ArrayList<SettingsItem> sl) {
- mView.getActivity().setTitle(R.string.preferences_debug);
-
- SettingSection coreSection = mSettings.getSection(Settings.SECTION_CORE);
- SettingSection rendererSection = mSettings.getSection(Settings.SECTION_RENDERER);
- Setting useCpuJit = coreSection.getSetting(SettingsFile.KEY_CPU_JIT);
- Setting hardwareRenderer = rendererSection.getSetting(SettingsFile.KEY_HW_RENDERER);
- Setting hardwareShader = rendererSection.getSetting(SettingsFile.KEY_HW_SHADER);
- Setting vsyncEnable = rendererSection.getSetting(SettingsFile.KEY_USE_VSYNC);
-
- sl.add(new HeaderSetting(null, null, R.string.debug_warning, 0));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_CPU_JIT, Settings.SECTION_CORE, R.string.cpu_jit, R.string.cpu_jit_description, true, useCpuJit, true, mView));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_HW_RENDERER, Settings.SECTION_RENDERER, R.string.hw_renderer, R.string.hw_renderer_description, true, hardwareRenderer, true, mView));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_HW_SHADER, Settings.SECTION_RENDERER, R.string.hw_shaders, R.string.hw_shaders_description, true, hardwareShader, true, mView));
- sl.add(new CheckBoxSetting(SettingsFile.KEY_USE_VSYNC, Settings.SECTION_RENDERER, R.string.vsync, R.string.vsync_description, true, vsyncEnable));
+ sl.add(new SliderSetting(SettingsFile.KEY_AUDIO_VOLUME, Settings.SECTION_AUDIO, R.string.audio_volume, R.string.audio_volume_description, 0, 100, "%", 100, audioVolume));
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java
deleted file mode 100644
index 6f8bef7d7..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.yuzu.yuzu_emu.features.settings.ui.viewholder;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.widget.TextView;
-
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.view.InputBindingSetting;
-import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem;
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter;
-
-public final class InputBindingSettingViewHolder extends SettingViewHolder {
- private InputBindingSetting mItem;
-
- private TextView mTextSettingName;
- private TextView mTextSettingDescription;
-
- private Context mContext;
-
- public InputBindingSettingViewHolder(View itemView, SettingsAdapter adapter, Context context) {
- super(itemView, adapter);
-
- mContext = context;
- }
-
- @Override
- protected void findViews(View root) {
- mTextSettingName = root.findViewById(R.id.text_setting_name);
- mTextSettingDescription = root.findViewById(R.id.text_setting_description);
- }
-
- @Override
- public void bind(SettingsItem item) {
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
-
- mItem = (InputBindingSetting) item;
-
- mTextSettingName.setText(item.getNameId());
-
- String key = sharedPreferences.getString(mItem.getKey(), "");
- if (key != null && !key.isEmpty()) {
- mTextSettingDescription.setText(key);
- mTextSettingDescription.setVisibility(View.VISIBLE);
- } else {
- mTextSettingDescription.setVisibility(View.GONE);
- }
- }
-
- @Override
- public void onClick(View clicked) {
- getAdapter().onInputBindingClick(mItem, getAdapterPosition());
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/PremiumViewHolder.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/PremiumViewHolder.java
deleted file mode 100644
index 1f862b281..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/PremiumViewHolder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.yuzu.yuzu_emu.features.settings.ui.viewholder;
-
-import android.view.View;
-import android.widget.TextView;
-
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem;
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter;
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsFragmentView;
-import org.yuzu.yuzu_emu.ui.main.MainActivity;
-
-public final class PremiumViewHolder extends SettingViewHolder {
- private TextView mHeaderName;
- private TextView mTextDescription;
- private SettingsFragmentView mView;
-
- public PremiumViewHolder(View itemView, SettingsAdapter adapter, SettingsFragmentView view) {
- super(itemView, adapter);
- mView = view;
- itemView.setOnClickListener(this);
- }
-
- @Override
- protected void findViews(View root) {
- mHeaderName = root.findViewById(R.id.text_setting_name);
- mTextDescription = root.findViewById(R.id.text_setting_description);
- }
-
- @Override
- public void bind(SettingsItem item) {
- updateText();
- }
-
- @Override
- public void onClick(View clicked) {
- if (MainActivity.isPremiumActive()) {
- return;
- }
-
- // Invoke billing flow if Premium is not already active, then refresh the UI to indicate
- // the purchase has completed.
- MainActivity.invokePremiumBilling(() -> updateText());
- }
-
- /**
- * Update the text shown to the user, based on whether Premium is active
- */
- private void updateText() {
- if (MainActivity.isPremiumActive()) {
- mHeaderName.setText(R.string.premium_settings_welcome);
- mTextDescription.setText(R.string.premium_settings_welcome_description);
- } else {
- mHeaderName.setText(R.string.premium_settings_upsell);
- mTextDescription.setText(R.string.premium_settings_upsell_description);
- }
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.java
index e3766f55e..539710395 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.java
@@ -5,7 +5,6 @@ import android.view.View;
import android.widget.TextView;
import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.view.PremiumSingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem;
import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting;
import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting;
@@ -46,17 +45,6 @@ public final class SingleChoiceViewHolder extends SettingViewHolder {
mTextSettingDescription.setText(choices[i]);
}
}
- } else if (item instanceof PremiumSingleChoiceSetting) {
- PremiumSingleChoiceSetting setting = (PremiumSingleChoiceSetting) item;
- int selected = setting.getSelectedValue();
- Resources resMgr = mTextSettingDescription.getContext().getResources();
- String[] choices = resMgr.getStringArray(setting.getChoicesId());
- int[] values = resMgr.getIntArray(setting.getValuesId());
- for (int i = 0; i < values.length; ++i) {
- if (values[i] == selected) {
- mTextSettingDescription.setText(choices[i]);
- }
- }
} else {
mTextSettingDescription.setVisibility(View.GONE);
}
@@ -67,8 +55,6 @@ public final class SingleChoiceViewHolder extends SettingViewHolder {
int position = getAdapterPosition();
if (mItem instanceof SingleChoiceSetting) {
getAdapter().onSingleChoiceClick((SingleChoiceSetting) mItem, position);
- } else if (mItem instanceof PremiumSingleChoiceSetting) {
- getAdapter().onSingleChoiceClick((PremiumSingleChoiceSetting) mItem, position);
} else if (mItem instanceof StringSingleChoiceSetting) {
getAdapter().onStringSingleChoiceClick((StringSingleChoiceSetting) mItem, position);
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java
index 9e58dedc2..6526f9139 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java
@@ -33,95 +33,23 @@ import java.util.TreeSet;
public final class SettingsFile {
public static final String FILE_NAME_CONFIG = "config";
- public static final String KEY_CPU_JIT = "use_cpu_jit";
-
public static final String KEY_DESIGN = "design";
- public static final String KEY_PREMIUM = "premium";
-
- public static final String KEY_HW_RENDERER = "use_hw_renderer";
- public static final String KEY_HW_SHADER = "use_hw_shader";
- public static final String KEY_SHADERS_ACCURATE_MUL = "shaders_accurate_mul";
- public static final String KEY_USE_SHADER_JIT = "use_shader_jit";
- public static final String KEY_USE_DISK_SHADER_CACHE = "use_disk_shader_cache";
- public static final String KEY_USE_VSYNC = "use_vsync_new";
- public static final String KEY_RESOLUTION_FACTOR = "resolution_factor";
- public static final String KEY_FRAME_LIMIT_ENABLED = "use_frame_limit";
- public static final String KEY_FRAME_LIMIT = "frame_limit";
- public static final String KEY_BACKGROUND_RED = "bg_red";
- public static final String KEY_BACKGROUND_BLUE = "bg_blue";
- public static final String KEY_BACKGROUND_GREEN = "bg_green";
- public static final String KEY_RENDER_3D = "render_3d";
- public static final String KEY_FACTOR_3D = "factor_3d";
- public static final String KEY_PP_SHADER_NAME = "pp_shader_name";
- public static final String KEY_FILTER_MODE = "filter_mode";
- public static final String KEY_TEXTURE_FILTER_NAME = "texture_filter_name";
- public static final String KEY_USE_ASYNCHRONOUS_GPU_EMULATION = "use_asynchronous_gpu_emulation";
-
- public static final String KEY_LAYOUT_OPTION = "layout_option";
- public static final String KEY_SWAP_SCREEN = "swap_screen";
- public static final String KEY_CARDBOARD_SCREEN_SIZE = "cardboard_screen_size";
- public static final String KEY_CARDBOARD_X_SHIFT = "cardboard_x_shift";
- public static final String KEY_CARDBOARD_Y_SHIFT = "cardboard_y_shift";
-
- public static final String KEY_DUMP_TEXTURES = "dump_textures";
- public static final String KEY_CUSTOM_TEXTURES = "custom_textures";
- public static final String KEY_PRELOAD_TEXTURES = "preload_textures";
-
- public static final String KEY_AUDIO_OUTPUT_ENGINE = "output_engine";
- public static final String KEY_ENABLE_AUDIO_STRETCHING = "enable_audio_stretching";
- public static final String KEY_VOLUME = "volume";
- public static final String KEY_MIC_INPUT_TYPE = "mic_input_type";
-
- public static final String KEY_USE_VIRTUAL_SD = "use_virtual_sd";
-
- public static final String KEY_IS_NEW_3DS = "is_new_3ds";
- public static final String KEY_REGION_VALUE = "region_value";
- public static final String KEY_LANGUAGE = "language";
-
- public static final String KEY_INIT_CLOCK = "init_clock";
- public static final String KEY_INIT_TIME = "init_time";
-
- public static final String KEY_BUTTON_A = "button_a";
- public static final String KEY_BUTTON_B = "button_b";
- public static final String KEY_BUTTON_X = "button_x";
- public static final String KEY_BUTTON_Y = "button_y";
- public static final String KEY_BUTTON_SELECT = "button_select";
- public static final String KEY_BUTTON_START = "button_start";
- public static final String KEY_BUTTON_UP = "button_up";
- public static final String KEY_BUTTON_DOWN = "button_down";
- public static final String KEY_BUTTON_LEFT = "button_left";
- public static final String KEY_BUTTON_RIGHT = "button_right";
- public static final String KEY_BUTTON_L = "button_l";
- public static final String KEY_BUTTON_R = "button_r";
- public static final String KEY_BUTTON_ZL = "button_zl";
- public static final String KEY_BUTTON_ZR = "button_zr";
- public static final String KEY_CIRCLEPAD_AXIS_VERTICAL = "circlepad_axis_vertical";
- public static final String KEY_CIRCLEPAD_AXIS_HORIZONTAL = "circlepad_axis_horizontal";
- public static final String KEY_CSTICK_AXIS_VERTICAL = "cstick_axis_vertical";
- public static final String KEY_CSTICK_AXIS_HORIZONTAL = "cstick_axis_horizontal";
- public static final String KEY_DPAD_AXIS_VERTICAL = "dpad_axis_vertical";
- public static final String KEY_DPAD_AXIS_HORIZONTAL = "dpad_axis_horizontal";
- public static final String KEY_CIRCLEPAD_UP = "circlepad_up";
- public static final String KEY_CIRCLEPAD_DOWN = "circlepad_down";
- public static final String KEY_CIRCLEPAD_LEFT = "circlepad_left";
- public static final String KEY_CIRCLEPAD_RIGHT = "circlepad_right";
- public static final String KEY_CSTICK_UP = "cstick_up";
- public static final String KEY_CSTICK_DOWN = "cstick_down";
- public static final String KEY_CSTICK_LEFT = "cstick_left";
- public static final String KEY_CSTICK_RIGHT = "cstick_right";
-
- public static final String KEY_CAMERA_OUTER_RIGHT_NAME = "camera_outer_right_name";
- public static final String KEY_CAMERA_OUTER_RIGHT_CONFIG = "camera_outer_right_config";
- public static final String KEY_CAMERA_OUTER_RIGHT_FLIP = "camera_outer_right_flip";
- public static final String KEY_CAMERA_OUTER_LEFT_NAME = "camera_outer_left_name";
- public static final String KEY_CAMERA_OUTER_LEFT_CONFIG = "camera_outer_left_config";
- public static final String KEY_CAMERA_OUTER_LEFT_FLIP = "camera_outer_left_flip";
- public static final String KEY_CAMERA_INNER_NAME = "camera_inner_name";
- public static final String KEY_CAMERA_INNER_CONFIG = "camera_inner_config";
- public static final String KEY_CAMERA_INNER_FLIP = "camera_inner_flip";
-
- public static final String KEY_LOG_FILTER = "log_filter";
+ // CPU
+ public static final String KEY_CPU_ACCURACY = "cpu_accuracy";
+ // System
+ public static final String KEY_USE_DOCKED_MODE = "use_docked_mode";
+ public static final String KEY_REGION_INDEX = "region_index";
+ public static final String KEY_LANGUAGE_INDEX = "language_index";
+ public static final String KEY_RENDERER_BACKEND = "backend";
+ // Renderer
+ public static final String KEY_RENDERER_RESOLUTION = "resolution_setup";
+ public static final String KEY_RENDERER_ACCURACY = "gpu_accuracy";
+ public static final String KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders";
+ public static final String KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit";
+ public static final String KEY_RENDERER_SPEED_LIMIT = "speed_limit";
+ // Audio
+ public static final String KEY_AUDIO_VOLUME = "volume";
private static BiMap<String, String> sectionsMap = new BiMap<>();
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.java
index b2083f858..f7a242171 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.java
@@ -29,7 +29,6 @@ import org.yuzu.yuzu_emu.overlay.InputOverlay;
import org.yuzu.yuzu_emu.utils.DirectoryInitialization;
import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState;
import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver;
-import org.yuzu.yuzu_emu.utils.EmulationMenuSettings;
import org.yuzu.yuzu_emu.utils.Log;
public final class EmulationFragment extends Fragment implements SurfaceHolder.Callback, Choreographer.FrameCallback {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java
index 6558a05c9..d419750a3 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java
@@ -18,7 +18,6 @@ import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity;
import org.yuzu.yuzu_emu.model.GameProvider;
import org.yuzu.yuzu_emu.ui.platform.PlatformGamesFragment;
import org.yuzu.yuzu_emu.utils.AddDirectoryHelper;
-import org.yuzu.yuzu_emu.utils.BillingManager;
import org.yuzu.yuzu_emu.utils.DirectoryInitialization;
import org.yuzu.yuzu_emu.utils.FileBrowserHelper;
import org.yuzu.yuzu_emu.utils.PermissionsHandler;
@@ -40,11 +39,6 @@ public final class MainActivity extends AppCompatActivity implements MainView {
private MainPresenter mPresenter = new MainPresenter(this);
- // Singleton to manage user billing state
- private static BillingManager mBillingManager;
-
- private static MenuItem mPremiumButton;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
ThemeUtil.applyTheme();
@@ -71,9 +65,6 @@ public final class MainActivity extends AppCompatActivity implements MainView {
}
PicassoUtils.init();
- // Setup billing manager, so we can globally query for Premium status
- mBillingManager = new BillingManager(this);
-
// Dismiss previous notifications (should not happen unless a crash occurred)
EmulationActivity.tryDismissRunningNotification(this);
}
@@ -107,22 +98,10 @@ public final class MainActivity extends AppCompatActivity implements MainView {
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_game_grid, menu);
- mPremiumButton = menu.findItem(R.id.button_premium);
-
- if (mBillingManager.isPremiumCached()) {
- // User had premium in a previous session, hide upsell option
- setPremiumButtonVisible(false);
- }
return true;
}
- static public void setPremiumButtonVisible(boolean isVisible) {
- if (mPremiumButton != null) {
- mPremiumButton.setVisible(isVisible);
- }
- }
-
/**
* MainView
*/
@@ -155,15 +134,8 @@ public final class MainActivity extends AppCompatActivity implements MainView {
FileBrowserHelper.openDirectoryPicker(this,
MainPresenter.REQUEST_ADD_DIRECTORY,
R.string.select_game_folder,
- Arrays.asList("xci", "nsp", "cci", "3ds",
- "cxi", "app", "3dsx", "cia",
- "rar", "zip", "7z", "torrent",
- "tar", "gz", "nro"));
- break;
- case MainPresenter.REQUEST_INSTALL_CIA:
- FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_INSTALL_CIA,
- R.string.install_cia_title,
- Collections.singletonList("cia"), true);
+ Arrays.asList("nso", "nro", "nca", "xci",
+ "nsp", "kip"));
break;
}
} else {
@@ -191,12 +163,6 @@ public final class MainActivity extends AppCompatActivity implements MainView {
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result));
}
break;
- case MainPresenter.REQUEST_INSTALL_CIA:
- // If the user picked a file, as opposed to just backing out.
- if (resultCode == MainActivity.RESULT_OK) {
- mPresenter.refeshGameList();
- }
- break;
}
}
@@ -248,20 +214,4 @@ public final class MainActivity extends AppCompatActivity implements MainView {
EmulationActivity.tryDismissRunningNotification(this);
super.onDestroy();
}
-
- /**
- * @return true if Premium subscription is currently active
- */
- public static boolean isPremiumActive() {
- return mBillingManager.isPremiumActive();
- }
-
- /**
- * Invokes the billing flow for Premium
- *
- * @param callback Optional callback, called once, on completion of billing
- */
- public static void invokePremiumBilling(Runnable callback) {
- mBillingManager.invokePremiumBilling(callback);
- }
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainPresenter.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainPresenter.java
index 2608df2c2..4cf643552 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainPresenter.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainPresenter.java
@@ -5,15 +5,12 @@ import android.os.SystemClock;
import org.yuzu.yuzu_emu.BuildConfig;
import org.yuzu.yuzu_emu.YuzuApplication;
import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.model.Settings;
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile;
import org.yuzu.yuzu_emu.model.GameDatabase;
import org.yuzu.yuzu_emu.utils.AddDirectoryHelper;
public final class MainPresenter {
public static final int REQUEST_ADD_DIRECTORY = 1;
- public static final int REQUEST_INSTALL_CIA = 2;
-
private final MainView mView;
private String mDirToAdd;
private long mLastClickTime = 0;
@@ -49,14 +46,6 @@ public final class MainPresenter {
case R.id.button_add_directory:
launchFileListActivity(REQUEST_ADD_DIRECTORY);
return true;
-
- case R.id.button_install_cia:
- launchFileListActivity(REQUEST_INSTALL_CIA);
- return true;
-
- case R.id.button_premium:
- mView.launchSettingsActivity(Settings.SECTION_PREMIUM);
- return true;
}
return false;
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/BillingManager.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/BillingManager.java
deleted file mode 100644
index 3d6dd1481..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/BillingManager.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package org.yuzu.yuzu_emu.utils;
-
-import android.app.Activity;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.widget.Toast;
-
-import com.android.billingclient.api.AcknowledgePurchaseParams;
-import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
-import com.android.billingclient.api.BillingClient;
-import com.android.billingclient.api.BillingClientStateListener;
-import com.android.billingclient.api.BillingFlowParams;
-import com.android.billingclient.api.BillingResult;
-import com.android.billingclient.api.Purchase;
-import com.android.billingclient.api.Purchase.PurchasesResult;
-import com.android.billingclient.api.PurchasesUpdatedListener;
-import com.android.billingclient.api.SkuDetails;
-import com.android.billingclient.api.SkuDetailsParams;
-
-import org.yuzu.yuzu_emu.YuzuApplication;
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile;
-import org.yuzu.yuzu_emu.ui.main.MainActivity;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class BillingManager implements PurchasesUpdatedListener {
- private final String BILLING_SKU_PREMIUM = "yuzu.yuzu_emu.product_id.premium";
-
- private final Activity mActivity;
- private BillingClient mBillingClient;
- private SkuDetails mSkuPremium;
- private boolean mIsPremiumActive = false;
- private boolean mIsServiceConnected = false;
- private Runnable mUpdateBillingCallback;
-
- private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.getAppContext());
-
- public BillingManager(Activity activity) {
- mActivity = activity;
- mBillingClient = BillingClient.newBuilder(mActivity).enablePendingPurchases().setListener(this).build();
- querySkuDetails();
- }
-
- static public boolean isPremiumCached() {
- return mPreferences.getBoolean(SettingsFile.KEY_PREMIUM, false);
- }
-
- /**
- * @return true if Premium subscription is currently active
- */
- public boolean isPremiumActive() {
- return mIsPremiumActive;
- }
-
- /**
- * Invokes the billing flow for Premium
- *
- * @param callback Optional callback, called once, on completion of billing
- */
- public void invokePremiumBilling(Runnable callback) {
- if (mSkuPremium == null) {
- return;
- }
-
- // Optional callback to refresh the UI for the caller when billing completes
- mUpdateBillingCallback = callback;
-
- // Invoke the billing flow
- BillingFlowParams flowParams = BillingFlowParams.newBuilder()
- .setSkuDetails(mSkuPremium)
- .build();
- mBillingClient.launchBillingFlow(mActivity, flowParams);
- }
-
- private void updatePremiumState(boolean isPremiumActive) {
- mIsPremiumActive = isPremiumActive;
-
- // Cache state for synchronous UI
- SharedPreferences.Editor editor = mPreferences.edit();
- editor.putBoolean(SettingsFile.KEY_PREMIUM, isPremiumActive);
- editor.apply();
-
- // No need to show button in action bar if Premium is active
- MainActivity.setPremiumButtonVisible(!isPremiumActive);
- }
-
- @Override
- public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchaseList) {
- if (purchaseList == null || purchaseList.isEmpty()) {
- // Premium is not active, or billing is unavailable
- updatePremiumState(false);
- return;
- }
-
- Purchase premiumPurchase = null;
- for (Purchase purchase : purchaseList) {
- if (purchase.getSku().equals(BILLING_SKU_PREMIUM)) {
- premiumPurchase = purchase;
- }
- }
-
- if (premiumPurchase != null && premiumPurchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
- // Premium has been purchased
- updatePremiumState(true);
-
- // Acknowledge the purchase if it hasn't already been acknowledged.
- if (!premiumPurchase.isAcknowledged()) {
- AcknowledgePurchaseParams acknowledgePurchaseParams =
- AcknowledgePurchaseParams.newBuilder()
- .setPurchaseToken(premiumPurchase.getPurchaseToken())
- .build();
-
- AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = billingResult1 -> {
- Toast.makeText(mActivity, R.string.premium_settings_welcome, Toast.LENGTH_SHORT).show();
- };
- mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
- }
-
- if (mUpdateBillingCallback != null) {
- try {
- mUpdateBillingCallback.run();
- } catch (Exception e) {
- e.printStackTrace();
- }
- mUpdateBillingCallback = null;
- }
- }
- }
-
- private void onQuerySkuDetailsFinished(List<SkuDetails> skuDetailsList) {
- if (skuDetailsList == null) {
- // This can happen when no user is signed in
- return;
- }
-
- if (skuDetailsList.isEmpty()) {
- return;
- }
-
- mSkuPremium = skuDetailsList.get(0);
-
- queryPurchases();
- }
-
- private void querySkuDetails() {
- Runnable queryToExecute = new Runnable() {
- @Override
- public void run() {
- SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
- List<String> skuList = new ArrayList<>();
-
- skuList.add(BILLING_SKU_PREMIUM);
- params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
-
- mBillingClient.querySkuDetailsAsync(params.build(),
- (billingResult, skuDetailsList) -> onQuerySkuDetailsFinished(skuDetailsList));
- }
- };
-
- executeServiceRequest(queryToExecute);
- }
-
- private void onQueryPurchasesFinished(PurchasesResult result) {
- // Have we been disposed of in the meantime? If so, or bad result code, then quit
- if (mBillingClient == null || result.getResponseCode() != BillingClient.BillingResponseCode.OK) {
- updatePremiumState(false);
- return;
- }
- // Update the UI and purchases inventory with new list of purchases
- onPurchasesUpdated(result.getBillingResult(), result.getPurchasesList());
- }
-
- private void queryPurchases() {
- Runnable queryToExecute = new Runnable() {
- @Override
- public void run() {
- final PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
- onQueryPurchasesFinished(purchasesResult);
- }
- };
-
- executeServiceRequest(queryToExecute);
- }
-
- private void startServiceConnection(final Runnable executeOnFinish) {
- mBillingClient.startConnection(new BillingClientStateListener() {
- @Override
- public void onBillingSetupFinished(BillingResult billingResult) {
- if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
- mIsServiceConnected = true;
- }
-
- if (executeOnFinish != null) {
- executeOnFinish.run();
- }
- }
-
- @Override
- public void onBillingServiceDisconnected() {
- mIsServiceConnected = false;
- }
- });
- }
-
- private void executeServiceRequest(Runnable runnable) {
- if (mIsServiceConnected) {
- runnable.run();
- } else {
- // If billing service was disconnected, we try to reconnect 1 time.
- startServiceConnection(runnable);
- }
- }
-}