Android: Infinity Base UI
Add a UI option for the Infinity Base within the Android Emulation Activity
This commit is contained in:
parent
6d9529a68d
commit
f8abc2c0e6
|
@ -38,7 +38,11 @@ import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.databinding.ActivityEmulationBinding;
|
import org.dolphinemu.dolphinemu.databinding.ActivityEmulationBinding;
|
||||||
import org.dolphinemu.dolphinemu.databinding.DialogInputAdjustBinding;
|
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.ControllerInterface;
|
||||||
import org.dolphinemu.dolphinemu.features.input.model.DolphinSensorEventListener;
|
import org.dolphinemu.dolphinemu.features.input.model.DolphinSensorEventListener;
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
|
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_CHANGE_DISC = 1;
|
||||||
public static final int REQUEST_SKYLANDER_FILE = 2;
|
public static final int REQUEST_SKYLANDER_FILE = 2;
|
||||||
public static final int REQUEST_CREATE_SKYLANDER = 3;
|
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;
|
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_ID = "SkylanderId";
|
||||||
public static final String EXTRA_SKYLANDER_VAR = "SkylanderVar";
|
public static final String EXTRA_SKYLANDER_VAR = "SkylanderVar";
|
||||||
public static final String EXTRA_SKYLANDER_NAME = "SkylanderName";
|
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)
|
@Retention(SOURCE)
|
||||||
@IntDef(
|
@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_RESET_OVERLAY, MENU_SET_IR_RECENTER, MENU_SET_IR_MODE,
|
||||||
MENU_ACTION_CHOOSE_DOUBLETAP, MENU_ACTION_PAUSE_EMULATION,
|
MENU_ACTION_CHOOSE_DOUBLETAP, MENU_ACTION_PAUSE_EMULATION,
|
||||||
MENU_ACTION_UNPAUSE_EMULATION, MENU_ACTION_OVERLAY_CONTROLS, MENU_ACTION_SETTINGS,
|
MENU_ACTION_UNPAUSE_EMULATION, MENU_ACTION_OVERLAY_CONTROLS, MENU_ACTION_SETTINGS,
|
||||||
MENU_ACTION_SKYLANDERS})
|
MENU_ACTION_SKYLANDERS, MENU_ACTION_INFINITY_BASE})
|
||||||
public @interface MenuAction
|
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_OVERLAY_CONTROLS = 34;
|
||||||
public static final int MENU_ACTION_SETTINGS = 35;
|
public static final int MENU_ACTION_SETTINGS = 35;
|
||||||
public static final int MENU_ACTION_SKYLANDERS = 36;
|
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 Skylander mSkylanderData = new Skylander(-1, -1, "Slot");
|
||||||
|
private Figure mInfinityFigureData = new Figure(-1, "Position");
|
||||||
|
|
||||||
private int mSkylanderSlot = -1;
|
private int mSkylanderSlot = -1;
|
||||||
|
private int mInfinityPosition = -1;
|
||||||
|
private int mInfinityListPosition = -1;
|
||||||
|
|
||||||
private DialogSkylandersManagerBinding mSkylandersBinding;
|
private DialogNfcFiguresManagerBinding mSkylandersBinding;
|
||||||
|
private DialogNfcFiguresManagerBinding mInfinityBinding;
|
||||||
|
|
||||||
private static List<SkylanderSlot> sSkylanderSlots = new ArrayList<>();
|
private static List<SkylanderSlot> sSkylanderSlots = new ArrayList<>();
|
||||||
|
private static List<FigureSlot> sInfinityFigures = new ArrayList<>();
|
||||||
|
|
||||||
private static final SparseIntArray buttonsActionsMap = new SparseIntArray();
|
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));
|
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
|
@Override
|
||||||
|
@ -364,6 +391,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
outState.putInt(EXTRA_SKYLANDER_ID, mSkylanderData.getId());
|
outState.putInt(EXTRA_SKYLANDER_ID, mSkylanderData.getId());
|
||||||
outState.putInt(EXTRA_SKYLANDER_VAR, mSkylanderData.getVariant());
|
outState.putInt(EXTRA_SKYLANDER_VAR, mSkylanderData.getVariant());
|
||||||
outState.putString(EXTRA_SKYLANDER_NAME, mSkylanderData.getName());
|
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);
|
super.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +407,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
mSkylanderData = new Skylander(savedInstanceState.getInt(EXTRA_SKYLANDER_ID),
|
mSkylanderData = new Skylander(savedInstanceState.getInt(EXTRA_SKYLANDER_ID),
|
||||||
savedInstanceState.getInt(EXTRA_SKYLANDER_VAR),
|
savedInstanceState.getInt(EXTRA_SKYLANDER_VAR),
|
||||||
savedInstanceState.getString(EXTRA_SKYLANDER_NAME));
|
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
|
@Override
|
||||||
|
@ -486,7 +521,7 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
clearSkylander(mSkylanderSlot);
|
clearSkylander(mSkylanderSlot);
|
||||||
sSkylanderSlots.get(mSkylanderSlot).setPortalSlot(slot.first);
|
sSkylanderSlots.get(mSkylanderSlot).setPortalSlot(slot.first);
|
||||||
sSkylanderSlots.get(mSkylanderSlot).setLabel(slot.second);
|
sSkylanderSlots.get(mSkylanderSlot).setLabel(slot.second);
|
||||||
mSkylandersBinding.skylandersManager.getAdapter().notifyItemChanged(mSkylanderSlot);
|
mSkylandersBinding.figureManager.getAdapter().notifyItemChanged(mSkylanderSlot);
|
||||||
mSkylanderSlot = -1;
|
mSkylanderSlot = -1;
|
||||||
mSkylanderData = Skylander.BLANK_SKYLANDER;
|
mSkylanderData = Skylander.BLANK_SKYLANDER;
|
||||||
}
|
}
|
||||||
|
@ -500,11 +535,48 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
clearSkylander(mSkylanderSlot);
|
clearSkylander(mSkylanderSlot);
|
||||||
sSkylanderSlots.get(mSkylanderSlot).setPortalSlot(slot.first);
|
sSkylanderSlots.get(mSkylanderSlot).setPortalSlot(slot.first);
|
||||||
sSkylanderSlots.get(mSkylanderSlot).setLabel(slot.second);
|
sSkylanderSlots.get(mSkylanderSlot).setLabel(slot.second);
|
||||||
mSkylandersBinding.skylandersManager.getAdapter().notifyItemChanged(mSkylanderSlot);
|
mSkylandersBinding.figureManager.getAdapter().notifyItemChanged(mSkylanderSlot);
|
||||||
mSkylanderSlot = -1;
|
mSkylanderSlot = -1;
|
||||||
mSkylanderData = Skylander.BLANK_SKYLANDER;
|
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();
|
showSkylanderPortalSettings();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MENU_ACTION_INFINITY_BASE:
|
||||||
|
showInfinityBaseSettings();
|
||||||
|
break;
|
||||||
|
|
||||||
case MENU_ACTION_EXIT:
|
case MENU_ACTION_EXIT:
|
||||||
mEmulationFragment.stopEmulation();
|
mEmulationFragment.stopEmulation();
|
||||||
break;
|
break;
|
||||||
|
@ -1036,10 +1112,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
private void showSkylanderPortalSettings()
|
private void showSkylanderPortalSettings()
|
||||||
{
|
{
|
||||||
mSkylandersBinding =
|
mSkylandersBinding =
|
||||||
DialogSkylandersManagerBinding.inflate(getLayoutInflater());
|
DialogNfcFiguresManagerBinding.inflate(getLayoutInflater());
|
||||||
mSkylandersBinding.skylandersManager.setLayoutManager(new LinearLayoutManager(this));
|
mSkylandersBinding.figureManager.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
|
||||||
mSkylandersBinding.skylandersManager.setAdapter(
|
mSkylandersBinding.figureManager.setAdapter(
|
||||||
new SkylanderSlotAdapter(sSkylanderSlots, this));
|
new SkylanderSlotAdapter(sSkylanderSlots, this));
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(this)
|
new MaterialAlertDialogBuilder(this)
|
||||||
|
@ -1048,6 +1124,21 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
.show();
|
.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)
|
public void setSkylanderData(int id, int var, String name, int slot)
|
||||||
{
|
{
|
||||||
mSkylanderData = new Skylander(id, var, name);
|
mSkylanderData = new Skylander(id, var, name);
|
||||||
|
@ -1057,7 +1148,43 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP
|
||||||
public void clearSkylander(int slot)
|
public void clearSkylander(int slot)
|
||||||
{
|
{
|
||||||
sSkylanderSlots.get(slot).setLabel(getString(R.string.skylander_slot, slot + 1));
|
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()
|
private void resetOverlay()
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.infinitybase
|
||||||
|
|
||||||
|
object InfinityConfig {
|
||||||
|
var LIST_FIGURES: Map<Long, String> = getFigureMap()
|
||||||
|
var REVERSE_LIST_FIGURES: Map<String, Long> = getInverseFigureMap()
|
||||||
|
|
||||||
|
private external fun getFigureMap(): Map<Long, String>
|
||||||
|
private external fun getInverseFigureMap(): Map<String, Long>
|
||||||
|
|
||||||
|
@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?
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
|
@ -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<FigureSlot>,
|
||||||
|
private val activity: EmulationActivity
|
||||||
|
) : RecyclerView.Adapter<FigureSlotAdapter.ViewHolder>(),
|
||||||
|
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<String> = 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())
|
||||||
|
}
|
||||||
|
}
|
|
@ -217,6 +217,12 @@ enum class BooleanSetting(
|
||||||
"EmulateSkylanderPortal",
|
"EmulateSkylanderPortal",
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
|
MAIN_EMULATE_INFINITY_BASE(
|
||||||
|
Settings.FILE_DOLPHIN,
|
||||||
|
Settings.SECTION_EMULATED_USB_DEVICES,
|
||||||
|
"EmulateInfinityBase",
|
||||||
|
false
|
||||||
|
),
|
||||||
MAIN_SHOW_GAME_TITLES(
|
MAIN_SHOW_GAME_TITLES(
|
||||||
Settings.FILE_DOLPHIN,
|
Settings.FILE_DOLPHIN,
|
||||||
Settings.SECTION_INI_ANDROID,
|
Settings.SECTION_INI_ANDROID,
|
||||||
|
@ -719,7 +725,8 @@ enum class BooleanSetting(
|
||||||
MAIN_RAM_OVERRIDE_ENABLE,
|
MAIN_RAM_OVERRIDE_ENABLE,
|
||||||
MAIN_CUSTOM_RTC_ENABLE,
|
MAIN_CUSTOM_RTC_ENABLE,
|
||||||
MAIN_DSP_JIT,
|
MAIN_DSP_JIT,
|
||||||
MAIN_EMULATE_SKYLANDER_PORTAL
|
MAIN_EMULATE_SKYLANDER_PORTAL,
|
||||||
|
MAIN_EMULATE_INFINITY_BASE
|
||||||
)
|
)
|
||||||
private val NOT_RUNTIME_EDITABLE: Set<BooleanSetting> =
|
private val NOT_RUNTIME_EDITABLE: Set<BooleanSetting> =
|
||||||
HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY))
|
HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY))
|
||||||
|
|
|
@ -115,6 +115,7 @@ class SettingsFragmentPresenter(
|
||||||
controllerNumber,
|
controllerNumber,
|
||||||
controllerType
|
controllerType
|
||||||
)
|
)
|
||||||
|
|
||||||
MenuTag.WIIMOTE_1,
|
MenuTag.WIIMOTE_1,
|
||||||
MenuTag.WIIMOTE_2,
|
MenuTag.WIIMOTE_2,
|
||||||
MenuTag.WIIMOTE_3,
|
MenuTag.WIIMOTE_3,
|
||||||
|
@ -122,6 +123,7 @@ class SettingsFragmentPresenter(
|
||||||
sl,
|
sl,
|
||||||
controllerNumber
|
controllerNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
MenuTag.WIIMOTE_EXTENSION_1,
|
MenuTag.WIIMOTE_EXTENSION_1,
|
||||||
MenuTag.WIIMOTE_EXTENSION_2,
|
MenuTag.WIIMOTE_EXTENSION_2,
|
||||||
MenuTag.WIIMOTE_EXTENSION_3,
|
MenuTag.WIIMOTE_EXTENSION_3,
|
||||||
|
@ -130,6 +132,7 @@ class SettingsFragmentPresenter(
|
||||||
controllerNumber,
|
controllerNumber,
|
||||||
controllerType
|
controllerType
|
||||||
)
|
)
|
||||||
|
|
||||||
MenuTag.WIIMOTE_GENERAL_1,
|
MenuTag.WIIMOTE_GENERAL_1,
|
||||||
MenuTag.WIIMOTE_GENERAL_2,
|
MenuTag.WIIMOTE_GENERAL_2,
|
||||||
MenuTag.WIIMOTE_GENERAL_3,
|
MenuTag.WIIMOTE_GENERAL_3,
|
||||||
|
@ -137,6 +140,7 @@ class SettingsFragmentPresenter(
|
||||||
sl,
|
sl,
|
||||||
controllerNumber
|
controllerNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
MenuTag.WIIMOTE_MOTION_SIMULATION_1,
|
MenuTag.WIIMOTE_MOTION_SIMULATION_1,
|
||||||
MenuTag.WIIMOTE_MOTION_SIMULATION_2,
|
MenuTag.WIIMOTE_MOTION_SIMULATION_2,
|
||||||
MenuTag.WIIMOTE_MOTION_SIMULATION_3,
|
MenuTag.WIIMOTE_MOTION_SIMULATION_3,
|
||||||
|
@ -144,6 +148,7 @@ class SettingsFragmentPresenter(
|
||||||
sl,
|
sl,
|
||||||
controllerNumber
|
controllerNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
MenuTag.WIIMOTE_MOTION_INPUT_1,
|
MenuTag.WIIMOTE_MOTION_INPUT_1,
|
||||||
MenuTag.WIIMOTE_MOTION_INPUT_2,
|
MenuTag.WIIMOTE_MOTION_INPUT_2,
|
||||||
MenuTag.WIIMOTE_MOTION_INPUT_3,
|
MenuTag.WIIMOTE_MOTION_INPUT_3,
|
||||||
|
@ -151,6 +156,7 @@ class SettingsFragmentPresenter(
|
||||||
sl,
|
sl,
|
||||||
controllerNumber
|
controllerNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> throw UnsupportedOperationException("Unimplemented menu")
|
else -> throw UnsupportedOperationException("Unimplemented menu")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,10 +460,12 @@ class SettingsFragmentPresenter(
|
||||||
BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, true)
|
BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, true)
|
||||||
BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, true)
|
BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
DSP_LLE_RECOMPILER -> {
|
DSP_LLE_RECOMPILER -> {
|
||||||
BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, false)
|
BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, false)
|
||||||
BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, true)
|
BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
DSP_LLE_INTERPRETER -> {
|
DSP_LLE_INTERPRETER -> {
|
||||||
BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, false)
|
BooleanSetting.MAIN_DSP_HLE.setBoolean(settings, false)
|
||||||
BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, false)
|
BooleanSetting.MAIN_DSP_JIT.setBoolean(settings, false)
|
||||||
|
@ -834,6 +842,14 @@ class SettingsFragmentPresenter(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
sl.add(
|
||||||
|
SwitchSetting(
|
||||||
|
context,
|
||||||
|
BooleanSetting.MAIN_EMULATE_INFINITY_BASE,
|
||||||
|
R.string.emulate_infinity_base,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addAdvancedSettings(sl: ArrayList<SettingsItem>) {
|
private fun addAdvancedSettings(sl: ArrayList<SettingsItem>) {
|
||||||
|
@ -856,10 +872,12 @@ class SettingsFragmentPresenter(
|
||||||
BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, false)
|
BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, false)
|
||||||
BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, false)
|
BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
SYNC_GPU_ON_IDLE_SKIP -> {
|
SYNC_GPU_ON_IDLE_SKIP -> {
|
||||||
BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, true)
|
BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, true)
|
||||||
BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, false)
|
BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
SYNC_GPU_ALWAYS -> {
|
SYNC_GPU_ALWAYS -> {
|
||||||
BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, true)
|
BooleanSetting.MAIN_SYNC_ON_SKIP_IDLE.setBoolean(settings, true)
|
||||||
BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, true)
|
BooleanSetting.MAIN_SYNC_GPU.setBoolean(settings, true)
|
||||||
|
@ -893,10 +911,12 @@ class SettingsFragmentPresenter(
|
||||||
emuCoresEntries = R.array.emuCoresEntriesX86_64
|
emuCoresEntries = R.array.emuCoresEntriesX86_64
|
||||||
emuCoresValues = R.array.emuCoresValuesX86_64
|
emuCoresValues = R.array.emuCoresValuesX86_64
|
||||||
}
|
}
|
||||||
|
|
||||||
4 -> {
|
4 -> {
|
||||||
emuCoresEntries = R.array.emuCoresEntriesARM64
|
emuCoresEntries = R.array.emuCoresEntriesARM64
|
||||||
emuCoresValues = R.array.emuCoresValuesARM64
|
emuCoresValues = R.array.emuCoresValuesARM64
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
emuCoresEntries = R.array.emuCoresEntriesGeneric
|
emuCoresEntries = R.array.emuCoresEntriesGeneric
|
||||||
emuCoresValues = R.array.emuCoresValuesGeneric
|
emuCoresValues = R.array.emuCoresValuesGeneric
|
||||||
|
@ -2246,6 +2266,7 @@ class SettingsFragmentPresenter(
|
||||||
setting.uiSuffix
|
setting.uiSuffix
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
NumericSetting.TYPE_BOOLEAN -> sl.add(
|
NumericSetting.TYPE_BOOLEAN -> sl.add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
InputMappingBooleanSetting(setting),
|
InputMappingBooleanSetting(setting),
|
||||||
|
|
|
@ -16,7 +16,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.dolphinemu.dolphinemu.R
|
import org.dolphinemu.dolphinemu.R
|
||||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
||||||
import org.dolphinemu.dolphinemu.databinding.DialogCreateSkylanderBinding
|
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
|
||||||
import org.dolphinemu.dolphinemu.features.skylanders.SkylanderConfig.removeSkylander
|
import org.dolphinemu.dolphinemu.features.skylanders.SkylanderConfig.removeSkylander
|
||||||
import org.dolphinemu.dolphinemu.features.skylanders.model.SkylanderPair
|
import org.dolphinemu.dolphinemu.features.skylanders.model.SkylanderPair
|
||||||
|
@ -25,27 +25,27 @@ class SkylanderSlotAdapter(
|
||||||
private val slots: List<SkylanderSlot>,
|
private val slots: List<SkylanderSlot>,
|
||||||
private val activity: EmulationActivity
|
private val activity: EmulationActivity
|
||||||
) : RecyclerView.Adapter<SkylanderSlotAdapter.ViewHolder>(), OnItemClickListener {
|
) : RecyclerView.Adapter<SkylanderSlotAdapter.ViewHolder>(), OnItemClickListener {
|
||||||
class ViewHolder(var binding: ListItemSkylanderSlotBinding) :
|
class ViewHolder(var binding: ListItemNfcFigureSlotBinding) :
|
||||||
RecyclerView.ViewHolder(binding.getRoot())
|
RecyclerView.ViewHolder(binding.getRoot())
|
||||||
|
|
||||||
private lateinit var binding: DialogCreateSkylanderBinding
|
private lateinit var binding: DialogCreateSkylanderBinding
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
val binding = ListItemSkylanderSlotBinding.inflate(inflater, parent, false)
|
val binding = ListItemNfcFigureSlotBinding.inflate(inflater, parent, false)
|
||||||
return ViewHolder(binding)
|
return ViewHolder(binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val slot = slots[position]
|
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)
|
removeSkylander(slot.portalSlot)
|
||||||
activity.clearSkylander(slot.slotNum)
|
activity.clearSkylander(slot.slotNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.binding.buttonLoadSkylander.setOnClickListener {
|
holder.binding.buttonLoadFigure.setOnClickListener {
|
||||||
val loadSkylander = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
val loadSkylander = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||||
loadSkylander.addCategory(Intent.CATEGORY_OPENABLE)
|
loadSkylander.addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
loadSkylander.type = "*/*"
|
loadSkylander.type = "*/*"
|
||||||
|
@ -71,14 +71,14 @@ class SkylanderSlotAdapter(
|
||||||
)
|
)
|
||||||
binding.skylanderDropdown.onItemClickListener = this
|
binding.skylanderDropdown.onItemClickListener = this
|
||||||
|
|
||||||
holder.binding.buttonCreateSkylander.setOnClickListener {
|
holder.binding.buttonCreateFigure.setOnClickListener {
|
||||||
if (binding.getRoot().parent != null) {
|
if (binding.getRoot().parent != null) {
|
||||||
(binding.getRoot().parent as ViewGroup).removeAllViews()
|
(binding.getRoot().parent as ViewGroup).removeAllViews()
|
||||||
}
|
}
|
||||||
val createDialog = MaterialAlertDialogBuilder(activity)
|
val createDialog = MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.create_skylander_title)
|
.setTitle(R.string.create_skylander_title)
|
||||||
.setView(binding.getRoot())
|
.setView(binding.getRoot())
|
||||||
.setPositiveButton(R.string.create_skylander, null)
|
.setPositiveButton(R.string.create_figure, null)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show()
|
.show()
|
||||||
createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||||
|
|
|
@ -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_exit, EmulationActivity.MENU_ACTION_EXIT);
|
||||||
buttonsActionsMap.append(R.id.menu_settings, EmulationActivity.MENU_ACTION_SETTINGS);
|
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_skylanders, EmulationActivity.MENU_ACTION_SKYLANDERS);
|
||||||
|
buttonsActionsMap.append(R.id.menu_infinitybase, EmulationActivity.MENU_ACTION_INFINITY_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FragmentIngameMenuBinding mBinding;
|
private FragmentIngameMenuBinding mBinding;
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/root"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="@dimen/spacing_medlarge">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/layout_infinity_dropdown"
|
||||||
|
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="@dimen/spacing_medlarge"
|
||||||
|
android:paddingHorizontal="@dimen/spacing_medlarge"
|
||||||
|
android:hint="@string/infinity_label"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.MaterialAutoCompleteTextView
|
||||||
|
android:id="@+id/infinity_dropdown"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:spinnerMode="dialog"
|
||||||
|
android:imeOptions="actionDone" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/layout_infinity_dropdown"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:baselineAligned="false">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/layout_infinity_num"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:hint="@string/infinity_number"
|
||||||
|
android:paddingHorizontal="@dimen/spacing_medlarge">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/infinity_num"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="number" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -4,10 +4,10 @@
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/skylanders_manager"
|
android:id="@+id/figure_manager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
android:scrollbars="vertical"
|
android:fadeScrollbars="false"
|
||||||
android:fadeScrollbars="false"/>
|
android:scrollbars="vertical" />
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -106,6 +106,11 @@
|
||||||
android:text="@string/emulate_skylander_portal"
|
android:text="@string/emulate_skylander_portal"
|
||||||
style="@style/InGameMenuOption" />
|
style="@style/InGameMenuOption" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/menu_infinitybase"
|
||||||
|
android:text="@string/emulate_infinity_base"
|
||||||
|
style="@style/InGameMenuOption" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -8,43 +8,43 @@
|
||||||
android:padding="@dimen/spacing_medlarge">
|
android:padding="@dimen/spacing_medlarge">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_create_skylander"
|
android:id="@+id/button_create_figure"
|
||||||
style="?attr/materialIconButtonFilledTonalStyle"
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginEnd="@dimen/spacing_small"
|
android:layout_marginEnd="@dimen/spacing_small"
|
||||||
android:layout_toStartOf="@id/button_load_skylander"
|
android:layout_toStartOf="@id/button_load_figure"
|
||||||
android:contentDescription="@string/create_skylander"
|
android:contentDescription="@string/create_figure"
|
||||||
android:tooltipText="@string/create_skylander"
|
android:tooltipText="@string/create_figure"
|
||||||
app:icon="@drawable/ic_add" />
|
app:icon="@drawable/ic_add" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_load_skylander"
|
android:id="@+id/button_load_figure"
|
||||||
style="?attr/materialIconButtonFilledTonalStyle"
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginEnd="@dimen/spacing_small"
|
android:layout_marginEnd="@dimen/spacing_small"
|
||||||
android:layout_toStartOf="@+id/button_clear_skylander"
|
android:layout_toStartOf="@+id/button_clear_figure"
|
||||||
android:contentDescription="@string/load_skylander"
|
android:contentDescription="@string/load_figure"
|
||||||
android:tooltipText="@string/load_skylander"
|
android:tooltipText="@string/load_figure"
|
||||||
app:icon="@drawable/ic_load" />
|
app:icon="@drawable/ic_load" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_clear_skylander"
|
android:id="@+id/button_clear_figure"
|
||||||
style="?attr/materialIconButtonFilledTonalStyle"
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginEnd="@dimen/spacing_large"
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
android:contentDescription="@string/remove_skylander"
|
android:contentDescription="@string/remove_figure"
|
||||||
android:tooltipText="@string/remove_skylander"
|
android:tooltipText="@string/remove_figure"
|
||||||
app:icon="@drawable/ic_clear" />
|
app:icon="@drawable/ic_clear" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/text_skylander_name"
|
android:id="@+id/text_figure_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||||
android:layout_marginEnd="@dimen/spacing_large"
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
android:layout_marginStart="@dimen/spacing_large"
|
android:layout_marginStart="@dimen/spacing_large"
|
||||||
android:layout_toStartOf="@+id/button_create_skylander"
|
android:layout_toStartOf="@+id/button_create_figure"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:textColor="?attr/colorOnSurface"
|
android:textColor="?attr/colorOnSurface"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
|
@ -846,9 +846,6 @@ It can efficiently compress both junk data and encrypted Wii data.
|
||||||
<string name="emulated_usb_devices">Emulated USB Devices</string>
|
<string name="emulated_usb_devices">Emulated USB Devices</string>
|
||||||
<string name="emulate_skylander_portal">Skylanders Portal</string>
|
<string name="emulate_skylander_portal">Skylanders Portal</string>
|
||||||
<string name="skylanders_manager">Skylanders Manager</string>
|
<string name="skylanders_manager">Skylanders Manager</string>
|
||||||
<string name="load_skylander">Load</string>
|
|
||||||
<string name="remove_skylander">Remove</string>
|
|
||||||
<string name="create_skylander">Create</string>
|
|
||||||
<string name="create_skylander_title">Create Skylander</string>
|
<string name="create_skylander_title">Create Skylander</string>
|
||||||
<string name="skylander_label">Skylander</string>
|
<string name="skylander_label">Skylander</string>
|
||||||
<string name="skylander_slot">Slot %1$d</string>
|
<string name="skylander_slot">Slot %1$d</string>
|
||||||
|
@ -856,4 +853,23 @@ It can efficiently compress both junk data and encrypted Wii data.
|
||||||
<string name="skylander_variant">Variant</string>
|
<string name="skylander_variant">Variant</string>
|
||||||
<string name="invalid_skylander">Invalid Skylander Selection</string>
|
<string name="invalid_skylander">Invalid Skylander Selection</string>
|
||||||
|
|
||||||
|
<string name="emulate_infinity_base">Infinity Base</string>
|
||||||
|
<string name="infinity_manager">Infinity Manager</string>
|
||||||
|
<string name="load_figure">Load</string>
|
||||||
|
<string name="remove_figure">Remove</string>
|
||||||
|
<string name="create_figure">Create</string>
|
||||||
|
<string name="create_figure_title">Create Figure</string>
|
||||||
|
<string name="infinity_label">Infinity Figure</string>
|
||||||
|
<string name="infinity_number">Figure Number</string>
|
||||||
|
<string name="invalid_infinity_figure">Invalid Figure Selection</string>
|
||||||
|
<string name="infinity_hexagon_label">Power Disc/Play Set</string>
|
||||||
|
<string name="infinity_p1_label">Player One</string>
|
||||||
|
<string name="infinity_p2_label">Player Two</string>
|
||||||
|
<string name="infinity_p1a1_label">P1 Ability One</string>
|
||||||
|
<string name="infinity_p2a1_label">P2 Ability One</string>
|
||||||
|
<string name="infinity_p1a2_label">P1 Ability Two</string>
|
||||||
|
<string name="infinity_p2a2_label">P2 Ability Two</string>
|
||||||
|
<string name="incompatible_figure_selected">Incompatible Figure Selected</string>
|
||||||
|
<string name="select_compatible_figure">Please select a compatible figure file</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -10,6 +10,7 @@ add_library(main SHARED
|
||||||
GameList/GameFile.cpp
|
GameList/GameFile.cpp
|
||||||
GameList/GameFile.h
|
GameList/GameFile.h
|
||||||
GameList/GameFileCache.cpp
|
GameList/GameFileCache.cpp
|
||||||
|
InfinityConfig.cpp
|
||||||
Input/Control.cpp
|
Input/Control.cpp
|
||||||
Input/Control.h
|
Input/Control.h
|
||||||
Input/ControlGroup.cpp
|
Input/ControlGroup.cpp
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
// Copyright 2023 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "AndroidCommon/AndroidCommon.h"
|
||||||
|
#include "Core/IOS/USB/Emulated/Infinity.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_infinitybase_InfinityConfig_getFigureMap(JNIEnv* env,
|
||||||
|
jobject obj)
|
||||||
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
|
||||||
|
jobject hash_map_obj = env->NewObject(IDCache::GetHashMapClass(), IDCache::GetHashMapInit(),
|
||||||
|
system.GetInfinityBase().GetFigureList().size());
|
||||||
|
|
||||||
|
jmethodID hash_map_put = env->GetMethodID(
|
||||||
|
hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
|
||||||
|
jclass long_class = env->FindClass("java/lang/Long");
|
||||||
|
jmethodID long_init = env->GetMethodID(long_class, "<init>", "(J)V");
|
||||||
|
|
||||||
|
for (const auto& it : system.GetInfinityBase().GetFigureList())
|
||||||
|
{
|
||||||
|
const std::string& name = it.first;
|
||||||
|
jobject figure_number = env->NewObject(long_class, long_init, (jlong)it.second);
|
||||||
|
env->CallObjectMethod(hash_map_obj, IDCache::GetHashMapPut(), figure_number,
|
||||||
|
ToJString(env, name));
|
||||||
|
env->DeleteLocalRef(figure_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash_map_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_infinitybase_InfinityConfig_getInverseFigureMap(JNIEnv* env,
|
||||||
|
jobject obj)
|
||||||
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
|
||||||
|
jobject hash_map_obj = env->NewObject(IDCache::GetHashMapClass(), IDCache::GetHashMapInit(),
|
||||||
|
system.GetInfinityBase().GetFigureList().size());
|
||||||
|
|
||||||
|
jmethodID hash_map_put = env->GetMethodID(
|
||||||
|
hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
|
||||||
|
jclass long_class = env->FindClass("java/lang/Long");
|
||||||
|
jmethodID long_init = env->GetMethodID(long_class, "<init>", "(J)V");
|
||||||
|
|
||||||
|
for (const auto& it : system.GetInfinityBase().GetFigureList())
|
||||||
|
{
|
||||||
|
const std::string& name = it.first;
|
||||||
|
jobject figure_number = env->NewObject(long_class, long_init, (jlong)it.second);
|
||||||
|
env->CallObjectMethod(hash_map_obj, IDCache::GetHashMapPut(), ToJString(env, name),
|
||||||
|
figure_number);
|
||||||
|
env->DeleteLocalRef(figure_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash_map_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_infinitybase_InfinityConfig_removeFigure(JNIEnv* env,
|
||||||
|
jclass clazz,
|
||||||
|
jint position)
|
||||||
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetInfinityBase().RemoveFigure(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_infinitybase_InfinityConfig_loadFigure(JNIEnv* env,
|
||||||
|
jclass clazz,
|
||||||
|
jint position,
|
||||||
|
jstring file_name)
|
||||||
|
{
|
||||||
|
File::IOFile inf_file(GetJString(env, file_name), "r+b");
|
||||||
|
if (!inf_file)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::array<u8, 0x14 * 0x10> file_data{};
|
||||||
|
if (!inf_file.ReadBytes(file_data.data(), file_data.size()))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetInfinityBase().RemoveFigure(position);
|
||||||
|
return ToJString(env,
|
||||||
|
system.GetInfinityBase().LoadFigure(file_data, std::move(inf_file), position));
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_infinitybase_InfinityConfig_createFigure(
|
||||||
|
JNIEnv* env, jclass clazz, jlong figure_number, jstring fileName, jint position)
|
||||||
|
{
|
||||||
|
u32 fig_num = static_cast<u32>(figure_number);
|
||||||
|
|
||||||
|
std::string file_name = GetJString(env, fileName);
|
||||||
|
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetInfinityBase().CreateFigure(file_name, fig_num);
|
||||||
|
system.GetInfinityBase().RemoveFigure(position);
|
||||||
|
|
||||||
|
File::IOFile inf_file(file_name, "r+b");
|
||||||
|
if (!inf_file)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::array<u8, 0x14 * 0x10> file_data{};
|
||||||
|
if (!inf_file.ReadBytes(file_data.data(), file_data.size()))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ToJString(env,
|
||||||
|
system.GetInfinityBase().LoadFigure(file_data, std::move(inf_file), position));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue