Merge pull request #11922 from t895/kotlin-model
Android: Convert "model" package to Kotlin
This commit is contained in:
commit
b149ea51cf
|
@ -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 =
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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?
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -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>
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue