Merge pull request #11615 from t895/kotlin-riivolution
Android: Convert Riivolution Boot Activity to Kotlin
This commit is contained in:
commit
1b7969bc62
|
@ -1,86 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.riivolution.model;
|
|
||||||
|
|
||||||
import androidx.annotation.Keep;
|
|
||||||
|
|
||||||
public class RiivolutionPatches
|
|
||||||
{
|
|
||||||
private String mGameId;
|
|
||||||
private int mRevision;
|
|
||||||
private int mDiscNumber;
|
|
||||||
|
|
||||||
private boolean mUnsavedChanges = false;
|
|
||||||
|
|
||||||
@Keep
|
|
||||||
private long mPointer;
|
|
||||||
|
|
||||||
public RiivolutionPatches(String gameId, int revision, int discNumber)
|
|
||||||
{
|
|
||||||
mGameId = gameId;
|
|
||||||
mRevision = revision;
|
|
||||||
mDiscNumber = discNumber;
|
|
||||||
|
|
||||||
mPointer = initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public native void finalize();
|
|
||||||
|
|
||||||
private static native long initialize();
|
|
||||||
|
|
||||||
public native int getDiscCount();
|
|
||||||
|
|
||||||
public native String getDiscName(int discIndex);
|
|
||||||
|
|
||||||
public native int getSectionCount(int discIndex);
|
|
||||||
|
|
||||||
public native String getSectionName(int discIndex, int sectionIndex);
|
|
||||||
|
|
||||||
public native int getOptionCount(int discIndex, int sectionIndex);
|
|
||||||
|
|
||||||
public native String getOptionName(int discIndex, int sectionIndex, int optionIndex);
|
|
||||||
|
|
||||||
public native int getChoiceCount(int discIndex, int sectionIndex, int optionIndex);
|
|
||||||
|
|
||||||
public native String getChoiceName(int discIndex, int sectionIndex, int optionIndex,
|
|
||||||
int choiceIndex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 0 if no choice is selected, otherwise the index of the selected choice plus one.
|
|
||||||
*/
|
|
||||||
public native int getSelectedChoice(int discIndex, int sectionIndex, int optionIndex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param choiceIndex 0 to select no choice, otherwise the choice index plus one.
|
|
||||||
*/
|
|
||||||
public void setSelectedChoice(int discIndex, int sectionIndex, int optionIndex, int choiceIndex)
|
|
||||||
{
|
|
||||||
mUnsavedChanges = true;
|
|
||||||
setSelectedChoiceImpl(discIndex, sectionIndex, optionIndex, choiceIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param choiceIndex 0 to select no choice, otherwise the choice index plus one.
|
|
||||||
*/
|
|
||||||
private native void setSelectedChoiceImpl(int discIndex, int sectionIndex, int optionIndex,
|
|
||||||
int choiceIndex);
|
|
||||||
|
|
||||||
public void loadConfig()
|
|
||||||
{
|
|
||||||
loadConfigImpl(mGameId, mRevision, mDiscNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
private native void loadConfigImpl(String gameId, int revision, int discNumber);
|
|
||||||
|
|
||||||
public void saveConfig()
|
|
||||||
{
|
|
||||||
if (mUnsavedChanges)
|
|
||||||
{
|
|
||||||
mUnsavedChanges = false;
|
|
||||||
saveConfigImpl(mGameId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private native void saveConfigImpl(String gameId);
|
|
||||||
}
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.riivolution.model
|
||||||
|
|
||||||
|
import androidx.annotation.Keep
|
||||||
|
|
||||||
|
class RiivolutionPatches(
|
||||||
|
private val gameId: String,
|
||||||
|
private val revision: Int,
|
||||||
|
private val discNumber: Int
|
||||||
|
) {
|
||||||
|
private var unsavedChanges = false
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
private val pointer: Long = initialize()
|
||||||
|
|
||||||
|
external fun finalize()
|
||||||
|
|
||||||
|
external fun getDiscCount(): Int
|
||||||
|
|
||||||
|
external fun getDiscName(discIndex: Int): String
|
||||||
|
|
||||||
|
external fun getSectionCount(discIndex: Int): Int
|
||||||
|
|
||||||
|
external fun getSectionName(discIndex: Int, sectionIndex: Int): String
|
||||||
|
|
||||||
|
external fun getOptionCount(discIndex: Int, sectionIndex: Int): Int
|
||||||
|
|
||||||
|
external fun getOptionName(discIndex: Int, sectionIndex: Int, optionIndex: Int): String
|
||||||
|
|
||||||
|
external fun getChoiceCount(discIndex: Int, sectionIndex: Int, optionIndex: Int): Int
|
||||||
|
|
||||||
|
external fun getChoiceName(
|
||||||
|
discIndex: Int,
|
||||||
|
sectionIndex: Int,
|
||||||
|
optionIndex: Int,
|
||||||
|
choiceIndex: Int
|
||||||
|
): String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 0 if no choice is selected, otherwise the index of the selected choice plus one.
|
||||||
|
*/
|
||||||
|
external fun getSelectedChoice(discIndex: Int, sectionIndex: Int, optionIndex: Int): Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param choiceIndex 0 to select no choice, otherwise the choice index plus one.
|
||||||
|
*/
|
||||||
|
fun setSelectedChoice(discIndex: Int, sectionIndex: Int, optionIndex: Int, choiceIndex: Int) {
|
||||||
|
unsavedChanges = true
|
||||||
|
setSelectedChoiceImpl(discIndex, sectionIndex, optionIndex, choiceIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param choiceIndex 0 to select no choice, otherwise the choice index plus one.
|
||||||
|
*/
|
||||||
|
private external fun setSelectedChoiceImpl(
|
||||||
|
discIndex: Int, sectionIndex: Int, optionIndex: Int,
|
||||||
|
choiceIndex: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
fun loadConfig() {
|
||||||
|
loadConfigImpl(gameId, revision, discNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
private external fun loadConfigImpl(gameId: String, revision: Int, discNumber: Int)
|
||||||
|
|
||||||
|
fun saveConfig() {
|
||||||
|
if (unsavedChanges) {
|
||||||
|
unsavedChanges = false
|
||||||
|
saveConfigImpl(gameId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private external fun saveConfigImpl(gameId: String)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
private external fun initialize(): Long
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,66 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.riivolution.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.databinding.ListItemRiivolutionBinding;
|
|
||||||
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class RiivolutionAdapter extends RecyclerView.Adapter<RiivolutionViewHolder>
|
|
||||||
{
|
|
||||||
private final Context mContext;
|
|
||||||
private final RiivolutionPatches mPatches;
|
|
||||||
private final ArrayList<RiivolutionItem> mItems = new ArrayList<>();
|
|
||||||
|
|
||||||
public RiivolutionAdapter(Context context, RiivolutionPatches patches)
|
|
||||||
{
|
|
||||||
mContext = context;
|
|
||||||
mPatches = patches;
|
|
||||||
|
|
||||||
int discCount = mPatches.getDiscCount();
|
|
||||||
for (int i = 0; i < discCount; i++)
|
|
||||||
{
|
|
||||||
mItems.add(new RiivolutionItem(i));
|
|
||||||
|
|
||||||
int sectionCount = mPatches.getSectionCount(i);
|
|
||||||
for (int j = 0; j < sectionCount; j++)
|
|
||||||
{
|
|
||||||
mItems.add(new RiivolutionItem(i, j));
|
|
||||||
|
|
||||||
int optionCount = mPatches.getOptionCount(i, j);
|
|
||||||
for (int k = 0; k < optionCount; k++)
|
|
||||||
{
|
|
||||||
mItems.add(new RiivolutionItem(i, j, k));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public RiivolutionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
|
||||||
{
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
|
||||||
ListItemRiivolutionBinding binding = ListItemRiivolutionBinding.inflate(inflater);
|
|
||||||
return new RiivolutionViewHolder(binding.getRoot(), binding);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RiivolutionViewHolder holder, int position)
|
|
||||||
{
|
|
||||||
holder.bind(mContext, mPatches, mItems.get(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount()
|
|
||||||
{
|
|
||||||
return mItems.size();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.riivolution.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.dolphinemu.dolphinemu.databinding.ListItemRiivolutionBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches
|
||||||
|
|
||||||
|
class RiivolutionAdapter(private val context: Context, private val patches: RiivolutionPatches) :
|
||||||
|
RecyclerView.Adapter<RiivolutionViewHolder>() {
|
||||||
|
private val items = ArrayList<RiivolutionItem>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
val discCount = patches.getDiscCount()
|
||||||
|
for (i in 0 until discCount) {
|
||||||
|
items.add(RiivolutionItem(i))
|
||||||
|
|
||||||
|
val sectionCount = patches.getSectionCount(i)
|
||||||
|
for (j in 0 until sectionCount) {
|
||||||
|
items.add(RiivolutionItem(i, j))
|
||||||
|
|
||||||
|
val optionCount = patches.getOptionCount(i, j)
|
||||||
|
for (k in 0 until optionCount) {
|
||||||
|
items.add(RiivolutionItem(i, j, k))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RiivolutionViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
val binding = ListItemRiivolutionBinding.inflate(inflater)
|
||||||
|
return RiivolutionViewHolder(binding.root, binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RiivolutionViewHolder, position: Int) {
|
||||||
|
holder.bind(context, patches, items[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return items.size
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,138 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.riivolution.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.core.graphics.Insets;
|
|
||||||
import androidx.core.view.ViewCompat;
|
|
||||||
import androidx.core.view.WindowCompat;
|
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import com.google.android.material.color.MaterialColors;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
|
||||||
import org.dolphinemu.dolphinemu.databinding.ActivityRiivolutionBootBinding;
|
|
||||||
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches;
|
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper;
|
|
||||||
|
|
||||||
public class RiivolutionBootActivity extends AppCompatActivity
|
|
||||||
{
|
|
||||||
private static final String ARG_GAME_PATH = "game_path";
|
|
||||||
private static final String ARG_GAME_ID = "game_id";
|
|
||||||
private static final String ARG_REVISION = "revision";
|
|
||||||
private static final String ARG_DISC_NUMBER = "disc_number";
|
|
||||||
|
|
||||||
private RiivolutionPatches mPatches;
|
|
||||||
|
|
||||||
private ActivityRiivolutionBootBinding mBinding;
|
|
||||||
|
|
||||||
public static void launch(Context context, String gamePath, String gameId, int revision,
|
|
||||||
int discNumber)
|
|
||||||
{
|
|
||||||
Intent launcher = new Intent(context, RiivolutionBootActivity.class);
|
|
||||||
launcher.putExtra(ARG_GAME_PATH, gamePath);
|
|
||||||
launcher.putExtra(ARG_GAME_ID, gameId);
|
|
||||||
launcher.putExtra(ARG_REVISION, revision);
|
|
||||||
launcher.putExtra(ARG_DISC_NUMBER, discNumber);
|
|
||||||
context.startActivity(launcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
ThemeHelper.setTheme(this);
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
mBinding = ActivityRiivolutionBootBinding.inflate(getLayoutInflater());
|
|
||||||
setContentView(mBinding.getRoot());
|
|
||||||
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
|
|
||||||
String path = getIntent().getStringExtra(ARG_GAME_PATH);
|
|
||||||
String gameId = intent.getStringExtra(ARG_GAME_ID);
|
|
||||||
int revision = intent.getIntExtra(ARG_REVISION, -1);
|
|
||||||
int discNumber = intent.getIntExtra(ARG_DISC_NUMBER, -1);
|
|
||||||
|
|
||||||
String loadPath = StringSetting.MAIN_LOAD_PATH.getStringGlobal();
|
|
||||||
if (loadPath.isEmpty())
|
|
||||||
loadPath = DirectoryInitialization.getUserDirectory() + "/Load";
|
|
||||||
|
|
||||||
mBinding.textSdRoot.setText(getString(R.string.riivolution_sd_root, loadPath + "/Riivolution"));
|
|
||||||
|
|
||||||
mBinding.buttonStart.setOnClickListener((v) ->
|
|
||||||
{
|
|
||||||
if (mPatches != null)
|
|
||||||
mPatches.saveConfig();
|
|
||||||
|
|
||||||
EmulationActivity.launch(this, path, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
new Thread(() ->
|
|
||||||
{
|
|
||||||
RiivolutionPatches patches = new RiivolutionPatches(gameId, revision, discNumber);
|
|
||||||
patches.loadConfig();
|
|
||||||
runOnUiThread(() -> populateList(patches));
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
mBinding.toolbarRiivolution.setTitle(getString(R.string.riivolution_riivolution));
|
|
||||||
setSupportActionBar(mBinding.toolbarRiivolution);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
|
|
||||||
setInsets();
|
|
||||||
ThemeHelper.enableScrollTint(this, mBinding.toolbarRiivolution, mBinding.appbarRiivolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop()
|
|
||||||
{
|
|
||||||
super.onStop();
|
|
||||||
|
|
||||||
if (mPatches != null)
|
|
||||||
mPatches.saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onSupportNavigateUp()
|
|
||||||
{
|
|
||||||
onBackPressed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateList(RiivolutionPatches patches)
|
|
||||||
{
|
|
||||||
mPatches = patches;
|
|
||||||
|
|
||||||
mBinding.recyclerView.setAdapter(new RiivolutionAdapter(this, patches));
|
|
||||||
mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setInsets()
|
|
||||||
{
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(mBinding.appbarRiivolution, (v, windowInsets) ->
|
|
||||||
{
|
|
||||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
|
||||||
|
|
||||||
InsetsHelper.insetAppBar(insets, mBinding.appbarRiivolution);
|
|
||||||
|
|
||||||
mBinding.scrollViewRiivolution.setPadding(insets.left, 0, insets.right, insets.bottom);
|
|
||||||
|
|
||||||
InsetsHelper.applyNavbarWorkaround(insets.bottom, mBinding.workaroundView);
|
|
||||||
ThemeHelper.setNavigationBarColor(this,
|
|
||||||
MaterialColors.getColor(mBinding.appbarRiivolution, R.attr.colorSurface));
|
|
||||||
|
|
||||||
return windowInsets;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.riivolution.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.google.android.material.color.MaterialColors
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.dolphinemu.dolphinemu.R
|
||||||
|
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
||||||
|
import org.dolphinemu.dolphinemu.databinding.ActivityRiivolutionBootBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches
|
||||||
|
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting
|
||||||
|
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
||||||
|
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||||
|
import org.dolphinemu.dolphinemu.utils.ThemeHelper
|
||||||
|
|
||||||
|
class RiivolutionBootActivity : AppCompatActivity() {
|
||||||
|
private var patches: RiivolutionPatches? = null
|
||||||
|
private lateinit var binding: ActivityRiivolutionBootBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
binding = ActivityRiivolutionBootBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
|
val path = intent.getStringExtra(ARG_GAME_PATH)
|
||||||
|
val gameId = intent.getStringExtra(ARG_GAME_ID)
|
||||||
|
val revision = intent.getIntExtra(ARG_REVISION, -1)
|
||||||
|
val discNumber = intent.getIntExtra(ARG_DISC_NUMBER, -1)
|
||||||
|
|
||||||
|
var loadPath = StringSetting.MAIN_LOAD_PATH.stringGlobal
|
||||||
|
if (loadPath.isEmpty()) loadPath = DirectoryInitialization.getUserDirectory() + "/Load"
|
||||||
|
|
||||||
|
binding.textSdRoot.text = getString(R.string.riivolution_sd_root, "$loadPath/Riivolution")
|
||||||
|
binding.buttonStart.setOnClickListener {
|
||||||
|
if (patches != null) patches!!.saveConfig()
|
||||||
|
EmulationActivity.launch(this, path, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
val patches = RiivolutionPatches(gameId!!, revision, discNumber)
|
||||||
|
patches.loadConfig()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
populateList(patches)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.toolbarRiivolution.title = getString(R.string.riivolution_riivolution)
|
||||||
|
setSupportActionBar(binding.toolbarRiivolution)
|
||||||
|
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
setInsets()
|
||||||
|
ThemeHelper.enableScrollTint(this, binding.toolbarRiivolution, binding.appbarRiivolution)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
if (patches != null) patches!!.saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun populateList(patches: RiivolutionPatches) {
|
||||||
|
this.patches = patches
|
||||||
|
binding.recyclerView.adapter = RiivolutionAdapter(this, patches)
|
||||||
|
binding.recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setInsets() {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.appbarRiivolution) { v: View?, windowInsets: WindowInsetsCompat ->
|
||||||
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
|
||||||
|
InsetsHelper.insetAppBar(insets, binding.appbarRiivolution)
|
||||||
|
|
||||||
|
binding.scrollViewRiivolution.setPadding(insets.left, 0, insets.right, insets.bottom)
|
||||||
|
|
||||||
|
InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView)
|
||||||
|
ThemeHelper.setNavigationBarColor(
|
||||||
|
this,
|
||||||
|
MaterialColors.getColor(binding.appbarRiivolution, R.attr.colorSurface)
|
||||||
|
)
|
||||||
|
|
||||||
|
windowInsets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val ARG_GAME_PATH = "game_path"
|
||||||
|
private const val ARG_GAME_ID = "game_id"
|
||||||
|
private const val ARG_REVISION = "revision"
|
||||||
|
private const val ARG_DISC_NUMBER = "disc_number"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun launch(
|
||||||
|
context: Context,
|
||||||
|
gamePath: String?,
|
||||||
|
gameId: String?,
|
||||||
|
revision: Int,
|
||||||
|
discNumber: Int
|
||||||
|
) {
|
||||||
|
val launcher = Intent(context, RiivolutionBootActivity::class.java)
|
||||||
|
launcher.putExtra(ARG_GAME_PATH, gamePath)
|
||||||
|
launcher.putExtra(ARG_GAME_ID, gameId)
|
||||||
|
launcher.putExtra(ARG_REVISION, revision)
|
||||||
|
launcher.putExtra(ARG_DISC_NUMBER, discNumber)
|
||||||
|
context.startActivity(launcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,40 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.riivolution.ui;
|
|
||||||
|
|
||||||
public class RiivolutionItem
|
|
||||||
{
|
|
||||||
public final int mDiscIndex;
|
|
||||||
public final int mSectionIndex;
|
|
||||||
public final int mOptionIndex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for a disc.
|
|
||||||
*/
|
|
||||||
public RiivolutionItem(int discIndex)
|
|
||||||
{
|
|
||||||
mDiscIndex = discIndex;
|
|
||||||
mSectionIndex = -1;
|
|
||||||
mOptionIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for a section.
|
|
||||||
*/
|
|
||||||
public RiivolutionItem(int discIndex, int sectionIndex)
|
|
||||||
{
|
|
||||||
mDiscIndex = discIndex;
|
|
||||||
mSectionIndex = sectionIndex;
|
|
||||||
mOptionIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for an option.
|
|
||||||
*/
|
|
||||||
public RiivolutionItem(int discIndex, int sectionIndex, int optionIndex)
|
|
||||||
{
|
|
||||||
mDiscIndex = discIndex;
|
|
||||||
mSectionIndex = sectionIndex;
|
|
||||||
mOptionIndex = optionIndex;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.riivolution.ui
|
||||||
|
|
||||||
|
class RiivolutionItem {
|
||||||
|
val mDiscIndex: Int
|
||||||
|
val mSectionIndex: Int
|
||||||
|
val mOptionIndex: Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for a disc.
|
||||||
|
*/
|
||||||
|
constructor(discIndex: Int) {
|
||||||
|
mDiscIndex = discIndex
|
||||||
|
mSectionIndex = -1
|
||||||
|
mOptionIndex = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for a section.
|
||||||
|
*/
|
||||||
|
constructor(discIndex: Int, sectionIndex: Int) {
|
||||||
|
mDiscIndex = discIndex
|
||||||
|
mSectionIndex = sectionIndex
|
||||||
|
mOptionIndex = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for an option.
|
||||||
|
*/
|
||||||
|
constructor(discIndex: Int, sectionIndex: Int, optionIndex: Int) {
|
||||||
|
mDiscIndex = discIndex
|
||||||
|
mSectionIndex = sectionIndex
|
||||||
|
mOptionIndex = optionIndex
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,87 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.riivolution.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
import org.dolphinemu.dolphinemu.databinding.ListItemRiivolutionBinding;
|
|
||||||
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches;
|
|
||||||
|
|
||||||
public class RiivolutionViewHolder extends RecyclerView.ViewHolder
|
|
||||||
implements AdapterView.OnItemClickListener
|
|
||||||
{
|
|
||||||
private final ListItemRiivolutionBinding mBinding;
|
|
||||||
|
|
||||||
private RiivolutionPatches mPatches;
|
|
||||||
private RiivolutionItem mItem;
|
|
||||||
|
|
||||||
public RiivolutionViewHolder(@NonNull View itemView, ListItemRiivolutionBinding binding)
|
|
||||||
{
|
|
||||||
super(itemView);
|
|
||||||
mBinding = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void bind(Context context, RiivolutionPatches patches, RiivolutionItem item)
|
|
||||||
{
|
|
||||||
// TODO: Remove workaround for text filtering issue in material components when fixed
|
|
||||||
// https://github.com/material-components/material-components-android/issues/1464
|
|
||||||
mBinding.dropdownChoice.setSaveEnabled(false);
|
|
||||||
|
|
||||||
String text;
|
|
||||||
if (item.mOptionIndex != -1)
|
|
||||||
{
|
|
||||||
mBinding.textName.setVisibility(View.GONE);
|
|
||||||
text = patches.getOptionName(item.mDiscIndex, item.mSectionIndex, item.mOptionIndex);
|
|
||||||
mBinding.layoutChoice.setHint(text);
|
|
||||||
}
|
|
||||||
else if (item.mSectionIndex != -1)
|
|
||||||
{
|
|
||||||
mBinding.textName.setTextAppearance(context, R.style.TextAppearance_AppCompat_Medium);
|
|
||||||
mBinding.layoutChoice.setVisibility(View.GONE);
|
|
||||||
text = patches.getSectionName(item.mDiscIndex, item.mSectionIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mBinding.layoutChoice.setVisibility(View.GONE);
|
|
||||||
text = patches.getDiscName(item.mDiscIndex);
|
|
||||||
}
|
|
||||||
mBinding.textName.setText(text);
|
|
||||||
|
|
||||||
if (item.mOptionIndex != -1)
|
|
||||||
{
|
|
||||||
mPatches = patches;
|
|
||||||
mItem = item;
|
|
||||||
|
|
||||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
|
|
||||||
R.layout.support_simple_spinner_dropdown_item);
|
|
||||||
|
|
||||||
int choiceCount =
|
|
||||||
patches.getChoiceCount(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex);
|
|
||||||
adapter.add(context.getString(R.string.riivolution_disabled));
|
|
||||||
for (int i = 0; i < choiceCount; i++)
|
|
||||||
{
|
|
||||||
adapter.add(patches.getChoiceName(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex,
|
|
||||||
i));
|
|
||||||
}
|
|
||||||
|
|
||||||
mBinding.dropdownChoice.setAdapter(adapter);
|
|
||||||
mBinding.dropdownChoice.setText(adapter.getItem(
|
|
||||||
patches.getSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex)),
|
|
||||||
false);
|
|
||||||
mBinding.dropdownChoice.setOnItemClickListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
|
||||||
{
|
|
||||||
mPatches.setSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex, position);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.riivolution.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.dolphinemu.dolphinemu.R
|
||||||
|
import org.dolphinemu.dolphinemu.databinding.ListItemRiivolutionBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches
|
||||||
|
|
||||||
|
class RiivolutionViewHolder(itemView: View, private val binding: ListItemRiivolutionBinding) :
|
||||||
|
RecyclerView.ViewHolder(itemView), OnItemClickListener {
|
||||||
|
private lateinit var patches: RiivolutionPatches
|
||||||
|
private lateinit var item: RiivolutionItem
|
||||||
|
|
||||||
|
fun bind(context: Context, patches: RiivolutionPatches, item: RiivolutionItem) {
|
||||||
|
// TODO: Remove workaround for text filtering issue in material components when fixed
|
||||||
|
// https://github.com/material-components/material-components-android/issues/1464
|
||||||
|
binding.dropdownChoice.isSaveEnabled = false
|
||||||
|
|
||||||
|
val text: String
|
||||||
|
if (item.mOptionIndex != -1) {
|
||||||
|
binding.textName.visibility = View.GONE
|
||||||
|
text = patches.getOptionName(item.mDiscIndex, item.mSectionIndex, item.mOptionIndex)
|
||||||
|
binding.layoutChoice.hint = text
|
||||||
|
} else if (item.mSectionIndex != -1) {
|
||||||
|
// TODO: Use supported version of setTextAppearance when min requirement is API 23
|
||||||
|
binding.textName.setTextAppearance(context, R.style.TextAppearance_AppCompat_Medium)
|
||||||
|
binding.layoutChoice.visibility = View.GONE
|
||||||
|
text = patches.getSectionName(item.mDiscIndex, item.mSectionIndex)
|
||||||
|
} else {
|
||||||
|
binding.layoutChoice.visibility = View.GONE
|
||||||
|
text = patches.getDiscName(item.mDiscIndex)
|
||||||
|
}
|
||||||
|
binding.textName.text = text
|
||||||
|
|
||||||
|
if (item.mOptionIndex != -1) {
|
||||||
|
this.patches = patches
|
||||||
|
this.item = item
|
||||||
|
val adapter = ArrayAdapter<String>(
|
||||||
|
context,
|
||||||
|
R.layout.support_simple_spinner_dropdown_item
|
||||||
|
)
|
||||||
|
val choiceCount = patches.getChoiceCount(
|
||||||
|
item.mDiscIndex,
|
||||||
|
item.mSectionIndex,
|
||||||
|
item.mOptionIndex
|
||||||
|
)
|
||||||
|
adapter.add(context.getString(R.string.riivolution_disabled))
|
||||||
|
for (i in 0 until choiceCount) {
|
||||||
|
adapter.add(
|
||||||
|
patches.getChoiceName(
|
||||||
|
item.mDiscIndex,
|
||||||
|
item.mSectionIndex,
|
||||||
|
item.mOptionIndex,
|
||||||
|
i
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.dropdownChoice.setAdapter(adapter)
|
||||||
|
binding.dropdownChoice.setText(
|
||||||
|
adapter.getItem(
|
||||||
|
patches.getSelectedChoice(
|
||||||
|
item.mDiscIndex,
|
||||||
|
item.mSectionIndex,
|
||||||
|
item.mOptionIndex
|
||||||
|
)
|
||||||
|
), false
|
||||||
|
)
|
||||||
|
binding.dropdownChoice.onItemClickListener = this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemClick(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||||
|
patches.setSelectedChoice(
|
||||||
|
item.mDiscIndex,
|
||||||
|
item.mSectionIndex,
|
||||||
|
item.mOptionIndex,
|
||||||
|
position
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -539,7 +539,7 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||||
env->FindClass("org/dolphinemu/dolphinemu/features/riivolution/model/RiivolutionPatches");
|
env->FindClass("org/dolphinemu/dolphinemu/features/riivolution/model/RiivolutionPatches");
|
||||||
s_riivolution_patches_class =
|
s_riivolution_patches_class =
|
||||||
reinterpret_cast<jclass>(env->NewGlobalRef(riivolution_patches_class));
|
reinterpret_cast<jclass>(env->NewGlobalRef(riivolution_patches_class));
|
||||||
s_riivolution_patches_pointer = env->GetFieldID(riivolution_patches_class, "mPointer", "J");
|
s_riivolution_patches_pointer = env->GetFieldID(riivolution_patches_class, "pointer", "J");
|
||||||
env->DeleteLocalRef(riivolution_patches_class);
|
env->DeleteLocalRef(riivolution_patches_class);
|
||||||
|
|
||||||
const jclass wii_update_cb_class =
|
const jclass wii_update_cb_class =
|
||||||
|
|
Loading…
Reference in New Issue