android: frontend: Add errors for unsupported ROM formats.

This commit is contained in:
bunnei 2019-09-10 23:04:16 -04:00
parent abfa49a6d7
commit 30ef4a1b7c
7 changed files with 79 additions and 43 deletions

View File

@ -8,11 +8,13 @@ package org.citra.citra_android;
import android.app.AlertDialog;
import android.content.res.Configuration;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.Surface;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.citra.citra_android.activities.EmulationActivity;
import org.citra.citra_android.utils.EmulationMenuSettings;
@ -444,6 +446,46 @@ public final class NativeLibrary {
return alertPromptButton;
}
public static void exitEmulationActivity(int resultCode) {
final int Success = 0;
final int ErrorNotInitialized = 1;
final int ErrorGetLoader = 2;
final int ErrorSystemMode = 3;
final int ErrorLoader = 4;
final int ErrorLoader_ErrorEncrypted = 5;
final int ErrorLoader_ErrorInvalidFormat = 6;
final int ErrorSystemFiles = 7;
final int ErrorVideoCore = 8;
final int ErrorVideoCore_ErrorGenericDrivers = 9;
final int ErrorVideoCore_ErrorBelowGL33 = 10;
final int ShutdownRequested = 11;
final int ErrorUnknown = 12;
final EmulationActivity emulationActivity = sEmulationActivity.get();
if (emulationActivity == null) {
Log.warning("[NativeLibrary] EmulationActivity is null, can't exit.");
return;
}
int captionId = R.string.loader_error_invalid_format;
if (resultCode == ErrorLoader_ErrorEncrypted) {
captionId = R.string.loader_error_encrypted;
}
AlertDialog.Builder builder = new AlertDialog.Builder(emulationActivity)
.setTitle(captionId)
.setMessage(Html.fromHtml("Please follow the guides to redump your <a href=\"https://citra-emu.org/wiki/dumping-game-cartridges/\">game cartidges</a> or <a href=\"https://citra-emu.org/wiki/dumping-installed-titles/\">installed titles</a>."))
.setPositiveButton(android.R.string.ok, (dialog, whichButton) -> emulationActivity.exitWithAnimation())
.setOnDismissListener(dialogInterface -> emulationActivity.exitWithAnimation());
emulationActivity.runOnUiThread(() -> {
AlertDialog alert = builder.create();
alert.show();
((TextView) alert.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
});
return;
}
public static void setEmulationActivity(EmulationActivity emulationActivity) {
Log.verbose("[NativeLibrary] Registering EmulationActivity.");
sEmulationActivity = new WeakReference<>(emulationActivity);

View File

@ -140,7 +140,7 @@ public final class GameDatabase extends SQLiteOpenHelper {
null); // Order of folders is irrelevant.
Set<String> allowedExtensions = new HashSet<String>(Arrays.asList(
".3ds", ".3dsx", ".elf", ".axf", ".cci", ".cxi", ".app"));
".3ds", ".3dsx", ".elf", ".axf", ".cci", ".cxi", ".cia", ".app", ".rar", ".zip", ".7z", ".torrent", ".tar", ".gz"));
// Possibly overly defensive, but ensures that moveToNext() does not skip a row.
folderCursor.moveToPosition(-1);

View File

@ -21,6 +21,7 @@ static jmethodID s_display_alert_prompt;
static jmethodID s_alert_prompt_button;
static jmethodID s_is_portrait_mode;
static jmethodID s_landscape_screen_layout;
static jmethodID s_exit_emulation_activity;
namespace IDCache {
@ -67,6 +68,10 @@ jmethodID GetLandscapeScreenLayout() {
return s_landscape_screen_layout;
}
jmethodID GetExitEmulationActivity() {
return s_exit_emulation_activity;
}
} // namespace IDCache
#ifdef __cplusplus
@ -103,6 +108,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
s_is_portrait_mode = env->GetStaticMethodID(s_native_library_class, "isPortraitMode", "()Z");
s_landscape_screen_layout =
env->GetStaticMethodID(s_native_library_class, "landscapeScreenLayout", "()I");
s_exit_emulation_activity =
env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V");
return JNI_VERSION;
}

View File

@ -15,5 +15,6 @@ jmethodID GetDisplayAlertPrompt();
jmethodID GetAlertPromptButton();
jmethodID GetIsPortraitMode();
jmethodID GetLandscapeScreenLayout();
jmethodID GetExitEmulationActivity();
} // namespace IDCache

View File

@ -109,7 +109,7 @@ public:
void ShowError(const std::string& error) override {}
};
static int RunCitra(const std::string& filepath) {
static Core::System::ResultStatus RunCitra(const std::string& filepath) {
// Citra core only supports a single running instance
std::lock_guard<std::mutex> lock(running_mutex);
@ -120,7 +120,7 @@ static int RunCitra(const std::string& filepath) {
if (filepath.empty()) {
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
return -1;
return Core::System::ResultStatus::ErrorLoader;
}
Core::System& system{Core::System::GetInstance()};
@ -143,33 +143,8 @@ static int RunCitra(const std::string& filepath) {
SCOPE_EXIT({ window.reset(); });
const Core::System::ResultStatus load_result{system.Load(*window, filepath)};
switch (load_result) {
case Core::System::ResultStatus::ErrorGetLoader:
LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filepath);
return -1;
case Core::System::ResultStatus::ErrorLoader:
LOG_CRITICAL(Frontend, "Failed to load ROM!");
return -1;
case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted:
LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before "
"being used with Citra. \n\n For more information on dumping and "
"decrypting games, please refer to: "
"https://citra-emu.org/wiki/dumping-game-cartridges/");
return -1;
case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported.");
return -1;
case Core::System::ResultStatus::ErrorNotInitialized:
LOG_CRITICAL(Frontend, "Core not initialized");
return -1;
case Core::System::ResultStatus::ErrorSystemMode:
LOG_CRITICAL(Frontend, "Failed to determine system mode!");
return -1;
case Core::System::ResultStatus::ErrorVideoCore:
LOG_CRITICAL(Frontend, "VideoCore not initialized");
return -1;
case Core::System::ResultStatus::Success:
break; // Expected case
if (load_result != Core::System::ResultStatus::Success) {
return load_result;
}
auto& telemetry_session = Core::System::GetInstance().TelemetrySession();
@ -192,7 +167,7 @@ static int RunCitra(const std::string& filepath) {
}
}
return {};
return Core::System::ResultStatus::Success;
}
void Java_org_citra_citra_1android_NativeLibrary_SurfaceChanged(JNIEnv* env, jobject obj,
@ -483,5 +458,10 @@ void Java_org_citra_citra_1android_NativeLibrary_Run__Ljava_lang_String_2(JNIEnv
is_running = false;
running_cv.notify_all();
}
RunCitra(path);
const Core::System::ResultStatus result{RunCitra(path)};
if (result != Core::System::ResultStatus::Success) {
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
IDCache::GetExitEmulationActivity(), static_cast<int>(result));
}
}

View File

@ -103,6 +103,10 @@
<string name="preferences_graphics">Graphics</string>
<string name="preferences_audio">Audio</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Your ROM is encrypted</string>
<string name="loader_error_invalid_format">Invalid ROM format</string>
<!-- Emulation Menu -->
<string name="emulation_screenshot">Take Screenshot</string>
<string name="emulation_exit">Exit</string>

View File

@ -516,15 +516,17 @@ void System::RegisterImageInterface(std::shared_ptr<Frontend::ImageInterface> im
void System::Shutdown(bool is_deserializing) {
// Log last frame performance stats
const auto perf_results = GetAndResetPerfStats();
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
perf_results.emulation_speed * 100.0);
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Framerate",
perf_results.game_fps);
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Frametime",
perf_results.frametime * 1000.0);
telemetry_session->AddField(Telemetry::FieldType::Performance, "Mean_Frametime_MS",
perf_stats->GetMeanFrametime());
if (telemetry_session) {
const auto perf_results = GetAndResetPerfStats();
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
perf_results.emulation_speed * 100.0);
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Framerate",
perf_results.game_fps);
telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Frametime",
perf_results.frametime * 1000.0);
telemetry_session->AddField(Telemetry::FieldType::Performance, "Mean_Frametime_MS",
perf_stats->GetMeanFrametime());
}
// Shutdown emulation session
VideoCore::Shutdown();
@ -544,7 +546,7 @@ void System::Shutdown(bool is_deserializing) {
cpu_cores.clear();
timing.reset();
if (video_dumper->IsDumping()) {
if (video_dumper && video_dumper->IsDumping()) {
video_dumper->StopDumping();
}