mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 14:25:37 +00:00
Android: Implement controller auto-fire
This commit is contained in:
parent
8f23a79d36
commit
350bae7e94
|
@ -465,7 +465,6 @@ void AndroidHostInterface::EmulationThreadEntryPoint(JNIEnv* env, jobject emulat
|
|||
emulation_activity = env->NewGlobalRef(emulation_activity);
|
||||
Assert(emulation_activity != nullptr);
|
||||
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_emulation_thread_running.store(true);
|
||||
|
@ -718,7 +717,8 @@ void AndroidHostInterface::OnRunningGameChanged(const std::string& path, CDImage
|
|||
if (!cover_path_str.empty())
|
||||
cover_path = env->NewStringUTF(cover_path_str.c_str());
|
||||
|
||||
env->CallVoidMethod(m_emulation_activity_object, s_EmulationActivity_method_onRunningGameChanged, path_string, code_string, title_string, cover_path);
|
||||
env->CallVoidMethod(m_emulation_activity_object, s_EmulationActivity_method_onRunningGameChanged, path_string,
|
||||
code_string, title_string, cover_path);
|
||||
|
||||
if (cover_path)
|
||||
env->DeleteLocalRef(cover_path);
|
||||
|
@ -998,7 +998,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
(s_AndroidHostInterface_field_mNativePointer =
|
||||
env->GetFieldID(s_AndroidHostInterface_class, "mNativePointer", "J")) == nullptr ||
|
||||
(s_AndroidHostInterface_field_mEmulationActivity =
|
||||
env->GetFieldID(s_AndroidHostInterface_class, "mEmulationActivity", "Lcom/github/stenzek/duckstation/EmulationActivity;")) == nullptr ||
|
||||
env->GetFieldID(s_AndroidHostInterface_class, "mEmulationActivity",
|
||||
"Lcom/github/stenzek/duckstation/EmulationActivity;")) == nullptr ||
|
||||
(s_AndroidHostInterface_method_reportError =
|
||||
env->GetMethodID(s_AndroidHostInterface_class, "reportError", "(Ljava/lang/String;)V")) == nullptr ||
|
||||
(s_AndroidHostInterface_method_reportMessage =
|
||||
|
@ -1014,7 +1015,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
(s_EmulationActivity_method_onEmulationStopped =
|
||||
env->GetMethodID(s_EmulationActivity_class, "onEmulationStopped", "()V")) == nullptr ||
|
||||
(s_EmulationActivity_method_onRunningGameChanged =
|
||||
env->GetMethodID(s_EmulationActivity_class, "onRunningGameChanged", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V")) == nullptr ||
|
||||
env->GetMethodID(s_EmulationActivity_class, "onRunningGameChanged",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V")) == nullptr ||
|
||||
(s_EmulationActivity_method_setVibration = env->GetMethodID(emulation_activity_class, "setVibration", "(Z)V")) ==
|
||||
nullptr ||
|
||||
(s_EmulationActivity_method_getRefreshRate =
|
||||
|
@ -1187,6 +1189,18 @@ DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setControllerButtonState, jobj
|
|||
AndroidHelpers::GetNativeClass(env, obj)->SetControllerButtonState(index, button_code, pressed);
|
||||
}
|
||||
|
||||
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setControllerAutoFireState, jobject obj, jint controller_index,
|
||||
jint autofire_index, jboolean active)
|
||||
{
|
||||
AndroidHostInterface* hi = AndroidHelpers::GetNativeClass(env, obj);
|
||||
if (!hi->IsEmulationThreadRunning())
|
||||
return;
|
||||
|
||||
hi->RunOnEmulationThread([hi, controller_index, autofire_index, active]() {
|
||||
hi->SetControllerAutoFireSlotState(controller_index, autofire_index, active);
|
||||
});
|
||||
}
|
||||
|
||||
DEFINE_JNI_ARGS_METHOD(jint, AndroidHostInterface_getControllerButtonCode, jobject unused, jstring controller_type,
|
||||
jstring button_name)
|
||||
{
|
||||
|
|
|
@ -79,6 +79,8 @@ public class AndroidHostInterface {
|
|||
|
||||
public native void setControllerAxisState(int index, int axisCode, float value);
|
||||
|
||||
public native void setControllerAutoFireState(int controllerIndex, int autoFireIndex, boolean active);
|
||||
|
||||
public native void setMousePosition(int positionX, int positionY);
|
||||
|
||||
public static native int getControllerButtonCode(String controllerType, String buttonName);
|
||||
|
|
|
@ -177,6 +177,15 @@ public class ControllerBindingPreference extends Preference {
|
|||
updateValue();
|
||||
}
|
||||
|
||||
public void initAutoFireButton(int controllerIndex, int autoFireSlot) {
|
||||
mBindingName = String.format("AutoFire%d", autoFireSlot);
|
||||
mDisplayName = getContext().getString(R.string.controller_binding_auto_fire_n, autoFireSlot);
|
||||
mType = Type.BUTTON;
|
||||
mVisualType = VisualType.BUTTON;
|
||||
setKey(String.format("Controller%d/AutoFire%d", controllerIndex, autoFireSlot));
|
||||
updateValue();
|
||||
}
|
||||
|
||||
private String prettyPrintBinding(String value) {
|
||||
final int index = value.indexOf('/');
|
||||
String device, binding;
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package com.github.stenzek.duckstation;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
@ -18,6 +22,7 @@ import androidx.preference.PreferenceCategory;
|
|||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SeekBarPreference;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
@ -33,6 +38,7 @@ public class ControllerSettingsCollectionFragment extends Fragment {
|
|||
private static final int NUM_MAIN_CONTROLLER_PORTS = 2;
|
||||
private static final int NUM_SUB_CONTROLLER_PORTS = 4;
|
||||
private static final char[] SUB_CONTROLLER_PORT_NAMES = new char[]{'A', 'B', 'C', 'D'};
|
||||
private static final int NUM_AUTO_FIRE_BUTTONS = 4;
|
||||
|
||||
public interface MultitapModeChangedListener {
|
||||
void onChanged();
|
||||
|
@ -150,6 +156,8 @@ public class ControllerSettingsCollectionFragment extends Fragment {
|
|||
private PreferenceCategory mButtonsCategory;
|
||||
private PreferenceCategory mAxisCategory;
|
||||
private PreferenceCategory mSettingsCategory;
|
||||
private PreferenceCategory mAutoFireCategory;
|
||||
private PreferenceCategory mAutoFireBindingsCategory;
|
||||
|
||||
public ControllerPortFragment(ControllerSettingsCollectionFragment parent, int controllerIndex) {
|
||||
this.parent = parent;
|
||||
|
@ -181,6 +189,14 @@ public class ControllerSettingsCollectionFragment extends Fragment {
|
|||
return pref;
|
||||
}
|
||||
|
||||
private String getAutoToggleSummary(SharedPreferences sp, int slot) {
|
||||
final String button = sp.getString(String.format("AutoFire%dButton", slot), null);
|
||||
if (button == null || button.length() == 0)
|
||||
return "Not Configured";
|
||||
|
||||
return String.format("%s every %d frames", button, sp.getInt("AutoFire%dFrequency", 2));
|
||||
}
|
||||
|
||||
private void createPreferences() {
|
||||
final PreferenceScreen ps = getPreferenceScreen();
|
||||
final SharedPreferences sp = getPreferenceManager().getSharedPreferences();
|
||||
|
@ -236,23 +252,34 @@ public class ControllerSettingsCollectionFragment extends Fragment {
|
|||
ps.addPreference(clearBindingsPreference);
|
||||
|
||||
mButtonsCategory = new PreferenceCategory(getContext());
|
||||
mButtonsCategory.setTitle(getContext().getString(R.string.controller_settings_category_button_bindings));
|
||||
mButtonsCategory.setTitle(R.string.controller_settings_category_button_bindings);
|
||||
mButtonsCategory.setIconSpaceReserved(false);
|
||||
ps.addPreference(mButtonsCategory);
|
||||
|
||||
mAxisCategory = new PreferenceCategory(getContext());
|
||||
mAxisCategory.setTitle(getContext().getString(R.string.controller_settings_category_axis_bindings));
|
||||
mAxisCategory.setTitle(R.string.controller_settings_category_axis_bindings);
|
||||
mAxisCategory.setIconSpaceReserved(false);
|
||||
ps.addPreference(mAxisCategory);
|
||||
|
||||
mSettingsCategory = new PreferenceCategory(getContext());
|
||||
mSettingsCategory.setTitle(getContext().getString(R.string.controller_settings_category_settings));
|
||||
mSettingsCategory.setTitle(R.string.controller_settings_category_settings);
|
||||
mSettingsCategory.setIconSpaceReserved(false);
|
||||
ps.addPreference(mSettingsCategory);
|
||||
|
||||
mAutoFireCategory = new PreferenceCategory(getContext());
|
||||
mAutoFireCategory.setTitle(R.string.controller_settings_category_auto_fire_buttons);
|
||||
mAutoFireCategory.setIconSpaceReserved(false);
|
||||
ps.addPreference(mAutoFireCategory);
|
||||
|
||||
mAutoFireBindingsCategory = new PreferenceCategory(getContext());
|
||||
mAutoFireBindingsCategory.setTitle(R.string.controller_settings_category_auto_fire_bindings);
|
||||
mAutoFireBindingsCategory.setIconSpaceReserved(false);
|
||||
ps.addPreference(mAutoFireBindingsCategory);
|
||||
|
||||
createPreferences(controllerType);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
private void createPreferences(String controllerType) {
|
||||
final PreferenceScreen ps = getPreferenceScreen();
|
||||
final SharedPreferences sp = getPreferenceManager().getSharedPreferences();
|
||||
|
@ -295,6 +322,33 @@ public class ControllerSettingsCollectionFragment extends Fragment {
|
|||
createTogglePreference(String.format("Controller%d/AnalogDPadInDigitalMode", controllerIndex),
|
||||
R.string.settings_use_analog_sticks_for_dpad, R.string.settings_summary_use_analog_sticks_for_dpad, true));
|
||||
}
|
||||
|
||||
for (int autoFireSlot = 1; autoFireSlot <= NUM_AUTO_FIRE_BUTTONS; autoFireSlot++) {
|
||||
final ListPreference autoFirePreference = new ListPreference(getContext());
|
||||
autoFirePreference.setEntries(buttonNames);
|
||||
autoFirePreference.setEntryValues(buttonNames);
|
||||
autoFirePreference.setKey(String.format("Controller%d/AutoFire%dButton", controllerIndex, autoFireSlot));
|
||||
autoFirePreference.setTitle(getContext().getString(R.string.controller_settings_auto_fire_n_button, autoFireSlot));
|
||||
autoFirePreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
|
||||
autoFirePreference.setIconSpaceReserved(false);
|
||||
mAutoFireCategory.addPreference(autoFirePreference);
|
||||
|
||||
final SeekBarPreference frequencyPreference = new SeekBarPreference(getContext());
|
||||
frequencyPreference.setMin(1);
|
||||
frequencyPreference.setMax(60);
|
||||
frequencyPreference.setKey(String.format("Controller%d/AutoFire%dFrequency", controllerIndex, autoFireSlot));
|
||||
frequencyPreference.setDefaultValue(2);
|
||||
frequencyPreference.setTitle(getContext().getString(R.string.controller_settings_auto_fire_n_frequency, autoFireSlot));
|
||||
frequencyPreference.setIconSpaceReserved(false);
|
||||
frequencyPreference.setShowSeekBarValue(true);
|
||||
mAutoFireCategory.addPreference(frequencyPreference);
|
||||
}
|
||||
|
||||
for (int autoFireSlot = 1; autoFireSlot <= NUM_AUTO_FIRE_BUTTONS; autoFireSlot++) {
|
||||
final ControllerBindingPreference bindingPreference = new ControllerBindingPreference(getContext(), null);
|
||||
bindingPreference.initAutoFireButton(controllerIndex, autoFireSlot);
|
||||
mAutoFireBindingsCategory.addPreference(bindingPreference);
|
||||
}
|
||||
}
|
||||
|
||||
private void removePreferences() {
|
||||
|
@ -312,6 +366,16 @@ public class ControllerSettingsCollectionFragment extends Fragment {
|
|||
parent.preferences.remove(mSettingsCategory.getPreference(i));
|
||||
}
|
||||
mSettingsCategory.removeAll();
|
||||
|
||||
for (int i = 0; i < mAutoFireCategory.getPreferenceCount(); i++) {
|
||||
parent.preferences.remove(mAutoFireCategory.getPreference(i));
|
||||
}
|
||||
mAutoFireCategory.removeAll();
|
||||
|
||||
for (int i = 0; i < mAutoFireBindingsCategory.getPreferenceCount(); i++) {
|
||||
parent.preferences.remove(mAutoFireBindingsCategory.getPreference(i));
|
||||
}
|
||||
mAutoFireBindingsCategory.removeAll();
|
||||
}
|
||||
|
||||
private void clearBindings() {
|
||||
|
|
|
@ -27,6 +27,7 @@ public final class TouchscreenControllerButtonView extends View {
|
|||
private boolean mHapticFeedback = false;
|
||||
private int mControllerIndex = -1;
|
||||
private int mButtonCode = -1;
|
||||
private int mAutoFireSlot = -1;
|
||||
private Hotkey mHotkey = Hotkey.NONE;
|
||||
private String mConfigName;
|
||||
private boolean mDefaultVisibility = true;
|
||||
|
@ -113,6 +114,11 @@ public final class TouchscreenControllerButtonView extends View {
|
|||
mButtonCode = code;
|
||||
}
|
||||
|
||||
public void setAutoFireSlot(int controllerIndex, int slot) {
|
||||
mControllerIndex = controllerIndex;
|
||||
mAutoFireSlot = slot;
|
||||
}
|
||||
|
||||
public void setHotkey(Hotkey hotkey) {
|
||||
mHotkey = hotkey;
|
||||
}
|
||||
|
@ -135,24 +141,27 @@ public final class TouchscreenControllerButtonView extends View {
|
|||
}
|
||||
|
||||
private void updateControllerState() {
|
||||
final AndroidHostInterface hi = AndroidHostInterface.getInstance();
|
||||
if (mButtonCode >= 0)
|
||||
AndroidHostInterface.getInstance().setControllerButtonState(mControllerIndex, mButtonCode, mPressed);
|
||||
hi.setControllerButtonState(mControllerIndex, mButtonCode, mPressed);
|
||||
if (mAutoFireSlot >= 0)
|
||||
hi.setControllerAutoFireState(mControllerIndex, mAutoFireSlot, mPressed);
|
||||
|
||||
switch (mHotkey)
|
||||
{
|
||||
case FAST_FORWARD:
|
||||
AndroidHostInterface.getInstance().setFastForwardEnabled(mPressed);
|
||||
hi.setFastForwardEnabled(mPressed);
|
||||
break;
|
||||
|
||||
case ANALOG_TOGGLE: {
|
||||
if (!mPressed)
|
||||
AndroidHostInterface.getInstance().toggleControllerAnalogMode();
|
||||
hi.toggleControllerAnalogMode();
|
||||
}
|
||||
break;
|
||||
|
||||
case OPEN_PAUSE_MENU: {
|
||||
if (!mPressed)
|
||||
AndroidHostInterface.getInstance().getEmulationActivity().openPauseMenu();
|
||||
hi.getEmulationActivity().openPauseMenu();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -308,6 +308,19 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
|
||||
linkAxis(mMainView, R.id.controller_axis_right, "RightAxis", "Right", true);
|
||||
|
||||
// GunCon
|
||||
linkButton(mMainView, R.id.controller_button_a, "AButton", "A", true, true);
|
||||
linkButton(mMainView, R.id.controller_button_b, "BButton", "B", true, true);
|
||||
if (pointerButtonName != null)
|
||||
linkPointer(pointerButtonName);
|
||||
|
||||
// Turbo/autofire buttons
|
||||
linkAutoFireButton(mMainView, R.id.controller_button_autofire_1, "AutoFire1", 0, false);
|
||||
linkAutoFireButton(mMainView, R.id.controller_button_autofire_2, "AutoFire2", 1, false);
|
||||
linkAutoFireButton(mMainView, R.id.controller_button_autofire_3, "AutoFire3", 2, false);
|
||||
linkAutoFireButton(mMainView, R.id.controller_button_autofire_4, "AutoFire4", 3, false);
|
||||
|
||||
// Hotkeys
|
||||
linkHotkeyButton(mMainView, R.id.controller_button_fast_forward, "FastForward",
|
||||
TouchscreenControllerButtonView.Hotkey.FAST_FORWARD, false);
|
||||
linkHotkeyButton(mMainView, R.id.controller_button_analog, "AnalogToggle",
|
||||
|
@ -315,11 +328,6 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
linkHotkeyButton(mMainView, R.id.controller_button_pause, "OpenPauseMenu",
|
||||
TouchscreenControllerButtonView.Hotkey.OPEN_PAUSE_MENU, true);
|
||||
|
||||
linkButton(mMainView, R.id.controller_button_a, "AButton", "A", true, true);
|
||||
linkButton(mMainView, R.id.controller_button_b, "BButton", "B", true, true);
|
||||
if (pointerButtonName != null)
|
||||
linkPointer(pointerButtonName);
|
||||
|
||||
reloadButtonSettings();
|
||||
updateOpacity();
|
||||
requestLayout();
|
||||
|
@ -412,6 +420,19 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
buttonView.setConfigName(configName);
|
||||
buttonView.setDefaultVisibility(defaultVisibility);
|
||||
buttonView.setHotkey(hotkey);
|
||||
buttonView.setIsGlidable(false);
|
||||
mButtonViews.add(buttonView);
|
||||
}
|
||||
|
||||
private void linkAutoFireButton(View view, int id, String configName, int slot, boolean defaultVisibility) {
|
||||
TouchscreenControllerButtonView buttonView = (TouchscreenControllerButtonView) view.findViewById(id);
|
||||
if (buttonView == null)
|
||||
return;
|
||||
|
||||
buttonView.setConfigName(configName);
|
||||
buttonView.setDefaultVisibility(defaultVisibility);
|
||||
buttonView.setAutoFireSlot(mControllerIndex, slot);
|
||||
buttonView.setIsGlidable(true);
|
||||
mButtonViews.add(buttonView);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M64.932,63.464H61.291V42.339q0,-1.82 0.042,-2.921 0.042,-1.101 0.127,-2.286 -0.677,0.677 -1.228,1.143 -0.55,0.466 -1.397,1.185l-3.217,2.625 -1.947,-2.498 8.17,-6.35h3.09z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#c9c9c9"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M64.932,63.464H61.291V42.339q0,-1.82 0.042,-2.921 0.042,-1.101 0.127,-2.286 -0.677,0.677 -1.228,1.143 -0.55,0.466 -1.397,1.185l-3.217,2.625 -1.947,-2.498 8.17,-6.35h3.09z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M71.917,63.464H51.936v-3.09l7.916,-8.001q2.286,-2.286 3.852,-4.064 1.566,-1.778 2.371,-3.471 0.804,-1.736 0.804,-3.768 0,-2.498 -1.482,-3.768 -1.482,-1.312 -3.852,-1.312 -2.201,0 -3.895,0.762 -1.651,0.762 -3.387,2.117l-1.99,-2.498q1.778,-1.482 4.064,-2.498 2.328,-1.058 5.207,-1.058 4.233,0 6.689,2.159 2.455,2.117 2.455,5.884 0,2.371 -0.974,4.445 -0.974,2.074 -2.709,4.106 -1.736,1.99 -4.064,4.276l-6.308,6.223v0.169h15.282z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#c9c9c9"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M71.917,63.464H51.936v-3.09l7.916,-8.001q2.286,-2.286 3.852,-4.064 1.566,-1.778 2.371,-3.471 0.804,-1.736 0.804,-3.768 0,-2.498 -1.482,-3.768 -1.482,-1.312 -3.852,-1.312 -2.201,0 -3.895,0.762 -1.651,0.762 -3.387,2.117l-1.99,-2.498q1.778,-1.482 4.064,-2.498 2.328,-1.058 5.207,-1.058 4.233,0 6.689,2.159 2.455,2.117 2.455,5.884 0,2.371 -0.974,4.445 -0.974,2.074 -2.709,4.106 -1.736,1.99 -4.064,4.276l-6.308,6.223v0.169h15.282z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="m70.774,40.307q0,3.048 -1.693,4.868 -1.693,1.778 -4.572,2.371v0.169q3.641,0.423 5.419,2.286 1.778,1.863 1.778,4.868 0,2.625 -1.228,4.699 -1.228,2.032 -3.81,3.175 -2.54,1.143 -6.562,1.143 -2.371,0 -4.403,-0.381 -2.032,-0.339 -3.895,-1.27v-3.471q1.905,0.931 4.106,1.482 2.201,0.508 4.233,0.508 4.064,0 5.842,-1.566 1.82,-1.609 1.82,-4.403 0,-2.836 -2.244,-4.064 -2.201,-1.27 -6.223,-1.27h-2.921v-3.175h2.963q3.725,0 5.63,-1.566 1.947,-1.566 1.947,-4.149 0,-2.201 -1.482,-3.387 -1.482,-1.228 -4.022,-1.228 -2.455,0 -4.191,0.72 -1.736,0.72 -3.429,1.82l-1.863,-2.54q1.609,-1.27 3.979,-2.201 2.413,-0.931 5.461,-0.931 4.741,0 7.027,2.117 2.328,2.117 2.328,5.376z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#c9c9c9"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="m70.774,40.307q0,3.048 -1.693,4.868 -1.693,1.778 -4.572,2.371v0.169q3.641,0.423 5.419,2.286 1.778,1.863 1.778,4.868 0,2.625 -1.228,4.699 -1.228,2.032 -3.81,3.175 -2.54,1.143 -6.562,1.143 -2.371,0 -4.403,-0.381 -2.032,-0.339 -3.895,-1.27v-3.471q1.905,0.931 4.106,1.482 2.201,0.508 4.233,0.508 4.064,0 5.842,-1.566 1.82,-1.609 1.82,-4.403 0,-2.836 -2.244,-4.064 -2.201,-1.27 -6.223,-1.27h-2.921v-3.175h2.963q3.725,0 5.63,-1.566 1.947,-1.566 1.947,-4.149 0,-2.201 -1.482,-3.387 -1.482,-1.228 -4.022,-1.228 -2.455,0 -4.191,0.72 -1.736,0.72 -3.429,1.82l-1.863,-2.54q1.609,-1.27 3.979,-2.201 2.413,-0.931 5.461,-0.931 4.741,0 7.027,2.117 2.328,2.117 2.328,5.376z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="m73.272,56.606h-4.403v6.858h-3.598V56.606h-14.478v-3.175l14.224,-20.362h3.852V53.261h4.403zM65.271,43.736q0,-2.201 0.085,-3.725 0.085,-1.566 0.127,-2.963h-0.169q-0.339,0.804 -0.847,1.736 -0.508,0.931 -0.974,1.566L54.433,53.261h10.837z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="100dp"
|
||||
android:height="100dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
<path
|
||||
android:pathData="M1.086,50.028a48.94,48.712 0,1 0,97.88 0a48.94,48.712 0,1 0,-97.88 0z"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#c9c9c9"
|
||||
android:strokeColor="#c8c8c8"/>
|
||||
<path
|
||||
android:pathData="M40.04,63.464H36.23V36.582H26.79V33.238H49.438v3.344h-9.398z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="m73.272,56.606h-4.403v6.858h-3.598V56.606h-14.478v-3.175l14.224,-20.362h3.852V53.261h4.403zM65.271,43.736q0,-2.201 0.085,-3.725 0.085,-1.566 0.127,-2.963h-0.169q-0.339,0.804 -0.847,1.736 -0.508,0.931 -0.974,1.566L54.433,53.261h10.837z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
|
@ -169,4 +169,56 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_pause_button"
|
||||
app:unpressedDrawable="@drawable/ic_controller_pause_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_1"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t1_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t1_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_2"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t2_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t2_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_3"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t3_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t3_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_4"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t4_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t4_button" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -191,4 +191,56 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_pause_button"
|
||||
app:unpressedDrawable="@drawable/ic_controller_pause_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_1"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t1_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t1_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_2"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t2_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t2_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_3"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t3_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t3_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_4"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t4_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t4_button" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -153,4 +153,56 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_pause_button"
|
||||
app:unpressedDrawable="@drawable/ic_controller_pause_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_1"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t1_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t1_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_2"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t2_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t2_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_3"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t3_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t3_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_4"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t4_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t4_button" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -52,4 +52,56 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_pause_button"
|
||||
app:unpressedDrawable="@drawable/ic_controller_pause_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_1"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t1_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t1_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_2"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t2_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t2_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_3"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t3_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t3_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_autofire_4"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="280dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_t4_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_t4_button" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -354,4 +354,9 @@
|
|||
<string name="settings_summary_cdrom_seek_speedup">Speeds up CD-ROM seeks by the specified factor. May improve loading speeds in some games, at the cost of breaking others.</string>
|
||||
<string name="settings_custom_aspect_ratio">Custom Aspect Ratio</string>
|
||||
<string name="settings_summary_custom_aspect_ratio">Used when aspect ratio is set to Custom.</string>
|
||||
<string name="controller_settings_category_auto_fire_buttons">Auto Fire Buttons</string>
|
||||
<string name="controller_settings_category_auto_fire_bindings">Auto Fire Triggers</string>
|
||||
<string name="controller_settings_auto_fire_n_button">Auto Fire %d Button</string>
|
||||
<string name="controller_settings_auto_fire_n_frequency">Auto Fire %d Frequency/Interval</string>
|
||||
<string name="controller_binding_auto_fire_n">Auto Fire %d</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue