mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	android: Open cheats by long pressing game in game list (#6491)
This commit is contained in:
		
							parent
							
								
									ebac6b17b0
								
							
						
					
					
						commit
						2e47afd48e
					
				
					 11 changed files with 145 additions and 31 deletions
				
			
		|  | @ -128,6 +128,8 @@ public final class NativeLibrary { | ||||||
| 
 | 
 | ||||||
|     public static native void InitGameIni(String gameID); |     public static native void InitGameIni(String gameID); | ||||||
| 
 | 
 | ||||||
|  |     public static native long GetTitleId(String filename); | ||||||
|  | 
 | ||||||
|     public static native String GetGitRevision(); |     public static native String GetGitRevision(); | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -186,6 +188,11 @@ public final class NativeLibrary { | ||||||
|      */ |      */ | ||||||
|     public static native boolean IsRunning(); |     public static native boolean IsRunning(); | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns the title ID of the currently running title, or 0 on failure. | ||||||
|  |      */ | ||||||
|  |     public static native long GetRunningTitleId(); | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Returns the performance stats for the current game |      * Returns the performance stats for the current game | ||||||
|      **/ |      **/ | ||||||
|  |  | ||||||
|  | @ -491,7 +491,7 @@ public final class EmulationActivity extends AppCompatActivity { | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|             case MENU_ACTION_OPEN_CHEATS: |             case MENU_ACTION_OPEN_CHEATS: | ||||||
|                 CheatsActivity.launch(this); |                 CheatsActivity.launch(this, NativeLibrary.GetRunningTitleId()); | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|             case MENU_ACTION_CLOSE_GAME: |             case MENU_ACTION_CLOSE_GAME: | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| package org.citra.citra_emu.adapters; | package org.citra.citra_emu.adapters; | ||||||
| 
 | 
 | ||||||
|  | import android.content.Context; | ||||||
| import android.database.Cursor; | import android.database.Cursor; | ||||||
| import android.database.DataSetObserver; | import android.database.DataSetObserver; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
|  | @ -14,10 +15,13 @@ import androidx.fragment.app.FragmentActivity; | ||||||
| import androidx.recyclerview.widget.RecyclerView; | import androidx.recyclerview.widget.RecyclerView; | ||||||
| 
 | 
 | ||||||
| import com.google.android.material.color.MaterialColors; | import com.google.android.material.color.MaterialColors; | ||||||
|  | import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||||
| 
 | 
 | ||||||
| import org.citra.citra_emu.CitraApplication; | import org.citra.citra_emu.CitraApplication; | ||||||
|  | import org.citra.citra_emu.NativeLibrary; | ||||||
| import org.citra.citra_emu.R; | import org.citra.citra_emu.R; | ||||||
| import org.citra.citra_emu.activities.EmulationActivity; | import org.citra.citra_emu.activities.EmulationActivity; | ||||||
|  | import org.citra.citra_emu.features.cheats.ui.CheatsActivity; | ||||||
| import org.citra.citra_emu.model.GameDatabase; | import org.citra.citra_emu.model.GameDatabase; | ||||||
| import org.citra.citra_emu.utils.FileUtil; | import org.citra.citra_emu.utils.FileUtil; | ||||||
| import org.citra.citra_emu.utils.Log; | import org.citra.citra_emu.utils.Log; | ||||||
|  | @ -31,8 +35,7 @@ import java.util.stream.Stream; | ||||||
|  * ContentProviders and Loaders, allows for efficient display of a limited view into a (possibly) |  * ContentProviders and Loaders, allows for efficient display of a limited view into a (possibly) | ||||||
|  * large dataset. |  * large dataset. | ||||||
|  */ |  */ | ||||||
| public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> implements | public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> { | ||||||
|         View.OnClickListener { |  | ||||||
|     private Cursor mCursor; |     private Cursor mCursor; | ||||||
|     private GameDataSetObserver mObserver; |     private GameDataSetObserver mObserver; | ||||||
| 
 | 
 | ||||||
|  | @ -61,7 +64,8 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl | ||||||
|         View gameCard = LayoutInflater.from(parent.getContext()) |         View gameCard = LayoutInflater.from(parent.getContext()) | ||||||
|                 .inflate(R.layout.card_game, parent, false); |                 .inflate(R.layout.card_game, parent, false); | ||||||
| 
 | 
 | ||||||
|         gameCard.setOnClickListener(this); |         gameCard.setOnClickListener(this::onClick); | ||||||
|  |         gameCard.setOnLongClickListener(this::onLongClick); | ||||||
| 
 | 
 | ||||||
|         // Use that view to create a ViewHolder. |         // Use that view to create a ViewHolder. | ||||||
|         return new GameViewHolder(gameCard); |         return new GameViewHolder(gameCard); | ||||||
|  | @ -193,10 +197,9 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl | ||||||
|     /** |     /** | ||||||
|      * Launches the game that was clicked on. |      * Launches the game that was clicked on. | ||||||
|      * |      * | ||||||
|      * @param view The card representing the game the user wants to play. |      * @param view The view representing the game the user wants to play. | ||||||
|      */ |      */ | ||||||
|     @Override |     private void onClick(View view) { | ||||||
|     public void onClick(View view) { |  | ||||||
|         // Double-click prevention, using threshold of 1000 ms |         // Double-click prevention, using threshold of 1000 ms | ||||||
|         if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { |         if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { | ||||||
|             return; |             return; | ||||||
|  | @ -208,6 +211,31 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl | ||||||
|         EmulationActivity.launch((FragmentActivity) view.getContext(), holder.path, holder.title); |         EmulationActivity.launch((FragmentActivity) view.getContext(), holder.path, holder.title); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Opens the cheats settings for the game that was clicked on. | ||||||
|  |      * | ||||||
|  |      * @param view The view representing the game the user wants to play. | ||||||
|  |      */ | ||||||
|  |     private boolean onLongClick(View view) { | ||||||
|  |         Context context = view.getContext(); | ||||||
|  |         GameViewHolder holder = (GameViewHolder) view.getTag(); | ||||||
|  | 
 | ||||||
|  |         final long titleId = NativeLibrary.GetTitleId(holder.path); | ||||||
|  | 
 | ||||||
|  |         if (titleId == 0) { | ||||||
|  |             new MaterialAlertDialogBuilder(context) | ||||||
|  |                     .setIcon(R.mipmap.ic_launcher) | ||||||
|  |                     .setTitle(R.string.properties) | ||||||
|  |                     .setMessage(R.string.properties_not_loaded) | ||||||
|  |                     .setPositiveButton(android.R.string.ok, null) | ||||||
|  |                     .show(); | ||||||
|  |         } else { | ||||||
|  |             CheatsActivity.launch(context, titleId); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private boolean isValidGame(String path) { |     private boolean isValidGame(String path) { | ||||||
|         return Stream.of( |         return Stream.of( | ||||||
|                 ".rar", ".zip", ".7z", ".torrent", ".tar", ".gz").noneMatch(suffix -> path.toLowerCase().endsWith(suffix)); |                 ".rar", ".zip", ".7z", ".torrent", ".tar", ".gz").noneMatch(suffix -> path.toLowerCase().endsWith(suffix)); | ||||||
|  |  | ||||||
|  | @ -1,13 +1,28 @@ | ||||||
| package org.citra.citra_emu.features.cheats.model; | package org.citra.citra_emu.features.cheats.model; | ||||||
| 
 | 
 | ||||||
|  | import androidx.annotation.Keep; | ||||||
|  | 
 | ||||||
| public class CheatEngine { | public class CheatEngine { | ||||||
|     public static native Cheat[] getCheats(); |     @Keep | ||||||
|  |     private final long mPointer; | ||||||
| 
 | 
 | ||||||
|     public static native void addCheat(Cheat cheat); |     @Keep | ||||||
|  |     public CheatEngine(long titleId) { | ||||||
|  |         mPointer = initialize(titleId); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public static native void removeCheat(int index); |     private static native long initialize(long titleId); | ||||||
| 
 | 
 | ||||||
|     public static native void updateCheat(int index, Cheat newCheat); |     @Override | ||||||
|  |     protected native void finalize(); | ||||||
| 
 | 
 | ||||||
|     public static native void saveCheatFile(); |     public native Cheat[] getCheats(); | ||||||
|  | 
 | ||||||
|  |     public native void addCheat(Cheat cheat); | ||||||
|  | 
 | ||||||
|  |     public native void removeCheat(int index); | ||||||
|  | 
 | ||||||
|  |     public native void updateCheat(int index, Cheat newCheat); | ||||||
|  | 
 | ||||||
|  |     public native void saveCheatFile(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,11 +19,17 @@ public class CheatsViewModel extends ViewModel { | ||||||
|     private final MutableLiveData<Integer> mCheatDeletedEvent = new MutableLiveData<>(null); |     private final MutableLiveData<Integer> mCheatDeletedEvent = new MutableLiveData<>(null); | ||||||
|     private final MutableLiveData<Boolean> mOpenDetailsViewEvent = new MutableLiveData<>(false); |     private final MutableLiveData<Boolean> mOpenDetailsViewEvent = new MutableLiveData<>(false); | ||||||
| 
 | 
 | ||||||
|  |     private CheatEngine mCheatEngine; | ||||||
|     private Cheat[] mCheats; |     private Cheat[] mCheats; | ||||||
|     private boolean mCheatsNeedSaving = false; |     private boolean mCheatsNeedSaving = false; | ||||||
| 
 | 
 | ||||||
|     public void load() { |     public void initialize(long titleId) { | ||||||
|         mCheats = CheatEngine.getCheats(); |         mCheatEngine = new CheatEngine(titleId); | ||||||
|  |         load(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void load() { | ||||||
|  |         mCheats = mCheatEngine.getCheats(); | ||||||
| 
 | 
 | ||||||
|         for (int i = 0; i < mCheats.length; i++) { |         for (int i = 0; i < mCheats.length; i++) { | ||||||
|             int position = i; |             int position = i; | ||||||
|  | @ -36,7 +42,7 @@ public class CheatsViewModel extends ViewModel { | ||||||
| 
 | 
 | ||||||
|     public void saveIfNeeded() { |     public void saveIfNeeded() { | ||||||
|         if (mCheatsNeedSaving) { |         if (mCheatsNeedSaving) { | ||||||
|             CheatEngine.saveCheatFile(); |             mCheatEngine.saveCheatFile(); | ||||||
|             mCheatsNeedSaving = false; |             mCheatsNeedSaving = false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -106,7 +112,7 @@ public class CheatsViewModel extends ViewModel { | ||||||
| 
 | 
 | ||||||
|         int position = mCheats.length; |         int position = mCheats.length; | ||||||
| 
 | 
 | ||||||
|         CheatEngine.addCheat(cheat); |         mCheatEngine.addCheat(cheat); | ||||||
| 
 | 
 | ||||||
|         mCheatsNeedSaving = true; |         mCheatsNeedSaving = true; | ||||||
|         load(); |         load(); | ||||||
|  | @ -132,7 +138,7 @@ public class CheatsViewModel extends ViewModel { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void updateSelectedCheat(Cheat newCheat) { |     public void updateSelectedCheat(Cheat newCheat) { | ||||||
|         CheatEngine.updateCheat(mSelectedCheatPosition, newCheat); |         mCheatEngine.updateCheat(mSelectedCheatPosition, newCheat); | ||||||
| 
 | 
 | ||||||
|         mCheatsNeedSaving = true; |         mCheatsNeedSaving = true; | ||||||
|         load(); |         load(); | ||||||
|  | @ -162,7 +168,7 @@ public class CheatsViewModel extends ViewModel { | ||||||
| 
 | 
 | ||||||
|         setSelectedCheat(null, -1); |         setSelectedCheat(null, -1); | ||||||
| 
 | 
 | ||||||
|         CheatEngine.removeCheat(position); |         mCheatEngine.removeCheat(position); | ||||||
| 
 | 
 | ||||||
|         mCheatsNeedSaving = true; |         mCheatsNeedSaving = true; | ||||||
|         load(); |         load(); | ||||||
|  |  | ||||||
|  | @ -32,6 +32,8 @@ import java.util.List; | ||||||
| 
 | 
 | ||||||
| public class CheatsActivity extends AppCompatActivity | public class CheatsActivity extends AppCompatActivity | ||||||
|         implements SlidingPaneLayout.PanelSlideListener { |         implements SlidingPaneLayout.PanelSlideListener { | ||||||
|  |     private static String ARG_TITLE_ID = "title_id"; | ||||||
|  | 
 | ||||||
|     private CheatsViewModel mViewModel; |     private CheatsViewModel mViewModel; | ||||||
| 
 | 
 | ||||||
|     private SlidingPaneLayout mSlidingPaneLayout; |     private SlidingPaneLayout mSlidingPaneLayout; | ||||||
|  | @ -41,8 +43,9 @@ public class CheatsActivity extends AppCompatActivity | ||||||
|     private View mCheatListLastFocus; |     private View mCheatListLastFocus; | ||||||
|     private View mCheatDetailsLastFocus; |     private View mCheatDetailsLastFocus; | ||||||
| 
 | 
 | ||||||
|     public static void launch(Context context) { |     public static void launch(Context context, long titleId) { | ||||||
|         Intent intent = new Intent(context, CheatsActivity.class); |         Intent intent = new Intent(context, CheatsActivity.class); | ||||||
|  |         intent.putExtra(ARG_TITLE_ID, titleId); | ||||||
|         context.startActivity(intent); |         context.startActivity(intent); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -54,8 +57,10 @@ public class CheatsActivity extends AppCompatActivity | ||||||
| 
 | 
 | ||||||
|         WindowCompat.setDecorFitsSystemWindows(getWindow(), false); |         WindowCompat.setDecorFitsSystemWindows(getWindow(), false); | ||||||
| 
 | 
 | ||||||
|  |         long titleId = getIntent().getLongExtra(ARG_TITLE_ID, -1); | ||||||
|  | 
 | ||||||
|         mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class); |         mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class); | ||||||
|         mViewModel.load(); |         mViewModel.initialize(titleId); | ||||||
| 
 | 
 | ||||||
|         setContentView(R.layout.activity_cheats); |         setContentView(R.layout.activity_cheats); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,9 +15,24 @@ | ||||||
| 
 | 
 | ||||||
| extern "C" { | extern "C" { | ||||||
| 
 | 
 | ||||||
|  | static Cheats::CheatEngine* GetPointer(JNIEnv* env, jobject obj) { | ||||||
|  |     return reinterpret_cast<Cheats::CheatEngine*>( | ||||||
|  |         env->GetLongField(obj, IDCache::GetCheatEnginePointer())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | JNIEXPORT jlong JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_initialize( | ||||||
|  |     JNIEnv* env, jclass, jlong title_id) { | ||||||
|  |     return reinterpret_cast<jlong>(new Cheats::CheatEngine(title_id, Core::System::GetInstance())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | JNIEXPORT void JNICALL | ||||||
|  | Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_finalize(JNIEnv* env, jobject obj) { | ||||||
|  |     delete GetPointer(env, obj); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| JNIEXPORT jobjectArray JNICALL | JNIEXPORT jobjectArray JNICALL | ||||||
| Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_getCheats(JNIEnv* env, jclass) { | Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_getCheats(JNIEnv* env, jobject obj) { | ||||||
|     auto cheats = Core::System::GetInstance().CheatEngine().GetCheats(); |     auto cheats = GetPointer(env, obj)->GetCheats(); | ||||||
| 
 | 
 | ||||||
|     const jobjectArray array = |     const jobjectArray array = | ||||||
|         env->NewObjectArray(static_cast<jsize>(cheats.size()), IDCache::GetCheatClass(), nullptr); |         env->NewObjectArray(static_cast<jsize>(cheats.size()), IDCache::GetCheatClass(), nullptr); | ||||||
|  | @ -30,22 +45,22 @@ Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_getCheats(JNIEnv* en | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_addCheat( | JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_addCheat( | ||||||
|     JNIEnv* env, jclass, jobject j_cheat) { |     JNIEnv* env, jobject obj, jobject j_cheat) { | ||||||
|     Core::System::GetInstance().CheatEngine().AddCheat(*CheatFromJava(env, j_cheat)); |     GetPointer(env, obj)->AddCheat(*CheatFromJava(env, j_cheat)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_removeCheat( | JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_removeCheat( | ||||||
|     JNIEnv* env, jclass, jint index) { |     JNIEnv* env, jobject obj, jint index) { | ||||||
|     Core::System::GetInstance().CheatEngine().RemoveCheat(index); |     GetPointer(env, obj)->RemoveCheat(index); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_updateCheat( | JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_updateCheat( | ||||||
|     JNIEnv* env, jclass, jint index, jobject j_new_cheat) { |     JNIEnv* env, jobject obj, jint index, jobject j_new_cheat) { | ||||||
|     Core::System::GetInstance().CheatEngine().UpdateCheat(index, *CheatFromJava(env, j_new_cheat)); |     GetPointer(env, obj)->UpdateCheat(index, *CheatFromJava(env, j_new_cheat)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| JNIEXPORT void JNICALL | JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_saveCheatFile( | ||||||
| Java_org_citra_citra_1emu_features_cheats_model_CheatEngine_saveCheatFile(JNIEnv* env, jclass) { |     JNIEnv* env, jobject obj) { | ||||||
|     Core::System::GetInstance().CheatEngine().SaveCheatFile(); |     GetPointer(env, obj)->SaveCheatFile(); | ||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -40,6 +40,8 @@ static jclass s_cheat_class; | ||||||
| static jfieldID s_cheat_pointer; | static jfieldID s_cheat_pointer; | ||||||
| static jmethodID s_cheat_constructor; | static jmethodID s_cheat_constructor; | ||||||
| 
 | 
 | ||||||
|  | static jfieldID s_cheat_engine_pointer; | ||||||
|  | 
 | ||||||
| static jfieldID s_game_info_pointer; | static jfieldID s_game_info_pointer; | ||||||
| 
 | 
 | ||||||
| static std::unordered_map<VideoCore::LoadCallbackStage, jobject> s_java_load_callback_stages; | static std::unordered_map<VideoCore::LoadCallbackStage, jobject> s_java_load_callback_stages; | ||||||
|  | @ -137,6 +139,10 @@ jmethodID GetCheatConstructor() { | ||||||
|     return s_cheat_constructor; |     return s_cheat_constructor; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | jfieldID GetCheatEnginePointer() { | ||||||
|  |     return s_cheat_engine_pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| jfieldID GetGameInfoPointer() { | jfieldID GetGameInfoPointer() { | ||||||
|     return s_game_info_pointer; |     return s_game_info_pointer; | ||||||
| } | } | ||||||
|  | @ -211,6 +217,12 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { | ||||||
|     s_cheat_constructor = env->GetMethodID(cheat_class, "<init>", "(J)V"); |     s_cheat_constructor = env->GetMethodID(cheat_class, "<init>", "(J)V"); | ||||||
|     env->DeleteLocalRef(cheat_class); |     env->DeleteLocalRef(cheat_class); | ||||||
| 
 | 
 | ||||||
|  |     // Initialize CheatEngine
 | ||||||
|  |     const jclass cheat_engine_class = | ||||||
|  |         env->FindClass("org/citra/citra_emu/features/cheats/model/CheatEngine"); | ||||||
|  |     s_cheat_engine_pointer = env->GetFieldID(cheat_engine_class, "mPointer", "J"); | ||||||
|  |     env->DeleteLocalRef(cheat_engine_class); | ||||||
|  | 
 | ||||||
|     // Initialize GameInfo
 |     // Initialize GameInfo
 | ||||||
|     const jclass game_info_class = env->FindClass("org/citra/citra_emu/model/GameInfo"); |     const jclass game_info_class = env->FindClass("org/citra/citra_emu/model/GameInfo"); | ||||||
|     s_game_info_pointer = env->GetFieldID(game_info_class, "mPointer", "J"); |     s_game_info_pointer = env->GetFieldID(game_info_class, "mPointer", "J"); | ||||||
|  |  | ||||||
|  | @ -34,6 +34,8 @@ jclass GetCheatClass(); | ||||||
| jfieldID GetCheatPointer(); | jfieldID GetCheatPointer(); | ||||||
| jmethodID GetCheatConstructor(); | jmethodID GetCheatConstructor(); | ||||||
| 
 | 
 | ||||||
|  | jfieldID GetCheatEnginePointer(); | ||||||
|  | 
 | ||||||
| jfieldID GetGameInfoPointer(); | jfieldID GetGameInfoPointer(); | ||||||
| 
 | 
 | ||||||
| jobject GetJavaLoadCallbackStage(VideoCore::LoadCallbackStage stage); | jobject GetJavaLoadCallbackStage(VideoCore::LoadCallbackStage stage); | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include "core/frontend/camera/factory.h" | #include "core/frontend/camera/factory.h" | ||||||
| #include "core/hle/service/am/am.h" | #include "core/hle/service/am/am.h" | ||||||
| #include "core/hle/service/nfc/nfc.h" | #include "core/hle/service/nfc/nfc.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| #include "core/savestate.h" | #include "core/savestate.h" | ||||||
| #include "jni/android_common/android_common.h" | #include "jni/android_common/android_common.h" | ||||||
| #include "jni/applets/mii_selector.h" | #include "jni/applets/mii_selector.h" | ||||||
|  | @ -379,6 +380,13 @@ jboolean Java_org_citra_citra_1emu_NativeLibrary_IsRunning(JNIEnv* env, | ||||||
|     return static_cast<jboolean>(!stop_run); |     return static_cast<jboolean>(!stop_run); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | jlong Java_org_citra_citra_1emu_NativeLibrary_GetRunningTitleId(JNIEnv* env, | ||||||
|  |                                                                 [[maybe_unused]] jclass clazz) { | ||||||
|  |     u64 title_id{}; | ||||||
|  |     Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id); | ||||||
|  |     return static_cast<jlong>(title_id); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadEvent(JNIEnv* env, | jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadEvent(JNIEnv* env, | ||||||
|                                                                 [[maybe_unused]] jclass clazz, |                                                                 [[maybe_unused]] jclass clazz, | ||||||
|                                                                 jstring j_device, jint j_button, |                                                                 jstring j_device, jint j_button, | ||||||
|  | @ -435,6 +443,18 @@ void Java_org_citra_citra_1emu_NativeLibrary_onTouchMoved(JNIEnv* env, | ||||||
|     window->OnTouchMoved((int)x, (int)y); |     window->OnTouchMoved((int)x, (int)y); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | jlong Java_org_citra_citra_1emu_NativeLibrary_GetTitleId(JNIEnv* env, [[maybe_unused]] jclass clazz, | ||||||
|  |                                                          jstring j_filename) { | ||||||
|  |     std::string filepath = GetJString(env, j_filename); | ||||||
|  |     const auto loader = Loader::GetLoader(filepath); | ||||||
|  | 
 | ||||||
|  |     u64 title_id{}; | ||||||
|  |     if (loader) { | ||||||
|  |         loader->ReadProgramId(title_id); | ||||||
|  |     } | ||||||
|  |     return static_cast<jlong>(title_id); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| jstring Java_org_citra_citra_1emu_NativeLibrary_GetGitRevision(JNIEnv* env, | jstring Java_org_citra_citra_1emu_NativeLibrary_GetGitRevision(JNIEnv* env, | ||||||
|                                                                [[maybe_unused]] jclass clazz) { |                                                                [[maybe_unused]] jclass clazz) { | ||||||
|     return nullptr; |     return nullptr; | ||||||
|  |  | ||||||
|  | @ -146,6 +146,10 @@ | ||||||
|     <string name="select_game_folder">Select Game Folder</string> |     <string name="select_game_folder">Select Game Folder</string> | ||||||
|     <string name="install_cia_title">Install CIA</string> |     <string name="install_cia_title">Install CIA</string> | ||||||
| 
 | 
 | ||||||
|  |     <!-- Game Properties --> | ||||||
|  |     <string name="properties">Properties</string> | ||||||
|  |     <string name="properties_not_loaded">The game properties could not be loaded.</string> | ||||||
|  | 
 | ||||||
|     <!-- Preferences Screen --> |     <!-- Preferences Screen --> | ||||||
|     <string name="preferences_settings">Settings</string> |     <string name="preferences_settings">Settings</string> | ||||||
|     <string name="preferences_premium">Premium</string> |     <string name="preferences_premium">Premium</string> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue