Merge pull request #11922 from t895/kotlin-model

Android: Convert "model" package to Kotlin
This commit is contained in:
JosJuice 2023-08-25 21:04:34 +02:00 committed by GitHub
commit b149ea51cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 291 additions and 357 deletions

View File

@ -61,12 +61,12 @@ class GameAdapter(private val mActivity: FragmentActivity) : RecyclerView.Adapte
holder.apply { holder.apply {
if (BooleanSetting.MAIN_SHOW_GAME_TITLES.boolean) { if (BooleanSetting.MAIN_SHOW_GAME_TITLES.boolean) {
binding.textGameTitle.text = gameFile.title binding.textGameTitle.text = gameFile.getTitle()
binding.textGameTitle.visibility = View.VISIBLE binding.textGameTitle.visibility = View.VISIBLE
binding.textGameTitleInner.visibility = View.GONE binding.textGameTitleInner.visibility = View.GONE
binding.textGameCaption.visibility = View.VISIBLE binding.textGameCaption.visibility = View.VISIBLE
} else { } else {
binding.textGameTitleInner.text = gameFile.title binding.textGameTitleInner.text = gameFile.getTitle()
binding.textGameTitleInner.visibility = View.VISIBLE binding.textGameTitleInner.visibility = View.VISIBLE
binding.textGameTitle.visibility = View.GONE binding.textGameTitle.visibility = View.GONE
binding.textGameCaption.visibility = View.GONE binding.textGameCaption.visibility = View.GONE
@ -94,9 +94,9 @@ class GameAdapter(private val mActivity: FragmentActivity) : RecyclerView.Adapte
holder.apply { holder.apply {
if (GameFileCacheManager.findSecondDisc(gameFile) != null) { if (GameFileCacheManager.findSecondDisc(gameFile) != null) {
binding.textGameCaption.text = binding.textGameCaption.text =
context.getString(R.string.disc_number, gameFile.discNumber + 1) context.getString(R.string.disc_number, gameFile.getDiscNumber() + 1)
} else { } else {
binding.textGameCaption.text = gameFile.company binding.textGameCaption.text = gameFile.getCompany()
} }
holder.gameFile = gameFile holder.gameFile = gameFile
binding.root.onFocusChangeListener = binding.root.onFocusChangeListener =

View File

@ -48,7 +48,7 @@ class GameRowPresenter(private val mActivity: FragmentActivity) : Presenter() {
holder.apply { holder.apply {
imageScreenshot.setImageDrawable(null) imageScreenshot.setImageDrawable(null)
cardParent.titleText = gameFile.title cardParent.titleText = gameFile.getTitle()
holder.gameFile = gameFile holder.gameFile = gameFile
// Set the background color of the card // Set the background color of the card
@ -64,9 +64,9 @@ class GameRowPresenter(private val mActivity: FragmentActivity) : Presenter() {
if (GameFileCacheManager.findSecondDisc(gameFile) != null) { if (GameFileCacheManager.findSecondDisc(gameFile) != null) {
holder.cardParent.contentText = holder.cardParent.contentText =
context.getString(R.string.disc_number, gameFile.discNumber + 1) context.getString(R.string.disc_number, gameFile.getDiscNumber() + 1)
} else { } else {
holder.cardParent.contentText = gameFile.company holder.cardParent.contentText = gameFile.getCompany()
} }
} }

View File

@ -25,8 +25,8 @@ class GameDetailsDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val gameFile = GameFileCacheManager.addOrGet(requireArguments().getString(ARG_GAME_PATH)) val gameFile = GameFileCacheManager.addOrGet(requireArguments().getString(ARG_GAME_PATH))
val country = resources.getStringArray(R.array.countryNames)[gameFile.country] val country = resources.getStringArray(R.array.countryNames)[gameFile.getCountry()]
val fileSize = NativeLibrary.FormatSize(gameFile.fileSize, 2) val fileSize = NativeLibrary.FormatSize(gameFile.getFileSize(), 2)
// TODO: Remove dialog_game_details_tv if we switch to an AppCompatActivity for leanback // TODO: Remove dialog_game_details_tv if we switch to an AppCompatActivity for leanback
val binding: DialogGameDetailsBinding val binding: DialogGameDetailsBinding
@ -35,16 +35,16 @@ class GameDetailsDialog : DialogFragment() {
if (requireActivity() is AppCompatActivity) { if (requireActivity() is AppCompatActivity) {
binding = DialogGameDetailsBinding.inflate(layoutInflater) binding = DialogGameDetailsBinding.inflate(layoutInflater)
binding.apply { binding.apply {
textGameTitle.text = gameFile.title textGameTitle.text = gameFile.getTitle()
textDescription.text = gameFile.description textDescription.text = gameFile.getDescription()
if (gameFile.description.isEmpty()) { if (gameFile.getDescription().isEmpty()) {
textDescription.visibility = View.GONE textDescription.visibility = View.GONE
} }
textCountry.text = country textCountry.text = country
textCompany.text = gameFile.company textCompany.text = gameFile.getCompany()
textGameId.text = gameFile.gameId textGameId.text = gameFile.getGameId()
textRevision.text = gameFile.revision.toString() textRevision.text = gameFile.getRevision().toString()
if (!gameFile.shouldShowFileFormatDetails()) { if (!gameFile.shouldShowFileFormatDetails()) {
labelFileFormat.setText(R.string.game_details_file_size) labelFileFormat.setText(R.string.game_details_file_size)
@ -55,19 +55,19 @@ class GameDetailsDialog : DialogFragment() {
labelBlockSize.visibility = View.GONE labelBlockSize.visibility = View.GONE
textBlockSize.visibility = View.GONE textBlockSize.visibility = View.GONE
} else { } else {
val blockSize = gameFile.blockSize val blockSize = gameFile.getBlockSize()
val compression = gameFile.compressionMethod val compression = gameFile.getCompressionMethod()
textFileFormat.text = resources.getString( textFileFormat.text = resources.getString(
R.string.game_details_size_and_format, R.string.game_details_size_and_format,
gameFile.fileFormatName, gameFile.getFileFormatName(),
fileSize fileSize
) )
if (compression.isEmpty()) { if (compression.isEmpty()) {
textCompression.setText(R.string.game_details_no_compression) textCompression.setText(R.string.game_details_no_compression)
} else { } else {
textCompression.text = gameFile.compressionMethod textCompression.text = gameFile.getCompressionMethod()
} }
if (blockSize > 0) { if (blockSize > 0) {
@ -87,16 +87,16 @@ class GameDetailsDialog : DialogFragment() {
} else { } else {
tvBinding = DialogGameDetailsTvBinding.inflate(layoutInflater) tvBinding = DialogGameDetailsTvBinding.inflate(layoutInflater)
tvBinding.apply { tvBinding.apply {
textGameTitle.text = gameFile.title textGameTitle.text = gameFile.getTitle()
textDescription.text = gameFile.description textDescription.text = gameFile.getDescription()
if (gameFile.description.isEmpty()) { if (gameFile.getDescription().isEmpty()) {
tvBinding.textDescription.visibility = View.GONE tvBinding.textDescription.visibility = View.GONE
} }
textCountry.text = country textCountry.text = country
textCompany.text = gameFile.company textCompany.text = gameFile.getCompany()
textGameId.text = gameFile.gameId textGameId.text = gameFile.getGameId()
textRevision.text = gameFile.revision.toString() textRevision.text = gameFile.getRevision().toString()
if (!gameFile.shouldShowFileFormatDetails()) { if (!gameFile.shouldShowFileFormatDetails()) {
labelFileFormat.setText(R.string.game_details_file_size) labelFileFormat.setText(R.string.game_details_file_size)
@ -107,19 +107,19 @@ class GameDetailsDialog : DialogFragment() {
labelBlockSize.visibility = View.GONE labelBlockSize.visibility = View.GONE
textBlockSize.visibility = View.GONE textBlockSize.visibility = View.GONE
} else { } else {
val blockSize = gameFile.blockSize val blockSize = gameFile.getBlockSize()
val compression = gameFile.compressionMethod val compression = gameFile.getCompressionMethod()
textFileFormat.text = resources.getString( textFileFormat.text = resources.getString(
R.string.game_details_size_and_format, R.string.game_details_size_and_format,
gameFile.fileFormatName, gameFile.getFileFormatName(),
fileSize fileSize
) )
if (compression.isEmpty()) { if (compression.isEmpty()) {
textCompression.setText(R.string.game_details_no_compression) textCompression.setText(R.string.game_details_no_compression)
} else { } else {
textCompression.text = gameFile.compressionMethod textCompression.text = gameFile.getCompressionMethod()
} }
if (blockSize > 0) { if (blockSize > 0) {
@ -141,9 +141,9 @@ class GameDetailsDialog : DialogFragment() {
} }
private suspend fun loadGameBanner(imageView: ImageView, gameFile: GameFile) { private suspend fun loadGameBanner(imageView: ImageView, gameFile: GameFile) {
val vector = gameFile.banner val vector = gameFile.getBanner()
val width = gameFile.bannerWidth val width = gameFile.getBannerWidth()
val height = gameFile.bannerHeight val height = gameFile.getBannerHeight()
imageView.scaleType = ImageView.ScaleType.FIT_CENTER imageView.scaleType = ImageView.ScaleType.FIT_CENTER
val request = ImageRequest.Builder(imageView.context) val request = ImageRequest.Builder(imageView.context)

View File

@ -210,7 +210,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
R.array.convertFormatValues, R.array.convertFormatValues,
format format
) )
if (gameFile.blobType == BLOB_TYPE_ISO) { if (gameFile.getBlobType() == BLOB_TYPE_ISO) {
setDropdownSelection( setDropdownSelection(
binding.dropdownFormat, binding.dropdownFormat,
format, format,
@ -240,6 +240,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
binding.dropdownBlockSize.adapter.getItem(0).toString(), false binding.dropdownBlockSize.adapter.getItem(0).toString(), false
) )
} }
BLOB_TYPE_WIA -> { BLOB_TYPE_WIA -> {
populateDropdown( populateDropdown(
binding.blockSize, binding.blockSize,
@ -253,6 +254,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
binding.dropdownBlockSize.adapter.getItem(0).toString(), false binding.dropdownBlockSize.adapter.getItem(0).toString(), false
) )
} }
BLOB_TYPE_RVZ -> { BLOB_TYPE_RVZ -> {
populateDropdown( populateDropdown(
binding.blockSize, binding.blockSize,
@ -266,6 +268,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
binding.dropdownBlockSize.adapter.getItem(2).toString(), false binding.dropdownBlockSize.adapter.getItem(2).toString(), false
) )
} }
else -> clearDropdown(binding.blockSize, binding.dropdownBlockSize, blockSize) else -> clearDropdown(binding.blockSize, binding.dropdownBlockSize, blockSize)
} }
} }
@ -285,6 +288,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
binding.dropdownCompression.adapter.getItem(0).toString(), false binding.dropdownCompression.adapter.getItem(0).toString(), false
) )
} }
BLOB_TYPE_WIA -> { BLOB_TYPE_WIA -> {
populateDropdown( populateDropdown(
binding.compression, binding.compression,
@ -298,6 +302,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
binding.dropdownCompression.adapter.getItem(0).toString(), false binding.dropdownCompression.adapter.getItem(0).toString(), false
) )
} }
BLOB_TYPE_RVZ -> { BLOB_TYPE_RVZ -> {
populateDropdown( populateDropdown(
binding.compression, binding.compression,
@ -311,6 +316,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
binding.dropdownCompression.adapter.getItem(4).toString(), false binding.dropdownCompression.adapter.getItem(4).toString(), false
) )
} }
else -> clearDropdown( else -> clearDropdown(
binding.compression, binding.compression,
binding.dropdownCompression, binding.dropdownCompression,
@ -336,6 +342,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
).toString(), false ).toString(), false
) )
} }
COMPRESSION_ZSTD -> { COMPRESSION_ZSTD -> {
// TODO: Query DiscIO for the supported compression levels, like we do in DolphinQt? // TODO: Query DiscIO for the supported compression levels, like we do in DolphinQt?
populateDropdown( populateDropdown(
@ -352,6 +359,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
).toString(), false ).toString(), false
) )
} }
else -> clearDropdown( else -> clearDropdown(
binding.compressionLevel, binding.compressionLevel,
binding.dropdownCompressionLevel, binding.dropdownCompressionLevel,
@ -362,7 +370,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
private fun populateRemoveJunkData() { private fun populateRemoveJunkData() {
val scrubbingAllowed = format.getValue(requireContext()) != BLOB_TYPE_RVZ && val scrubbingAllowed = format.getValue(requireContext()) != BLOB_TYPE_RVZ &&
!gameFile.isDatelDisc !gameFile.isDatelDisc()
binding.switchRemoveJunkData.isEnabled = scrubbingAllowed binding.switchRemoveJunkData.isEnabled = scrubbingAllowed
if (!scrubbingAllowed) binding.switchRemoveJunkData.isChecked = false if (!scrubbingAllowed) binding.switchRemoveJunkData.isChecked = false
@ -374,11 +382,11 @@ class ConvertFragment : Fragment(), View.OnClickListener {
var action = Runnable { showSavePrompt() } var action = Runnable { showSavePrompt() }
if (gameFile.isNKit) { if (gameFile.isNKit()) {
action = addAreYouSureDialog(action, R.string.convert_warning_nkit) action = addAreYouSureDialog(action, R.string.convert_warning_nkit)
} }
if (!scrub && format == BLOB_TYPE_GCZ && !gameFile.isDatelDisc && gameFile.platform == Platform.WII.toInt()) { if (!scrub && format == BLOB_TYPE_GCZ && !gameFile.isDatelDisc() && gameFile.getPlatform() == Platform.WII.toInt()) {
action = addAreYouSureDialog(action, R.string.convert_warning_gcz) action = addAreYouSureDialog(action, R.string.convert_warning_gcz)
} }
@ -401,7 +409,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
} }
private fun showSavePrompt() { private fun showSavePrompt() {
val originalPath = gameFile.path val originalPath = gameFile.getPath()
val filename = StringBuilder(File(originalPath).name) val filename = StringBuilder(File(originalPath).name)
val dotIndex = filename.lastIndexOf(".") val dotIndex = filename.lastIndexOf(".")
@ -449,9 +457,9 @@ class ConvertFragment : Fragment(), View.OnClickListener {
thread = Thread { thread = Thread {
val success = NativeLibrary.ConvertDiscImage( val success = NativeLibrary.ConvertDiscImage(
gameFile.path, gameFile.getPath(),
outPath, outPath,
gameFile.platform, gameFile.getPlatform(),
format.getValue(context), format.getValue(context),
blockSize.getValueOr(context, 0), blockSize.getValueOr(context, 0),
compression.getValueOr(context, 0), compression.getValueOr(context, 0),

View File

@ -1,78 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model;
import androidx.annotation.Keep;
public class GameFile
{
public static int REGION_NTSC_J = 0;
public static int REGION_NTSC_U = 1;
public static int REGION_PAL = 2;
public static int REGION_NTSC_K = 4;
@Keep
private long mPointer;
@Keep
private GameFile(long pointer)
{
mPointer = pointer;
}
public native static GameFile parse(String path);
@Override
public native void finalize();
public native int getPlatform();
public native String getTitle();
public native String getDescription();
public native String getCompany();
public native int getCountry();
public native int getRegion();
public native String getPath();
public native String getGameId();
public native String getGameTdbId();
public native int getDiscNumber();
public native int getRevision();
public native int getBlobType();
public native String getFileFormatName();
public native long getBlockSize();
public native String getCompressionMethod();
public native boolean shouldShowFileFormatDetails();
public native boolean shouldAllowConversion();
public native long getFileSize();
public native boolean isDatelDisc();
public native boolean isNKit();
public native int[] getBanner();
public native int getBannerWidth();
public native int getBannerHeight();
public String getCustomCoverPath()
{
return getPath().substring(0, getPath().lastIndexOf(".")) + ".cover.png";
}
}

View File

@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model
import androidx.annotation.Keep
@Keep
class GameFile private constructor(private val pointer: Long) {
external fun finalize()
external fun getPlatform(): Int
external fun getTitle(): String
external fun getDescription(): String
external fun getCompany(): String
external fun getCountry(): Int
external fun getRegion(): Int
external fun getPath(): String
external fun getGameId(): String
external fun getGameTdbId(): String
external fun getDiscNumber(): Int
external fun getRevision(): Int
external fun getBlobType(): Int
external fun getFileFormatName(): String
external fun getBlockSize(): Long
external fun getCompressionMethod(): String
external fun shouldShowFileFormatDetails(): Boolean
external fun shouldAllowConversion(): Boolean
external fun getFileSize(): Long
external fun isDatelDisc(): Boolean
external fun isNKit(): Boolean
external fun getBanner(): IntArray
external fun getBannerWidth(): Int
external fun getBannerHeight(): Int
val customCoverPath: String
get() = "${getPath().substring(0, getPath().lastIndexOf("."))}.cover.png"
companion object {
var REGION_NTSC_J = 0
var REGION_NTSC_U = 1
var REGION_PAL = 2
var REGION_NTSC_K = 4
@JvmStatic
external fun parse(path: String): GameFile?
}
}

View File

@ -1,139 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model;
import androidx.annotation.Keep;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.utils.ContentHandler;
import org.dolphinemu.dolphinemu.utils.IniFile;
import java.io.File;
import java.util.LinkedHashSet;
public class GameFileCache
{
@Keep
private long mPointer;
public GameFileCache()
{
mPointer = newGameFileCache();
}
private static native long newGameFileCache();
@Override
public native void finalize();
public static void addGameFolder(String path)
{
File dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN);
IniFile dolphinIni = new IniFile(dolphinFile);
LinkedHashSet<String> pathSet = getPathSet(false);
int totalISOPaths =
dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0);
if (!pathSet.contains(path))
{
dolphinIni.setInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS,
totalISOPaths + 1);
dolphinIni.setString(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATH_BASE +
totalISOPaths, path);
dolphinIni.save(dolphinFile);
NativeLibrary.ReloadConfig();
}
}
private static LinkedHashSet<String> getPathSet(boolean removeNonExistentFolders)
{
File dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN);
IniFile dolphinIni = new IniFile(dolphinFile);
LinkedHashSet<String> pathSet = new LinkedHashSet<>();
int totalISOPaths =
dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0);
for (int i = 0; i < totalISOPaths; i++)
{
String path = dolphinIni.getString(Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATH_BASE + i, "");
if (ContentHandler.isContentUri(path) ? ContentHandler.exists(path) : new File(path).exists())
{
pathSet.add(path);
}
}
if (removeNonExistentFolders && totalISOPaths > pathSet.size())
{
int setIndex = 0;
dolphinIni.setInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS,
pathSet.size());
// One or more folders have been removed.
for (String entry : pathSet)
{
dolphinIni.setString(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATH_BASE +
setIndex, entry);
setIndex++;
}
// Delete known unnecessary keys. Ignore i values beyond totalISOPaths.
for (int i = setIndex; i < totalISOPaths; i++)
{
dolphinIni.deleteKey(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATH_BASE + i);
}
dolphinIni.save(dolphinFile);
NativeLibrary.ReloadConfig();
}
return pathSet;
}
public static String[] getAllGamePaths()
{
boolean recursiveScan = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBoolean();
LinkedHashSet<String> folderPathsSet = getPathSet(true);
String[] folderPaths = folderPathsSet.toArray(new String[0]);
return getAllGamePaths(folderPaths, recursiveScan);
}
public static native String[] getAllGamePaths(String[] folderPaths, boolean recursiveScan);
public synchronized native int getSize();
public synchronized native GameFile[] getAllGames();
public synchronized native GameFile addOrGet(String gamePath);
/**
* Sets the list of games to cache.
*
* Games which are in the passed-in list but not in the cache are scanned and added to the cache,
* and games which are in the cache but not in the passed-in list are removed from the cache.
*
* @return true if the cache was modified
*/
public synchronized native boolean update(String[] gamePaths);
/**
* For each game that already is in the cache, scans the folder that contains the game
* for additional metadata files (PNG/XML).
*
* @return true if the cache was modified
*/
public synchronized native boolean updateAdditionalMetadata();
public synchronized native boolean load();
public synchronized native boolean save();
}

View File

@ -0,0 +1,152 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model
import androidx.annotation.Keep
import org.dolphinemu.dolphinemu.NativeLibrary
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
import org.dolphinemu.dolphinemu.features.settings.model.Settings
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile
import org.dolphinemu.dolphinemu.utils.ContentHandler
import org.dolphinemu.dolphinemu.utils.IniFile
import java.io.File
class GameFileCache {
@Keep
private val pointer: Long = newGameFileCache()
external fun finalize()
@Synchronized
external fun getSize(): Int
@Synchronized
external fun getAllGames(): Array<GameFile>
@Synchronized
external fun addOrGet(gamePath: String): GameFile?
/**
* Sets the list of games to cache.
*
* Games which are in the passed-in list but not in the cache are scanned and added to the cache,
* and games which are in the cache but not in the passed-in list are removed from the cache.
*
* @return true if the cache was modified
*/
@Synchronized
external fun update(gamePaths: Array<String>): Boolean
/**
* For each game that already is in the cache, scans the folder that contains the game
* for additional metadata files (PNG/XML).
*
* @return true if the cache was modified
*/
@Synchronized
external fun updateAdditionalMetadata(): Boolean
@Synchronized
external fun load(): Boolean
@Synchronized
external fun save(): Boolean
companion object {
@JvmStatic
private external fun newGameFileCache(): Long
fun addGameFolder(path: String) {
val dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN)
val dolphinIni = IniFile(dolphinFile)
val pathSet = getPathSet(false)
val totalISOPaths =
dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0)
if (!pathSet.contains(path)) {
dolphinIni.setInt(
Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATHS,
totalISOPaths + 1
)
dolphinIni.setString(
Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATH_BASE + totalISOPaths,
path
)
dolphinIni.save(dolphinFile)
NativeLibrary.ReloadConfig()
}
}
private fun getPathSet(removeNonExistentFolders: Boolean): LinkedHashSet<String> {
val dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN)
val dolphinIni = IniFile(dolphinFile)
val pathSet = LinkedHashSet<String>()
val totalISOPaths =
dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0)
for (i in 0 until totalISOPaths) {
val path = dolphinIni.getString(
Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATH_BASE + i,
""
)
val pathExists = if (ContentHandler.isContentUri(path))
ContentHandler.exists(path)
else
File(path).exists()
if (pathExists) {
pathSet.add(path)
}
}
if (removeNonExistentFolders && totalISOPaths > pathSet.size) {
var setIndex = 0
dolphinIni.setInt(
Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATHS,
pathSet.size
)
// One or more folders have been removed.
for (entry in pathSet) {
dolphinIni.setString(
Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATH_BASE + setIndex,
entry
)
setIndex++
}
// Delete known unnecessary keys. Ignore i values beyond totalISOPaths.
for (i in setIndex until totalISOPaths) {
dolphinIni.deleteKey(
Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_ISO_PATH_BASE + i
)
}
dolphinIni.save(dolphinFile)
NativeLibrary.ReloadConfig()
}
return pathSet
}
@JvmStatic
fun getAllGamePaths(): Array<String> {
val recursiveScan = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
val folderPathsSet = getPathSet(true)
val folderPaths = folderPathsSet.toTypedArray()
return getAllGamePaths(folderPaths, recursiveScan)
}
@JvmStatic
external fun getAllGamePaths(
folderPaths: Array<String>,
recursiveScan: Boolean
): Array<String>
}
}

View File

@ -1,63 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model;
import android.net.Uri;
/**
* Represents a home screen channel for Android TV api 26+
*/
public class HomeScreenChannel
{
private long channelId;
private String name;
private String description;
private Uri appLinkIntentUri;
public HomeScreenChannel(String name, String description, Uri appLinkIntentUri)
{
this.name = name;
this.description = description;
this.appLinkIntentUri = appLinkIntentUri;
}
public long getChannelId()
{
return channelId;
}
public void setChannelId(long channelId)
{
this.channelId = channelId;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public Uri getAppLinkIntentUri()
{
return appLinkIntentUri;
}
public void setAppLinkIntentUri(Uri appLinkIntentUri)
{
this.appLinkIntentUri = appLinkIntentUri;
}
}

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model
import android.net.Uri
/**
* Represents a home screen channel for Android TV api 26+
*/
class HomeScreenChannel(var name: String, var description: String, var appLinkIntentUri: Uri) {
var channelId: Long = 0
}

View File

@ -1,32 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model;
public final class TvSettingsItem
{
private final int mItemId;
private final int mIconId;
private final int mLabelId;
public TvSettingsItem(int itemId, int iconId, int labelId)
{
mItemId = itemId;
mIconId = iconId;
mLabelId = labelId;
}
public int getItemId()
{
return mItemId;
}
public int getIconId()
{
return mIconId;
}
public int getLabelId()
{
return mLabelId;
}
}

View File

@ -0,0 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.model
class TvSettingsItem(val itemId: Int, val iconId: Int, val labelId: Int)

View File

@ -123,7 +123,7 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
fun onResume() { fun onResume() {
if (dirToAdd != null) { if (dirToAdd != null) {
GameFileCache.addGameFolder(dirToAdd) GameFileCache.addGameFolder(dirToAdd!!)
dirToAdd = null dirToAdd = null
} }

View File

@ -8,16 +8,16 @@ object CoverHelper {
@JvmStatic @JvmStatic
fun buildGameTDBUrl(game: GameFile, region: String?): String { fun buildGameTDBUrl(game: GameFile, region: String?): String {
val baseUrl = "https://art.gametdb.com/wii/cover/%s/%s.png" val baseUrl = "https://art.gametdb.com/wii/cover/%s/%s.png"
return String.format(baseUrl, region, game.gameTdbId) return String.format(baseUrl, region, game.getGameTdbId())
} }
@JvmStatic @JvmStatic
fun getRegion(game: GameFile): String { fun getRegion(game: GameFile): String {
val region: String = when (game.region) { val region: String = when (game.getRegion()) {
GameFile.REGION_NTSC_J -> "JA" GameFile.REGION_NTSC_J -> "JA"
GameFile.REGION_NTSC_U -> "US" GameFile.REGION_NTSC_U -> "US"
GameFile.REGION_NTSC_K -> "KO" GameFile.REGION_NTSC_K -> "KO"
GameFile.REGION_PAL -> when (game.country) { GameFile.REGION_PAL -> when (game.getCountry()) {
3 -> "AU" // Australia 3 -> "AU" // Australia
4 -> "FR" // France 4 -> "FR" // France
5 -> "DE" // Germany 5 -> "DE" // Germany

View File

@ -563,14 +563,14 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile"); const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile");
s_game_file_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_class)); s_game_file_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_class));
s_game_file_pointer = env->GetFieldID(game_file_class, "mPointer", "J"); s_game_file_pointer = env->GetFieldID(game_file_class, "pointer", "J");
s_game_file_constructor = env->GetMethodID(game_file_class, "<init>", "(J)V"); s_game_file_constructor = env->GetMethodID(game_file_class, "<init>", "(J)V");
env->DeleteLocalRef(game_file_class); env->DeleteLocalRef(game_file_class);
const jclass game_file_cache_class = const jclass game_file_cache_class =
env->FindClass("org/dolphinemu/dolphinemu/model/GameFileCache"); env->FindClass("org/dolphinemu/dolphinemu/model/GameFileCache");
s_game_file_cache_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_cache_class)); s_game_file_cache_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_cache_class));
s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "mPointer", "J"); s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "pointer", "J");
env->DeleteLocalRef(game_file_cache_class); env->DeleteLocalRef(game_file_cache_class);
const jclass analytics_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Analytics"); const jclass analytics_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Analytics");