Android: Update platform enum values

71f654c added a new platform in the middle of the C++ platform enum
without updating the corresponding Android code, making the Android code
incorrectly treat Wii discs as WAD files, WAD files as DOL/ELF files,
and so on. This commit fixes the problem.

To be able to add the new Triforce entry into the Platform enum without
it leading to the UI getting an additional tab, I'm splitting the enum
into Platform and PlatformTab. Platform now exactly matches the C++
enum (previously it excluded ELFOrDOL), and PlatformTab has the same
content as the old Platform.
This commit is contained in:
JosJuice 2025-04-22 20:02:52 +02:00
parent fd8ce3ce80
commit 25fdde4204
11 changed files with 94 additions and 56 deletions

View file

@ -7,16 +7,16 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.ui.platform.Platform
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesFragment
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
class PlatformPagerAdapter(
fm: FragmentManager,
private val onRefreshListener: OnRefreshListener
) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment {
val platform = Platform.fromPosition(position)
val fragment = PlatformGamesFragment.newInstance(platform)
val platformTab = PlatformTab.fromPosition(position)
val fragment = PlatformGamesFragment.newInstance(platformTab)
fragment.setOnRefreshListener(onRefreshListener)
return fragment
}

View file

@ -72,8 +72,9 @@ public class GamePropertiesDialog extends DialogFragment
requireArguments().getBoolean(ARG_SHOULD_ALLOW_CONVERSION);
final boolean isDisc = platform == Platform.GAMECUBE.toInt() ||
platform == Platform.WII.toInt();
final boolean isWii = platform != Platform.GAMECUBE.toInt();
platform == Platform.TRIFORCE.toInt() || platform == Platform.WII.toInt();
final boolean isWii = platform == Platform.WII.toInt() ||
platform == Platform.WIIWARE.toInt();
AlertDialogItemsBuilder itemsBuilder = new AlertDialogItemsBuilder(requireContext());

View file

@ -13,6 +13,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.ConfigChangedCallback;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.model.GameFileCache;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab;
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
import java.util.ArrayList;
@ -46,18 +47,18 @@ public final class GameFileCacheManager
return sGameFiles;
}
public static List<GameFile> getGameFilesForPlatform(Platform platform)
public static List<GameFile> getGameFilesForPlatformTab(PlatformTab platformTab)
{
GameFile[] allGames = sGameFiles.getValue();
ArrayList<GameFile> platformGames = new ArrayList<>();
ArrayList<GameFile> platformTabGames = new ArrayList<>();
for (GameFile game : allGames)
{
if (Platform.fromNativeInt(game.getPlatform()) == platform)
if (Platform.fromInt(game.getPlatform()).toPlatformTab() == platformTab)
{
platformGames.add(game);
platformTabGames.add(game);
}
}
return platformGames;
return platformTabGames;
}
public static GameFile getGameFileByGameId(String gameId)

View file

@ -16,7 +16,7 @@ import androidx.tvprovider.media.tv.TvContractCompat;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab;
import org.dolphinemu.dolphinemu.utils.AppLinkHelper;
import org.dolphinemu.dolphinemu.utils.TvUtil;
@ -96,12 +96,12 @@ public class SyncProgramsJobService extends JobService
for (Long channelId : params)
{
Channel channel = TvUtil.getChannelById(context, channelId);
for (Platform platform : Platform.values())
for (PlatformTab platformTab : PlatformTab.values())
{
if (channel != null &&
channel.getAppLinkIntentUri().equals(AppLinkHelper.buildBrowseUri(platform)))
channel.getAppLinkIntentUri().equals(AppLinkHelper.buildBrowseUri(platformTab)))
{
getGamesByPlatform(platform);
getGamesByPlatform(platformTab);
syncPrograms(channelId);
}
}
@ -110,9 +110,9 @@ public class SyncProgramsJobService extends JobService
return true;
}
private void getGamesByPlatform(Platform platform)
private void getGamesByPlatform(PlatformTab platformTab)
{
updatePrograms = GameFileCacheManager.getGameFilesForPlatform(platform);
updatePrograms = GameFileCacheManager.getGameFilesForPlatformTab(platformTab);
}
private void syncPrograms(long channelId)

View file

@ -27,8 +27,8 @@ import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity
import org.dolphinemu.dolphinemu.fragments.GridOptionDialogFragment
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.ui.platform.Platform
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
import org.dolphinemu.dolphinemu.utils.Action1
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
@ -258,17 +258,17 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
GridOptionDialogFragment().show(supportFragmentManager, "gridOptions")
private fun forEachPlatformGamesView(action: Action1<PlatformGamesView>) {
for (platform in Platform.values()) {
val fragment = getPlatformGamesView(platform)
for (platformTab in PlatformTab.values()) {
val fragment = getPlatformGamesView(platformTab)
if (fragment != null) {
action.call(fragment)
}
}
}
private fun getPlatformGamesView(platform: Platform): PlatformGamesView? {
private fun getPlatformGamesView(platformTab: PlatformTab): PlatformGamesView? {
val fragmentTag =
"android:switcher:" + binding.pagerPlatforms.id + ":" + platform.toInt()
"android:switcher:" + binding.pagerPlatforms.id + ":" + platformTab.toInt()
return supportFragmentManager.findFragmentByTag(fragmentTag) as PlatformGamesView?
}

View file

@ -30,7 +30,7 @@ import org.dolphinemu.dolphinemu.fragments.GridOptionDialogFragment
import org.dolphinemu.dolphinemu.model.GameFile
import org.dolphinemu.dolphinemu.model.TvSettingsItem
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.ui.platform.Platform
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
import org.dolphinemu.dolphinemu.utils.PermissionsHandler
@ -240,9 +240,11 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
GameFileCacheManager.startLoad()
}
for (platform in Platform.values()) {
val row =
buildGamesRow(platform, GameFileCacheManager.getGameFilesForPlatform(platform))
for (platformTab in PlatformTab.values()) {
val row = buildGamesRow(
platformTab,
GameFileCacheManager.getGameFilesForPlatformTab(platformTab)
)
// Add row to the adapter only if it is not empty.
if (row != null) {
@ -255,7 +257,7 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
browseFragment!!.adapter = rowsAdapter
}
private fun buildGamesRow(platform: Platform, gameFiles: Collection<GameFile?>): ListRow? {
private fun buildGamesRow(platformTab: PlatformTab, gameFiles: Collection<GameFile?>): ListRow? {
// If there are no games, don't return a Row.
if (gameFiles.isEmpty()) {
return null
@ -269,7 +271,7 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
gameRows.add(row)
// Create a header for this row.
val header = HeaderItem(platform.toInt().toLong(), getString(platform.headerName))
val header = HeaderItem(platformTab.toInt().toLong(), getString(platformTab.headerName))
// Create the row, passing it the filled adapter and the header, and give it to the master adapter.
return ListRow(header, row)

View file

@ -7,30 +7,34 @@ import org.dolphinemu.dolphinemu.R
/**
* Enum to represent platform (eg GameCube, Wii).
*/
enum class Platform(private val value: Int, val headerName: Int, val idString: String) {
GAMECUBE(0, R.string.platform_gamecube, "GameCube Games"),
WII(1, R.string.platform_wii, "Wii Games"),
WIIWARE(2, R.string.platform_wiiware, "WiiWare Games");
enum class Platform(private val value: Int) {
GAMECUBE(0),
TRIFORCE(1),
WII(2),
WIIWARE(3),
ELF_DOL(4);
fun toInt(): Int {
return value
}
/**
* Returns which UI tab this platform should be shown in.
*/
fun toPlatformTab(): PlatformTab {
return when (this) {
GAMECUBE -> PlatformTab.GAMECUBE
TRIFORCE -> PlatformTab.GAMECUBE
WII -> PlatformTab.WII
WIIWARE -> PlatformTab.WIIWARE
ELF_DOL -> PlatformTab.WIIWARE
}
}
companion object {
@JvmStatic
fun fromInt(i: Int): Platform {
return values()[i]
}
@JvmStatic
fun fromNativeInt(i: Int): Platform {
// TODO: Proper support for DOL and ELF files
val inRange = i >= 0 && i < values().size
return values()[if (inRange) i else WIIWARE.value]
}
@JvmStatic
fun fromPosition(position: Int): Platform {
return values()[position]
}
}
}

View file

@ -73,9 +73,9 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
return
if (binding.gridGames.adapter != null) {
val platform = requireArguments().getSerializable(ARG_PLATFORM) as Platform
val platformTab = requireArguments().getSerializable(ARG_PLATFORM_TAB) as PlatformTab
(binding.gridGames.adapter as GameAdapter?)!!.swapDataSet(
GameFileCacheManager.getGameFilesForPlatform(platform)
GameFileCacheManager.getGameFilesForPlatformTab(platformTab)
)
}
}
@ -108,13 +108,13 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
}
companion object {
private const val ARG_PLATFORM = "platform"
private const val ARG_PLATFORM_TAB = "platform_tab"
@JvmStatic
fun newInstance(platform: Platform?): PlatformGamesFragment {
fun newInstance(platformTab: PlatformTab?): PlatformGamesFragment {
val fragment = PlatformGamesFragment()
val args = Bundle()
args.putSerializable(ARG_PLATFORM, platform)
args.putSerializable(ARG_PLATFORM_TAB, platformTab)
fragment.arguments = args
return fragment
}

View file

@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.ui.platform
import org.dolphinemu.dolphinemu.R
/**
* Enum to represent platform tabs in the UI.
*
* Each platform tab corresponds to one or more platforms.
*/
enum class PlatformTab(private val value: Int, val headerName: Int, val idString: String) {
GAMECUBE(0, R.string.platform_gamecube, "GameCube Games"),
WII(1, R.string.platform_wii, "Wii Games"),
WIIWARE(2, R.string.platform_wiiware, "WiiWare Games");
fun toInt(): Int {
return value
}
companion object {
fun fromInt(i: Int): PlatformTab {
return values()[i]
}
fun fromPosition(position: Int): PlatformTab {
return values()[position]
}
}
}

View file

@ -6,7 +6,7 @@ import android.net.Uri;
import androidx.annotation.StringDef;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab;
import java.util.List;
@ -33,9 +33,9 @@ public class AppLinkHelper
.build();
}
public static Uri buildBrowseUri(Platform platform)
public static Uri buildBrowseUri(PlatformTab platformTab)
{
return Uri.parse(URI_VIEW).buildUpon().appendPath(platform.getIdString()).build();
return Uri.parse(URI_VIEW).buildUpon().appendPath(platformTab.getIdString()).build();
}
public static AppLinkAction extractAction(Uri uri)

View file

@ -30,7 +30,7 @@ import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.model.HomeScreenChannel;
import org.dolphinemu.dolphinemu.services.SyncChannelJobService;
import org.dolphinemu.dolphinemu.services.SyncProgramsJobService;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab;
import java.io.File;
import java.io.FileNotFoundException;
@ -279,12 +279,12 @@ public class TvUtil
private static List<HomeScreenChannel> createPlatformSubscriptions(Context context)
{
List<HomeScreenChannel> subs = new ArrayList<>();
for (Platform platform : Platform.values())
for (PlatformTab platformTab : PlatformTab.values())
{
subs.add(new HomeScreenChannel(
context.getString(platform.getHeaderName()),
context.getString(platform.getHeaderName()),
AppLinkHelper.buildBrowseUri(platform)));
context.getString(platformTab.getHeaderName()),
context.getString(platformTab.getHeaderName()),
AppLinkHelper.buildBrowseUri(platformTab)));
}
return subs;
}