From 6a6bbd707177d17702bb7327984dd6adeabb09af Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Jul 2019 20:42:09 +1000 Subject: [PATCH 1/4] Android: Support bypassing game file cache to parse file --- .../org/dolphinemu/dolphinemu/model/GameFile.java | 2 ++ Source/Android/jni/GameList/GameFile.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java index 5a247137ab..70be6cd080 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java @@ -11,6 +11,8 @@ public class GameFile mPointer = pointer; } + public native static GameFile parse(String path); + @Override public native void finalize(); diff --git a/Source/Android/jni/GameList/GameFile.cpp b/Source/Android/jni/GameList/GameFile.cpp index ee889709fd..b9f7a28df4 100644 --- a/Source/Android/jni/GameList/GameFile.cpp +++ b/Source/Android/jni/GameList/GameFile.cpp @@ -165,6 +165,17 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBannerHe return static_cast(GetRef(env, obj)->GetBannerImage().height); } +JNIEXPORT jobject JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_parse(JNIEnv* env, + jobject obj, + jstring path) +{ + auto game_file = std::make_shared(GetJString(env, path)); + if (!game_file->IsValid()) + game_file.reset(); + + return GameFileToJava(env, game_file); +} + #ifdef __cplusplus } #endif From 34e6a41d050acb60e844ed825011a76545617a7b Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Jul 2019 20:42:42 +1000 Subject: [PATCH 2/4] Android: Support opening files directly This enables us to boot FIFO logs as well as homebrew directly, without having to add it to the game list first. --- .../activities/EmulationActivity.java | 34 ++++++++++++++++++- .../dolphinemu/ui/main/MainActivity.java | 15 ++++++++ .../dolphinemu/ui/main/MainPresenter.java | 5 +++ .../dolphinemu/ui/main/MainView.java | 2 ++ .../dolphinemu/ui/main/TvMainActivity.java | 14 ++++++++ .../dolphinemu/utils/FileBrowserHelper.java | 20 +++++++++-- .../app/src/main/res/menu/menu_game_grid.xml | 5 +++ 7 files changed, 92 insertions(+), 3 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index a49db4197f..259767ff86 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -198,6 +198,38 @@ public final class EmulationActivity extends AppCompatActivity activity.startActivity(launcher); } + public static void launchFile(FragmentActivity activity, String[] filePaths) + { + Intent launcher = new Intent(activity, EmulationActivity.class); + launcher.putExtra(EXTRA_SELECTED_GAMES, filePaths); + + // Try parsing a GameFile first. This should succeed for disc images. + GameFile gameFile = GameFile.parse(filePaths[0]); + if (gameFile != null) + { + // We don't want to pollute the game file cache with this new file, + // so we can't just call launch() and let it handle the setup. + launcher.putExtra(EXTRA_SELECTED_TITLE, gameFile.getTitle()); + launcher.putExtra(EXTRA_SELECTED_GAMEID, gameFile.getGameId()); + launcher.putExtra(EXTRA_PLATFORM, gameFile.getPlatform()); + } + else + { + // Display the path to the file as the game title in the menu. + launcher.putExtra(EXTRA_SELECTED_TITLE, filePaths); + + // Use 00000000 as the game ID. This should match the Desktop version behavior. + // TODO: This should really be pulled from the Core. + launcher.putExtra(EXTRA_SELECTED_GAMEID, "00000000"); + + // GameFile might be a FIFO log. Assume GameCube for the platform. It doesn't really matter + // anyway, since this only controls the input, and the FIFO player doesn't take any input. + launcher.putExtra(EXTRA_PLATFORM, Platform.GAMECUBE); + } + + activity.startActivity(launcher); + } + @Override protected void onCreate(Bundle savedInstanceState) { @@ -589,7 +621,7 @@ public final class EmulationActivity extends AppCompatActivity return; case MENU_ACTION_CHANGE_DISC: - FileBrowserHelper.openFilePicker(this, REQUEST_CHANGE_DISC); + FileBrowserHelper.openFilePicker(this, REQUEST_CHANGE_DISC, false); return; case MENU_SET_IR_SENSITIVITY: diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java index 4aed5bf166..84506567fd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java @@ -16,6 +16,7 @@ import android.view.View; import android.widget.Toast; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.activities.EmulationActivity; import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter; import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity; @@ -143,6 +144,12 @@ public final class MainActivity extends AppCompatActivity implements MainView FileBrowserHelper.openDirectoryPicker(this); } + @Override + public void launchOpenFileActivity() + { + FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_OPEN_FILE, true); + } + /** * @param requestCode An int describing whether the Activity that is returning did so successfully. * @param resultCode An int describing what Activity is giving us this callback. @@ -160,6 +167,14 @@ public final class MainActivity extends AppCompatActivity implements MainView mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result)); } break; + + case MainPresenter.REQUEST_OPEN_FILE: + // If the user picked a file, as opposed to just backing out. + if (resultCode == MainActivity.RESULT_OK) + { + EmulationActivity.launchFile(this, FileBrowserHelper.getSelectedFiles(result)); + } + break; } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java index 29afda89fe..54ef3cf377 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java @@ -15,6 +15,7 @@ import org.dolphinemu.dolphinemu.services.GameFileCacheService; public final class MainPresenter { public static final int REQUEST_ADD_DIRECTORY = 1; + public static final int REQUEST_OPEN_FILE = 2; private final MainView mView; private final Context mContext; @@ -85,6 +86,10 @@ public final class MainPresenter case R.id.button_add_directory: mView.launchFileListActivity(); return true; + + case R.id.menu_open_file: + mView.launchOpenFileActivity(); + return true; } return false; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java index d9ef95cdf1..5e3dc6243e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java @@ -21,6 +21,8 @@ public interface MainView void launchFileListActivity(); + void launchOpenFileActivity(); + /** * To be called when the game file cache is updated. */ diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java index 0457de51e6..c3acef8add 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java @@ -143,6 +143,12 @@ public final class TvMainActivity extends FragmentActivity implements MainView FileBrowserHelper.openDirectoryPicker(this); } + @Override + public void launchOpenFileActivity() + { + FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_OPEN_FILE, true); + } + @Override public void showGames() { @@ -171,6 +177,14 @@ public final class TvMainActivity extends FragmentActivity implements MainView mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result)); } break; + + case MainPresenter.REQUEST_OPEN_FILE: + // If the user picked a file, as opposed to just backing out. + if (resultCode == MainActivity.RESULT_OK) + { + EmulationActivity.launchFile(this, FileBrowserHelper.getSelectedFiles(result)); + } + break; } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java index 22e574aa0a..8e94bf3153 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java @@ -30,11 +30,11 @@ public final class FileBrowserHelper activity.startActivityForResult(i, MainPresenter.REQUEST_ADD_DIRECTORY); } - public static void openFilePicker(FragmentActivity activity, int requestCode) + public static void openFilePicker(FragmentActivity activity, int requestCode, boolean allowMulti) { Intent i = new Intent(activity, CustomFilePickerActivity.class); - i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false); + i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, allowMulti); i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false); i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE); i.putExtra(FilePickerActivity.EXTRA_START_PATH, @@ -56,4 +56,20 @@ public final class FileBrowserHelper return null; } + + @Nullable + public static String[] getSelectedFiles(Intent result) + { + // Use the provided utility method to parse the result + List files = Utils.getSelectedFilesFromResult(result); + if (!files.isEmpty()) + { + String[] paths = new String[files.size()]; + for (int i = 0; i < files.size(); i++) + paths[i] = Utils.getFileForUri(files.get(i)).getAbsolutePath(); + return paths; + } + + return null; + } } diff --git a/Source/Android/app/src/main/res/menu/menu_game_grid.xml b/Source/Android/app/src/main/res/menu/menu_game_grid.xml index 60e7309ff3..72facc4eaa 100644 --- a/Source/Android/app/src/main/res/menu/menu_game_grid.xml +++ b/Source/Android/app/src/main/res/menu/menu_game_grid.xml @@ -31,5 +31,10 @@ android:title="@string/grid_menu_refresh" android:icon="@drawable/ic_refresh" app:showAsAction="ifRoom"/> + \ No newline at end of file From 9961e2866a143b5fa7bd21ce5c81c3b98f40db4b Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Jul 2019 20:43:23 +1000 Subject: [PATCH 3/4] Android: Support opening .dff files This is also shared by the disc change code, but changing discs to a .dol doesn't make sense either. --- .../org/dolphinemu/dolphinemu/activities/EmulationActivity.java | 2 +- .../dolphinemu/fragments/CustomFilePickerFragment.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 259767ff86..518a7bc38c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -216,7 +216,7 @@ public final class EmulationActivity extends AppCompatActivity else { // Display the path to the file as the game title in the menu. - launcher.putExtra(EXTRA_SELECTED_TITLE, filePaths); + launcher.putExtra(EXTRA_SELECTED_TITLE, filePaths[0]); // Use 00000000 as the game ID. This should match the Desktop version behavior. // TODO: This should really be pulled from the Core. diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/CustomFilePickerFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/CustomFilePickerFragment.java index 8197dfc955..58cfcb9121 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/CustomFilePickerFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/CustomFilePickerFragment.java @@ -19,7 +19,7 @@ import java.util.Set; public class CustomFilePickerFragment extends FilePickerFragment { private static final Set extensions = new HashSet<>(Arrays.asList( - "gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wad", "dol", "elf")); + "gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wad", "dol", "elf", "dff")); @NonNull @Override From 6a29e8fa5845c7b6fcc0c38cdab30141309e09ff Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Jul 2019 22:00:26 +1000 Subject: [PATCH 4/4] Android: Use EmulationActivity.launchFile() for StartupHandler --- .../java/org/dolphinemu/dolphinemu/utils/StartupHandler.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java index 30253de9c8..8631e5ed8d 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java @@ -44,9 +44,7 @@ public final class StartupHandler if (start_files != null && start_files.length > 0) { // Start the emulation activity, send the ISO passed in and finish the main activity - Intent emulation_intent = new Intent(parent, EmulationActivity.class); - emulation_intent.putExtra(EmulationActivity.EXTRA_SELECTED_GAMES, start_files); - parent.startActivity(emulation_intent); + EmulationActivity.launchFile(parent, start_files); parent.finish(); } }