diff options
6 files changed, 66 insertions, 94 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt index dd6c895fd..f54dccc69 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt | |||
| @@ -29,7 +29,6 @@ import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager | |||
| 29 | import org.yuzu.yuzu_emu.model.Game | 29 | import org.yuzu.yuzu_emu.model.Game |
| 30 | import org.yuzu.yuzu_emu.model.GamesViewModel | 30 | import org.yuzu.yuzu_emu.model.GamesViewModel |
| 31 | import org.yuzu.yuzu_emu.model.HomeViewModel | 31 | import org.yuzu.yuzu_emu.model.HomeViewModel |
| 32 | import org.yuzu.yuzu_emu.utils.FileUtil | ||
| 33 | 32 | ||
| 34 | class SearchFragment : Fragment() { | 33 | class SearchFragment : Fragment() { |
| 35 | private var _binding: FragmentSearchBinding? = null | 34 | private var _binding: FragmentSearchBinding? = null |
| @@ -128,10 +127,7 @@ class SearchFragment : Fragment() { | |||
| 128 | 127 | ||
| 129 | R.id.chip_homebrew -> baseList.filter { it.isHomebrew } | 128 | R.id.chip_homebrew -> baseList.filter { it.isHomebrew } |
| 130 | 129 | ||
| 131 | R.id.chip_retail -> baseList.filter { | 130 | R.id.chip_retail -> baseList.filter { !it.isHomebrew } |
| 132 | FileUtil.hasExtension(it.path, "xci") || | ||
| 133 | FileUtil.hasExtension(it.path, "nsp") | ||
| 134 | } | ||
| 135 | 131 | ||
| 136 | else -> baseList | 132 | else -> baseList |
| 137 | } | 133 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt index 6a048e39f..6527c64ab 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt | |||
| @@ -43,7 +43,7 @@ class Game( | |||
| 43 | 43 | ||
| 44 | companion object { | 44 | companion object { |
| 45 | val extensions: Set<String> = HashSet( | 45 | val extensions: Set<String> = HashSet( |
| 46 | listOf(".xci", ".nsp", ".nca", ".nro") | 46 | listOf("xci", "nsp", "nca", "nro") |
| 47 | ) | 47 | ) |
| 48 | } | 48 | } |
| 49 | } | 49 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index 3086cfad3..f7d7aed1e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt | |||
| @@ -296,7 +296,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { | |||
| 296 | return@registerForActivityResult | 296 | return@registerForActivityResult |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | if (!FileUtil.hasExtension(result, "keys")) { | 299 | if (FileUtil.getExtension(result) != "keys") { |
| 300 | MessageDialogFragment.newInstance( | 300 | MessageDialogFragment.newInstance( |
| 301 | R.string.reading_keys_failure, | 301 | R.string.reading_keys_failure, |
| 302 | R.string.install_prod_keys_failure_extension_description | 302 | R.string.install_prod_keys_failure_extension_description |
| @@ -393,7 +393,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { | |||
| 393 | return@registerForActivityResult | 393 | return@registerForActivityResult |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | if (!FileUtil.hasExtension(result, "bin")) { | 396 | if (FileUtil.getExtension(result) != "bin") { |
| 397 | MessageDialogFragment.newInstance( | 397 | MessageDialogFragment.newInstance( |
| 398 | R.string.reading_keys_failure, | 398 | R.string.reading_keys_failure, |
| 399 | R.string.install_amiibo_keys_failure_extension_description | 399 | R.string.install_amiibo_keys_failure_extension_description |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt index 9f3bbe56f..142af5f26 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt | |||
| @@ -7,7 +7,6 @@ import android.content.Context | |||
| 7 | import android.database.Cursor | 7 | import android.database.Cursor |
| 8 | import android.net.Uri | 8 | import android.net.Uri |
| 9 | import android.provider.DocumentsContract | 9 | import android.provider.DocumentsContract |
| 10 | import android.provider.OpenableColumns | ||
| 11 | import androidx.documentfile.provider.DocumentFile | 10 | import androidx.documentfile.provider.DocumentFile |
| 12 | import java.io.BufferedInputStream | 11 | import java.io.BufferedInputStream |
| 13 | import java.io.File | 12 | import java.io.File |
| @@ -185,19 +184,18 @@ object FileUtil { | |||
| 185 | 184 | ||
| 186 | /** | 185 | /** |
| 187 | * Get file display name from given path | 186 | * Get file display name from given path |
| 188 | * @param path content uri path | 187 | * @param uri content uri |
| 189 | * @return String display name | 188 | * @return String display name |
| 190 | */ | 189 | */ |
| 191 | fun getFilename(context: Context, path: String): String { | 190 | fun getFilename(uri: Uri): String { |
| 192 | val resolver = context.contentResolver | 191 | val resolver = YuzuApplication.appContext.contentResolver |
| 193 | val columns = arrayOf( | 192 | val columns = arrayOf( |
| 194 | DocumentsContract.Document.COLUMN_DISPLAY_NAME | 193 | DocumentsContract.Document.COLUMN_DISPLAY_NAME |
| 195 | ) | 194 | ) |
| 196 | var filename = "" | 195 | var filename = "" |
| 197 | var c: Cursor? = null | 196 | var c: Cursor? = null |
| 198 | try { | 197 | try { |
| 199 | val mUri = Uri.parse(path) | 198 | c = resolver.query(uri, columns, null, null, null) |
| 200 | c = resolver.query(mUri, columns, null, null, null) | ||
| 201 | c!!.moveToNext() | 199 | c!!.moveToNext() |
| 202 | filename = c.getString(0) | 200 | filename = c.getString(0) |
| 203 | } catch (e: Exception) { | 201 | } catch (e: Exception) { |
| @@ -326,25 +324,9 @@ object FileUtil { | |||
| 326 | } | 324 | } |
| 327 | } | 325 | } |
| 328 | 326 | ||
| 329 | fun hasExtension(path: String, extension: String): Boolean = | 327 | fun getExtension(uri: Uri): String { |
| 330 | path.substring(path.lastIndexOf(".") + 1).contains(extension) | 328 | val fileName = getFilename(uri) |
| 331 | 329 | return fileName.substring(fileName.lastIndexOf(".") + 1) | |
| 332 | fun hasExtension(uri: Uri, extension: String): Boolean { | 330 | .lowercase() |
| 333 | val fileName: String? | ||
| 334 | val cursor = YuzuApplication.appContext.contentResolver.query(uri, null, null, null, null) | ||
| 335 | val nameIndex = cursor?.getColumnIndex(OpenableColumns.DISPLAY_NAME) | ||
| 336 | cursor?.moveToFirst() | ||
| 337 | |||
| 338 | if (nameIndex == null) { | ||
| 339 | return false | ||
| 340 | } | ||
| 341 | |||
| 342 | fileName = cursor.getString(nameIndex) | ||
| 343 | cursor.close() | ||
| 344 | |||
| 345 | if (fileName == null) { | ||
| 346 | return false | ||
| 347 | } | ||
| 348 | return fileName.substring(fileName.lastIndexOf(".") + 1).contains(extension) | ||
| 349 | } | 331 | } |
| 350 | } | 332 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt index ee9f3e570..f8e7eeca7 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt | |||
| @@ -6,7 +6,6 @@ package org.yuzu.yuzu_emu.utils | |||
| 6 | import android.content.SharedPreferences | 6 | import android.content.SharedPreferences |
| 7 | import android.net.Uri | 7 | import android.net.Uri |
| 8 | import androidx.preference.PreferenceManager | 8 | import androidx.preference.PreferenceManager |
| 9 | import java.util.* | ||
| 10 | import kotlinx.serialization.encodeToString | 9 | import kotlinx.serialization.encodeToString |
| 11 | import kotlinx.serialization.json.Json | 10 | import kotlinx.serialization.json.Json |
| 12 | import org.yuzu.yuzu_emu.NativeLibrary | 11 | import org.yuzu.yuzu_emu.NativeLibrary |
| @@ -33,15 +32,9 @@ object GameHelper { | |||
| 33 | val children = FileUtil.listFiles(context, gamesUri) | 32 | val children = FileUtil.listFiles(context, gamesUri) |
| 34 | for (file in children) { | 33 | for (file in children) { |
| 35 | if (!file.isDirectory) { | 34 | if (!file.isDirectory) { |
| 36 | val filename = file.uri.toString() | 35 | // Check that the file has an extension we care about before trying to read out of it. |
| 37 | val extensionStart = filename.lastIndexOf('.') | 36 | if (Game.extensions.contains(FileUtil.getExtension(file.uri))) { |
| 38 | if (extensionStart > 0) { | 37 | games.add(getGame(file.uri)) |
| 39 | val fileExtension = filename.substring(extensionStart) | ||
| 40 | |||
| 41 | // Check that the file has an extension we care about before trying to read out of it. | ||
| 42 | if (Game.extensions.contains(fileExtension.lowercase(Locale.getDefault()))) { | ||
| 43 | games.add(getGame(filename)) | ||
| 44 | } | ||
| 45 | } | 38 | } |
| 46 | } | 39 | } |
| 47 | } | 40 | } |
| @@ -59,21 +52,19 @@ object GameHelper { | |||
| 59 | return games.toList() | 52 | return games.toList() |
| 60 | } | 53 | } |
| 61 | 54 | ||
| 62 | private fun getGame(filePath: String): Game { | 55 | private fun getGame(uri: Uri): Game { |
| 56 | val filePath = uri.toString() | ||
| 63 | var name = NativeLibrary.getTitle(filePath) | 57 | var name = NativeLibrary.getTitle(filePath) |
| 64 | 58 | ||
| 65 | // If the game's title field is empty, use the filename. | 59 | // If the game's title field is empty, use the filename. |
| 66 | if (name.isEmpty()) { | 60 | if (name.isEmpty()) { |
| 67 | name = filePath.substring(filePath.lastIndexOf("/") + 1) | 61 | name = FileUtil.getFilename(uri) |
| 68 | } | 62 | } |
| 69 | var gameId = NativeLibrary.getGameId(filePath) | 63 | var gameId = NativeLibrary.getGameId(filePath) |
| 70 | 64 | ||
| 71 | // If the game's ID field is empty, use the filename without extension. | 65 | // If the game's ID field is empty, use the filename without extension. |
| 72 | if (gameId.isEmpty()) { | 66 | if (gameId.isEmpty()) { |
| 73 | gameId = filePath.substring( | 67 | gameId = name.substring(0, name.lastIndexOf(".")) |
| 74 | filePath.lastIndexOf("/") + 1, | ||
| 75 | filePath.lastIndexOf(".") | ||
| 76 | ) | ||
| 77 | } | 68 | } |
| 78 | 69 | ||
| 79 | val newGame = Game( | 70 | val newGame = Game( |
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index d576aac50..8bc6a4a04 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -60,6 +60,9 @@ | |||
| 60 | #include "video_core/rasterizer_interface.h" | 60 | #include "video_core/rasterizer_interface.h" |
| 61 | #include "video_core/renderer_base.h" | 61 | #include "video_core/renderer_base.h" |
| 62 | 62 | ||
| 63 | #define jconst [[maybe_unused]] const auto | ||
| 64 | #define jauto [[maybe_unused]] auto | ||
| 65 | |||
| 63 | namespace { | 66 | namespace { |
| 64 | 67 | ||
| 65 | class EmulationSession final { | 68 | class EmulationSession final { |
| @@ -99,8 +102,8 @@ public: | |||
| 99 | } | 102 | } |
| 100 | 103 | ||
| 101 | int InstallFileToNand(std::string filename) { | 104 | int InstallFileToNand(std::string filename) { |
| 102 | const auto copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest, | 105 | jconst copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest, |
| 103 | std::size_t block_size) { | 106 | std::size_t block_size) { |
| 104 | if (src == nullptr || dest == nullptr) { | 107 | if (src == nullptr || dest == nullptr) { |
| 105 | return false; | 108 | return false; |
| 106 | } | 109 | } |
| @@ -109,10 +112,10 @@ public: | |||
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | using namespace Common::Literals; | 114 | using namespace Common::Literals; |
| 112 | std::vector<u8> buffer(1_MiB); | 115 | [[maybe_unused]] std::vector<u8> buffer(1_MiB); |
| 113 | 116 | ||
| 114 | for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) { | 117 | for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) { |
| 115 | const auto read = src->Read(buffer.data(), buffer.size(), i); | 118 | jconst read = src->Read(buffer.data(), buffer.size(), i); |
| 116 | dest->Write(buffer.data(), read, i); | 119 | dest->Write(buffer.data(), read, i); |
| 117 | } | 120 | } |
| 118 | return true; | 121 | return true; |
| @@ -129,14 +132,14 @@ public: | |||
| 129 | m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); | 132 | m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); |
| 130 | m_system.GetFileSystemController().CreateFactories(*m_vfs); | 133 | m_system.GetFileSystemController().CreateFactories(*m_vfs); |
| 131 | 134 | ||
| 132 | std::shared_ptr<FileSys::NSP> nsp; | 135 | [[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp; |
| 133 | if (filename.ends_with("nsp")) { | 136 | if (filename.ends_with("nsp")) { |
| 134 | nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read)); | 137 | nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read)); |
| 135 | if (nsp->IsExtractedType()) { | 138 | if (nsp->IsExtractedType()) { |
| 136 | return InstallError; | 139 | return InstallError; |
| 137 | } | 140 | } |
| 138 | } else if (filename.ends_with("xci")) { | 141 | } else if (filename.ends_with("xci")) { |
| 139 | const auto xci = | 142 | jconst xci = |
| 140 | std::make_shared<FileSys::XCI>(m_vfs->OpenFile(filename, FileSys::Mode::Read)); | 143 | std::make_shared<FileSys::XCI>(m_vfs->OpenFile(filename, FileSys::Mode::Read)); |
| 141 | nsp = xci->GetSecurePartitionNSP(); | 144 | nsp = xci->GetSecurePartitionNSP(); |
| 142 | } else { | 145 | } else { |
| @@ -151,7 +154,7 @@ public: | |||
| 151 | return InstallError; | 154 | return InstallError; |
| 152 | } | 155 | } |
| 153 | 156 | ||
| 154 | const auto res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry( | 157 | jconst res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry( |
| 155 | *nsp, true, copy_func); | 158 | *nsp, true, copy_func); |
| 156 | 159 | ||
| 157 | switch (res) { | 160 | switch (res) { |
| @@ -234,7 +237,7 @@ public: | |||
| 234 | m_system.SetFilesystem(m_vfs); | 237 | m_system.SetFilesystem(m_vfs); |
| 235 | 238 | ||
| 236 | // Initialize system. | 239 | // Initialize system. |
| 237 | auto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>(); | 240 | jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>(); |
| 238 | m_software_keyboard = android_keyboard.get(); | 241 | m_software_keyboard = android_keyboard.get(); |
| 239 | m_system.SetShuttingDown(false); | 242 | m_system.SetShuttingDown(false); |
| 240 | m_system.ApplySettings(); | 243 | m_system.ApplySettings(); |
| @@ -332,7 +335,7 @@ public: | |||
| 332 | 335 | ||
| 333 | while (true) { | 336 | while (true) { |
| 334 | { | 337 | { |
| 335 | std::unique_lock lock(m_mutex); | 338 | [[maybe_unused]] std::unique_lock lock(m_mutex); |
| 336 | if (m_cv.wait_for(lock, std::chrono::milliseconds(800), | 339 | if (m_cv.wait_for(lock, std::chrono::milliseconds(800), |
| 337 | [&]() { return !m_is_running; })) { | 340 | [&]() { return !m_is_running; })) { |
| 338 | // Emulation halted. | 341 | // Emulation halted. |
| @@ -364,7 +367,7 @@ public: | |||
| 364 | } | 367 | } |
| 365 | 368 | ||
| 366 | bool IsHandheldOnly() { | 369 | bool IsHandheldOnly() { |
| 367 | const auto npad_style_set = m_system.HIDCore().GetSupportedStyleTag(); | 370 | jconst npad_style_set = m_system.HIDCore().GetSupportedStyleTag(); |
| 368 | 371 | ||
| 369 | if (npad_style_set.fullkey == 1) { | 372 | if (npad_style_set.fullkey == 1) { |
| 370 | return false; | 373 | return false; |
| @@ -377,17 +380,17 @@ public: | |||
| 377 | return !Settings::values.use_docked_mode.GetValue(); | 380 | return !Settings::values.use_docked_mode.GetValue(); |
| 378 | } | 381 | } |
| 379 | 382 | ||
| 380 | void SetDeviceType(int index, int type) { | 383 | void SetDeviceType([[maybe_unused]] int index, int type) { |
| 381 | auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); | 384 | jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); |
| 382 | controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type)); | 385 | controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type)); |
| 383 | } | 386 | } |
| 384 | 387 | ||
| 385 | void OnGamepadConnectEvent(int index) { | 388 | void OnGamepadConnectEvent([[maybe_unused]] int index) { |
| 386 | auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); | 389 | jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); |
| 387 | 390 | ||
| 388 | // Ensure that player1 is configured correctly and handheld disconnected | 391 | // Ensure that player1 is configured correctly and handheld disconnected |
| 389 | if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) { | 392 | if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) { |
| 390 | auto handheld = | 393 | jauto handheld = |
| 391 | m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | 394 | m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); |
| 392 | 395 | ||
| 393 | if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) { | 396 | if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) { |
| @@ -399,7 +402,8 @@ public: | |||
| 399 | 402 | ||
| 400 | // Ensure that handheld is configured correctly and player 1 disconnected | 403 | // Ensure that handheld is configured correctly and player 1 disconnected |
| 401 | if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) { | 404 | if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) { |
| 402 | auto player1 = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | 405 | jauto player1 = |
| 406 | m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||
| 403 | 407 | ||
| 404 | if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) { | 408 | if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) { |
| 405 | player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); | 409 | player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); |
| @@ -413,8 +417,8 @@ public: | |||
| 413 | } | 417 | } |
| 414 | } | 418 | } |
| 415 | 419 | ||
| 416 | void OnGamepadDisconnectEvent(int index) { | 420 | void OnGamepadDisconnectEvent([[maybe_unused]] int index) { |
| 417 | auto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); | 421 | jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); |
| 418 | controller->Disconnect(); | 422 | controller->Disconnect(); |
| 419 | } | 423 | } |
| 420 | 424 | ||
| @@ -430,7 +434,7 @@ private: | |||
| 430 | }; | 434 | }; |
| 431 | 435 | ||
| 432 | RomMetadata GetRomMetadata(const std::string& path) { | 436 | RomMetadata GetRomMetadata(const std::string& path) { |
| 433 | if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) { | 437 | if (jauto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) { |
| 434 | return search->second; | 438 | return search->second; |
| 435 | } | 439 | } |
| 436 | 440 | ||
| @@ -438,14 +442,14 @@ private: | |||
| 438 | } | 442 | } |
| 439 | 443 | ||
| 440 | RomMetadata CacheRomMetadata(const std::string& path) { | 444 | RomMetadata CacheRomMetadata(const std::string& path) { |
| 441 | const auto file = Core::GetGameFileFromPath(m_vfs, path); | 445 | jconst file = Core::GetGameFileFromPath(m_vfs, path); |
| 442 | auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0); | 446 | jauto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0); |
| 443 | 447 | ||
| 444 | RomMetadata entry; | 448 | RomMetadata entry; |
| 445 | loader->ReadTitle(entry.title); | 449 | loader->ReadTitle(entry.title); |
| 446 | loader->ReadIcon(entry.icon); | 450 | loader->ReadIcon(entry.icon); |
| 447 | if (loader->GetFileType() == Loader::FileType::NRO) { | 451 | if (loader->GetFileType() == Loader::FileType::NRO) { |
| 448 | auto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get()); | 452 | jauto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get()); |
| 449 | entry.isHomebrew = loader_nro->IsHomebrew(); | 453 | entry.isHomebrew = loader_nro->IsHomebrew(); |
| 450 | } else { | 454 | } else { |
| 451 | entry.isHomebrew = false; | 455 | entry.isHomebrew = false; |
| @@ -516,7 +520,7 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath) { | |||
| 516 | 520 | ||
| 517 | SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); }); | 521 | SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); }); |
| 518 | 522 | ||
| 519 | const auto result = EmulationSession::GetInstance().InitializeEmulation(filepath); | 523 | jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath); |
| 520 | if (result != Core::SystemResultStatus::Success) { | 524 | if (result != Core::SystemResultStatus::Success) { |
| 521 | return result; | 525 | return result; |
| 522 | } | 526 | } |
| @@ -528,24 +532,25 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath) { | |||
| 528 | 532 | ||
| 529 | extern "C" { | 533 | extern "C" { |
| 530 | 534 | ||
| 531 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceChanged(JNIEnv* env, jclass clazz, jobject surf) { | 535 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceChanged(JNIEnv* env, jobject instance, |
| 536 | [[maybe_unused]] jobject surf) { | ||
| 532 | EmulationSession::GetInstance().SetNativeWindow(ANativeWindow_fromSurface(env, surf)); | 537 | EmulationSession::GetInstance().SetNativeWindow(ANativeWindow_fromSurface(env, surf)); |
| 533 | EmulationSession::GetInstance().SurfaceChanged(); | 538 | EmulationSession::GetInstance().SurfaceChanged(); |
| 534 | } | 539 | } |
| 535 | 540 | ||
| 536 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceDestroyed(JNIEnv* env, jclass clazz) { | 541 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceDestroyed(JNIEnv* env, jobject instance) { |
| 537 | ANativeWindow_release(EmulationSession::GetInstance().NativeWindow()); | 542 | ANativeWindow_release(EmulationSession::GetInstance().NativeWindow()); |
| 538 | EmulationSession::GetInstance().SetNativeWindow(nullptr); | 543 | EmulationSession::GetInstance().SetNativeWindow(nullptr); |
| 539 | EmulationSession::GetInstance().SurfaceChanged(); | 544 | EmulationSession::GetInstance().SurfaceChanged(); |
| 540 | } | 545 | } |
| 541 | 546 | ||
| 542 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env, jclass clazz, | 547 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env, jobject instance, |
| 543 | jstring j_directory) { | 548 | [[maybe_unused]] jstring j_directory) { |
| 544 | Common::FS::SetAppDirectory(GetJString(env, j_directory)); | 549 | Common::FS::SetAppDirectory(GetJString(env, j_directory)); |
| 545 | } | 550 | } |
| 546 | 551 | ||
| 547 | int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jclass clazz, | 552 | int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject instance, |
| 548 | jstring j_file) { | 553 | [[maybe_unused]] jstring j_file) { |
| 549 | return EmulationSession::GetInstance().InstallFileToNand(GetJString(env, j_file)); | 554 | return EmulationSession::GetInstance().InstallFileToNand(GetJString(env, j_file)); |
| 550 | } | 555 | } |
| 551 | 556 | ||
| @@ -570,7 +575,7 @@ void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(JNIEnv* e | |||
| 570 | } | 575 | } |
| 571 | 576 | ||
| 572 | jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDriverLoading( | 577 | jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDriverLoading( |
| 573 | JNIEnv* env, [[maybe_unused]] jobject instance) { | 578 | JNIEnv* env, jobject instance) { |
| 574 | #ifdef ARCHITECTURE_arm64 | 579 | #ifdef ARCHITECTURE_arm64 |
| 575 | // If the KGSL device exists custom drivers can be loaded using adrenotools | 580 | // If the KGSL device exists custom drivers can be loaded using adrenotools |
| 576 | return SupportsCustomDriver(); | 581 | return SupportsCustomDriver(); |
| @@ -648,8 +653,8 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadDisconnectEvent(JNIEnv* | |||
| 648 | return static_cast<jboolean>(true); | 653 | return static_cast<jboolean>(true); |
| 649 | } | 654 | } |
| 650 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadButtonEvent(JNIEnv* env, jclass clazz, | 655 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadButtonEvent(JNIEnv* env, jclass clazz, |
| 651 | [[maybe_unused]] jint j_device, | 656 | jint j_device, jint j_button, |
| 652 | jint j_button, jint action) { | 657 | jint action) { |
| 653 | if (EmulationSession::GetInstance().IsRunning()) { | 658 | if (EmulationSession::GetInstance().IsRunning()) { |
| 654 | // Ensure gamepad is connected | 659 | // Ensure gamepad is connected |
| 655 | EmulationSession::GetInstance().OnGamepadConnectEvent(j_device); | 660 | EmulationSession::GetInstance().OnGamepadConnectEvent(j_device); |
| @@ -718,8 +723,8 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchReleased(JNIEnv* env, jclass c | |||
| 718 | } | 723 | } |
| 719 | 724 | ||
| 720 | jbyteArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getIcon(JNIEnv* env, jclass clazz, | 725 | jbyteArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getIcon(JNIEnv* env, jclass clazz, |
| 721 | [[maybe_unused]] jstring j_filename) { | 726 | jstring j_filename) { |
| 722 | auto icon_data = EmulationSession::GetInstance().GetRomIcon(GetJString(env, j_filename)); | 727 | jauto icon_data = EmulationSession::GetInstance().GetRomIcon(GetJString(env, j_filename)); |
| 723 | jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size())); | 728 | jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size())); |
| 724 | env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon), | 729 | env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon), |
| 725 | reinterpret_cast<jbyte*>(icon_data.data())); | 730 | reinterpret_cast<jbyte*>(icon_data.data())); |
| @@ -727,8 +732,8 @@ jbyteArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getIcon(JNIEnv* env, jclass cla | |||
| 727 | } | 732 | } |
| 728 | 733 | ||
| 729 | jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getTitle(JNIEnv* env, jclass clazz, | 734 | jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getTitle(JNIEnv* env, jclass clazz, |
| 730 | [[maybe_unused]] jstring j_filename) { | 735 | jstring j_filename) { |
| 731 | auto title = EmulationSession::GetInstance().GetRomTitle(GetJString(env, j_filename)); | 736 | jauto title = EmulationSession::GetInstance().GetRomTitle(GetJString(env, j_filename)); |
| 732 | return env->NewStringUTF(title.c_str()); | 737 | return env->NewStringUTF(title.c_str()); |
| 733 | } | 738 | } |
| 734 | 739 | ||
| @@ -743,22 +748,21 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGameId(JNIEnv* env, jclass claz | |||
| 743 | } | 748 | } |
| 744 | 749 | ||
| 745 | jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRegions(JNIEnv* env, jclass clazz, | 750 | jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRegions(JNIEnv* env, jclass clazz, |
| 746 | [[maybe_unused]] jstring j_filename) { | 751 | jstring j_filename) { |
| 747 | return env->NewStringUTF(""); | 752 | return env->NewStringUTF(""); |
| 748 | } | 753 | } |
| 749 | 754 | ||
| 750 | jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCompany(JNIEnv* env, jclass clazz, | 755 | jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCompany(JNIEnv* env, jclass clazz, |
| 751 | [[maybe_unused]] jstring j_filename) { | 756 | jstring j_filename) { |
| 752 | return env->NewStringUTF(""); | 757 | return env->NewStringUTF(""); |
| 753 | } | 758 | } |
| 754 | 759 | ||
| 755 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHomebrew(JNIEnv* env, jclass clazz, | 760 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHomebrew(JNIEnv* env, jclass clazz, |
| 756 | [[maybe_unused]] jstring j_filename) { | 761 | jstring j_filename) { |
| 757 | return EmulationSession::GetInstance().GetIsHomebrew(GetJString(env, j_filename)); | 762 | return EmulationSession::GetInstance().GetIsHomebrew(GetJString(env, j_filename)); |
| 758 | } | 763 | } |
| 759 | 764 | ||
| 760 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation | 765 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation(JNIEnv* env, jclass clazz) { |
| 761 | [[maybe_unused]] (JNIEnv* env, jclass clazz) { | ||
| 762 | // Create the default config.ini. | 766 | // Create the default config.ini. |
| 763 | Config{}; | 767 | Config{}; |
| 764 | // Initialize the emulated system. | 768 | // Initialize the emulated system. |
| @@ -770,8 +774,7 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass cl | |||
| 770 | } | 774 | } |
| 771 | 775 | ||
| 772 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z( | 776 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z( |
| 773 | JNIEnv* env, jclass clazz, [[maybe_unused]] jstring j_file, | 777 | JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate) {} |
| 774 | [[maybe_unused]] jstring j_savestate, [[maybe_unused]] jboolean j_delete_savestate) {} | ||
| 775 | 778 | ||
| 776 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadSettings(JNIEnv* env, jclass clazz) { | 779 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadSettings(JNIEnv* env, jclass clazz) { |
| 777 | Config{}; | 780 | Config{}; |
| @@ -816,7 +819,7 @@ jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jcl | |||
| 816 | jdoubleArray j_stats = env->NewDoubleArray(4); | 819 | jdoubleArray j_stats = env->NewDoubleArray(4); |
| 817 | 820 | ||
| 818 | if (EmulationSession::GetInstance().IsRunning()) { | 821 | if (EmulationSession::GetInstance().IsRunning()) { |
| 819 | const auto results = EmulationSession::GetInstance().PerfStats(); | 822 | jconst results = EmulationSession::GetInstance().PerfStats(); |
| 820 | 823 | ||
| 821 | // Converting the structure into an array makes it easier to pass it to the frontend | 824 | // Converting the structure into an array makes it easier to pass it to the frontend |
| 822 | double stats[4] = {results.system_fps, results.average_game_fps, results.frametime, | 825 | double stats[4] = {results.system_fps, results.average_game_fps, results.frametime, |