From f8abc2c0e6f75e7475ef836234d14cd77b7cb244 Mon Sep 17 00:00:00 2001 From: Joshua de Reeper Date: Mon, 1 May 2023 22:30:31 +1200 Subject: [PATCH] Android: Infinity Base UI Add a UI option for the Infinity Base within the Android Emulation Activity --- .../activities/EmulationActivity.java | 145 +++++++++++++++-- .../features/infinitybase/InfinityConfig.kt | 24 +++ .../features/infinitybase/model/Figure.kt | 11 ++ .../features/infinitybase/ui/FigureSlot.kt | 5 + .../infinitybase/ui/FigureSlotAdapter.kt | 149 ++++++++++++++++++ .../features/settings/model/BooleanSetting.kt | 9 +- .../settings/ui/SettingsFragmentPresenter.kt | 21 +++ .../skylanders/ui/SkylanderSlotAdapter.kt | 16 +- .../dolphinemu/fragments/MenuFragment.java | 1 + .../layout/dialog_create_infinity_figure.xml | 56 +++++++ ...ger.xml => dialog_nfc_figures_manager.xml} | 6 +- .../main/res/layout/fragment_ingame_menu.xml | 5 + ...slot.xml => list_item_nfc_figure_slot.xml} | 26 +-- .../app/src/main/res/values/strings.xml | 22 ++- Source/Android/jni/CMakeLists.txt | 1 + Source/Android/jni/InfinityConfig.cpp | 126 +++++++++++++++ 16 files changed, 586 insertions(+), 37 deletions(-) create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/InfinityConfig.kt create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/model/Figure.kt create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlot.kt create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlotAdapter.kt create mode 100644 Source/Android/app/src/main/res/layout/dialog_create_infinity_figure.xml rename Source/Android/app/src/main/res/layout/{dialog_skylanders_manager.xml => dialog_nfc_figures_manager.xml} (78%) rename Source/Android/app/src/main/res/layout/{list_item_skylander_slot.xml => list_item_nfc_figure_slot.xml} (72%) create mode 100644 Source/Android/jni/InfinityConfig.cpp diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index b9a9eab46e..f43da9bed3 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -38,7 +38,11 @@ import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.databinding.ActivityEmulationBinding; import org.dolphinemu.dolphinemu.databinding.DialogInputAdjustBinding; -import org.dolphinemu.dolphinemu.databinding.DialogSkylandersManagerBinding; +import org.dolphinemu.dolphinemu.databinding.DialogNfcFiguresManagerBinding; +import org.dolphinemu.dolphinemu.features.infinitybase.InfinityConfig; +import org.dolphinemu.dolphinemu.features.infinitybase.model.Figure; +import org.dolphinemu.dolphinemu.features.infinitybase.ui.FigureSlot; +import org.dolphinemu.dolphinemu.features.infinitybase.ui.FigureSlotAdapter; import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface; import org.dolphinemu.dolphinemu.features.input.model.DolphinSensorEventListener; import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; @@ -78,6 +82,8 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP public static final int REQUEST_CHANGE_DISC = 1; public static final int REQUEST_SKYLANDER_FILE = 2; public static final int REQUEST_CREATE_SKYLANDER = 3; + public static final int REQUEST_INFINITY_FIGURE_FILE = 4; + public static final int REQUEST_CREATE_INFINITY_FIGURE = 5; private EmulationFragment mEmulationFragment; @@ -107,6 +113,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP public static final String EXTRA_SKYLANDER_ID = "SkylanderId"; public static final String EXTRA_SKYLANDER_VAR = "SkylanderVar"; public static final String EXTRA_SKYLANDER_NAME = "SkylanderName"; + public static final String EXTRA_INFINITY_POSITION = "FigurePosition"; + public static final String EXTRA_INFINITY_LIST_POSITION = "FigureListPosition"; + public static final String EXTRA_INFINITY_NUM = "FigureNum"; + public static final String EXTRA_INFINITY_NAME = "FigureName"; @Retention(SOURCE) @IntDef( @@ -121,7 +131,7 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP MENU_ACTION_RESET_OVERLAY, MENU_SET_IR_RECENTER, MENU_SET_IR_MODE, MENU_ACTION_CHOOSE_DOUBLETAP, MENU_ACTION_PAUSE_EMULATION, MENU_ACTION_UNPAUSE_EMULATION, MENU_ACTION_OVERLAY_CONTROLS, MENU_ACTION_SETTINGS, - MENU_ACTION_SKYLANDERS}) + MENU_ACTION_SKYLANDERS, MENU_ACTION_INFINITY_BASE}) public @interface MenuAction { } @@ -160,14 +170,20 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP public static final int MENU_ACTION_OVERLAY_CONTROLS = 34; public static final int MENU_ACTION_SETTINGS = 35; public static final int MENU_ACTION_SKYLANDERS = 36; + public static final int MENU_ACTION_INFINITY_BASE = 37; private Skylander mSkylanderData = new Skylander(-1, -1, "Slot"); + private Figure mInfinityFigureData = new Figure(-1, "Position"); private int mSkylanderSlot = -1; + private int mInfinityPosition = -1; + private int mInfinityListPosition = -1; - private DialogSkylandersManagerBinding mSkylandersBinding; + private DialogNfcFiguresManagerBinding mSkylandersBinding; + private DialogNfcFiguresManagerBinding mInfinityBinding; private static List sSkylanderSlots = new ArrayList<>(); + private static List sInfinityFigures = new ArrayList<>(); private static final SparseIntArray buttonsActionsMap = new SparseIntArray(); @@ -348,6 +364,17 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP sSkylanderSlots.add(new SkylanderSlot(getString(R.string.skylander_slot, i + 1), i)); } } + + if (sInfinityFigures.isEmpty()) + { + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_hexagon_label), 0)); + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_p1_label), 1)); + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_p1a1_label), 3)); + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_p1a2_label), 5)); + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_p2_label), 2)); + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_p2a1_label), 4)); + sInfinityFigures.add(new FigureSlot(getString(R.string.infinity_p2a2_label), 6)); + } } @Override @@ -364,6 +391,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP outState.putInt(EXTRA_SKYLANDER_ID, mSkylanderData.getId()); outState.putInt(EXTRA_SKYLANDER_VAR, mSkylanderData.getVariant()); outState.putString(EXTRA_SKYLANDER_NAME, mSkylanderData.getName()); + outState.putInt(EXTRA_INFINITY_POSITION, mInfinityPosition); + outState.putInt(EXTRA_INFINITY_LIST_POSITION, mInfinityListPosition); + outState.putLong(EXTRA_INFINITY_NUM, mInfinityFigureData.getNumber()); + outState.putString(EXTRA_INFINITY_NAME, mInfinityFigureData.getName()); super.onSaveInstanceState(outState); } @@ -376,6 +407,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP mSkylanderData = new Skylander(savedInstanceState.getInt(EXTRA_SKYLANDER_ID), savedInstanceState.getInt(EXTRA_SKYLANDER_VAR), savedInstanceState.getString(EXTRA_SKYLANDER_NAME)); + mInfinityPosition = savedInstanceState.getInt(EXTRA_INFINITY_POSITION); + mInfinityListPosition = savedInstanceState.getInt(EXTRA_INFINITY_LIST_POSITION); + mInfinityFigureData = new Figure(savedInstanceState.getLong(EXTRA_INFINITY_NUM), + savedInstanceState.getString(EXTRA_INFINITY_NAME)); } @Override @@ -486,7 +521,7 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP clearSkylander(mSkylanderSlot); sSkylanderSlots.get(mSkylanderSlot).setPortalSlot(slot.first); sSkylanderSlots.get(mSkylanderSlot).setLabel(slot.second); - mSkylandersBinding.skylandersManager.getAdapter().notifyItemChanged(mSkylanderSlot); + mSkylandersBinding.figureManager.getAdapter().notifyItemChanged(mSkylanderSlot); mSkylanderSlot = -1; mSkylanderData = Skylander.BLANK_SKYLANDER; } @@ -500,11 +535,48 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP clearSkylander(mSkylanderSlot); sSkylanderSlots.get(mSkylanderSlot).setPortalSlot(slot.first); sSkylanderSlots.get(mSkylanderSlot).setLabel(slot.second); - mSkylandersBinding.skylandersManager.getAdapter().notifyItemChanged(mSkylanderSlot); + mSkylandersBinding.figureManager.getAdapter().notifyItemChanged(mSkylanderSlot); mSkylanderSlot = -1; mSkylanderData = Skylander.BLANK_SKYLANDER; } } + else if (requestCode == REQUEST_INFINITY_FIGURE_FILE) + { + String label = InfinityConfig.loadFigure(mInfinityPosition, result.getData().toString()); + if (label != null && !label.equals("Unknown Figure")) + { + clearInfinityFigure(mInfinityListPosition); + sInfinityFigures.get(mInfinityListPosition).setLabel(label); + mInfinityBinding.figureManager.getAdapter().notifyItemChanged(mInfinityListPosition); + mInfinityPosition = -1; + mInfinityListPosition = -1; + mInfinityFigureData = Figure.BLANK_FIGURE; + } + else + { + new MaterialAlertDialogBuilder(this) + .setTitle(R.string.incompatible_figure_selected) + .setMessage(R.string.select_compatible_figure) + .setPositiveButton(R.string.ok, null) + .show(); + } + } + else if (requestCode == REQUEST_CREATE_INFINITY_FIGURE) + { + if (!(mInfinityFigureData.getNumber() == -1)) + { + String label = + InfinityConfig.createFigure(mInfinityFigureData.getNumber(), + result.getData().toString(), + mInfinityPosition); + clearInfinityFigure(mInfinityListPosition); + sInfinityFigures.get(mInfinityListPosition).setLabel(label); + mInfinityBinding.figureManager.getAdapter().notifyItemChanged(mInfinityListPosition); + mInfinityPosition = -1; + mInfinityListPosition = -1; + mInfinityFigureData = Figure.BLANK_FIGURE; + } + } } } @@ -775,6 +847,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP showSkylanderPortalSettings(); break; + case MENU_ACTION_INFINITY_BASE: + showInfinityBaseSettings(); + break; + case MENU_ACTION_EXIT: mEmulationFragment.stopEmulation(); break; @@ -1036,10 +1112,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP private void showSkylanderPortalSettings() { mSkylandersBinding = - DialogSkylandersManagerBinding.inflate(getLayoutInflater()); - mSkylandersBinding.skylandersManager.setLayoutManager(new LinearLayoutManager(this)); + DialogNfcFiguresManagerBinding.inflate(getLayoutInflater()); + mSkylandersBinding.figureManager.setLayoutManager(new LinearLayoutManager(this)); - mSkylandersBinding.skylandersManager.setAdapter( + mSkylandersBinding.figureManager.setAdapter( new SkylanderSlotAdapter(sSkylanderSlots, this)); new MaterialAlertDialogBuilder(this) @@ -1048,6 +1124,21 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP .show(); } + private void showInfinityBaseSettings() + { + mInfinityBinding = + DialogNfcFiguresManagerBinding.inflate(getLayoutInflater()); + mInfinityBinding.figureManager.setLayoutManager(new LinearLayoutManager(this)); + + mInfinityBinding.figureManager.setAdapter( + new FigureSlotAdapter(sInfinityFigures, this)); + + new MaterialAlertDialogBuilder(this) + .setTitle(R.string.infinity_manager) + .setView(mInfinityBinding.getRoot()) + .show(); + } + public void setSkylanderData(int id, int var, String name, int slot) { mSkylanderData = new Skylander(id, var, name); @@ -1057,7 +1148,43 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP public void clearSkylander(int slot) { sSkylanderSlots.get(slot).setLabel(getString(R.string.skylander_slot, slot + 1)); - mSkylandersBinding.skylandersManager.getAdapter().notifyItemChanged(slot); + mSkylandersBinding.figureManager.getAdapter().notifyItemChanged(slot); + } + + public void setInfinityFigureData(Long num, String name, int position, int listPosition) + { + mInfinityFigureData = new Figure(num, name); + mInfinityPosition = position; + mInfinityListPosition = listPosition; + } + + public void clearInfinityFigure(int position) + { + switch (position) + { + case 0: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_hexagon_label)); + break; + case 1: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_p1_label)); + break; + case 2: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_p1a1_label)); + break; + case 3: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_p1a2_label)); + break; + case 4: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_p2_label)); + break; + case 5: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_p2a1_label)); + break; + case 6: + sInfinityFigures.get(position).setLabel(getString(R.string.infinity_p2a2_label)); + break; + } + mInfinityBinding.figureManager.getAdapter().notifyItemChanged(position); } private void resetOverlay() diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/InfinityConfig.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/InfinityConfig.kt new file mode 100644 index 0000000000..0e2e54acb5 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/InfinityConfig.kt @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.infinitybase + +object InfinityConfig { + var LIST_FIGURES: Map = getFigureMap() + var REVERSE_LIST_FIGURES: Map = getInverseFigureMap() + + private external fun getFigureMap(): Map + private external fun getInverseFigureMap(): Map + + @JvmStatic + external fun removeFigure(position: Int) + + @JvmStatic + external fun loadFigure(position: Int, fileName: String): String? + + @JvmStatic + external fun createFigure( + figureNumber: Long, + fileName: String, + position: Int + ): String? +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/model/Figure.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/model/Figure.kt new file mode 100644 index 0000000000..b65b978e37 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/model/Figure.kt @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.infinitybase.model + +data class Figure(var number: Long, var name: String) { + + companion object { + @JvmField + val BLANK_FIGURE = Figure(-1, "Blank") + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlot.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlot.kt new file mode 100644 index 0000000000..7823fe1a92 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlot.kt @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.infinitybase.ui + +data class FigureSlot(var label: String, val position: Int) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlotAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlotAdapter.kt new file mode 100644 index 0000000000..8d88c37ccb --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/infinitybase/ui/FigureSlotAdapter.kt @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.infinitybase.ui + +import android.app.AlertDialog +import android.content.Intent +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.AdapterView.OnItemClickListener +import android.widget.ArrayAdapter +import android.widget.Toast +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.dolphinemu.dolphinemu.R +import org.dolphinemu.dolphinemu.activities.EmulationActivity +import org.dolphinemu.dolphinemu.databinding.DialogCreateInfinityFigureBinding +import org.dolphinemu.dolphinemu.databinding.ListItemNfcFigureSlotBinding +import org.dolphinemu.dolphinemu.features.infinitybase.InfinityConfig +import org.dolphinemu.dolphinemu.features.infinitybase.InfinityConfig.removeFigure + +class FigureSlotAdapter( + private val figures: List, + private val activity: EmulationActivity +) : RecyclerView.Adapter(), + OnItemClickListener { + + class ViewHolder(var binding: ListItemNfcFigureSlotBinding) : + RecyclerView.ViewHolder(binding.getRoot()) + + private lateinit var binding: DialogCreateInfinityFigureBinding + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + val binding = ListItemNfcFigureSlotBinding.inflate(inflater, parent, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val figure = figures[position] + holder.binding.textFigureName.text = figure.label + + holder.binding.buttonClearFigure.setOnClickListener { + removeFigure(figure.position) + activity.clearInfinityFigure(position) + } + + holder.binding.buttonLoadFigure.setOnClickListener { + val loadFigure = Intent(Intent.ACTION_OPEN_DOCUMENT) + loadFigure.addCategory(Intent.CATEGORY_OPENABLE) + loadFigure.type = "*/*" + activity.setInfinityFigureData(0, "", figure.position, position) + activity.startActivityForResult( + loadFigure, + EmulationActivity.REQUEST_INFINITY_FIGURE_FILE + ) + } + + val inflater = LayoutInflater.from(activity) + binding = DialogCreateInfinityFigureBinding.inflate(inflater) + + binding.infinityDropdown.onItemClickListener = this + + holder.binding.buttonCreateFigure.setOnClickListener { + var validFigures = InfinityConfig.REVERSE_LIST_FIGURES + // Filter adapter list by position, either Hexagon Pieces, Characters or Abilities + validFigures = when (figure.position) { + 0 -> { + // Hexagon Pieces + validFigures.filter { (_, value) -> value in 2000000..2999999 || value in 4000000..4999999 } + } + + 1, 2 -> { + // Characters + validFigures.filter { (_, value) -> value in 1000000..1999999 } + } + + else -> { + // Abilities + validFigures.filter { (_, value) -> value in 3000000..3999999 } + } + } + val figureListKeys = validFigures.keys.toMutableList() + figureListKeys.sort() + val figureNames: ArrayList = ArrayList(figureListKeys) + binding.infinityDropdown.setAdapter( + ArrayAdapter( + activity, R.layout.support_simple_spinner_dropdown_item, + figureNames + ) + ) + + if (binding.getRoot().parent != null) { + (binding.getRoot().parent as ViewGroup).removeAllViews() + } + val createDialog = MaterialAlertDialogBuilder(activity) + .setTitle(R.string.create_figure_title) + .setView(binding.getRoot()) + .setPositiveButton(R.string.create_figure, null) + .setNegativeButton(R.string.cancel, null) + .show() + createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + if (binding.infinityNum.text.toString().isNotBlank()) { + val createFigure = Intent(Intent.ACTION_CREATE_DOCUMENT) + createFigure.addCategory(Intent.CATEGORY_OPENABLE) + createFigure.type = "*/*" + val num = binding.infinityNum.text.toString().toLong() + val name = InfinityConfig.LIST_FIGURES[num] + if (name != null) { + createFigure.putExtra( + Intent.EXTRA_TITLE, + "$name.bin" + ) + activity.setInfinityFigureData(num, name, figure.position, position) + } else { + createFigure.putExtra( + Intent.EXTRA_TITLE, + "Unknown(Number: $num).bin" + ) + activity.setInfinityFigureData(num, "Unknown", figure.position, position) + } + activity.startActivityForResult( + createFigure, + EmulationActivity.REQUEST_CREATE_INFINITY_FIGURE + ) + createDialog.dismiss() + } else { + Toast.makeText( + activity, R.string.invalid_infinity_figure, + Toast.LENGTH_SHORT + ).show() + } + } + } + } + + override fun getItemCount(): Int { + return figures.size + } + + override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { + val figureNumber = InfinityConfig.REVERSE_LIST_FIGURES[parent.getItemAtPosition(position)] + binding.infinityNum.setText(figureNumber.toString()) + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt index e59cb8a097..80060f61dd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt @@ -217,6 +217,12 @@ enum class BooleanSetting( "EmulateSkylanderPortal", false ), + MAIN_EMULATE_INFINITY_BASE( + Settings.FILE_DOLPHIN, + Settings.SECTION_EMULATED_USB_DEVICES, + "EmulateInfinityBase", + false + ), MAIN_SHOW_GAME_TITLES( Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, @@ -719,7 +725,8 @@ enum class BooleanSetting( MAIN_RAM_OVERRIDE_ENABLE, MAIN_CUSTOM_RTC_ENABLE, MAIN_DSP_JIT, - MAIN_EMULATE_SKYLANDER_PORTAL + MAIN_EMULATE_SKYLANDER_PORTAL, + MAIN_EMULATE_INFINITY_BASE ) private val NOT_RUNTIME_EDITABLE: Set = HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY)) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index 72649a39fd..e119813183 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -115,6 +115,7 @@ class SettingsFragmentPresenter( controllerNumber, controllerType ) + MenuTag.WIIMOTE_1, MenuTag.WIIMOTE_2, MenuTag.WIIMOTE_3, @@ -122,6 +123,7 @@ class SettingsFragmentPresenter( sl, controllerNumber ) + MenuTag.WIIMOTE_EXTENSION_1, MenuTag.WIIMOTE_EXTENSION_2, MenuTag.WIIMOTE_EXTENSION_3, @@ -130,6 +132,7 @@ class SettingsFragmentPresenter( controllerNumber, controllerType ) + MenuTag.WIIMOTE_GENERAL_1, MenuTag.WIIMOTE_GENERAL_2, MenuTag.WIIMOTE_GENERAL_3, @@ -137,6 +140,7 @@ class SettingsFragmentPresenter( sl, controllerNumber ) + MenuTag.WIIMOTE_MOTION_SIMULATION_1, MenuTag.WIIMOTE_MOTION_SIMULATION_2, MenuTag.WIIMOTE_MOTION_SIMULATION_3, @@ -144,6 +148,7 @@ class SettingsFragmentPresenter( sl, controllerNumber ) + MenuTag.WIIMOTE_MOTION_INPUT_1, MenuTag.WIIMOTE_MOTION_INPUT_2, MenuTag.WIIMOTE_MOTION_INPUT_3, @@ -151,6 +156,7 @@ class SettingsFragmentPresenter( sl, controllerNumber ) + else -> throw UnsupportedOperationException("Unimplemented menu") } @@ -454,10 +460,12 @@ class SettingsFragmentPresenter( BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, true) BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, true) } + DSP_LLE_RECOMPILER -> { BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, false) BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, true) } + DSP_LLE_INTERPRETER -> { BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, false) BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, false) @@ -834,6 +842,14 @@ class SettingsFragmentPresenter( 0 ) ) + sl.add( + SwitchSetting( + context, + BooleanSetting.MAIN_EMULATE_INFINITY_BASE, + R.string.emulate_infinity_base, + 0 + ) + ) } private fun addAdvancedSettings(sl: ArrayList) { @@ -856,10 +872,12 @@ class SettingsFragmentPresenter( BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, false) BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, false) } + SYNC_GPU_ON_IDLE_SKIP -> { BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, true) BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, false) } + SYNC_GPU_ALWAYS -> { BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, true) BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, true) @@ -893,10 +911,12 @@ class SettingsFragmentPresenter( emuCoresEntries = R.array.emuCoresEntriesX86_64 emuCoresValues = R.array.emuCoresValuesX86_64 } + 4 -> { emuCoresEntries = R.array.emuCoresEntriesARM64 emuCoresValues = R.array.emuCoresValuesARM64 } + else -> { emuCoresEntries = R.array.emuCoresEntriesGeneric emuCoresValues = R.array.emuCoresValuesGeneric @@ -2246,6 +2266,7 @@ class SettingsFragmentPresenter( setting.uiSuffix ) ) + NumericSetting.TYPE_BOOLEAN -> sl.add( SwitchSetting( InputMappingBooleanSetting(setting), diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/skylanders/ui/SkylanderSlotAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/skylanders/ui/SkylanderSlotAdapter.kt index bc23ca3f37..aa4157a54b 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/skylanders/ui/SkylanderSlotAdapter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/skylanders/ui/SkylanderSlotAdapter.kt @@ -16,7 +16,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.activities.EmulationActivity import org.dolphinemu.dolphinemu.databinding.DialogCreateSkylanderBinding -import org.dolphinemu.dolphinemu.databinding.ListItemSkylanderSlotBinding +import org.dolphinemu.dolphinemu.databinding.ListItemNfcFigureSlotBinding import org.dolphinemu.dolphinemu.features.skylanders.SkylanderConfig import org.dolphinemu.dolphinemu.features.skylanders.SkylanderConfig.removeSkylander import org.dolphinemu.dolphinemu.features.skylanders.model.SkylanderPair @@ -25,27 +25,27 @@ class SkylanderSlotAdapter( private val slots: List, private val activity: EmulationActivity ) : RecyclerView.Adapter(), OnItemClickListener { - class ViewHolder(var binding: ListItemSkylanderSlotBinding) : + class ViewHolder(var binding: ListItemNfcFigureSlotBinding) : RecyclerView.ViewHolder(binding.getRoot()) private lateinit var binding: DialogCreateSkylanderBinding override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) - val binding = ListItemSkylanderSlotBinding.inflate(inflater, parent, false) + val binding = ListItemNfcFigureSlotBinding.inflate(inflater, parent, false) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val slot = slots[position] - holder.binding.textSkylanderName.text = slot.label + holder.binding.textFigureName.text = slot.label - holder.binding.buttonClearSkylander.setOnClickListener { + holder.binding.buttonClearFigure.setOnClickListener { removeSkylander(slot.portalSlot) activity.clearSkylander(slot.slotNum) } - holder.binding.buttonLoadSkylander.setOnClickListener { + holder.binding.buttonLoadFigure.setOnClickListener { val loadSkylander = Intent(Intent.ACTION_OPEN_DOCUMENT) loadSkylander.addCategory(Intent.CATEGORY_OPENABLE) loadSkylander.type = "*/*" @@ -71,14 +71,14 @@ class SkylanderSlotAdapter( ) binding.skylanderDropdown.onItemClickListener = this - holder.binding.buttonCreateSkylander.setOnClickListener { + holder.binding.buttonCreateFigure.setOnClickListener { if (binding.getRoot().parent != null) { (binding.getRoot().parent as ViewGroup).removeAllViews() } val createDialog = MaterialAlertDialogBuilder(activity) .setTitle(R.string.create_skylander_title) .setView(binding.getRoot()) - .setPositiveButton(R.string.create_skylander, null) + .setPositiveButton(R.string.create_figure, null) .setNegativeButton(R.string.cancel, null) .show() createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index b30ba94b37..25263e1ffd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -61,6 +61,7 @@ public final class MenuFragment extends Fragment implements View.OnClickListener buttonsActionsMap.append(R.id.menu_exit, EmulationActivity.MENU_ACTION_EXIT); buttonsActionsMap.append(R.id.menu_settings, EmulationActivity.MENU_ACTION_SETTINGS); buttonsActionsMap.append(R.id.menu_skylanders, EmulationActivity.MENU_ACTION_SKYLANDERS); + buttonsActionsMap.append(R.id.menu_infinitybase, EmulationActivity.MENU_ACTION_INFINITY_BASE); } private FragmentIngameMenuBinding mBinding; diff --git a/Source/Android/app/src/main/res/layout/dialog_create_infinity_figure.xml b/Source/Android/app/src/main/res/layout/dialog_create_infinity_figure.xml new file mode 100644 index 0000000000..75e7b0a2e0 --- /dev/null +++ b/Source/Android/app/src/main/res/layout/dialog_create_infinity_figure.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Android/app/src/main/res/layout/dialog_skylanders_manager.xml b/Source/Android/app/src/main/res/layout/dialog_nfc_figures_manager.xml similarity index 78% rename from Source/Android/app/src/main/res/layout/dialog_skylanders_manager.xml rename to Source/Android/app/src/main/res/layout/dialog_nfc_figures_manager.xml index 517399ff3a..c880f7c518 100644 --- a/Source/Android/app/src/main/res/layout/dialog_skylanders_manager.xml +++ b/Source/Android/app/src/main/res/layout/dialog_nfc_figures_manager.xml @@ -4,10 +4,10 @@ android:layout_height="wrap_content"> + android:fadeScrollbars="false" + android:scrollbars="vertical" /> diff --git a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml index 0619f22087..07e3e42a6c 100644 --- a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml +++ b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml @@ -106,6 +106,11 @@ android:text="@string/emulate_skylander_portal" style="@style/InGameMenuOption" /> +