mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Android: Add checkboxes for toggling cheats enabled
This commit is contained in:
parent
67a8855d9a
commit
93a1271386
@ -5,7 +5,7 @@ package org.dolphinemu.dolphinemu.features.cheats.model;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class ARCheat implements Cheat
|
||||
public class ARCheat extends AbstractCheat
|
||||
{
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
@ -22,6 +22,13 @@ public class ARCheat implements Cheat
|
||||
@NonNull
|
||||
public native String getName();
|
||||
|
||||
public native boolean getEnabled();
|
||||
|
||||
@Override
|
||||
protected native void setEnabledImpl(boolean enabled);
|
||||
|
||||
@NonNull
|
||||
public static native ARCheat[] loadCodes(String gameId, int revision);
|
||||
|
||||
public static native void saveCodes(String gameId, int revision, ARCheat[] codes);
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.cheats.model;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public abstract class AbstractCheat implements Cheat
|
||||
{
|
||||
private Runnable mChangedCallback = null;
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
setEnabledImpl(enabled);
|
||||
onChanged();
|
||||
}
|
||||
|
||||
public void setChangedCallback(@Nullable Runnable callback)
|
||||
{
|
||||
mChangedCallback = callback;
|
||||
}
|
||||
|
||||
protected void onChanged()
|
||||
{
|
||||
if (mChangedCallback != null)
|
||||
mChangedCallback.run();
|
||||
}
|
||||
|
||||
protected abstract void setEnabledImpl(boolean enabled);
|
||||
}
|
@ -8,4 +8,8 @@ public interface Cheat
|
||||
{
|
||||
@NonNull
|
||||
String getName();
|
||||
|
||||
boolean getEnabled();
|
||||
|
||||
void setEnabled(boolean enabled);
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ public class CheatsViewModel extends ViewModel
|
||||
private ARCheat[] mARCheats;
|
||||
private GeckoCheat[] mGeckoCheats;
|
||||
|
||||
private boolean mPatchCheatsNeedSaving = false;
|
||||
private boolean mARCheatsNeedSaving = false;
|
||||
private boolean mGeckoCheatsNeedSaving = false;
|
||||
|
||||
public void load(String gameID, int revision)
|
||||
{
|
||||
if (mLoaded)
|
||||
@ -21,9 +25,43 @@ public class CheatsViewModel extends ViewModel
|
||||
mARCheats = ARCheat.loadCodes(gameID, revision);
|
||||
mGeckoCheats = GeckoCheat.loadCodes(gameID, revision);
|
||||
|
||||
for (PatchCheat cheat : mPatchCheats)
|
||||
{
|
||||
cheat.setChangedCallback(() -> mPatchCheatsNeedSaving = true);
|
||||
}
|
||||
for (ARCheat cheat : mARCheats)
|
||||
{
|
||||
cheat.setChangedCallback(() -> mARCheatsNeedSaving = true);
|
||||
}
|
||||
for (GeckoCheat cheat : mGeckoCheats)
|
||||
{
|
||||
cheat.setChangedCallback(() -> mGeckoCheatsNeedSaving = true);
|
||||
}
|
||||
|
||||
mLoaded = true;
|
||||
}
|
||||
|
||||
public void saveIfNeeded(String gameID, int revision)
|
||||
{
|
||||
if (mPatchCheatsNeedSaving)
|
||||
{
|
||||
PatchCheat.saveCodes(gameID, revision, mPatchCheats);
|
||||
mPatchCheatsNeedSaving = false;
|
||||
}
|
||||
|
||||
if (mARCheatsNeedSaving)
|
||||
{
|
||||
ARCheat.saveCodes(gameID, revision, mARCheats);
|
||||
mARCheatsNeedSaving = false;
|
||||
}
|
||||
|
||||
if (mGeckoCheatsNeedSaving)
|
||||
{
|
||||
GeckoCheat.saveCodes(gameID, revision, mGeckoCheats);
|
||||
mGeckoCheatsNeedSaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Cheat[] getPatchCheats()
|
||||
{
|
||||
return mPatchCheats;
|
||||
|
@ -5,7 +5,7 @@ package org.dolphinemu.dolphinemu.features.cheats.model;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class GeckoCheat implements Cheat
|
||||
public class GeckoCheat extends AbstractCheat
|
||||
{
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
@ -22,6 +22,13 @@ public class GeckoCheat implements Cheat
|
||||
@NonNull
|
||||
public native String getName();
|
||||
|
||||
public native boolean getEnabled();
|
||||
|
||||
@Override
|
||||
protected native void setEnabledImpl(boolean enabled);
|
||||
|
||||
@NonNull
|
||||
public static native GeckoCheat[] loadCodes(String gameId, int revision);
|
||||
|
||||
public static native void saveCodes(String gameId, int revision, GeckoCheat[] codes);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ package org.dolphinemu.dolphinemu.features.cheats.model;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class PatchCheat implements Cheat
|
||||
public class PatchCheat extends AbstractCheat
|
||||
{
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
@ -22,6 +22,13 @@ public class PatchCheat implements Cheat
|
||||
@NonNull
|
||||
public native String getName();
|
||||
|
||||
public native boolean getEnabled();
|
||||
|
||||
@Override
|
||||
protected native void setEnabledImpl(boolean enabled);
|
||||
|
||||
@NonNull
|
||||
public static native PatchCheat[] loadCodes(String gameId, int revision);
|
||||
|
||||
public static native void saveCodes(String gameId, int revision, PatchCheat[] codes);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
package org.dolphinemu.dolphinemu.features.cheats.ui;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -11,19 +13,35 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
|
||||
|
||||
public class CheatViewHolder extends ViewHolder
|
||||
public class CheatViewHolder extends ViewHolder implements CompoundButton.OnCheckedChangeListener
|
||||
{
|
||||
private TextView mName;
|
||||
private final TextView mName;
|
||||
private final CheckBox mCheckbox;
|
||||
|
||||
private Cheat mCheat;
|
||||
|
||||
public CheatViewHolder(@NonNull View itemView)
|
||||
{
|
||||
super(itemView);
|
||||
|
||||
mName = itemView.findViewById(R.id.text_name);
|
||||
mCheckbox = itemView.findViewById(R.id.checkbox);
|
||||
}
|
||||
|
||||
public void bind(Cheat item)
|
||||
{
|
||||
mCheckbox.setOnCheckedChangeListener(null);
|
||||
|
||||
mName.setText(item.getName());
|
||||
mCheckbox.setChecked(item.getEnabled());
|
||||
|
||||
mCheat = item;
|
||||
|
||||
mCheckbox.setOnCheckedChangeListener(this);
|
||||
}
|
||||
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
mCheat.setEnabled(isChecked);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ public class CheatsActivity extends AppCompatActivity
|
||||
private static final String ARG_GAME_ID = "game_id";
|
||||
private static final String ARG_REVISION = "revision";
|
||||
|
||||
private String mGameId;
|
||||
private int mRevision;
|
||||
private CheatsViewModel mViewModel;
|
||||
|
||||
public static void launch(Context context, String gameId, int revision)
|
||||
{
|
||||
Intent intent = new Intent(context, CheatsActivity.class);
|
||||
@ -34,14 +38,22 @@ public class CheatsActivity extends AppCompatActivity
|
||||
MainPresenter.skipRescanningLibrary();
|
||||
|
||||
Intent intent = getIntent();
|
||||
String gameId = intent.getStringExtra(ARG_GAME_ID);
|
||||
int revision = intent.getIntExtra(ARG_REVISION, 0);
|
||||
mGameId = intent.getStringExtra(ARG_GAME_ID);
|
||||
mRevision = intent.getIntExtra(ARG_REVISION, 0);
|
||||
|
||||
setTitle(getString(R.string.cheats_with_game_id, gameId));
|
||||
setTitle(getString(R.string.cheats_with_game_id, mGameId));
|
||||
|
||||
CheatsViewModel viewModel = new ViewModelProvider(this).get(CheatsViewModel.class);
|
||||
viewModel.load(gameId, revision);
|
||||
mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class);
|
||||
mViewModel.load(mGameId, mRevision);
|
||||
|
||||
setContentView(R.layout.activity_cheats);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop()
|
||||
{
|
||||
super.onStop();
|
||||
|
||||
mViewModel.saveIfNeeded(mGameId, mRevision);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,19 @@
|
||||
tools:text="Hyrule Field Speed Hack"
|
||||
android:layout_margin="@dimen/spacing_large"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/checkbox"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="64dp"
|
||||
app:layout_constraintStart_toEndOf="@id/text_name"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:gravity="center"
|
||||
android:focusable="true" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -39,6 +39,18 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_ARCheat_getName(JNIEnv* env
|
||||
return ToJString(env, GetPointer(env, obj)->name);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_ARCheat_getEnabled(JNIEnv* env, jobject obj)
|
||||
{
|
||||
return static_cast<jboolean>(GetPointer(env, obj)->enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_ARCheat_setEnabledImpl(
|
||||
JNIEnv* env, jobject obj, jboolean enabled)
|
||||
{
|
||||
GetPointer(env, obj)->enabled = static_cast<bool>(enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_ARCheat_loadCodes(JNIEnv* env, jclass,
|
||||
jstring jGameID,
|
||||
@ -64,4 +76,27 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_ARCheat_loadCodes(JNIEnv* e
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_ARCheat_saveCodes(
|
||||
JNIEnv* env, jclass, jstring jGameID, jint revision, jobjectArray jCodes)
|
||||
{
|
||||
const jsize size = env->GetArrayLength(jCodes);
|
||||
std::vector<ActionReplay::ARCode> vector;
|
||||
vector.reserve(size);
|
||||
|
||||
for (jsize i = 0; i < size; ++i)
|
||||
{
|
||||
jobject code = reinterpret_cast<jstring>(env->GetObjectArrayElement(jCodes, i));
|
||||
vector.emplace_back(*GetPointer(env, code));
|
||||
env->DeleteLocalRef(code);
|
||||
}
|
||||
|
||||
const std::string game_id = GetJString(env, jGameID);
|
||||
const std::string ini_path = File::GetUserPath(D_GAMESETTINGS_IDX) + game_id + ".ini";
|
||||
|
||||
IniFile game_ini_local;
|
||||
game_ini_local.Load(ini_path);
|
||||
ActionReplay::SaveCodes(&game_ini_local, vector);
|
||||
game_ini_local.Save(ini_path);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,20 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_getName(JNIEnv*
|
||||
return ToJString(env, GetPointer(env, obj)->name);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_getEnabled(JNIEnv* env, jobject obj)
|
||||
{
|
||||
return static_cast<jboolean>(GetPointer(env, obj)->enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_setEnabledImpl(JNIEnv* env,
|
||||
jobject obj,
|
||||
jboolean enabled)
|
||||
{
|
||||
GetPointer(env, obj)->enabled = static_cast<bool>(enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_loadCodes(JNIEnv* env, jclass,
|
||||
jstring jGameID,
|
||||
@ -64,4 +78,27 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_loadCodes(JNIEnv
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_saveCodes(
|
||||
JNIEnv* env, jclass, jstring jGameID, jint revision, jobjectArray jCodes)
|
||||
{
|
||||
const jsize size = env->GetArrayLength(jCodes);
|
||||
std::vector<Gecko::GeckoCode> vector;
|
||||
vector.reserve(size);
|
||||
|
||||
for (jsize i = 0; i < size; ++i)
|
||||
{
|
||||
jobject code = reinterpret_cast<jstring>(env->GetObjectArrayElement(jCodes, i));
|
||||
vector.emplace_back(*GetPointer(env, code));
|
||||
env->DeleteLocalRef(code);
|
||||
}
|
||||
|
||||
const std::string game_id = GetJString(env, jGameID);
|
||||
const std::string ini_path = File::GetUserPath(D_GAMESETTINGS_IDX) + game_id + ".ini";
|
||||
|
||||
IniFile game_ini_local;
|
||||
game_ini_local.Load(ini_path);
|
||||
Gecko::SaveCodes(game_ini_local, vector);
|
||||
game_ini_local.Save(ini_path);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,20 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_PatchCheat_getName(JNIEnv*
|
||||
return ToJString(env, GetPointer(env, obj)->name);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_PatchCheat_getEnabled(JNIEnv* env, jobject obj)
|
||||
{
|
||||
return static_cast<jboolean>(GetPointer(env, obj)->enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_PatchCheat_setEnabledImpl(JNIEnv* env,
|
||||
jobject obj,
|
||||
jboolean enabled)
|
||||
{
|
||||
GetPointer(env, obj)->enabled = static_cast<bool>(enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_cheats_model_PatchCheat_loadCodes(JNIEnv* env, jclass,
|
||||
jstring jGameID,
|
||||
@ -64,4 +78,27 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_PatchCheat_loadCodes(JNIEnv
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_PatchCheat_saveCodes(
|
||||
JNIEnv* env, jclass, jstring jGameID, jint revision, jobjectArray jCodes)
|
||||
{
|
||||
const jsize size = env->GetArrayLength(jCodes);
|
||||
std::vector<PatchEngine::Patch> vector;
|
||||
vector.reserve(size);
|
||||
|
||||
for (jsize i = 0; i < size; ++i)
|
||||
{
|
||||
jobject code = reinterpret_cast<jstring>(env->GetObjectArrayElement(jCodes, i));
|
||||
vector.emplace_back(*GetPointer(env, code));
|
||||
env->DeleteLocalRef(code);
|
||||
}
|
||||
|
||||
const std::string game_id = GetJString(env, jGameID);
|
||||
const std::string ini_path = File::GetUserPath(D_GAMESETTINGS_IDX) + game_id + ".ini";
|
||||
|
||||
IniFile game_ini_local;
|
||||
game_ini_local.Load(ini_path);
|
||||
PatchEngine::SavePatchSection(&game_ini_local, vector);
|
||||
game_ini_local.Save(ini_path);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user