Compare commits
64 Commits
android-20
...
android-21
Author | SHA1 | Date | |
---|---|---|---|
28a23c4380 | |||
c768c19898 | |||
7273701bc2 | |||
3bf0492edb | |||
ce2eb6e8ee | |||
8b47465586 | |||
3065ab0fd8 | |||
a2407a2964 | |||
16b79df836 | |||
6a4b25699d | |||
bd8635e26a | |||
4349cdba07 | |||
f2fb761bac | |||
59aee2b461 | |||
4d206d849e | |||
744c0173d1 | |||
55482ab5dc | |||
e56b44dee6 | |||
f2012e5aff | |||
4526fdaf64 | |||
bc22b4e782 | |||
f70821ce0d | |||
a774ff935c | |||
431df5ae93 | |||
677c2c2cd2 | |||
ee540c712c | |||
d23c4393fd | |||
b24a111136 | |||
91636deaaf | |||
68cbf67f4c | |||
645961613f | |||
53b321c945 | |||
975deb7528 | |||
2c049ae06d | |||
54372fdff5 | |||
c60ab6bbf6 | |||
cc09c265e1 | |||
0f9288e38d | |||
06fb7f90da | |||
e04368ad7c | |||
3e2d3548f2 | |||
eb9036d75b | |||
01a2d978eb | |||
6e67b25af9 | |||
e91667ba75 | |||
d45561ace0 | |||
0fdd6e8934 | |||
35794f4f18 | |||
b8be8dff69 | |||
bc317a9807 | |||
97ca160b08 | |||
1a3fc3724a | |||
7b01454d5f | |||
f3749394ac | |||
807f421752 | |||
e4915fb7d2 | |||
a76f6a2775 | |||
ba518f6899 | |||
ad4622da2c | |||
3b1c2896d9 | |||
fc5d76e6e2 | |||
5f9a45ada9 | |||
a120f8ff4d | |||
96833cd809 |
@ -2,18 +2,20 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
find_path(SimpleIni_INCLUDE_DIR SimpleIni.h)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(SimpleIni
|
|
||||||
REQUIRED_VARS SimpleIni_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
|
find_package(SimpleIni QUIET CONFIG)
|
||||||
add_library(SimpleIni::SimpleIni INTERFACE IMPORTED)
|
if (SimpleIni_CONSIDERED_CONFIGS)
|
||||||
set_target_properties(SimpleIni::SimpleIni PROPERTIES
|
find_package_handle_standard_args(SimpleIni CONFIG_MODE)
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${SimpleIni_INCLUDE_DIR}"
|
else()
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
pkg_search_module(SIMPLEINI QUIET IMPORTED_TARGET simpleini)
|
||||||
|
find_package_handle_standard_args(SimpleIni
|
||||||
|
REQUIRED_VARS SIMPLEINI_INCLUDEDIR
|
||||||
|
VERSION_VAR SIMPLEINI_VERSION
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
mark_as_advanced(SimpleIni_INCLUDE_DIR)
|
if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
|
||||||
|
add_library(SimpleIni::SimpleIni ALIAS PkgConfig::SIMPLEINI)
|
||||||
|
endif()
|
||||||
|
11
README.md
11
README.md
@ -1,3 +1,14 @@
|
|||||||
|
| Pull Request | Commit | Title | Author | Merged? |
|
||||||
|
|----|----|----|----|----|
|
||||||
|
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e3171486d`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||||
|
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`2c33ba278`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||||
|
| [12802](https://github.com/yuzu-emu/yuzu-android//pull/12802) | [`c5e88c654`](https://github.com/yuzu-emu/yuzu-android//pull/12802/files) | service: mii: Migrate service to new interface | [german77](https://github.com/german77/) | Yes |
|
||||||
|
|
||||||
|
|
||||||
|
End of merge log. You can find the original README.md below the break.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
3
externals/CMakeLists.txt
vendored
3
externals/CMakeLists.txt
vendored
@ -178,6 +178,9 @@ if (NOT TARGET stb::headers)
|
|||||||
add_library(stb::headers ALIAS stb)
|
add_library(stb::headers ALIAS stb)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_library(tz tz/tz/tz.cpp)
|
||||||
|
target_include_directories(tz PUBLIC ./tz)
|
||||||
|
|
||||||
add_library(bc_decoder bc_decoder/bc_decoder.cpp)
|
add_library(bc_decoder bc_decoder/bc_decoder.cpp)
|
||||||
target_include_directories(bc_decoder PUBLIC ./bc_decoder)
|
target_include_directories(bc_decoder PUBLIC ./bc_decoder)
|
||||||
|
|
||||||
|
2
externals/nx_tzdb/CMakeLists.txt
vendored
2
externals/nx_tzdb/CMakeLists.txt
vendored
@ -32,7 +32,7 @@ set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip")
|
|||||||
|
|
||||||
set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb")
|
set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb")
|
||||||
|
|
||||||
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE})
|
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR})
|
||||||
set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
|
set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
|
||||||
|
|
||||||
message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")
|
message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")
|
||||||
|
4
externals/nx_tzdb/NxTzdbCreateHeader.cmake
vendored
4
externals/nx_tzdb/NxTzdbCreateHeader.cmake
vendored
@ -11,6 +11,10 @@ execute_process(
|
|||||||
WORKING_DIRECTORY ${ZONE_PATH}
|
WORKING_DIRECTORY ${ZONE_PATH}
|
||||||
OUTPUT_VARIABLE FILE_LIST)
|
OUTPUT_VARIABLE FILE_LIST)
|
||||||
|
|
||||||
|
if (NOT FILE_LIST)
|
||||||
|
message(FATAL_ERROR "No timezone files found in directory ${ZONE_PATH}, did the download fail?")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(DIRECTORY_NAME ${HEADER_NAME})
|
set(DIRECTORY_NAME ${HEADER_NAME})
|
||||||
|
|
||||||
set(FILE_DATA "")
|
set(FILE_DATA "")
|
||||||
|
1636
externals/tz/tz/tz.cpp
vendored
Normal file
1636
externals/tz/tz/tz.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
81
externals/tz/tz/tz.h
vendored
Normal file
81
externals/tz/tz/tz.h
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: 1996 Arthur David Olson
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
#include <span>
|
||||||
|
#include <array>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
namespace Tz {
|
||||||
|
using u8 = uint8_t;
|
||||||
|
using s8 = int8_t;
|
||||||
|
using u16 = uint16_t;
|
||||||
|
using s16 = int16_t;
|
||||||
|
using u32 = uint32_t;
|
||||||
|
using s32 = int32_t;
|
||||||
|
using u64 = uint64_t;
|
||||||
|
using s64 = int64_t;
|
||||||
|
|
||||||
|
constexpr size_t TZ_MAX_TIMES = 1000;
|
||||||
|
constexpr size_t TZ_MAX_TYPES = 128;
|
||||||
|
constexpr size_t TZ_MAX_CHARS = 50;
|
||||||
|
constexpr size_t MY_TZNAME_MAX = 255;
|
||||||
|
constexpr size_t TZNAME_MAXIMUM = 255;
|
||||||
|
constexpr size_t TZ_MAX_LEAPS = 50;
|
||||||
|
constexpr s64 TIME_T_MAX = std::numeric_limits<s64>::max();
|
||||||
|
constexpr s64 TIME_T_MIN = std::numeric_limits<s64>::min();
|
||||||
|
constexpr size_t CHARS_EXTRA = 3;
|
||||||
|
constexpr size_t MAX_ZONE_CHARS = std::max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof("UTC"));
|
||||||
|
constexpr size_t MAX_TZNAME_CHARS = 2 * (MY_TZNAME_MAX + 1);
|
||||||
|
|
||||||
|
struct ttinfo {
|
||||||
|
s32 tt_utoff;
|
||||||
|
bool tt_isdst;
|
||||||
|
s32 tt_desigidx;
|
||||||
|
bool tt_ttisstd;
|
||||||
|
bool tt_ttisut;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ttinfo) == 0x10, "ttinfo has the wrong size!");
|
||||||
|
|
||||||
|
struct Rule {
|
||||||
|
s32 timecnt;
|
||||||
|
s32 typecnt;
|
||||||
|
s32 charcnt;
|
||||||
|
bool goback;
|
||||||
|
bool goahead;
|
||||||
|
std::array <u8, 0x2> padding0;
|
||||||
|
std::array<s64, TZ_MAX_TIMES> ats;
|
||||||
|
std::array<u8, TZ_MAX_TIMES> types;
|
||||||
|
std::array<ttinfo, TZ_MAX_TYPES> ttis;
|
||||||
|
std::array<char, std::max(MAX_ZONE_CHARS, MAX_TZNAME_CHARS)> chars;
|
||||||
|
s32 defaulttype;
|
||||||
|
std::array <u8, 0x12C4> padding1;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Rule) == 0x4000, "Rule has the wrong size!");
|
||||||
|
|
||||||
|
struct CalendarTimeInternal {
|
||||||
|
s32 tm_sec;
|
||||||
|
s32 tm_min;
|
||||||
|
s32 tm_hour;
|
||||||
|
s32 tm_mday;
|
||||||
|
s32 tm_mon;
|
||||||
|
s32 tm_year;
|
||||||
|
s32 tm_wday;
|
||||||
|
s32 tm_yday;
|
||||||
|
s32 tm_isdst;
|
||||||
|
std::array<char, 16> tm_zone;
|
||||||
|
s32 tm_utoff;
|
||||||
|
s32 time_index;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CalendarTimeInternal) == 0x3C, "CalendarTimeInternal has the wrong size!");
|
||||||
|
|
||||||
|
s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary);
|
||||||
|
|
||||||
|
bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep);
|
||||||
|
u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp);
|
||||||
|
|
||||||
|
} // namespace Tz
|
@ -303,6 +303,11 @@ object NativeLibrary {
|
|||||||
*/
|
*/
|
||||||
external fun getCpuBackend(): String
|
external fun getCpuBackend(): String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current GPU Driver.
|
||||||
|
*/
|
||||||
|
external fun getGpuDriver(): String
|
||||||
|
|
||||||
external fun applySettings()
|
external fun applySettings()
|
||||||
|
|
||||||
external fun logSettings()
|
external fun logSettings()
|
||||||
@ -614,6 +619,11 @@ object NativeLibrary {
|
|||||||
*/
|
*/
|
||||||
external fun clearFilesystemProvider()
|
external fun clearFilesystemProvider()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if all necessary keys are present for decryption
|
||||||
|
*/
|
||||||
|
external fun areKeysPresent(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Button type for use in onTouchEvent
|
* Button type for use in onTouchEvent
|
||||||
*/
|
*/
|
||||||
|
@ -193,6 +193,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
|||||||
return super.dispatchKeyEvent(event)
|
return super.dispatchKeyEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emulationViewModel.drawerOpen.value) {
|
||||||
|
return super.dispatchKeyEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
return InputHandler.dispatchKeyEvent(event)
|
return InputHandler.dispatchKeyEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +207,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
|||||||
return super.dispatchGenericMotionEvent(event)
|
return super.dispatchGenericMotionEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emulationViewModel.drawerOpen.value) {
|
||||||
|
return super.dispatchGenericMotionEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
// Don't attempt to do anything if we are disconnecting a device.
|
// Don't attempt to do anything if we are disconnecting a device.
|
||||||
if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
|
if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
|
||||||
return true
|
return true
|
||||||
|
@ -14,15 +14,20 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
* Generic adapter that implements an [AsyncDifferConfig] and covers some of the basic boilerplate
|
* Generic adapter that implements an [AsyncDifferConfig] and covers some of the basic boilerplate
|
||||||
* code used in every [RecyclerView].
|
* code used in every [RecyclerView].
|
||||||
* Type assigned to [Model] must inherit from [Object] in order to be compared properly.
|
* Type assigned to [Model] must inherit from [Object] in order to be compared properly.
|
||||||
|
* @param exact Decides whether each item will be compared by reference or by their contents
|
||||||
*/
|
*/
|
||||||
abstract class AbstractDiffAdapter<Model : Any, Holder : AbstractViewHolder<Model>> :
|
abstract class AbstractDiffAdapter<Model : Any, Holder : AbstractViewHolder<Model>>(
|
||||||
ListAdapter<Model, Holder>(AsyncDifferConfig.Builder(DiffCallback<Model>()).build()) {
|
exact: Boolean = true
|
||||||
|
) : ListAdapter<Model, Holder>(AsyncDifferConfig.Builder(DiffCallback<Model>(exact)).build()) {
|
||||||
override fun onBindViewHolder(holder: Holder, position: Int) =
|
override fun onBindViewHolder(holder: Holder, position: Int) =
|
||||||
holder.bind(currentList[position])
|
holder.bind(currentList[position])
|
||||||
|
|
||||||
private class DiffCallback<Model> : DiffUtil.ItemCallback<Model>() {
|
private class DiffCallback<Model>(val exact: Boolean) : DiffUtil.ItemCallback<Model>() {
|
||||||
override fun areItemsTheSame(oldItem: Model & Any, newItem: Model & Any): Boolean {
|
override fun areItemsTheSame(oldItem: Model & Any, newItem: Model & Any): Boolean {
|
||||||
return oldItem === newItem
|
if (exact) {
|
||||||
|
return oldItem === newItem
|
||||||
|
}
|
||||||
|
return oldItem == newItem
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DiffUtilEquals")
|
@SuppressLint("DiffUtilEquals")
|
||||||
|
@ -30,7 +30,7 @@ import org.yuzu.yuzu_emu.utils.GameIconUtils
|
|||||||
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
|
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
|
||||||
|
|
||||||
class GameAdapter(private val activity: AppCompatActivity) :
|
class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>() {
|
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameViewHolder {
|
||||||
CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
.also { return GameViewHolder(it) }
|
.also { return GameViewHolder(it) }
|
||||||
|
@ -77,7 +77,7 @@ class AboutFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.textVersionName.text = BuildConfig.VERSION_NAME
|
binding.textVersionName.text = BuildConfig.VERSION_NAME
|
||||||
binding.textVersionName.setOnClickListener {
|
binding.buttonVersionName.setOnClickListener {
|
||||||
val clipBoard =
|
val clipBoard =
|
||||||
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
val clip = ClipData.newPlainText(getString(R.string.build), BuildConfig.GIT_HASH)
|
val clip = ClipData.newPlainText(getString(R.string.build), BuildConfig.GIT_HASH)
|
||||||
|
@ -141,7 +141,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
|
|
||||||
// So this fragment doesn't restart on configuration changes; i.e. rotation.
|
// So this fragment doesn't restart on configuration changes; i.e. rotation.
|
||||||
retainInstance = true
|
retainInstance = true
|
||||||
emulationState = EmulationState(game.path)
|
emulationState = EmulationState(game.path) {
|
||||||
|
return@EmulationState driverViewModel.isInteractionAllowed.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,10 +185,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
|
|
||||||
override fun onDrawerOpened(drawerView: View) {
|
override fun onDrawerOpened(drawerView: View) {
|
||||||
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
|
binding.inGameMenu.requestFocus()
|
||||||
|
emulationViewModel.setDrawerOpen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDrawerClosed(drawerView: View) {
|
override fun onDrawerClosed(drawerView: View) {
|
||||||
binding.drawerLayout.setDrawerLockMode(IntSetting.LOCK_DRAWER.getInt())
|
binding.drawerLayout.setDrawerLockMode(IntSetting.LOCK_DRAWER.getInt())
|
||||||
|
emulationViewModel.setDrawerOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDrawerStateChanged(newState: Int) {
|
override fun onDrawerStateChanged(newState: Int) {
|
||||||
@ -238,6 +243,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
requireContext().theme
|
requireContext().theme
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
binding.inGameMenu.requestFocus()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +252,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
null,
|
null,
|
||||||
Settings.MenuTag.SECTION_ROOT
|
Settings.MenuTag.SECTION_ROOT
|
||||||
)
|
)
|
||||||
|
binding.inGameMenu.requestFocus()
|
||||||
binding.root.findNavController().navigate(action)
|
binding.root.findNavController().navigate(action)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -255,6 +262,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
args.game,
|
args.game,
|
||||||
Settings.MenuTag.SECTION_ROOT
|
Settings.MenuTag.SECTION_ROOT
|
||||||
)
|
)
|
||||||
|
binding.inGameMenu.requestFocus()
|
||||||
binding.root.findNavController().navigate(action)
|
binding.root.findNavController().navigate(action)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -286,15 +294,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binding.inGameMenu.requestFocus()
|
||||||
NativeConfig.saveGlobalConfig()
|
NativeConfig.saveGlobalConfig()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_exit -> {
|
R.id.menu_exit -> {
|
||||||
emulationState.stop()
|
emulationState.stop()
|
||||||
|
NativeConfig.reloadGlobalConfig()
|
||||||
emulationViewModel.setIsEmulationStopping(true)
|
emulationViewModel.setIsEmulationStopping(true)
|
||||||
binding.drawerLayout.close()
|
binding.drawerLayout.close()
|
||||||
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
binding.inGameMenu.requestFocus()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,12 +321,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
if (!NativeLibrary.isRunning()) {
|
if (!NativeLibrary.isRunning()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
emulationViewModel.setDrawerOpen(!binding.drawerLayout.isOpen)
|
||||||
if (binding.drawerLayout.isOpen) {
|
|
||||||
binding.drawerLayout.close()
|
|
||||||
} else {
|
|
||||||
binding.drawerLayout.open()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -370,6 +375,15 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
|
driverViewModel.isInteractionAllowed.collect {
|
||||||
|
if (it) {
|
||||||
|
startEmulation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
launch {
|
launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||||
emulationViewModel.emulationStarted.collectLatest {
|
emulationViewModel.emulationStarted.collectLatest {
|
||||||
@ -399,10 +413,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
launch {
|
launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||||
driverViewModel.isInteractionAllowed.collect {
|
emulationViewModel.drawerOpen.collect {
|
||||||
if (it) {
|
if (it) {
|
||||||
onEmulationStart()
|
binding.drawerLayout.open()
|
||||||
|
binding.inGameMenu.requestFocus()
|
||||||
|
} else {
|
||||||
|
binding.drawerLayout.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,7 +427,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onEmulationStart() {
|
private fun startEmulation() {
|
||||||
if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
|
if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
|
||||||
if (!DirectoryInitialization.areDirectoriesReady) {
|
if (!DirectoryInitialization.areDirectoriesReady) {
|
||||||
DirectoryInitialization.start()
|
DirectoryInitialization.start()
|
||||||
@ -485,12 +502,15 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
val FRAMETIME = 2
|
val FRAMETIME = 2
|
||||||
val SPEED = 3
|
val SPEED = 3
|
||||||
perfStatsUpdater = {
|
perfStatsUpdater = {
|
||||||
if (emulationViewModel.emulationStarted.value) {
|
if (emulationViewModel.emulationStarted.value &&
|
||||||
|
!emulationViewModel.isEmulationStopping.value
|
||||||
|
) {
|
||||||
val perfStats = NativeLibrary.getPerfStats()
|
val perfStats = NativeLibrary.getPerfStats()
|
||||||
val cpuBackend = NativeLibrary.getCpuBackend()
|
val cpuBackend = NativeLibrary.getCpuBackend()
|
||||||
|
val gpuDriver = NativeLibrary.getGpuDriver()
|
||||||
if (_binding != null) {
|
if (_binding != null) {
|
||||||
binding.showFpsText.text =
|
binding.showFpsText.text =
|
||||||
String.format("FPS: %.1f\n%s", perfStats[FPS], cpuBackend)
|
String.format("FPS: %.1f\n%s/%s", perfStats[FPS], cpuBackend, gpuDriver)
|
||||||
}
|
}
|
||||||
perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 800)
|
perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 800)
|
||||||
}
|
}
|
||||||
@ -807,7 +827,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EmulationState(private val gamePath: String) {
|
private class EmulationState(
|
||||||
|
private val gamePath: String,
|
||||||
|
private val emulationCanStart: () -> Boolean
|
||||||
|
) {
|
||||||
private var state: State
|
private var state: State
|
||||||
private var surface: Surface? = null
|
private var surface: Surface? = null
|
||||||
|
|
||||||
@ -901,6 +924,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
State.PAUSED -> Log.warning(
|
State.PAUSED -> Log.warning(
|
||||||
"[EmulationFragment] Surface cleared while emulation paused."
|
"[EmulationFragment] Surface cleared while emulation paused."
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> Log.warning(
|
else -> Log.warning(
|
||||||
"[EmulationFragment] Surface cleared while emulation stopped."
|
"[EmulationFragment] Surface cleared while emulation stopped."
|
||||||
)
|
)
|
||||||
@ -910,6 +934,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
|
|
||||||
private fun runWithValidSurface() {
|
private fun runWithValidSurface() {
|
||||||
NativeLibrary.surfaceChanged(surface)
|
NativeLibrary.surfaceChanged(surface)
|
||||||
|
if (!emulationCanStart.invoke()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
when (state) {
|
when (state) {
|
||||||
State.STOPPED -> {
|
State.STOPPED -> {
|
||||||
val emulationThread = Thread({
|
val emulationThread = Thread({
|
||||||
|
@ -153,7 +153,13 @@ class HomeSettingsFragment : Fragment() {
|
|||||||
cancellable = true
|
cancellable = true
|
||||||
) { progressCallback, _ ->
|
) { progressCallback, _ ->
|
||||||
val result = NativeLibrary.verifyInstalledContents(progressCallback)
|
val result = NativeLibrary.verifyInstalledContents(progressCallback)
|
||||||
return@newInstance if (result.isEmpty()) {
|
return@newInstance if (progressCallback.invoke(100, 100)) {
|
||||||
|
// Invoke the progress callback to check if the process was cancelled
|
||||||
|
MessageDialogFragment.newInstance(
|
||||||
|
titleId = R.string.verify_no_result,
|
||||||
|
descriptionId = R.string.verify_no_result_description
|
||||||
|
)
|
||||||
|
} else if (result.isEmpty()) {
|
||||||
MessageDialogFragment.newInstance(
|
MessageDialogFragment.newInstance(
|
||||||
titleId = R.string.verify_success,
|
titleId = R.string.verify_success,
|
||||||
descriptionId = R.string.operation_completed_successfully
|
descriptionId = R.string.operation_completed_successfully
|
||||||
|
@ -26,9 +26,15 @@ class MessageDialogFragment : DialogFragment() {
|
|||||||
val descriptionId = requireArguments().getInt(DESCRIPTION_ID)
|
val descriptionId = requireArguments().getInt(DESCRIPTION_ID)
|
||||||
val descriptionString = requireArguments().getString(DESCRIPTION_STRING)!!
|
val descriptionString = requireArguments().getString(DESCRIPTION_STRING)!!
|
||||||
val helpLinkId = requireArguments().getInt(HELP_LINK)
|
val helpLinkId = requireArguments().getInt(HELP_LINK)
|
||||||
|
val dismissible = requireArguments().getBoolean(DISMISSIBLE)
|
||||||
|
val clearPositiveAction = requireArguments().getBoolean(CLEAR_POSITIVE_ACTION)
|
||||||
|
|
||||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
val builder = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
|
||||||
|
if (clearPositiveAction) {
|
||||||
|
messageDialogViewModel.positiveAction = null
|
||||||
|
}
|
||||||
|
|
||||||
if (messageDialogViewModel.positiveAction == null) {
|
if (messageDialogViewModel.positiveAction == null) {
|
||||||
builder.setPositiveButton(R.string.close, null)
|
builder.setPositiveButton(R.string.close, null)
|
||||||
} else {
|
} else {
|
||||||
@ -51,6 +57,8 @@ class MessageDialogFragment : DialogFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isCancelable = dismissible
|
||||||
|
|
||||||
return builder.show()
|
return builder.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +75,8 @@ class MessageDialogFragment : DialogFragment() {
|
|||||||
private const val DESCRIPTION_ID = "DescriptionId"
|
private const val DESCRIPTION_ID = "DescriptionId"
|
||||||
private const val DESCRIPTION_STRING = "DescriptionString"
|
private const val DESCRIPTION_STRING = "DescriptionString"
|
||||||
private const val HELP_LINK = "Link"
|
private const val HELP_LINK = "Link"
|
||||||
|
private const val DISMISSIBLE = "Dismissible"
|
||||||
|
private const val CLEAR_POSITIVE_ACTION = "ClearPositiveAction"
|
||||||
|
|
||||||
fun newInstance(
|
fun newInstance(
|
||||||
activity: FragmentActivity? = null,
|
activity: FragmentActivity? = null,
|
||||||
@ -75,22 +85,28 @@ class MessageDialogFragment : DialogFragment() {
|
|||||||
descriptionId: Int = 0,
|
descriptionId: Int = 0,
|
||||||
descriptionString: String = "",
|
descriptionString: String = "",
|
||||||
helpLinkId: Int = 0,
|
helpLinkId: Int = 0,
|
||||||
|
dismissible: Boolean = true,
|
||||||
positiveAction: (() -> Unit)? = null
|
positiveAction: (() -> Unit)? = null
|
||||||
): MessageDialogFragment {
|
): MessageDialogFragment {
|
||||||
val dialog = MessageDialogFragment()
|
var clearPositiveAction = false
|
||||||
val bundle = Bundle()
|
|
||||||
bundle.apply {
|
|
||||||
putInt(TITLE_ID, titleId)
|
|
||||||
putString(TITLE_STRING, titleString)
|
|
||||||
putInt(DESCRIPTION_ID, descriptionId)
|
|
||||||
putString(DESCRIPTION_STRING, descriptionString)
|
|
||||||
putInt(HELP_LINK, helpLinkId)
|
|
||||||
}
|
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
ViewModelProvider(activity)[MessageDialogViewModel::class.java].apply {
|
ViewModelProvider(activity)[MessageDialogViewModel::class.java].apply {
|
||||||
clear()
|
clear()
|
||||||
this.positiveAction = positiveAction
|
this.positiveAction = positiveAction
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
clearPositiveAction = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val dialog = MessageDialogFragment()
|
||||||
|
val bundle = Bundle().apply {
|
||||||
|
putInt(TITLE_ID, titleId)
|
||||||
|
putString(TITLE_STRING, titleString)
|
||||||
|
putInt(DESCRIPTION_ID, descriptionId)
|
||||||
|
putString(DESCRIPTION_STRING, descriptionString)
|
||||||
|
putInt(HELP_LINK, helpLinkId)
|
||||||
|
putBoolean(DISMISSIBLE, dismissible)
|
||||||
|
putBoolean(CLEAR_POSITIVE_ACTION, clearPositiveAction)
|
||||||
}
|
}
|
||||||
dialog.arguments = bundle
|
dialog.arguments = bundle
|
||||||
return dialog
|
return dialog
|
||||||
|
@ -31,6 +31,7 @@ import androidx.preference.PreferenceManager
|
|||||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||||
import com.google.android.material.transition.MaterialFadeThrough
|
import com.google.android.material.transition.MaterialFadeThrough
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
@ -162,7 +163,7 @@ class SetupFragment : Fragment() {
|
|||||||
R.string.install_prod_keys_warning_help,
|
R.string.install_prod_keys_warning_help,
|
||||||
{
|
{
|
||||||
val file = File(DirectoryInitialization.userDirectory + "/keys/prod.keys")
|
val file = File(DirectoryInitialization.userDirectory + "/keys/prod.keys")
|
||||||
if (file.exists()) {
|
if (file.exists() && NativeLibrary.areKeysPresent()) {
|
||||||
StepState.COMPLETE
|
StepState.COMPLETE
|
||||||
} else {
|
} else {
|
||||||
StepState.INCOMPLETE
|
StepState.INCOMPLETE
|
||||||
@ -347,7 +348,8 @@ class SetupFragment : Fragment() {
|
|||||||
val getProdKey =
|
val getProdKey =
|
||||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
if (mainActivity.processKey(result)) {
|
mainActivity.processKey(result)
|
||||||
|
if (NativeLibrary.areKeysPresent()) {
|
||||||
keyCallback.onStepCompleted()
|
keyCallback.onStepCompleted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,7 @@ class DriverViewModel : ViewModel() {
|
|||||||
val selectedDriverFile = File(StringSetting.DRIVER_PATH.getString())
|
val selectedDriverFile = File(StringSetting.DRIVER_PATH.getString())
|
||||||
val selectedDriverMetadata = GpuDriverHelper.customDriverSettingData
|
val selectedDriverMetadata = GpuDriverHelper.customDriverSettingData
|
||||||
if (GpuDriverHelper.installedCustomDriverData == selectedDriverMetadata) {
|
if (GpuDriverHelper.installedCustomDriverData == selectedDriverMetadata) {
|
||||||
|
setDriverReady()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ package org.yuzu.yuzu_emu.model
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
class EmulationViewModel : ViewModel() {
|
class EmulationViewModel : ViewModel() {
|
||||||
val emulationStarted: StateFlow<Boolean> get() = _emulationStarted
|
val emulationStarted: StateFlow<Boolean> get() = _emulationStarted
|
||||||
@ -23,6 +24,9 @@ class EmulationViewModel : ViewModel() {
|
|||||||
val shaderMessage: StateFlow<String> get() = _shaderMessage
|
val shaderMessage: StateFlow<String> get() = _shaderMessage
|
||||||
private val _shaderMessage = MutableStateFlow("")
|
private val _shaderMessage = MutableStateFlow("")
|
||||||
|
|
||||||
|
private val _drawerOpen = MutableStateFlow(false)
|
||||||
|
val drawerOpen = _drawerOpen.asStateFlow()
|
||||||
|
|
||||||
fun setEmulationStarted(started: Boolean) {
|
fun setEmulationStarted(started: Boolean) {
|
||||||
_emulationStarted.value = started
|
_emulationStarted.value = started
|
||||||
}
|
}
|
||||||
@ -49,6 +53,10 @@ class EmulationViewModel : ViewModel() {
|
|||||||
setTotalShaders(max)
|
setTotalShaders(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setDrawerOpen(value: Boolean) {
|
||||||
|
_drawerOpen.value = value
|
||||||
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
setEmulationStarted(false)
|
setEmulationStarted(false)
|
||||||
setIsEmulationStopping(false)
|
setIsEmulationStopping(false)
|
||||||
|
@ -70,11 +70,19 @@ class Game(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is Game) {
|
if (this === other) return true
|
||||||
return false
|
if (javaClass != other?.javaClass) return false
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode() == other.hashCode()
|
other as Game
|
||||||
|
|
||||||
|
if (title != other.title) return false
|
||||||
|
if (path != other.path) return false
|
||||||
|
if (programId != other.programId) return false
|
||||||
|
if (developer != other.developer) return false
|
||||||
|
if (version != other.version) return false
|
||||||
|
if (isHomebrew != other.isHomebrew) return false
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
|
@ -31,6 +31,9 @@ class HomeViewModel : ViewModel() {
|
|||||||
private val _reloadPropertiesList = MutableStateFlow(false)
|
private val _reloadPropertiesList = MutableStateFlow(false)
|
||||||
val reloadPropertiesList get() = _reloadPropertiesList.asStateFlow()
|
val reloadPropertiesList get() = _reloadPropertiesList.asStateFlow()
|
||||||
|
|
||||||
|
private val _checkKeys = MutableStateFlow(false)
|
||||||
|
val checkKeys = _checkKeys.asStateFlow()
|
||||||
|
|
||||||
var navigatedToSetup = false
|
var navigatedToSetup = false
|
||||||
|
|
||||||
fun setNavigationVisibility(visible: Boolean, animated: Boolean) {
|
fun setNavigationVisibility(visible: Boolean, animated: Boolean) {
|
||||||
@ -66,4 +69,8 @@ class HomeViewModel : ViewModel() {
|
|||||||
fun reloadPropertiesList(reload: Boolean) {
|
fun reloadPropertiesList(reload: Boolean) {
|
||||||
_reloadPropertiesList.value = reload
|
_reloadPropertiesList.value = reload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCheckKeys(value: Boolean) {
|
||||||
|
_checkKeys.value = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
|
|
||||||
override var themeId: Int = 0
|
override var themeId: Int = 0
|
||||||
|
|
||||||
|
private val CHECKED_DECRYPTION = "CheckedDecryption"
|
||||||
|
private var checkedDecryption = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val splashScreen = installSplashScreen()
|
val splashScreen = installSplashScreen()
|
||||||
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
||||||
@ -75,6 +78,18 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
checkedDecryption = savedInstanceState.getBoolean(CHECKED_DECRYPTION)
|
||||||
|
}
|
||||||
|
if (!checkedDecryption) {
|
||||||
|
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||||
|
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||||
|
if (!firstTimeSetup) {
|
||||||
|
checkKeys()
|
||||||
|
}
|
||||||
|
checkedDecryption = true
|
||||||
|
}
|
||||||
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
|
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
|
||||||
|
|
||||||
@ -150,6 +165,16 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||||
|
homeViewModel.checkKeys.collect {
|
||||||
|
if (it) {
|
||||||
|
checkKeys()
|
||||||
|
homeViewModel.setCheckKeys(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dismiss previous notifications (should not happen unless a crash occurred)
|
// Dismiss previous notifications (should not happen unless a crash occurred)
|
||||||
@ -158,6 +183,21 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
setInsets()
|
setInsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkKeys() {
|
||||||
|
if (!NativeLibrary.areKeysPresent()) {
|
||||||
|
MessageDialogFragment.newInstance(
|
||||||
|
titleId = R.string.keys_missing,
|
||||||
|
descriptionId = R.string.keys_missing_description,
|
||||||
|
helpLinkId = R.string.keys_missing_help
|
||||||
|
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
outState.putBoolean(CHECKED_DECRYPTION, checkedDecryption)
|
||||||
|
}
|
||||||
|
|
||||||
fun finishSetup(navController: NavController) {
|
fun finishSetup(navController: NavController) {
|
||||||
navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment)
|
navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment)
|
||||||
(binding.navigationView as NavigationBarView).setupWithNavController(navController)
|
(binding.navigationView as NavigationBarView).setupWithNavController(navController)
|
||||||
@ -349,6 +389,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
R.string.install_keys_success,
|
R.string.install_keys_success,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
|
homeViewModel.setCheckKeys(true)
|
||||||
gamesViewModel.reloadGames(true)
|
gamesViewModel.reloadGames(true)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -399,6 +440,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
firmwarePath.deleteRecursively()
|
firmwarePath.deleteRecursively()
|
||||||
cacheFirmwareDir.copyRecursively(firmwarePath, true)
|
cacheFirmwareDir.copyRecursively(firmwarePath, true)
|
||||||
NativeLibrary.initializeSystem(true)
|
NativeLibrary.initializeSystem(true)
|
||||||
|
homeViewModel.setCheckKeys(true)
|
||||||
getString(R.string.save_file_imported_success)
|
getString(R.string.save_file_imported_success)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -82,7 +82,7 @@ AndroidKeyboard::ResultData AndroidKeyboard::ResultData::CreateFromFrontend(jobj
|
|||||||
const jstring string = reinterpret_cast<jstring>(env->GetObjectField(
|
const jstring string = reinterpret_cast<jstring>(env->GetObjectField(
|
||||||
object, env->GetFieldID(s_keyboard_data_class, "text", "Ljava/lang/String;")));
|
object, env->GetFieldID(s_keyboard_data_class, "text", "Ljava/lang/String;")));
|
||||||
return ResultData{GetJString(env, string),
|
return ResultData{GetJString(env, string),
|
||||||
static_cast<Service::AM::Applets::SwkbdResult>(env->GetIntField(
|
static_cast<Service::AM::Frontend::SwkbdResult>(env->GetIntField(
|
||||||
object, env->GetFieldID(s_keyboard_data_class, "result", "I")))};
|
object, env->GetFieldID(s_keyboard_data_class, "result", "I")))};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ void AndroidKeyboard::ShowNormalKeyboard() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AndroidKeyboard::ShowTextCheckDialog(
|
void AndroidKeyboard::ShowTextCheckDialog(
|
||||||
Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
Service::AM::Frontend::SwkbdTextCheckResult text_check_result,
|
||||||
std::u16string text_check_message) const {
|
std::u16string text_check_message) const {
|
||||||
LOG_WARNING(Frontend, "(STUBBED) called, backend requested to show the text check dialog.");
|
LOG_WARNING(Frontend, "(STUBBED) called, backend requested to show the text check dialog.");
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ void AndroidKeyboard::InlineTextChanged(
|
|||||||
"\ncursor_position={}",
|
"\ncursor_position={}",
|
||||||
Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
|
Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
|
||||||
|
|
||||||
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
|
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString,
|
||||||
text_parameters.input_text, text_parameters.cursor_position);
|
text_parameters.input_text, text_parameters.cursor_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ void AndroidKeyboard::SubmitInlineKeyboardText(std::u16string submitted_text) {
|
|||||||
|
|
||||||
m_current_text += submitted_text;
|
m_current_text += submitted_text;
|
||||||
|
|
||||||
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString, m_current_text,
|
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
|
||||||
m_current_text.size());
|
m_current_text.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,12 +236,12 @@ void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
|
|||||||
case KEYCODE_BACK:
|
case KEYCODE_BACK:
|
||||||
case KEYCODE_ENTER:
|
case KEYCODE_ENTER:
|
||||||
m_is_inline_active = false;
|
m_is_inline_active = false;
|
||||||
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::DecidedEnter, m_current_text,
|
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::DecidedEnter, m_current_text,
|
||||||
static_cast<s32>(m_current_text.size()));
|
static_cast<s32>(m_current_text.size()));
|
||||||
break;
|
break;
|
||||||
case KEYCODE_DEL:
|
case KEYCODE_DEL:
|
||||||
m_current_text.pop_back();
|
m_current_text.pop_back();
|
||||||
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString, m_current_text,
|
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
|
||||||
m_current_text.size());
|
m_current_text.size());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
|
|
||||||
void ShowNormalKeyboard() const override;
|
void ShowNormalKeyboard() const override;
|
||||||
|
|
||||||
void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
void ShowTextCheckDialog(Service::AM::Frontend::SwkbdTextCheckResult text_check_result,
|
||||||
std::u16string text_check_message) const override;
|
std::u16string text_check_message) const override;
|
||||||
|
|
||||||
void ShowInlineKeyboard(
|
void ShowInlineKeyboard(
|
||||||
@ -45,7 +45,7 @@ private:
|
|||||||
static ResultData CreateFromFrontend(jobject object);
|
static ResultData CreateFromFrontend(jobject object);
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
Service::AM::Applets::SwkbdResult result{};
|
Service::AM::Frontend::SwkbdResult result{};
|
||||||
};
|
};
|
||||||
|
|
||||||
void SubmitNormalText(const ResultData& result) const;
|
void SubmitNormalText(const ResultData& result) const;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <core/core.h>
|
#include "core/core.h"
|
||||||
#include <core/file_sys/mode.h>
|
#include "core/file_sys/fs_filesystem.h"
|
||||||
#include <core/file_sys/patch_manager.h>
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include <core/loader/nro.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
#include "core/loader/nro.h"
|
||||||
|
#include "jni.h"
|
||||||
#include "jni/android_common/android_common.h"
|
#include "jni/android_common/android_common.h"
|
||||||
#include "native.h"
|
#include "native.h"
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ extern "C" {
|
|||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
|
||||||
jstring jpath) {
|
jstring jpath) {
|
||||||
const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
||||||
GetJString(env, jpath), FileSys::Mode::Read);
|
GetJString(env, jpath), FileSys::OpenMode::Read);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -35,20 +35,22 @@
|
|||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/card_image.h"
|
#include "core/file_sys/card_image.h"
|
||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
|
#include "core/file_sys/fs_filesystem.h"
|
||||||
#include "core/file_sys/submission_package.h"
|
#include "core/file_sys/submission_package.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs/vfs_real.h"
|
||||||
#include "core/frontend/applets/cabinet.h"
|
#include "core/frontend/applets/cabinet.h"
|
||||||
#include "core/frontend/applets/controller.h"
|
#include "core/frontend/applets/controller.h"
|
||||||
#include "core/frontend/applets/error.h"
|
#include "core/frontend/applets/error.h"
|
||||||
#include "core/frontend/applets/general_frontend.h"
|
#include "core/frontend/applets/general.h"
|
||||||
#include "core/frontend/applets/mii_edit.h"
|
#include "core/frontend/applets/mii_edit.h"
|
||||||
#include "core/frontend/applets/profile_select.h"
|
#include "core/frontend/applets/profile_select.h"
|
||||||
#include "core/frontend/applets/software_keyboard.h"
|
#include "core/frontend/applets/software_keyboard.h"
|
||||||
#include "core/frontend/applets/web_browser.h"
|
#include "core/frontend/applets/web_browser.h"
|
||||||
#include "core/hle/service/am/applet_ae.h"
|
#include "core/hle/service/am/applet_ae.h"
|
||||||
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/applet_oe.h"
|
#include "core/hle/service/am/applet_oe.h"
|
||||||
#include "core/hle/service/am/applets/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "frontend_common/config.h"
|
#include "frontend_common/config.h"
|
||||||
@ -154,7 +156,7 @@ void EmulationSession::SurfaceChanged() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) {
|
void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) {
|
||||||
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
|
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::OpenMode::Read);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -207,6 +209,12 @@ void EmulationSession::InitializeSystem(bool reload) {
|
|||||||
m_system.GetFileSystemController().CreateFactories(*m_vfs);
|
m_system.GetFileSystemController().CreateFactories(*m_vfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmulationSession::SetAppletId(int applet_id) {
|
||||||
|
m_applet_id = applet_id;
|
||||||
|
m_system.GetFrontendAppletHolder().SetCurrentAppletId(
|
||||||
|
static_cast<Service::AM::AppletId>(m_applet_id));
|
||||||
|
}
|
||||||
|
|
||||||
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) {
|
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) {
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
@ -221,7 +229,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
|
|||||||
m_system.ApplySettings();
|
m_system.ApplySettings();
|
||||||
Settings::LogSettings();
|
Settings::LogSettings();
|
||||||
m_system.HIDCore().ReloadInputDevices();
|
m_system.HIDCore().ReloadInputDevices();
|
||||||
m_system.SetAppletFrontendSet({
|
m_system.SetFrontendAppletSet({
|
||||||
nullptr, // Amiibo Settings
|
nullptr, // Amiibo Settings
|
||||||
nullptr, // Controller Selector
|
nullptr, // Controller Selector
|
||||||
nullptr, // Error Display
|
nullptr, // Error Display
|
||||||
@ -237,7 +245,10 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
|
|||||||
ConfigureFilesystemProvider(filepath);
|
ConfigureFilesystemProvider(filepath);
|
||||||
|
|
||||||
// Load the ROM.
|
// Load the ROM.
|
||||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath);
|
Service::AM::FrontendAppletParameters params{
|
||||||
|
.applet_id = static_cast<Service::AM::AppletId>(m_applet_id),
|
||||||
|
};
|
||||||
|
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params);
|
||||||
if (m_load_result != Core::SystemResultStatus::Success) {
|
if (m_load_result != Core::SystemResultStatus::Success) {
|
||||||
return m_load_result;
|
return m_load_result;
|
||||||
}
|
}
|
||||||
@ -247,6 +258,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
|
|||||||
m_system.GetCpuManager().OnGpuReady();
|
m_system.GetCpuManager().OnGpuReady();
|
||||||
m_system.RegisterExitCallback([&] { HaltEmulation(); });
|
m_system.RegisterExitCallback([&] { HaltEmulation(); });
|
||||||
|
|
||||||
|
OnEmulationStarted();
|
||||||
return Core::SystemResultStatus::Success;
|
return Core::SystemResultStatus::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,6 +333,9 @@ void EmulationSession::RunEmulation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset current applet ID.
|
||||||
|
m_applet_id = static_cast<int>(Service::AM::AppletId::Application);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulationSession::IsHandheldOnly() {
|
bool EmulationSession::IsHandheldOnly() {
|
||||||
@ -463,8 +478,8 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject
|
|||||||
};
|
};
|
||||||
|
|
||||||
return static_cast<int>(
|
return static_cast<int>(
|
||||||
ContentManager::InstallNSP(&EmulationSession::GetInstance().System(),
|
ContentManager::InstallNSP(EmulationSession::GetInstance().System(),
|
||||||
EmulationSession::GetInstance().System().GetFilesystem().get(),
|
*EmulationSession::GetInstance().System().GetFilesystem(),
|
||||||
GetJString(env, j_file), callback));
|
GetJString(env, j_file), callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,8 +489,8 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* en
|
|||||||
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
|
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||||
std::string updatePath = GetJString(env, jupdatePath);
|
std::string updatePath = GetJString(env, jupdatePath);
|
||||||
std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
|
std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
|
||||||
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(updatePath,
|
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
||||||
FileSys::Mode::Read));
|
updatePath, FileSys::OpenMode::Read));
|
||||||
for (const auto& item : nsp->GetNCAs()) {
|
for (const auto& item : nsp->GetNCAs()) {
|
||||||
for (const auto& nca_details : item.second) {
|
for (const auto& nca_details : item.second) {
|
||||||
if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
|
if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
|
||||||
@ -674,6 +689,11 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuBackend(JNIEnv* env, jclass
|
|||||||
return ToJString(env, "JIT");
|
return ToJString(env, "JIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGpuDriver(JNIEnv* env, jobject jobj) {
|
||||||
|
return ToJString(env,
|
||||||
|
EmulationSession::GetInstance().System().GPU().Renderer().GetDeviceVendor());
|
||||||
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_applySettings(JNIEnv* env, jobject jobj) {
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_applySettings(JNIEnv* env, jobject jobj) {
|
||||||
EmulationSession::GetInstance().System().ApplySettings();
|
EmulationSession::GetInstance().System().ApplySettings();
|
||||||
}
|
}
|
||||||
@ -713,7 +733,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv*
|
|||||||
jobject instance) {
|
jobject instance) {
|
||||||
const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
|
const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
|
||||||
auto vfs_nand_dir = EmulationSession::GetInstance().System().GetFilesystem()->OpenDirectory(
|
auto vfs_nand_dir = EmulationSession::GetInstance().System().GetFilesystem()->OpenDirectory(
|
||||||
Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read);
|
Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
|
||||||
|
|
||||||
const auto user_id = EmulationSession::GetInstance().System().GetProfileManager().GetUser(
|
const auto user_id = EmulationSession::GetInstance().System().GetProfileManager().GetUser(
|
||||||
static_cast<std::size_t>(0));
|
static_cast<std::size_t>(0));
|
||||||
@ -748,13 +768,12 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, j
|
|||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
|
||||||
jint jappletId) {
|
jint jappletId) {
|
||||||
EmulationSession::GetInstance().System().GetAppletManager().SetCurrentAppletId(
|
EmulationSession::GetInstance().SetAppletId(jappletId);
|
||||||
static_cast<Service::AM::Applets::AppletId>(jappletId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass clazz,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass clazz,
|
||||||
jint jcabinetMode) {
|
jint jcabinetMode) {
|
||||||
EmulationSession::GetInstance().System().GetAppletManager().SetCabinetMode(
|
EmulationSession::GetInstance().System().GetFrontendAppletHolder().SetCabinetMode(
|
||||||
static_cast<Service::NFP::CabinetMode>(jcabinetMode));
|
static_cast<Service::NFP::CabinetMode>(jcabinetMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,7 +838,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeUpdate(JNIEnv* env, jobject job
|
|||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeDLC(JNIEnv* env, jobject jobj,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeDLC(JNIEnv* env, jobject jobj,
|
||||||
jstring jprogramId) {
|
jstring jprogramId) {
|
||||||
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
|
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||||
ContentManager::RemoveAllDLC(&EmulationSession::GetInstance().System(), program_id);
|
ContentManager::RemoveAllDLC(EmulationSession::GetInstance().System(), program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeMod(JNIEnv* env, jobject jobj, jstring jprogramId,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeMod(JNIEnv* env, jobject jobj, jstring jprogramId,
|
||||||
@ -829,8 +848,9 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeMod(JNIEnv* env, jobject jobj,
|
|||||||
program_id, GetJString(env, jname));
|
program_id, GetJString(env, jname));
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEnv* env, jobject jobj,
|
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEnv* env,
|
||||||
jobject jcallback) {
|
jobject jobj,
|
||||||
|
jobject jcallback) {
|
||||||
auto jlambdaClass = env->GetObjectClass(jcallback);
|
auto jlambdaClass = env->GetObjectClass(jcallback);
|
||||||
auto jlambdaInvokeMethod = env->GetMethodID(
|
auto jlambdaInvokeMethod = env->GetMethodID(
|
||||||
jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
@ -842,7 +862,7 @@ jobject Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEnv* en
|
|||||||
|
|
||||||
auto& session = EmulationSession::GetInstance();
|
auto& session = EmulationSession::GetInstance();
|
||||||
std::vector<std::string> result = ContentManager::VerifyInstalledContents(
|
std::vector<std::string> result = ContentManager::VerifyInstalledContents(
|
||||||
&session.System(), session.GetContentProvider(), callback);
|
session.System(), *session.GetContentProvider(), callback);
|
||||||
jobjectArray jresult =
|
jobjectArray jresult =
|
||||||
env->NewObjectArray(result.size(), IDCache::GetStringClass(), ToJString(env, ""));
|
env->NewObjectArray(result.size(), IDCache::GetStringClass(), ToJString(env, ""));
|
||||||
for (size_t i = 0; i < result.size(); ++i) {
|
for (size_t i = 0; i < result.size(); ++i) {
|
||||||
@ -863,7 +883,7 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyGameContents(JNIEnv* env, jobje
|
|||||||
};
|
};
|
||||||
auto& session = EmulationSession::GetInstance();
|
auto& session = EmulationSession::GetInstance();
|
||||||
return static_cast<jint>(
|
return static_cast<jint>(
|
||||||
ContentManager::VerifyGameContents(&session.System(), GetJString(env, jpath), callback));
|
ContentManager::VerifyGameContents(session.System(), GetJString(env, jpath), callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
|
||||||
@ -882,7 +902,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
|
|||||||
|
|
||||||
const auto nandDir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
|
const auto nandDir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
|
||||||
auto vfsNandDir = system.GetFilesystem()->OpenDirectory(Common::FS::PathToUTF8String(nandDir),
|
auto vfsNandDir = system.GetFilesystem()->OpenDirectory(Common::FS::PathToUTF8String(nandDir),
|
||||||
FileSys::Mode::Read);
|
FileSys::OpenMode::Read);
|
||||||
|
|
||||||
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
|
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
|
||||||
{}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
|
{}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
|
||||||
@ -912,4 +932,10 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env,
|
|||||||
EmulationSession::GetInstance().GetContentProvider()->ClearAllEntries();
|
EmulationSession::GetInstance().GetContentProvider()->ClearAllEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_areKeysPresent(JNIEnv* env, jobject jobj) {
|
||||||
|
auto& system = EmulationSession::GetInstance().System();
|
||||||
|
system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
|
||||||
|
return ContentManager::AreKeysPresent();
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
const Core::PerfStatsResults& PerfStats();
|
const Core::PerfStatsResults& PerfStats();
|
||||||
void ConfigureFilesystemProvider(const std::string& filepath);
|
void ConfigureFilesystemProvider(const std::string& filepath);
|
||||||
void InitializeSystem(bool reload);
|
void InitializeSystem(bool reload);
|
||||||
|
void SetAppletId(int applet_id);
|
||||||
Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
|
Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
|
||||||
|
|
||||||
bool IsHandheldOnly();
|
bool IsHandheldOnly();
|
||||||
@ -77,6 +78,7 @@ private:
|
|||||||
std::atomic<bool> m_is_paused = false;
|
std::atomic<bool> m_is_paused = false;
|
||||||
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
|
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
|
||||||
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
|
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
|
||||||
|
int m_applet_id{1};
|
||||||
|
|
||||||
// GPU driver parameters
|
// GPU driver parameters
|
||||||
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
android:id="@+id/appbar_about"
|
android:id="@+id/appbar_about"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_about"
|
android:id="@+id/toolbar_about"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back"
|
app:navigationIcon="@drawable/ic_back"
|
||||||
app:title="@string/about" />
|
app:title="@string/about" />
|
||||||
|
|
||||||
@ -28,6 +30,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fadeScrollbars="false"
|
android:fadeScrollbars="false"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -0,0 +1,155 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/coordinator_about"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/scroll_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/content_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:baselineAligned="false">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_weight="3"
|
||||||
|
android:gravity="top|center_horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_copy"
|
||||||
|
style="@style/Widget.Material3.Button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/copy_details" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_verify_integrity"
|
||||||
|
style="@style/Widget.Material3.Button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/verify_integrity" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/path"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/path_field"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:editable="false"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="none"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="1.0.0" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/program_id"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/program_id_field"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:editable="false"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="none"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="1.0.0" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/developer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/developer_field"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:editable="false"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="none"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="1.0.0" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/version"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/version_field"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:editable="false"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="none"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="1.0.0" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -14,6 +14,7 @@
|
|||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:fadeScrollbars="false"
|
android:fadeScrollbars="false"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/icon_layout"
|
app:layout_constraintStart_toEndOf="@+id/icon_layout"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
|
android:focusable="false"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:checked="false" />
|
android:checked="false" />
|
||||||
|
|
||||||
|
@ -6,16 +6,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="16dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
android:layout_marginVertical="12dp"
|
android:layout_marginVertical="12dp">
|
||||||
android:focusable="true">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical">
|
||||||
android:animateLayoutChanges="true">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/path"
|
android:id="@+id/path"
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
android:id="@+id/appbar_about"
|
android:id="@+id/appbar_about"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_about"
|
android:id="@+id/toolbar_about"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:title="@string/about"
|
app:title="@string/about"
|
||||||
app:navigationIcon="@drawable/ic_back" />
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
@ -28,6 +30,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:fadeScrollbars="false"
|
android:fadeScrollbars="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
@ -19,6 +20,7 @@
|
|||||||
android:id="@+id/toolbar_addons"
|
android:id="@+id/toolbar_addons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back" />
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
@ -28,6 +30,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
|
android:nextFocusDown="@id/button_install"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
android:id="@+id/appbar_applets"
|
android:id="@+id/appbar_applets"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_applets"
|
android:id="@+id/toolbar_applets"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back"
|
app:navigationIcon="@drawable/ic_back"
|
||||||
app:title="@string/applets" />
|
app:title="@string/applets" />
|
||||||
|
|
||||||
|
@ -15,12 +15,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:liftOnScrollTargetViewId="@id/list_drivers">
|
app:liftOnScrollTargetViewId="@id/list_drivers">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_drivers"
|
android:id="@+id/toolbar_drivers"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back"
|
app:navigationIcon="@drawable/ic_back"
|
||||||
app:title="@string/gpu_driver_manager" />
|
app:title="@string/gpu_driver_manager" />
|
||||||
|
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
android:id="@+id/appbar_ea"
|
android:id="@+id/appbar_ea"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_about"
|
android:id="@+id/toolbar_about"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back"
|
app:navigationIcon="@drawable/ic_back"
|
||||||
app:title="@string/early_access" />
|
app:title="@string/early_access" />
|
||||||
|
|
||||||
@ -30,6 +32,7 @@
|
|||||||
android:paddingBottom="20dp"
|
android:paddingBottom="20dp"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:fadeScrollbars="false"
|
android:fadeScrollbars="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:keepScreenOn="true"
|
android:keepScreenOn="true"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
tools:context="org.yuzu.yuzu_emu.fragments.EmulationFragment"
|
tools:context="org.yuzu.yuzu_emu.fragments.EmulationFragment"
|
||||||
tools:openDrawer="start">
|
tools:openDrawer="start">
|
||||||
|
|
||||||
@ -24,7 +25,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
android:focusableInTouchMode="false" />
|
android:focusableInTouchMode="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/loading_indicator"
|
android:id="@+id/loading_indicator"
|
||||||
@ -32,7 +34,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:focusable="false"
|
android:defaultFocusHighlightEnabled="false"
|
||||||
android:clickable="false">
|
android:clickable="false">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
@ -118,6 +120,7 @@
|
|||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:focusableInTouchMode="true"
|
android:focusableInTouchMode="true"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
android:visibility="invisible" />
|
android:visibility="invisible" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -160,6 +163,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
|
android:focusedByDefault="true"
|
||||||
app:headerLayout="@layout/header_in_game"
|
app:headerLayout="@layout/header_in_game"
|
||||||
app:menu="@menu/menu_in_game"
|
app:menu="@menu/menu_in_game"
|
||||||
tools:visibility="gone" />
|
tools:visibility="gone" />
|
||||||
|
@ -15,12 +15,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:liftOnScrollTargetViewId="@id/list_folders">
|
app:liftOnScrollTargetViewId="@id/list_folders">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_folders"
|
android:id="@+id/toolbar_folders"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back"
|
app:navigationIcon="@drawable/ic_back"
|
||||||
app:title="@string/game_folders" />
|
app:title="@string/game_folders" />
|
||||||
|
|
||||||
@ -31,6 +33,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
android:id="@+id/appbar_info"
|
android:id="@+id/appbar_info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_info"
|
android:id="@+id/toolbar_info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:navigationIcon="@drawable/ic_back" />
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
@ -25,6 +27,7 @@
|
|||||||
android:id="@+id/scroll_info"
|
android:id="@+id/scroll_info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:fadeScrollbars="false"
|
android:fadeScrollbars="false"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layout_all"
|
android:id="@+id/layout_all"
|
||||||
@ -86,7 +87,7 @@
|
|||||||
android:id="@+id/list_properties"
|
android:id="@+id/list_properties"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:listitem="@layout/card_simple_outlined" />
|
android:defaultFocusHighlightEnabled="false" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
tools:listitem="@layout/card_game" />
|
tools:listitem="@layout/card_game" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
android:background="?attr/colorSurface"
|
android:background="?attr/colorSurface"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:fadeScrollbars="false"
|
android:fadeScrollbars="false"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false">
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:id="@+id/linear_layout_settings"
|
android:id="@+id/linear_layout_settings"
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
android:id="@+id/appbar_installables"
|
android:id="@+id/appbar_installables"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_installables"
|
android:id="@+id/toolbar_installables"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:title="@string/manage_yuzu_data"
|
app:title="@string/manage_yuzu_data"
|
||||||
app:navigationIcon="@drawable/ic_back" />
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
android:id="@+id/appbar_licenses"
|
android:id="@+id/appbar_licenses"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar_licenses"
|
android:id="@+id/toolbar_licenses"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:title="@string/licenses"
|
app:title="@string/licenses"
|
||||||
app:navigationIcon="@drawable/ic_back" />
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:elevation="0dp">
|
app:elevation="0dp">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
@ -24,6 +25,7 @@
|
|||||||
android:id="@+id/toolbar_settings"
|
android:id="@+id/toolbar_settings"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
app:layout_collapseMode="pin"
|
app:layout_collapseMode="pin"
|
||||||
app:navigationIcon="@drawable/ic_back" />
|
app:navigationIcon="@drawable/ic_back" />
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:focusable="true"
|
android:focusable="false"
|
||||||
android:paddingHorizontal="20dp"
|
android:paddingHorizontal="20dp"
|
||||||
android:paddingVertical="16dp">
|
android:paddingVertical="16dp">
|
||||||
|
|
||||||
|
@ -12,4 +12,5 @@
|
|||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:textColor="?attr/colorPrimary"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
android:focusable="false"
|
||||||
tools:text="CPU Settings" />
|
tools:text="CPU Settings" />
|
||||||
|
@ -144,6 +144,9 @@
|
|||||||
<string name="no_save_data_found">No save data found</string>
|
<string name="no_save_data_found">No save data found</string>
|
||||||
<string name="verify_installed_content">Verify installed content</string>
|
<string name="verify_installed_content">Verify installed content</string>
|
||||||
<string name="verify_installed_content_description">Checks all installed content for corruption</string>
|
<string name="verify_installed_content_description">Checks all installed content for corruption</string>
|
||||||
|
<string name="keys_missing">Encryption keys are missing</string>
|
||||||
|
<string name="keys_missing_description">Firmware and retail games cannot be decrypted</string>
|
||||||
|
<string name="keys_missing_help">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
||||||
|
|
||||||
<!-- Applet launcher strings -->
|
<!-- Applet launcher strings -->
|
||||||
<string name="applets">Applet launcher</string>
|
<string name="applets">Applet launcher</string>
|
||||||
|
@ -106,6 +106,7 @@ add_library(common STATIC
|
|||||||
precompiled_headers.h
|
precompiled_headers.h
|
||||||
quaternion.h
|
quaternion.h
|
||||||
range_map.h
|
range_map.h
|
||||||
|
range_mutex.h
|
||||||
reader_writer_queue.h
|
reader_writer_queue.h
|
||||||
ring_buffer.h
|
ring_buffer.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp
|
${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp
|
||||||
|
@ -30,27 +30,27 @@ NativeClock::NativeClock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
||||||
return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_cntfrq_factor)};
|
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::microseconds NativeClock::GetTimeUS() const {
|
std::chrono::microseconds NativeClock::GetTimeUS() const {
|
||||||
return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_cntfrq_factor)};
|
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
||||||
return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_cntfrq_factor)};
|
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetCNTPCT() const {
|
s64 NativeClock::GetCNTPCT() const {
|
||||||
return MultiplyHigh(GetHostTicksElapsed(), guest_cntfrq_factor);
|
return MultiplyHigh(GetUptime(), guest_cntfrq_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetGPUTick() const {
|
s64 NativeClock::GetGPUTick() const {
|
||||||
return MultiplyHigh(GetHostTicksElapsed(), gputick_cntfrq_factor);
|
return MultiplyHigh(GetUptime(), gputick_cntfrq_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetHostTicksNow() const {
|
s64 NativeClock::GetUptime() const {
|
||||||
u64 cntvct_el0 = 0;
|
s64 cntvct_el0 = 0;
|
||||||
asm volatile("dsb ish\n\t"
|
asm volatile("dsb ish\n\t"
|
||||||
"mrs %[cntvct_el0], cntvct_el0\n\t"
|
"mrs %[cntvct_el0], cntvct_el0\n\t"
|
||||||
"dsb ish\n\t"
|
"dsb ish\n\t"
|
||||||
@ -58,15 +58,11 @@ u64 NativeClock::GetHostTicksNow() const {
|
|||||||
return cntvct_el0;
|
return cntvct_el0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetHostTicksElapsed() const {
|
|
||||||
return GetHostTicksNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NativeClock::IsNative() const {
|
bool NativeClock::IsNative() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetHostCNTFRQ() {
|
s64 NativeClock::GetHostCNTFRQ() {
|
||||||
u64 cntfrq_el0 = 0;
|
u64 cntfrq_el0 = 0;
|
||||||
std::string_view board{""};
|
std::string_view board{""};
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
@ -17,17 +17,15 @@ public:
|
|||||||
|
|
||||||
std::chrono::milliseconds GetTimeMS() const override;
|
std::chrono::milliseconds GetTimeMS() const override;
|
||||||
|
|
||||||
u64 GetCNTPCT() const override;
|
s64 GetCNTPCT() const override;
|
||||||
|
|
||||||
u64 GetGPUTick() const override;
|
s64 GetGPUTick() const override;
|
||||||
|
|
||||||
u64 GetHostTicksNow() const override;
|
s64 GetUptime() const override;
|
||||||
|
|
||||||
u64 GetHostTicksElapsed() const override;
|
|
||||||
|
|
||||||
bool IsNative() const override;
|
bool IsNative() const override;
|
||||||
|
|
||||||
static u64 GetHostCNTFRQ();
|
static s64 GetHostCNTFRQ();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using FactorType = unsigned __int128;
|
using FactorType = unsigned __int128;
|
||||||
|
@ -18,4 +18,4 @@ struct MemoryInfo {
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] const MemoryInfo& GetMemInfo();
|
[[nodiscard]] const MemoryInfo& GetMemInfo();
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "bit_cast.h"
|
#include "bit_cast.h"
|
||||||
|
|
||||||
@ -19,4 +20,21 @@ inline T WrappingAdd(T lhs, T rhs) {
|
|||||||
return BitCast<T>(lhs_u + rhs_u);
|
return BitCast<T>(lhs_u + rhs_u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
requires(std::is_integral_v<T> && std::is_signed_v<T>)
|
||||||
|
inline bool CanAddWithoutOverflow(T lhs, T rhs) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
if (lhs >= 0 && rhs >= 0) {
|
||||||
|
return WrappingAdd(lhs, rhs) >= std::max(lhs, rhs);
|
||||||
|
} else if (lhs < 0 && rhs < 0) {
|
||||||
|
return WrappingAdd(lhs, rhs) <= std::min(lhs, rhs);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
T res;
|
||||||
|
return !__builtin_add_overflow(lhs, rhs, &res);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
93
src/common/range_mutex.h
Normal file
93
src/common/range_mutex.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "common/intrusive_list.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
|
||||||
|
class ScopedRangeLock;
|
||||||
|
|
||||||
|
class RangeMutex {
|
||||||
|
public:
|
||||||
|
explicit RangeMutex() = default;
|
||||||
|
~RangeMutex() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class ScopedRangeLock;
|
||||||
|
|
||||||
|
void Lock(ScopedRangeLock& l);
|
||||||
|
void Unlock(ScopedRangeLock& l);
|
||||||
|
bool HasIntersectionLocked(ScopedRangeLock& l);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex m_mutex;
|
||||||
|
std::condition_variable m_cv;
|
||||||
|
|
||||||
|
using LockList = Common::IntrusiveListBaseTraits<ScopedRangeLock>::ListType;
|
||||||
|
LockList m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScopedRangeLock : public Common::IntrusiveListBaseNode<ScopedRangeLock> {
|
||||||
|
public:
|
||||||
|
explicit ScopedRangeLock(RangeMutex& mutex, u64 address, u64 size)
|
||||||
|
: m_mutex(mutex), m_address(address), m_size(size) {
|
||||||
|
if (m_size > 0) {
|
||||||
|
m_mutex.Lock(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~ScopedRangeLock() {
|
||||||
|
if (m_size > 0) {
|
||||||
|
m_mutex.Unlock(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetAddress() const {
|
||||||
|
return m_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetSize() const {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RangeMutex& m_mutex;
|
||||||
|
const u64 m_address{};
|
||||||
|
const u64 m_size{};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void RangeMutex::Lock(ScopedRangeLock& l) {
|
||||||
|
std::unique_lock lk{m_mutex};
|
||||||
|
m_cv.wait(lk, [&] { return !HasIntersectionLocked(l); });
|
||||||
|
m_list.push_back(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RangeMutex::Unlock(ScopedRangeLock& l) {
|
||||||
|
{
|
||||||
|
std::scoped_lock lk{m_mutex};
|
||||||
|
m_list.erase(m_list.iterator_to(l));
|
||||||
|
}
|
||||||
|
m_cv.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool RangeMutex::HasIntersectionLocked(ScopedRangeLock& l) {
|
||||||
|
const auto cur_begin = l.GetAddress();
|
||||||
|
const auto cur_last = l.GetAddress() + l.GetSize() - 1;
|
||||||
|
|
||||||
|
for (const auto& other : m_list) {
|
||||||
|
const auto other_begin = other.GetAddress();
|
||||||
|
const auto other_last = other.GetAddress() + other.GetSize() - 1;
|
||||||
|
|
||||||
|
if (cur_begin <= other_last && other_begin <= cur_last) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Common
|
@ -419,9 +419,16 @@ struct Values {
|
|||||||
linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
|
linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
|
||||||
SwitchableSetting<s64> custom_rtc{
|
SwitchableSetting<s64> custom_rtc{
|
||||||
linkage, 0, "custom_rtc", Category::System, Specialization::Time,
|
linkage, 0, "custom_rtc", Category::System, Specialization::Time,
|
||||||
true, true, &custom_rtc_enabled};
|
false, true, &custom_rtc_enabled};
|
||||||
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
|
SwitchableSetting<s64, true> custom_rtc_offset{linkage,
|
||||||
s64 custom_rtc_differential;
|
0,
|
||||||
|
std::numeric_limits<int>::min(),
|
||||||
|
std::numeric_limits<int>::max(),
|
||||||
|
"custom_rtc_offset",
|
||||||
|
Category::System,
|
||||||
|
Specialization::Countable,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
SwitchableSetting<bool> rng_seed_enabled{
|
SwitchableSetting<bool> rng_seed_enabled{
|
||||||
linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true};
|
linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true};
|
||||||
SwitchableSetting<u32> rng_seed{
|
SwitchableSetting<u32> rng_seed{
|
||||||
|
@ -88,7 +88,17 @@ std::string FindSystemTimeZone() {
|
|||||||
LOG_ERROR(Common, "Time zone {} not handled, defaulting to hour offset.", tz_index);
|
LOG_ERROR(Common, "Time zone {} not handled, defaulting to hour offset.", tz_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
|
|
||||||
|
// For some reason the Etc/GMT times are reversed. GMT+6 contains -21600 as its offset,
|
||||||
|
// -6 hours instead of +6 hours, so these signs are purposefully reversed to fix it.
|
||||||
|
std::string postfix{""};
|
||||||
|
if (hours > 0) {
|
||||||
|
postfix = fmt::format("-{:d}", std::abs(hours));
|
||||||
|
} else if (hours < 0) {
|
||||||
|
postfix = fmt::format("+{:d}", std::abs(hours));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format("Etc/GMT{:s}", postfix);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Common::TimeZone
|
} // namespace Common::TimeZone
|
||||||
|
@ -12,9 +12,8 @@
|
|||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
struct UUID {
|
struct UUID {
|
||||||
std::array<u8, 0x10> uuid{};
|
std::array<u8, 0x10> uuid;
|
||||||
|
|
||||||
/// Constructs an invalid UUID.
|
|
||||||
constexpr UUID() = default;
|
constexpr UUID() = default;
|
||||||
|
|
||||||
/// Constructs a UUID from a reference to a 128 bit array.
|
/// Constructs a UUID from a reference to a 128 bit array.
|
||||||
@ -34,14 +33,6 @@ struct UUID {
|
|||||||
*/
|
*/
|
||||||
explicit UUID(std::string_view uuid_string);
|
explicit UUID(std::string_view uuid_string);
|
||||||
|
|
||||||
~UUID() = default;
|
|
||||||
|
|
||||||
constexpr UUID(const UUID&) noexcept = default;
|
|
||||||
constexpr UUID(UUID&&) noexcept = default;
|
|
||||||
|
|
||||||
constexpr UUID& operator=(const UUID&) noexcept = default;
|
|
||||||
constexpr UUID& operator=(UUID&&) noexcept = default;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the stored UUID is valid or not.
|
* Returns whether the stored UUID is valid or not.
|
||||||
*
|
*
|
||||||
@ -121,6 +112,7 @@ struct UUID {
|
|||||||
friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
|
friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(UUID) == 0x10, "UUID has incorrect size.");
|
static_assert(sizeof(UUID) == 0x10, "UUID has incorrect size.");
|
||||||
|
static_assert(std::is_trivial_v<UUID>);
|
||||||
|
|
||||||
/// An invalid UUID. This UUID has all its bytes set to 0.
|
/// An invalid UUID. This UUID has all its bytes set to 0.
|
||||||
constexpr UUID InvalidUUID = {};
|
constexpr UUID InvalidUUID = {};
|
||||||
|
@ -18,42 +18,40 @@ namespace Common {
|
|||||||
|
|
||||||
class StandardWallClock final : public WallClock {
|
class StandardWallClock final : public WallClock {
|
||||||
public:
|
public:
|
||||||
explicit StandardWallClock() : start_time{SteadyClock::Now()} {}
|
explicit StandardWallClock() {}
|
||||||
|
|
||||||
std::chrono::nanoseconds GetTimeNS() const override {
|
std::chrono::nanoseconds GetTimeNS() const override {
|
||||||
return SteadyClock::Now() - start_time;
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::microseconds GetTimeUS() const override {
|
std::chrono::microseconds GetTimeUS() const override {
|
||||||
return static_cast<std::chrono::microseconds>(GetHostTicksElapsed() / NsToUsRatio::den);
|
return std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds GetTimeMS() const override {
|
std::chrono::milliseconds GetTimeMS() const override {
|
||||||
return static_cast<std::chrono::milliseconds>(GetHostTicksElapsed() / NsToMsRatio::den);
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetCNTPCT() const override {
|
s64 GetCNTPCT() const override {
|
||||||
return GetHostTicksElapsed() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetGPUTick() const override {
|
s64 GetGPUTick() const override {
|
||||||
return GetHostTicksElapsed() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
|
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetHostTicksNow() const override {
|
s64 GetUptime() const override {
|
||||||
return static_cast<u64>(SteadyClock::Now().time_since_epoch().count());
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||||
}
|
std::chrono::steady_clock::now().time_since_epoch())
|
||||||
|
.count();
|
||||||
u64 GetHostTicksElapsed() const override {
|
|
||||||
return static_cast<u64>(GetTimeNS().count());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNative() const override {
|
bool IsNative() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
SteadyClock::time_point start_time;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<WallClock> CreateOptimalClock() {
|
std::unique_ptr<WallClock> CreateOptimalClock() {
|
||||||
|
@ -29,16 +29,13 @@ public:
|
|||||||
virtual std::chrono::milliseconds GetTimeMS() const = 0;
|
virtual std::chrono::milliseconds GetTimeMS() const = 0;
|
||||||
|
|
||||||
/// @returns The guest CNTPCT ticks since the construction of this clock.
|
/// @returns The guest CNTPCT ticks since the construction of this clock.
|
||||||
virtual u64 GetCNTPCT() const = 0;
|
virtual s64 GetCNTPCT() const = 0;
|
||||||
|
|
||||||
/// @returns The guest GPU ticks since the construction of this clock.
|
/// @returns The guest GPU ticks since the construction of this clock.
|
||||||
virtual u64 GetGPUTick() const = 0;
|
virtual s64 GetGPUTick() const = 0;
|
||||||
|
|
||||||
/// @returns The raw host timer ticks since an indeterminate epoch.
|
/// @returns The raw host timer ticks since an indeterminate epoch.
|
||||||
virtual u64 GetHostTicksNow() const = 0;
|
virtual s64 GetUptime() const = 0;
|
||||||
|
|
||||||
/// @returns The raw host timer ticks since the construction of this clock.
|
|
||||||
virtual u64 GetHostTicksElapsed() const = 0;
|
|
||||||
|
|
||||||
/// @returns Whether the clock directly uses the host's hardware clock.
|
/// @returns Whether the clock directly uses the host's hardware clock.
|
||||||
virtual bool IsNative() const = 0;
|
virtual bool IsNative() const = 0;
|
||||||
|
@ -8,39 +8,35 @@
|
|||||||
namespace Common::X64 {
|
namespace Common::X64 {
|
||||||
|
|
||||||
NativeClock::NativeClock(u64 rdtsc_frequency_)
|
NativeClock::NativeClock(u64 rdtsc_frequency_)
|
||||||
: start_ticks{FencedRDTSC()}, rdtsc_frequency{rdtsc_frequency_},
|
: rdtsc_frequency{rdtsc_frequency_}, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den,
|
||||||
ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency)},
|
rdtsc_frequency)},
|
||||||
us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)},
|
us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)},
|
||||||
ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)},
|
ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)},
|
||||||
cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)},
|
cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)},
|
||||||
gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {}
|
gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {}
|
||||||
|
|
||||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
||||||
return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_rdtsc_factor)};
|
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::microseconds NativeClock::GetTimeUS() const {
|
std::chrono::microseconds NativeClock::GetTimeUS() const {
|
||||||
return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_rdtsc_factor)};
|
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
||||||
return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_rdtsc_factor)};
|
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetCNTPCT() const {
|
s64 NativeClock::GetCNTPCT() const {
|
||||||
return MultiplyHigh(GetHostTicksElapsed(), cntpct_rdtsc_factor);
|
return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetGPUTick() const {
|
s64 NativeClock::GetGPUTick() const {
|
||||||
return MultiplyHigh(GetHostTicksElapsed(), gputick_rdtsc_factor);
|
return MultiplyHigh(GetUptime(), gputick_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetHostTicksNow() const {
|
s64 NativeClock::GetUptime() const {
|
||||||
return FencedRDTSC();
|
return static_cast<s64>(FencedRDTSC());
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetHostTicksElapsed() const {
|
|
||||||
return FencedRDTSC() - start_ticks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeClock::IsNative() const {
|
bool NativeClock::IsNative() const {
|
||||||
|
@ -17,18 +17,15 @@ public:
|
|||||||
|
|
||||||
std::chrono::milliseconds GetTimeMS() const override;
|
std::chrono::milliseconds GetTimeMS() const override;
|
||||||
|
|
||||||
u64 GetCNTPCT() const override;
|
s64 GetCNTPCT() const override;
|
||||||
|
|
||||||
u64 GetGPUTick() const override;
|
s64 GetGPUTick() const override;
|
||||||
|
|
||||||
u64 GetHostTicksNow() const override;
|
s64 GetUptime() const override;
|
||||||
|
|
||||||
u64 GetHostTicksElapsed() const override;
|
|
||||||
|
|
||||||
bool IsNative() const override;
|
bool IsNative() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 start_ticks;
|
|
||||||
u64 rdtsc_frequency;
|
u64 rdtsc_frequency;
|
||||||
|
|
||||||
u64 ns_rdtsc_factor;
|
u64 ns_rdtsc_factor;
|
||||||
|
@ -20,28 +20,49 @@ add_library(core STATIC
|
|||||||
cpu_manager.h
|
cpu_manager.h
|
||||||
crypto/aes_util.cpp
|
crypto/aes_util.cpp
|
||||||
crypto/aes_util.h
|
crypto/aes_util.h
|
||||||
|
crypto/ctr_encryption_layer.cpp
|
||||||
|
crypto/ctr_encryption_layer.h
|
||||||
crypto/encryption_layer.cpp
|
crypto/encryption_layer.cpp
|
||||||
crypto/encryption_layer.h
|
crypto/encryption_layer.h
|
||||||
crypto/key_manager.cpp
|
crypto/key_manager.cpp
|
||||||
crypto/key_manager.h
|
crypto/key_manager.h
|
||||||
crypto/partition_data_manager.cpp
|
crypto/partition_data_manager.cpp
|
||||||
crypto/partition_data_manager.h
|
crypto/partition_data_manager.h
|
||||||
crypto/ctr_encryption_layer.cpp
|
|
||||||
crypto/ctr_encryption_layer.h
|
|
||||||
crypto/xts_encryption_layer.cpp
|
crypto/xts_encryption_layer.cpp
|
||||||
crypto/xts_encryption_layer.h
|
crypto/xts_encryption_layer.h
|
||||||
debugger/debugger_interface.h
|
|
||||||
debugger/debugger.cpp
|
debugger/debugger.cpp
|
||||||
debugger/debugger.h
|
debugger/debugger.h
|
||||||
debugger/gdbstub_arch.cpp
|
debugger/debugger_interface.h
|
||||||
debugger/gdbstub_arch.h
|
|
||||||
debugger/gdbstub.cpp
|
debugger/gdbstub.cpp
|
||||||
debugger/gdbstub.h
|
debugger/gdbstub.h
|
||||||
|
debugger/gdbstub_arch.cpp
|
||||||
|
debugger/gdbstub_arch.h
|
||||||
device_memory_manager.h
|
device_memory_manager.h
|
||||||
device_memory_manager.inc
|
device_memory_manager.inc
|
||||||
device_memory.cpp
|
device_memory.cpp
|
||||||
device_memory.h
|
device_memory.h
|
||||||
|
file_sys/bis_factory.cpp
|
||||||
|
file_sys/bis_factory.h
|
||||||
|
file_sys/card_image.cpp
|
||||||
|
file_sys/card_image.h
|
||||||
|
file_sys/common_funcs.h
|
||||||
|
file_sys/content_archive.cpp
|
||||||
|
file_sys/content_archive.h
|
||||||
|
file_sys/control_metadata.cpp
|
||||||
|
file_sys/control_metadata.h
|
||||||
|
file_sys/errors.h
|
||||||
|
file_sys/fs_directory.h
|
||||||
|
file_sys/fs_file.h
|
||||||
|
file_sys/fs_filesystem.h
|
||||||
|
file_sys/fs_memory_management.h
|
||||||
|
file_sys/fs_operate_range.h
|
||||||
|
file_sys/fs_path.h
|
||||||
|
file_sys/fs_path_utility.h
|
||||||
|
file_sys/fs_string_util.h
|
||||||
|
file_sys/fsmitm_romfsbuild.cpp
|
||||||
|
file_sys/fsmitm_romfsbuild.h
|
||||||
file_sys/fssystem/fs_i_storage.h
|
file_sys/fssystem/fs_i_storage.h
|
||||||
|
file_sys/fssystem/fs_types.h
|
||||||
file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.cpp
|
file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.cpp
|
||||||
file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h
|
file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h
|
||||||
file_sys/fssystem/fssystem_aes_ctr_storage.cpp
|
file_sys/fssystem/fssystem_aes_ctr_storage.cpp
|
||||||
@ -83,25 +104,10 @@ add_library(core STATIC
|
|||||||
file_sys/fssystem/fssystem_switch_storage.h
|
file_sys/fssystem/fssystem_switch_storage.h
|
||||||
file_sys/fssystem/fssystem_utility.cpp
|
file_sys/fssystem/fssystem_utility.cpp
|
||||||
file_sys/fssystem/fssystem_utility.h
|
file_sys/fssystem/fssystem_utility.h
|
||||||
file_sys/fssystem/fs_types.h
|
|
||||||
file_sys/bis_factory.cpp
|
|
||||||
file_sys/bis_factory.h
|
|
||||||
file_sys/card_image.cpp
|
|
||||||
file_sys/card_image.h
|
|
||||||
file_sys/common_funcs.h
|
|
||||||
file_sys/content_archive.cpp
|
|
||||||
file_sys/content_archive.h
|
|
||||||
file_sys/control_metadata.cpp
|
|
||||||
file_sys/control_metadata.h
|
|
||||||
file_sys/directory.h
|
|
||||||
file_sys/errors.h
|
|
||||||
file_sys/fsmitm_romfsbuild.cpp
|
|
||||||
file_sys/fsmitm_romfsbuild.h
|
|
||||||
file_sys/ips_layer.cpp
|
file_sys/ips_layer.cpp
|
||||||
file_sys/ips_layer.h
|
file_sys/ips_layer.h
|
||||||
file_sys/kernel_executable.cpp
|
file_sys/kernel_executable.cpp
|
||||||
file_sys/kernel_executable.h
|
file_sys/kernel_executable.h
|
||||||
file_sys/mode.h
|
|
||||||
file_sys/nca_metadata.cpp
|
file_sys/nca_metadata.cpp
|
||||||
file_sys/nca_metadata.h
|
file_sys/nca_metadata.h
|
||||||
file_sys/partition_filesystem.cpp
|
file_sys/partition_filesystem.cpp
|
||||||
@ -146,22 +152,22 @@ add_library(core STATIC
|
|||||||
file_sys/system_archive/system_version.h
|
file_sys/system_archive/system_version.h
|
||||||
file_sys/system_archive/time_zone_binary.cpp
|
file_sys/system_archive/time_zone_binary.cpp
|
||||||
file_sys/system_archive/time_zone_binary.h
|
file_sys/system_archive/time_zone_binary.h
|
||||||
file_sys/vfs.cpp
|
file_sys/vfs/vfs.cpp
|
||||||
file_sys/vfs.h
|
file_sys/vfs/vfs.h
|
||||||
file_sys/vfs_cached.cpp
|
file_sys/vfs/vfs_cached.cpp
|
||||||
file_sys/vfs_cached.h
|
file_sys/vfs/vfs_cached.h
|
||||||
file_sys/vfs_concat.cpp
|
file_sys/vfs/vfs_concat.cpp
|
||||||
file_sys/vfs_concat.h
|
file_sys/vfs/vfs_concat.h
|
||||||
file_sys/vfs_layered.cpp
|
file_sys/vfs/vfs_layered.cpp
|
||||||
file_sys/vfs_layered.h
|
file_sys/vfs/vfs_layered.h
|
||||||
file_sys/vfs_offset.cpp
|
file_sys/vfs/vfs_offset.cpp
|
||||||
file_sys/vfs_offset.h
|
file_sys/vfs/vfs_offset.h
|
||||||
file_sys/vfs_real.cpp
|
file_sys/vfs/vfs_real.cpp
|
||||||
file_sys/vfs_real.h
|
file_sys/vfs/vfs_real.h
|
||||||
file_sys/vfs_static.h
|
file_sys/vfs/vfs_static.h
|
||||||
file_sys/vfs_types.h
|
file_sys/vfs/vfs_types.h
|
||||||
file_sys/vfs_vector.cpp
|
file_sys/vfs/vfs_vector.cpp
|
||||||
file_sys/vfs_vector.h
|
file_sys/vfs/vfs_vector.h
|
||||||
file_sys/xts_archive.cpp
|
file_sys/xts_archive.cpp
|
||||||
file_sys/xts_archive.h
|
file_sys/xts_archive.h
|
||||||
frontend/applets/cabinet.cpp
|
frontend/applets/cabinet.cpp
|
||||||
@ -170,8 +176,8 @@ add_library(core STATIC
|
|||||||
frontend/applets/controller.h
|
frontend/applets/controller.h
|
||||||
frontend/applets/error.cpp
|
frontend/applets/error.cpp
|
||||||
frontend/applets/error.h
|
frontend/applets/error.h
|
||||||
frontend/applets/general_frontend.cpp
|
frontend/applets/general.cpp
|
||||||
frontend/applets/general_frontend.h
|
frontend/applets/general.h
|
||||||
frontend/applets/mii_edit.cpp
|
frontend/applets/mii_edit.cpp
|
||||||
frontend/applets/mii_edit.h
|
frontend/applets/mii_edit.h
|
||||||
frontend/applets/profile_select.cpp
|
frontend/applets/profile_select.cpp
|
||||||
@ -194,7 +200,6 @@ add_library(core STATIC
|
|||||||
hle/kernel/board/nintendo/nx/secure_monitor.h
|
hle/kernel/board/nintendo/nx/secure_monitor.h
|
||||||
hle/kernel/code_set.cpp
|
hle/kernel/code_set.cpp
|
||||||
hle/kernel/code_set.h
|
hle/kernel/code_set.h
|
||||||
hle/kernel/svc_results.h
|
|
||||||
hle/kernel/global_scheduler_context.cpp
|
hle/kernel/global_scheduler_context.cpp
|
||||||
hle/kernel/global_scheduler_context.h
|
hle/kernel/global_scheduler_context.h
|
||||||
hle/kernel/init/init_slab_setup.cpp
|
hle/kernel/init/init_slab_setup.cpp
|
||||||
@ -204,11 +209,11 @@ add_library(core STATIC
|
|||||||
hle/kernel/k_address_arbiter.h
|
hle/kernel/k_address_arbiter.h
|
||||||
hle/kernel/k_address_space_info.cpp
|
hle/kernel/k_address_space_info.cpp
|
||||||
hle/kernel/k_address_space_info.h
|
hle/kernel/k_address_space_info.h
|
||||||
|
hle/kernel/k_affinity_mask.h
|
||||||
hle/kernel/k_auto_object.cpp
|
hle/kernel/k_auto_object.cpp
|
||||||
hle/kernel/k_auto_object.h
|
hle/kernel/k_auto_object.h
|
||||||
hle/kernel/k_auto_object_container.cpp
|
hle/kernel/k_auto_object_container.cpp
|
||||||
hle/kernel/k_auto_object_container.h
|
hle/kernel/k_auto_object_container.h
|
||||||
hle/kernel/k_affinity_mask.h
|
|
||||||
hle/kernel/k_capabilities.cpp
|
hle/kernel/k_capabilities.cpp
|
||||||
hle/kernel/k_capabilities.h
|
hle/kernel/k_capabilities.h
|
||||||
hle/kernel/k_class_token.cpp
|
hle/kernel/k_class_token.cpp
|
||||||
@ -232,9 +237,9 @@ add_library(core STATIC
|
|||||||
hle/kernel/k_event_info.h
|
hle/kernel/k_event_info.h
|
||||||
hle/kernel/k_handle_table.cpp
|
hle/kernel/k_handle_table.cpp
|
||||||
hle/kernel/k_handle_table.h
|
hle/kernel/k_handle_table.h
|
||||||
hle/kernel/k_hardware_timer_base.h
|
|
||||||
hle/kernel/k_hardware_timer.cpp
|
hle/kernel/k_hardware_timer.cpp
|
||||||
hle/kernel/k_hardware_timer.h
|
hle/kernel/k_hardware_timer.h
|
||||||
|
hle/kernel/k_hardware_timer_base.h
|
||||||
hle/kernel/k_interrupt_manager.cpp
|
hle/kernel/k_interrupt_manager.cpp
|
||||||
hle/kernel/k_interrupt_manager.h
|
hle/kernel/k_interrupt_manager.h
|
||||||
hle/kernel/k_light_client_session.cpp
|
hle/kernel/k_light_client_session.cpp
|
||||||
@ -261,10 +266,10 @@ add_library(core STATIC
|
|||||||
hle/kernel/k_page_bitmap.h
|
hle/kernel/k_page_bitmap.h
|
||||||
hle/kernel/k_page_buffer.cpp
|
hle/kernel/k_page_buffer.cpp
|
||||||
hle/kernel/k_page_buffer.h
|
hle/kernel/k_page_buffer.h
|
||||||
hle/kernel/k_page_heap.cpp
|
|
||||||
hle/kernel/k_page_heap.h
|
|
||||||
hle/kernel/k_page_group.cpp
|
hle/kernel/k_page_group.cpp
|
||||||
hle/kernel/k_page_group.h
|
hle/kernel/k_page_group.h
|
||||||
|
hle/kernel/k_page_heap.cpp
|
||||||
|
hle/kernel/k_page_heap.h
|
||||||
hle/kernel/k_page_table.h
|
hle/kernel/k_page_table.h
|
||||||
hle/kernel/k_page_table_base.cpp
|
hle/kernel/k_page_table_base.cpp
|
||||||
hle/kernel/k_page_table_base.h
|
hle/kernel/k_page_table_base.h
|
||||||
@ -329,8 +334,6 @@ add_library(core STATIC
|
|||||||
hle/kernel/slab_helpers.h
|
hle/kernel/slab_helpers.h
|
||||||
hle/kernel/svc.cpp
|
hle/kernel/svc.cpp
|
||||||
hle/kernel/svc.h
|
hle/kernel/svc.h
|
||||||
hle/kernel/svc_common.h
|
|
||||||
hle/kernel/svc_types.h
|
|
||||||
hle/kernel/svc/svc_activity.cpp
|
hle/kernel/svc/svc_activity.cpp
|
||||||
hle/kernel/svc/svc_address_arbiter.cpp
|
hle/kernel/svc/svc_address_arbiter.cpp
|
||||||
hle/kernel/svc/svc_address_translation.cpp
|
hle/kernel/svc/svc_address_translation.cpp
|
||||||
@ -368,6 +371,9 @@ add_library(core STATIC
|
|||||||
hle/kernel/svc/svc_thread_profiler.cpp
|
hle/kernel/svc/svc_thread_profiler.cpp
|
||||||
hle/kernel/svc/svc_tick.cpp
|
hle/kernel/svc/svc_tick.cpp
|
||||||
hle/kernel/svc/svc_transfer_memory.cpp
|
hle/kernel/svc/svc_transfer_memory.cpp
|
||||||
|
hle/kernel/svc_common.h
|
||||||
|
hle/kernel/svc_results.h
|
||||||
|
hle/kernel/svc_types.h
|
||||||
hle/result.h
|
hle/result.h
|
||||||
hle/service/acc/acc.cpp
|
hle/service/acc/acc.cpp
|
||||||
hle/service/acc/acc.h
|
hle/service/acc/acc.h
|
||||||
@ -384,39 +390,101 @@ add_library(core STATIC
|
|||||||
hle/service/acc/errors.h
|
hle/service/acc/errors.h
|
||||||
hle/service/acc/profile_manager.cpp
|
hle/service/acc/profile_manager.cpp
|
||||||
hle/service/acc/profile_manager.h
|
hle/service/acc/profile_manager.h
|
||||||
|
hle/service/am/frontend/applet_cabinet.cpp
|
||||||
|
hle/service/am/frontend/applet_cabinet.h
|
||||||
|
hle/service/am/frontend/applet_controller.cpp
|
||||||
|
hle/service/am/frontend/applet_controller.h
|
||||||
|
hle/service/am/frontend/applet_error.cpp
|
||||||
|
hle/service/am/frontend/applet_error.h
|
||||||
|
hle/service/am/frontend/applet_general.cpp
|
||||||
|
hle/service/am/frontend/applet_general.h
|
||||||
|
hle/service/am/frontend/applet_mii_edit.cpp
|
||||||
|
hle/service/am/frontend/applet_mii_edit.h
|
||||||
|
hle/service/am/frontend/applet_mii_edit_types.h
|
||||||
|
hle/service/am/frontend/applet_profile_select.cpp
|
||||||
|
hle/service/am/frontend/applet_profile_select.h
|
||||||
|
hle/service/am/frontend/applet_software_keyboard.cpp
|
||||||
|
hle/service/am/frontend/applet_software_keyboard.h
|
||||||
|
hle/service/am/frontend/applet_software_keyboard_types.h
|
||||||
|
hle/service/am/frontend/applet_web_browser.cpp
|
||||||
|
hle/service/am/frontend/applet_web_browser.h
|
||||||
|
hle/service/am/frontend/applet_web_browser_types.h
|
||||||
|
hle/service/am/frontend/applets.cpp
|
||||||
|
hle/service/am/frontend/applets.h
|
||||||
hle/service/am/am.cpp
|
hle/service/am/am.cpp
|
||||||
hle/service/am/am.h
|
hle/service/am/am.h
|
||||||
|
hle/service/am/am_results.h
|
||||||
|
hle/service/am/am_types.h
|
||||||
|
hle/service/am/applet.cpp
|
||||||
|
hle/service/am/applet.h
|
||||||
hle/service/am/applet_ae.cpp
|
hle/service/am/applet_ae.cpp
|
||||||
hle/service/am/applet_ae.h
|
hle/service/am/applet_ae.h
|
||||||
|
hle/service/am/applet_manager.cpp
|
||||||
|
hle/service/am/applet_data_broker.cpp
|
||||||
|
hle/service/am/applet_data_broker.h
|
||||||
|
hle/service/am/applet_manager.h
|
||||||
hle/service/am/applet_oe.cpp
|
hle/service/am/applet_oe.cpp
|
||||||
hle/service/am/applet_oe.h
|
hle/service/am/applet_oe.h
|
||||||
hle/service/am/applets/applet_cabinet.cpp
|
hle/service/am/applet_common_functions.cpp
|
||||||
hle/service/am/applets/applet_cabinet.h
|
hle/service/am/applet_common_functions.h
|
||||||
hle/service/am/applets/applet_controller.cpp
|
hle/service/am/applet_message_queue.cpp
|
||||||
hle/service/am/applets/applet_controller.h
|
hle/service/am/applet_message_queue.h
|
||||||
hle/service/am/applets/applet_error.cpp
|
hle/service/am/application_creator.cpp
|
||||||
hle/service/am/applets/applet_error.h
|
hle/service/am/application_creator.h
|
||||||
hle/service/am/applets/applet_general_backend.cpp
|
hle/service/am/application_functions.cpp
|
||||||
hle/service/am/applets/applet_general_backend.h
|
hle/service/am/application_functions.h
|
||||||
hle/service/am/applets/applet_mii_edit.cpp
|
hle/service/am/application_proxy.cpp
|
||||||
hle/service/am/applets/applet_mii_edit.h
|
hle/service/am/application_proxy.h
|
||||||
hle/service/am/applets/applet_mii_edit_types.h
|
hle/service/am/audio_controller.cpp
|
||||||
hle/service/am/applets/applet_profile_select.cpp
|
hle/service/am/audio_controller.h
|
||||||
hle/service/am/applets/applet_profile_select.h
|
hle/service/am/common_state_getter.cpp
|
||||||
hle/service/am/applets/applet_software_keyboard.cpp
|
hle/service/am/common_state_getter.h
|
||||||
hle/service/am/applets/applet_software_keyboard.h
|
hle/service/am/debug_functions.cpp
|
||||||
hle/service/am/applets/applet_software_keyboard_types.h
|
hle/service/am/debug_functions.h
|
||||||
hle/service/am/applets/applet_web_browser.cpp
|
hle/service/am/display_controller.cpp
|
||||||
hle/service/am/applets/applet_web_browser.h
|
hle/service/am/display_controller.h
|
||||||
hle/service/am/applets/applet_web_browser_types.h
|
hle/service/am/global_state_controller.cpp
|
||||||
hle/service/am/applets/applets.cpp
|
hle/service/am/global_state_controller.h
|
||||||
hle/service/am/applets/applets.h
|
hle/service/am/hid_registration.cpp
|
||||||
|
hle/service/am/hid_registration.h
|
||||||
|
hle/service/am/home_menu_functions.cpp
|
||||||
|
hle/service/am/home_menu_functions.h
|
||||||
hle/service/am/idle.cpp
|
hle/service/am/idle.cpp
|
||||||
hle/service/am/idle.h
|
hle/service/am/idle.h
|
||||||
|
hle/service/am/library_applet_accessor.cpp
|
||||||
|
hle/service/am/library_applet_accessor.h
|
||||||
|
hle/service/am/library_applet_creator.cpp
|
||||||
|
hle/service/am/library_applet_creator.h
|
||||||
|
hle/service/am/library_applet_proxy.cpp
|
||||||
|
hle/service/am/library_applet_proxy.h
|
||||||
|
hle/service/am/library_applet_self_accessor.cpp
|
||||||
|
hle/service/am/library_applet_self_accessor.h
|
||||||
|
hle/service/am/library_applet_storage.cpp
|
||||||
|
hle/service/am/library_applet_storage.h
|
||||||
|
hle/service/am/lock_accessor.cpp
|
||||||
|
hle/service/am/lock_accessor.h
|
||||||
|
hle/service/am/managed_layer_holder.cpp
|
||||||
|
hle/service/am/managed_layer_holder.h
|
||||||
hle/service/am/omm.cpp
|
hle/service/am/omm.cpp
|
||||||
hle/service/am/omm.h
|
hle/service/am/omm.h
|
||||||
|
hle/service/am/process_winding_controller.cpp
|
||||||
|
hle/service/am/process_winding_controller.h
|
||||||
|
hle/service/am/process.cpp
|
||||||
|
hle/service/am/process.h
|
||||||
|
hle/service/am/self_controller.cpp
|
||||||
|
hle/service/am/self_controller.h
|
||||||
|
hle/service/am/system_applet_proxy.cpp
|
||||||
|
hle/service/am/system_applet_proxy.h
|
||||||
|
hle/service/am/system_buffer_manager.cpp
|
||||||
|
hle/service/am/system_buffer_manager.h
|
||||||
hle/service/am/spsm.cpp
|
hle/service/am/spsm.cpp
|
||||||
hle/service/am/spsm.h
|
hle/service/am/spsm.h
|
||||||
|
hle/service/am/storage_accessor.cpp
|
||||||
|
hle/service/am/storage_accessor.h
|
||||||
|
hle/service/am/storage.cpp
|
||||||
|
hle/service/am/storage.h
|
||||||
|
hle/service/am/window_controller.cpp
|
||||||
|
hle/service/am/window_controller.h
|
||||||
hle/service/aoc/aoc_u.cpp
|
hle/service/aoc/aoc_u.cpp
|
||||||
hle/service/aoc/aoc_u.h
|
hle/service/aoc/aoc_u.h
|
||||||
hle/service/apm/apm.cpp
|
hle/service/apm/apm.cpp
|
||||||
@ -472,26 +540,41 @@ add_library(core STATIC
|
|||||||
hle/service/caps/caps_types.h
|
hle/service/caps/caps_types.h
|
||||||
hle/service/caps/caps_u.cpp
|
hle/service/caps/caps_u.cpp
|
||||||
hle/service/caps/caps_u.h
|
hle/service/caps/caps_u.h
|
||||||
|
hle/service/cmif_serialization.h
|
||||||
|
hle/service/cmif_types.h
|
||||||
hle/service/erpt/erpt.cpp
|
hle/service/erpt/erpt.cpp
|
||||||
hle/service/erpt/erpt.h
|
hle/service/erpt/erpt.h
|
||||||
hle/service/es/es.cpp
|
hle/service/es/es.cpp
|
||||||
hle/service/es/es.h
|
hle/service/es/es.h
|
||||||
hle/service/eupld/eupld.cpp
|
hle/service/eupld/eupld.cpp
|
||||||
hle/service/eupld/eupld.h
|
hle/service/eupld/eupld.h
|
||||||
|
hle/service/event.cpp
|
||||||
|
hle/service/event.h
|
||||||
hle/service/fatal/fatal.cpp
|
hle/service/fatal/fatal.cpp
|
||||||
hle/service/fatal/fatal.h
|
hle/service/fatal/fatal.h
|
||||||
hle/service/fatal/fatal_p.cpp
|
hle/service/fatal/fatal_p.cpp
|
||||||
hle/service/fatal/fatal_p.h
|
hle/service/fatal/fatal_p.h
|
||||||
hle/service/fatal/fatal_u.cpp
|
hle/service/fatal/fatal_u.cpp
|
||||||
hle/service/fatal/fatal_u.h
|
hle/service/fatal/fatal_u.h
|
||||||
|
hle/service/fgm/fgm.cpp
|
||||||
|
hle/service/fgm/fgm.h
|
||||||
hle/service/filesystem/filesystem.cpp
|
hle/service/filesystem/filesystem.cpp
|
||||||
hle/service/filesystem/filesystem.h
|
hle/service/filesystem/filesystem.h
|
||||||
hle/service/filesystem/fsp_ldr.cpp
|
hle/service/filesystem/fsp/fs_i_directory.cpp
|
||||||
hle/service/filesystem/fsp_ldr.h
|
hle/service/filesystem/fsp/fs_i_directory.h
|
||||||
hle/service/filesystem/fsp_pr.cpp
|
hle/service/filesystem/fsp/fs_i_file.cpp
|
||||||
hle/service/filesystem/fsp_pr.h
|
hle/service/filesystem/fsp/fs_i_file.h
|
||||||
hle/service/filesystem/fsp_srv.cpp
|
hle/service/filesystem/fsp/fs_i_filesystem.cpp
|
||||||
hle/service/filesystem/fsp_srv.h
|
hle/service/filesystem/fsp/fs_i_filesystem.h
|
||||||
|
hle/service/filesystem/fsp/fs_i_storage.cpp
|
||||||
|
hle/service/filesystem/fsp/fs_i_storage.h
|
||||||
|
hle/service/filesystem/fsp/fsp_ldr.cpp
|
||||||
|
hle/service/filesystem/fsp/fsp_ldr.h
|
||||||
|
hle/service/filesystem/fsp/fsp_pr.cpp
|
||||||
|
hle/service/filesystem/fsp/fsp_pr.h
|
||||||
|
hle/service/filesystem/fsp/fsp_srv.cpp
|
||||||
|
hle/service/filesystem/fsp/fsp_srv.h
|
||||||
|
hle/service/filesystem/fsp/fsp_util.h
|
||||||
hle/service/filesystem/romfs_controller.cpp
|
hle/service/filesystem/romfs_controller.cpp
|
||||||
hle/service/filesystem/romfs_controller.h
|
hle/service/filesystem/romfs_controller.h
|
||||||
hle/service/filesystem/save_data_controller.cpp
|
hle/service/filesystem/save_data_controller.cpp
|
||||||
@ -515,6 +598,24 @@ add_library(core STATIC
|
|||||||
hle/service/glue/glue_manager.h
|
hle/service/glue/glue_manager.h
|
||||||
hle/service/glue/notif.cpp
|
hle/service/glue/notif.cpp
|
||||||
hle/service/glue/notif.h
|
hle/service/glue/notif.h
|
||||||
|
hle/service/glue/time/alarm_worker.cpp
|
||||||
|
hle/service/glue/time/alarm_worker.h
|
||||||
|
hle/service/glue/time/file_timestamp_worker.cpp
|
||||||
|
hle/service/glue/time/file_timestamp_worker.h
|
||||||
|
hle/service/glue/time/manager.cpp
|
||||||
|
hle/service/glue/time/manager.h
|
||||||
|
hle/service/glue/time/pm_state_change_handler.cpp
|
||||||
|
hle/service/glue/time/pm_state_change_handler.h
|
||||||
|
hle/service/glue/time/standard_steady_clock_resource.cpp
|
||||||
|
hle/service/glue/time/standard_steady_clock_resource.h
|
||||||
|
hle/service/glue/time/static.cpp
|
||||||
|
hle/service/glue/time/static.h
|
||||||
|
hle/service/glue/time/time_zone.cpp
|
||||||
|
hle/service/glue/time/time_zone.h
|
||||||
|
hle/service/glue/time/time_zone_binary.cpp
|
||||||
|
hle/service/glue/time/time_zone_binary.h
|
||||||
|
hle/service/glue/time/worker.cpp
|
||||||
|
hle/service/glue/time/worker.h
|
||||||
hle/service/grc/grc.cpp
|
hle/service/grc/grc.cpp
|
||||||
hle/service/grc/grc.h
|
hle/service/grc/grc.h
|
||||||
hle/service/hid/hid.cpp
|
hle/service/hid/hid.cpp
|
||||||
@ -531,13 +632,18 @@ add_library(core STATIC
|
|||||||
hle/service/hid/irs.h
|
hle/service/hid/irs.h
|
||||||
hle/service/hid/xcd.cpp
|
hle/service/hid/xcd.cpp
|
||||||
hle/service/hid/xcd.h
|
hle/service/hid/xcd.h
|
||||||
|
hle/service/hle_ipc.cpp
|
||||||
|
hle/service/hle_ipc.h
|
||||||
|
hle/service/ipc_helpers.h
|
||||||
|
hle/service/kernel_helpers.cpp
|
||||||
|
hle/service/kernel_helpers.h
|
||||||
hle/service/lbl/lbl.cpp
|
hle/service/lbl/lbl.cpp
|
||||||
hle/service/lbl/lbl.h
|
hle/service/lbl/lbl.h
|
||||||
hle/service/ldn/lan_discovery.cpp
|
hle/service/ldn/lan_discovery.cpp
|
||||||
hle/service/ldn/lan_discovery.h
|
hle/service/ldn/lan_discovery.h
|
||||||
hle/service/ldn/ldn_results.h
|
|
||||||
hle/service/ldn/ldn.cpp
|
hle/service/ldn/ldn.cpp
|
||||||
hle/service/ldn/ldn.h
|
hle/service/ldn/ldn.h
|
||||||
|
hle/service/ldn/ldn_results.h
|
||||||
hle/service/ldn/ldn_types.h
|
hle/service/ldn/ldn_types.h
|
||||||
hle/service/ldr/ldr.cpp
|
hle/service/ldr/ldr.cpp
|
||||||
hle/service/ldr/ldr.h
|
hle/service/ldr/ldr.h
|
||||||
@ -545,16 +651,6 @@ add_library(core STATIC
|
|||||||
hle/service/lm/lm.h
|
hle/service/lm/lm.h
|
||||||
hle/service/mig/mig.cpp
|
hle/service/mig/mig.cpp
|
||||||
hle/service/mig/mig.h
|
hle/service/mig/mig.h
|
||||||
hle/service/mii/types/char_info.cpp
|
|
||||||
hle/service/mii/types/char_info.h
|
|
||||||
hle/service/mii/types/core_data.cpp
|
|
||||||
hle/service/mii/types/core_data.h
|
|
||||||
hle/service/mii/types/raw_data.cpp
|
|
||||||
hle/service/mii/types/raw_data.h
|
|
||||||
hle/service/mii/types/store_data.cpp
|
|
||||||
hle/service/mii/types/store_data.h
|
|
||||||
hle/service/mii/types/ver3_store_data.cpp
|
|
||||||
hle/service/mii/types/ver3_store_data.h
|
|
||||||
hle/service/mii/mii.cpp
|
hle/service/mii/mii.cpp
|
||||||
hle/service/mii/mii.h
|
hle/service/mii/mii.h
|
||||||
hle/service/mii/mii_database.cpp
|
hle/service/mii/mii_database.cpp
|
||||||
@ -566,10 +662,22 @@ add_library(core STATIC
|
|||||||
hle/service/mii/mii_result.h
|
hle/service/mii/mii_result.h
|
||||||
hle/service/mii/mii_types.h
|
hle/service/mii/mii_types.h
|
||||||
hle/service/mii/mii_util.h
|
hle/service/mii/mii_util.h
|
||||||
|
hle/service/mii/types/char_info.cpp
|
||||||
|
hle/service/mii/types/char_info.h
|
||||||
|
hle/service/mii/types/core_data.cpp
|
||||||
|
hle/service/mii/types/core_data.h
|
||||||
|
hle/service/mii/types/raw_data.cpp
|
||||||
|
hle/service/mii/types/raw_data.h
|
||||||
|
hle/service/mii/types/store_data.cpp
|
||||||
|
hle/service/mii/types/store_data.h
|
||||||
|
hle/service/mii/types/ver3_store_data.cpp
|
||||||
|
hle/service/mii/types/ver3_store_data.h
|
||||||
hle/service/mm/mm_u.cpp
|
hle/service/mm/mm_u.cpp
|
||||||
hle/service/mm/mm_u.h
|
hle/service/mm/mm_u.h
|
||||||
hle/service/mnpp/mnpp_app.cpp
|
hle/service/mnpp/mnpp_app.cpp
|
||||||
hle/service/mnpp/mnpp_app.h
|
hle/service/mnpp/mnpp_app.h
|
||||||
|
hle/service/mutex.cpp
|
||||||
|
hle/service/mutex.h
|
||||||
hle/service/ncm/ncm.cpp
|
hle/service/ncm/ncm.cpp
|
||||||
hle/service/ncm/ncm.h
|
hle/service/ncm/ncm.h
|
||||||
hle/service/nfc/common/amiibo_crypto.cpp
|
hle/service/nfc/common/amiibo_crypto.cpp
|
||||||
@ -693,25 +801,58 @@ add_library(core STATIC
|
|||||||
hle/service/prepo/prepo.h
|
hle/service/prepo/prepo.h
|
||||||
hle/service/psc/psc.cpp
|
hle/service/psc/psc.cpp
|
||||||
hle/service/psc/psc.h
|
hle/service/psc/psc.h
|
||||||
|
hle/service/psc/time/alarms.cpp
|
||||||
|
hle/service/psc/time/alarms.h
|
||||||
|
hle/service/psc/time/clocks/context_writers.cpp
|
||||||
|
hle/service/psc/time/clocks/context_writers.h
|
||||||
|
hle/service/psc/time/clocks/ephemeral_network_system_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/standard_local_system_clock_core.cpp
|
||||||
|
hle/service/psc/time/clocks/standard_local_system_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/standard_network_system_clock_core.cpp
|
||||||
|
hle/service/psc/time/clocks/standard_network_system_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/standard_steady_clock_core.cpp
|
||||||
|
hle/service/psc/time/clocks/standard_steady_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/standard_user_system_clock_core.cpp
|
||||||
|
hle/service/psc/time/clocks/standard_user_system_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/steady_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/system_clock_core.cpp
|
||||||
|
hle/service/psc/time/clocks/system_clock_core.h
|
||||||
|
hle/service/psc/time/clocks/tick_based_steady_clock_core.cpp
|
||||||
|
hle/service/psc/time/clocks/tick_based_steady_clock_core.h
|
||||||
|
hle/service/psc/time/common.cpp
|
||||||
|
hle/service/psc/time/common.h
|
||||||
|
hle/service/psc/time/errors.h
|
||||||
|
hle/service/psc/time/shared_memory.cpp
|
||||||
|
hle/service/psc/time/shared_memory.h
|
||||||
|
hle/service/psc/time/static.cpp
|
||||||
|
hle/service/psc/time/static.h
|
||||||
|
hle/service/psc/time/manager.h
|
||||||
|
hle/service/psc/time/power_state_service.cpp
|
||||||
|
hle/service/psc/time/power_state_service.h
|
||||||
|
hle/service/psc/time/service_manager.cpp
|
||||||
|
hle/service/psc/time/service_manager.h
|
||||||
|
hle/service/psc/time/steady_clock.cpp
|
||||||
|
hle/service/psc/time/steady_clock.h
|
||||||
|
hle/service/psc/time/system_clock.cpp
|
||||||
|
hle/service/psc/time/system_clock.h
|
||||||
|
hle/service/psc/time/time_zone.cpp
|
||||||
|
hle/service/psc/time/time_zone.h
|
||||||
|
hle/service/psc/time/time_zone_service.cpp
|
||||||
|
hle/service/psc/time/time_zone_service.h
|
||||||
|
hle/service/psc/time/power_state_request_manager.cpp
|
||||||
|
hle/service/psc/time/power_state_request_manager.h
|
||||||
hle/service/ptm/psm.cpp
|
hle/service/ptm/psm.cpp
|
||||||
hle/service/ptm/psm.h
|
hle/service/ptm/psm.h
|
||||||
hle/service/ptm/ptm.cpp
|
hle/service/ptm/ptm.cpp
|
||||||
hle/service/ptm/ptm.h
|
hle/service/ptm/ptm.h
|
||||||
hle/service/ptm/ts.cpp
|
hle/service/ptm/ts.cpp
|
||||||
hle/service/ptm/ts.h
|
hle/service/ptm/ts.h
|
||||||
hle/service/hle_ipc.cpp
|
hle/service/ro/ro.cpp
|
||||||
hle/service/hle_ipc.h
|
hle/service/ro/ro.h
|
||||||
hle/service/ipc_helpers.h
|
|
||||||
hle/service/kernel_helpers.cpp
|
|
||||||
hle/service/kernel_helpers.h
|
|
||||||
hle/service/mutex.cpp
|
|
||||||
hle/service/mutex.h
|
|
||||||
hle/service/ro/ro_nro_utils.cpp
|
hle/service/ro/ro_nro_utils.cpp
|
||||||
hle/service/ro/ro_nro_utils.h
|
hle/service/ro/ro_nro_utils.h
|
||||||
hle/service/ro/ro_results.h
|
hle/service/ro/ro_results.h
|
||||||
hle/service/ro/ro_types.h
|
hle/service/ro/ro_types.h
|
||||||
hle/service/ro/ro.cpp
|
|
||||||
hle/service/ro/ro.h
|
|
||||||
hle/service/server_manager.cpp
|
hle/service/server_manager.cpp
|
||||||
hle/service/server_manager.h
|
hle/service/server_manager.h
|
||||||
hle/service/service.cpp
|
hle/service/service.cpp
|
||||||
@ -760,40 +901,6 @@ add_library(core STATIC
|
|||||||
hle/service/ssl/ssl.cpp
|
hle/service/ssl/ssl.cpp
|
||||||
hle/service/ssl/ssl.h
|
hle/service/ssl/ssl.h
|
||||||
hle/service/ssl/ssl_backend.h
|
hle/service/ssl/ssl_backend.h
|
||||||
hle/service/time/clock_types.h
|
|
||||||
hle/service/time/ephemeral_network_system_clock_context_writer.h
|
|
||||||
hle/service/time/ephemeral_network_system_clock_core.h
|
|
||||||
hle/service/time/errors.h
|
|
||||||
hle/service/time/local_system_clock_context_writer.h
|
|
||||||
hle/service/time/network_system_clock_context_writer.h
|
|
||||||
hle/service/time/standard_local_system_clock_core.h
|
|
||||||
hle/service/time/standard_network_system_clock_core.h
|
|
||||||
hle/service/time/standard_steady_clock_core.cpp
|
|
||||||
hle/service/time/standard_steady_clock_core.h
|
|
||||||
hle/service/time/standard_user_system_clock_core.cpp
|
|
||||||
hle/service/time/standard_user_system_clock_core.h
|
|
||||||
hle/service/time/steady_clock_core.h
|
|
||||||
hle/service/time/system_clock_context_update_callback.cpp
|
|
||||||
hle/service/time/system_clock_context_update_callback.h
|
|
||||||
hle/service/time/system_clock_core.cpp
|
|
||||||
hle/service/time/system_clock_core.h
|
|
||||||
hle/service/time/tick_based_steady_clock_core.cpp
|
|
||||||
hle/service/time/tick_based_steady_clock_core.h
|
|
||||||
hle/service/time/time.cpp
|
|
||||||
hle/service/time/time.h
|
|
||||||
hle/service/time/time_interface.cpp
|
|
||||||
hle/service/time/time_interface.h
|
|
||||||
hle/service/time/time_manager.cpp
|
|
||||||
hle/service/time/time_manager.h
|
|
||||||
hle/service/time/time_sharedmemory.cpp
|
|
||||||
hle/service/time/time_sharedmemory.h
|
|
||||||
hle/service/time/time_zone_content_manager.cpp
|
|
||||||
hle/service/time/time_zone_content_manager.h
|
|
||||||
hle/service/time/time_zone_manager.cpp
|
|
||||||
hle/service/time/time_zone_manager.h
|
|
||||||
hle/service/time/time_zone_service.cpp
|
|
||||||
hle/service/time/time_zone_service.h
|
|
||||||
hle/service/time/time_zone_types.h
|
|
||||||
hle/service/usb/usb.cpp
|
hle/service/usb/usb.cpp
|
||||||
hle/service/usb/usb.h
|
hle/service/usb/usb.h
|
||||||
hle/service/vi/display/vi_display.cpp
|
hle/service/vi/display/vi_display.cpp
|
||||||
@ -812,9 +919,9 @@ add_library(core STATIC
|
|||||||
internal_network/network.h
|
internal_network/network.h
|
||||||
internal_network/network_interface.cpp
|
internal_network/network_interface.cpp
|
||||||
internal_network/network_interface.h
|
internal_network/network_interface.h
|
||||||
internal_network/sockets.h
|
|
||||||
internal_network/socket_proxy.cpp
|
internal_network/socket_proxy.cpp
|
||||||
internal_network/socket_proxy.h
|
internal_network/socket_proxy.h
|
||||||
|
internal_network/sockets.h
|
||||||
loader/deconstructed_rom_directory.cpp
|
loader/deconstructed_rom_directory.cpp
|
||||||
loader/deconstructed_rom_directory.h
|
loader/deconstructed_rom_directory.h
|
||||||
loader/kip.cpp
|
loader/kip.cpp
|
||||||
@ -833,13 +940,13 @@ add_library(core STATIC
|
|||||||
loader/nsp.h
|
loader/nsp.h
|
||||||
loader/xci.cpp
|
loader/xci.cpp
|
||||||
loader/xci.h
|
loader/xci.h
|
||||||
|
memory.cpp
|
||||||
|
memory.h
|
||||||
memory/cheat_engine.cpp
|
memory/cheat_engine.cpp
|
||||||
memory/cheat_engine.h
|
memory/cheat_engine.h
|
||||||
memory/dmnt_cheat_types.h
|
memory/dmnt_cheat_types.h
|
||||||
memory/dmnt_cheat_vm.cpp
|
memory/dmnt_cheat_vm.cpp
|
||||||
memory/dmnt_cheat_vm.h
|
memory/dmnt_cheat_vm.h
|
||||||
memory.cpp
|
|
||||||
memory.h
|
|
||||||
perf_stats.cpp
|
perf_stats.cpp
|
||||||
perf_stats.h
|
perf_stats.h
|
||||||
precompiled_headers.h
|
precompiled_headers.h
|
||||||
@ -874,7 +981,7 @@ endif()
|
|||||||
|
|
||||||
create_target_directory_groups(core)
|
create_target_directory_groups(core)
|
||||||
|
|
||||||
target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb)
|
target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz)
|
||||||
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
|
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
|
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
#include "core/debugger/debugger.h"
|
#include "core/debugger/debugger.h"
|
||||||
#include "core/device_memory.h"
|
#include "core/device_memory.h"
|
||||||
#include "core/file_sys/bis_factory.h"
|
#include "core/file_sys/bis_factory.h"
|
||||||
#include "core/file_sys/mode.h"
|
#include "core/file_sys/fs_filesystem.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
#include "core/file_sys/romfs_factory.h"
|
#include "core/file_sys/romfs_factory.h"
|
||||||
#include "core/file_sys/savedata_factory.h"
|
#include "core/file_sys/savedata_factory.h"
|
||||||
#include "core/file_sys/vfs_concat.h"
|
#include "core/file_sys/vfs/vfs_concat.h"
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs/vfs_real.h"
|
||||||
#include "core/gpu_dirty_memory_manager.h"
|
#include "core/gpu_dirty_memory_manager.h"
|
||||||
#include "core/hle/kernel/k_memory_manager.h"
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
@ -36,13 +36,19 @@
|
|||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/physical_core.h"
|
#include "core/hle/kernel/physical_core.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/am/applets/applets.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/apm/apm_controller.h"
|
#include "core/hle/service/apm/apm_controller.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
|
#include "core/hle/service/glue/time/static.h"
|
||||||
|
#include "core/hle/service/psc/time/static.h"
|
||||||
|
#include "core/hle/service/psc/time/steady_clock.h"
|
||||||
|
#include "core/hle/service/psc/time/system_clock.h"
|
||||||
|
#include "core/hle/service/psc/time/time_zone_service.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "core/hle/service/set/system_settings_server.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/hle/service/time/time_manager.h"
|
|
||||||
#include "core/internal_network/network.h"
|
#include "core/internal_network/network.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
@ -97,7 +103,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
|||||||
Common::SplitPath(path, &dir_name, &filename, nullptr);
|
Common::SplitPath(path, &dir_name, &filename, nullptr);
|
||||||
|
|
||||||
if (filename == "00") {
|
if (filename == "00") {
|
||||||
const auto dir = vfs->OpenDirectory(dir_name, FileSys::Mode::Read);
|
const auto dir = vfs->OpenDirectory(dir_name, FileSys::OpenMode::Read);
|
||||||
std::vector<FileSys::VirtualFile> concat;
|
std::vector<FileSys::VirtualFile> concat;
|
||||||
|
|
||||||
for (u32 i = 0; i < 0x10; ++i) {
|
for (u32 i = 0; i < 0x10; ++i) {
|
||||||
@ -122,16 +128,16 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Common::FS::IsDir(path)) {
|
if (Common::FS::IsDir(path)) {
|
||||||
return vfs->OpenFile(path + "/main", FileSys::Mode::Read);
|
return vfs->OpenFile(path + "/main", FileSys::OpenMode::Read);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vfs->OpenFile(path, FileSys::Mode::Read);
|
return vfs->OpenFile(path, FileSys::OpenMode::Read);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct System::Impl {
|
struct System::Impl {
|
||||||
explicit Impl(System& system)
|
explicit Impl(System& system)
|
||||||
: kernel{system}, fs_controller{system}, hid_core{}, room_network{}, cpu_manager{system},
|
: kernel{system}, fs_controller{system}, hid_core{}, room_network{}, cpu_manager{system},
|
||||||
reporter{system}, applet_manager{system}, profile_manager{}, time_manager{system} {}
|
reporter{system}, applet_manager{system}, frontend_applets{system}, profile_manager{} {}
|
||||||
|
|
||||||
void Initialize(System& system) {
|
void Initialize(System& system) {
|
||||||
device_memory = std::make_unique<Core::DeviceMemory>();
|
device_memory = std::make_unique<Core::DeviceMemory>();
|
||||||
@ -143,8 +149,6 @@ struct System::Impl {
|
|||||||
core_timing.SetMulticore(is_multicore);
|
core_timing.SetMulticore(is_multicore);
|
||||||
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
||||||
|
|
||||||
RefreshTime();
|
|
||||||
|
|
||||||
// Create a default fs if one doesn't already exist.
|
// Create a default fs if one doesn't already exist.
|
||||||
if (virtual_filesystem == nullptr) {
|
if (virtual_filesystem == nullptr) {
|
||||||
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
|
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
|
||||||
@ -154,7 +158,7 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create default implementations of applets if one is not provided.
|
// Create default implementations of applets if one is not provided.
|
||||||
applet_manager.SetDefaultAppletsIfMissing();
|
frontend_applets.SetDefaultAppletsIfMissing();
|
||||||
|
|
||||||
is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
|
is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
|
||||||
|
|
||||||
@ -182,14 +186,57 @@ struct System::Impl {
|
|||||||
Initialize(system);
|
Initialize(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefreshTime() {
|
void RefreshTime(System& system) {
|
||||||
|
if (!system.IsPoweredOn()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto settings_service =
|
||||||
|
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys",
|
||||||
|
true);
|
||||||
|
auto static_service_a =
|
||||||
|
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:a", true);
|
||||||
|
|
||||||
|
auto static_service_s =
|
||||||
|
system.ServiceManager().GetService<Service::PSC::Time::StaticService>("time:s", true);
|
||||||
|
|
||||||
|
std::shared_ptr<Service::PSC::Time::SystemClock> user_clock;
|
||||||
|
static_service_a->GetStandardUserSystemClock(user_clock);
|
||||||
|
|
||||||
|
std::shared_ptr<Service::PSC::Time::SystemClock> local_clock;
|
||||||
|
static_service_a->GetStandardLocalSystemClock(local_clock);
|
||||||
|
|
||||||
|
std::shared_ptr<Service::PSC::Time::SystemClock> network_clock;
|
||||||
|
static_service_s->GetStandardNetworkSystemClock(network_clock);
|
||||||
|
|
||||||
|
std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service;
|
||||||
|
static_service_a->GetTimeZoneService(timezone_service);
|
||||||
|
|
||||||
|
Service::PSC::Time::LocationName name{};
|
||||||
|
auto new_name = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
|
||||||
|
std::memcpy(name.name.data(), new_name.data(), std::min(name.name.size(), new_name.size()));
|
||||||
|
|
||||||
|
timezone_service->SetDeviceLocation(name);
|
||||||
|
|
||||||
|
u64 time_offset = 0;
|
||||||
|
if (Settings::values.custom_rtc_enabled) {
|
||||||
|
time_offset = Settings::values.custom_rtc_offset.GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
|
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
|
||||||
const auto current_time =
|
const u64 current_time =
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
|
+std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
|
||||||
Settings::values.custom_rtc_differential =
|
const u64 new_time = current_time + time_offset;
|
||||||
(Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue()
|
|
||||||
: current_time) -
|
Service::PSC::Time::SystemClockContext context{};
|
||||||
current_time;
|
settings_service->SetUserSystemClockContext(context);
|
||||||
|
user_clock->SetCurrentTime(new_time);
|
||||||
|
|
||||||
|
local_clock->SetCurrentTime(new_time);
|
||||||
|
|
||||||
|
network_clock->GetSystemClockContext(context);
|
||||||
|
settings_service->SetNetworkSystemClockContext(context);
|
||||||
|
network_clock->SetCurrentTime(new_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run() {
|
void Run() {
|
||||||
@ -265,9 +312,6 @@ struct System::Impl {
|
|||||||
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
|
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
|
||||||
services = std::make_unique<Service::Services>(service_manager, system);
|
services = std::make_unique<Service::Services>(service_manager, system);
|
||||||
|
|
||||||
// Initialize time manager, which must happen after kernel is created
|
|
||||||
time_manager.Initialize();
|
|
||||||
|
|
||||||
is_powered_on = true;
|
is_powered_on = true;
|
||||||
exit_locked = false;
|
exit_locked = false;
|
||||||
exit_requested = false;
|
exit_requested = false;
|
||||||
@ -287,16 +331,27 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
||||||
const std::string& filepath, u64 program_id,
|
const std::string& filepath,
|
||||||
std::size_t program_index) {
|
Service::AM::FrontendAppletParameters& params) {
|
||||||
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
|
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
|
||||||
program_id, program_index);
|
params.program_id, params.program_index);
|
||||||
|
|
||||||
if (!app_loader) {
|
if (!app_loader) {
|
||||||
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||||
return SystemResultStatus::ErrorGetLoader;
|
return SystemResultStatus::ErrorGetLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) {
|
||||||
|
LOG_ERROR(Core, "Failed to find title id for ROM!");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = "Unknown program";
|
||||||
|
if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) {
|
||||||
|
LOG_ERROR(Core, "Failed to read title for ROM!");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(Core, "Loading {} ({})", name, params.program_id);
|
||||||
|
|
||||||
InitializeKernel(system);
|
InitializeKernel(system);
|
||||||
|
|
||||||
// Create the application process.
|
// Create the application process.
|
||||||
@ -330,9 +385,14 @@ struct System::Impl {
|
|||||||
cheat_engine->Initialize();
|
cheat_engine->Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register with applet manager.
|
||||||
|
applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(),
|
||||||
|
params);
|
||||||
|
|
||||||
// All threads are started, begin main process execution, now that we're in the clear.
|
// All threads are started, begin main process execution, now that we're in the clear.
|
||||||
main_process->Run(load_parameters->main_thread_priority,
|
main_process->Run(load_parameters->main_thread_priority,
|
||||||
load_parameters->main_thread_stack_size);
|
load_parameters->main_thread_stack_size);
|
||||||
|
main_process->Close();
|
||||||
|
|
||||||
if (Settings::values.gamecard_inserted) {
|
if (Settings::values.gamecard_inserted) {
|
||||||
if (Settings::values.gamecard_current_game) {
|
if (Settings::values.gamecard_current_game) {
|
||||||
@ -343,21 +403,13 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app_loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) {
|
perf_stats = std::make_unique<PerfStats>(params.program_id);
|
||||||
LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", load_result);
|
|
||||||
}
|
|
||||||
perf_stats = std::make_unique<PerfStats>(program_id);
|
|
||||||
// Reset counters and set time origin to current frame
|
// Reset counters and set time origin to current frame
|
||||||
GetAndResetPerfStats();
|
GetAndResetPerfStats();
|
||||||
perf_stats->BeginSystemFrame();
|
perf_stats->BeginSystemFrame();
|
||||||
|
|
||||||
std::string name = "Unknown Game";
|
|
||||||
if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) {
|
|
||||||
LOG_ERROR(Core, "Failed to read title for ROM (Error {})", load_result);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string title_version;
|
std::string title_version;
|
||||||
const FileSys::PatchManager pm(program_id, system.GetFileSystemController(),
|
const FileSys::PatchManager pm(params.program_id, system.GetFileSystemController(),
|
||||||
system.GetContentProvider());
|
system.GetContentProvider());
|
||||||
const auto metadata = pm.GetControlMetadata();
|
const auto metadata = pm.GetControlMetadata();
|
||||||
if (metadata.first != nullptr) {
|
if (metadata.first != nullptr) {
|
||||||
@ -366,14 +418,15 @@ struct System::Impl {
|
|||||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||||
Network::GameInfo game_info;
|
Network::GameInfo game_info;
|
||||||
game_info.name = name;
|
game_info.name = name;
|
||||||
game_info.id = program_id;
|
game_info.id = params.program_id;
|
||||||
game_info.version = title_version;
|
game_info.version = title_version;
|
||||||
room_member->SendGameInfo(game_info);
|
room_member->SendGameInfo(game_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workarounds:
|
// Workarounds:
|
||||||
// Activate this in Super Smash Brothers Ultimate, it only affects AMD cards using AMDVLK
|
// Activate this in Super Smash Brothers Ultimate, it only affects AMD cards using AMDVLK
|
||||||
Settings::values.renderer_amdvlk_depth_bias_workaround = program_id == 0x1006A800016E000ULL;
|
Settings::values.renderer_amdvlk_depth_bias_workaround =
|
||||||
|
params.program_id == 0x1006A800016E000ULL;
|
||||||
|
|
||||||
status = SystemResultStatus::Success;
|
status = SystemResultStatus::Success;
|
||||||
return status;
|
return status;
|
||||||
@ -412,12 +465,12 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
kernel.CloseServices();
|
kernel.CloseServices();
|
||||||
kernel.ShutdownCores();
|
kernel.ShutdownCores();
|
||||||
|
applet_manager.Reset();
|
||||||
services.reset();
|
services.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
cheat_engine.reset();
|
cheat_engine.reset();
|
||||||
telemetry_session.reset();
|
telemetry_session.reset();
|
||||||
time_manager.Shutdown();
|
|
||||||
core_timing.ClearPendingEvents();
|
core_timing.ClearPendingEvents();
|
||||||
app_loader.reset();
|
app_loader.reset();
|
||||||
audio_core.reset();
|
audio_core.reset();
|
||||||
@ -524,8 +577,9 @@ struct System::Impl {
|
|||||||
|
|
||||||
std::unique_ptr<Tools::RenderdocAPI> renderdoc_api;
|
std::unique_ptr<Tools::RenderdocAPI> renderdoc_api;
|
||||||
|
|
||||||
/// Frontend applets
|
/// Applets
|
||||||
Service::AM::Applets::AppletManager applet_manager;
|
Service::AM::AppletManager applet_manager;
|
||||||
|
Service::AM::Frontend::FrontendAppletHolder frontend_applets;
|
||||||
|
|
||||||
/// APM (Performance) services
|
/// APM (Performance) services
|
||||||
Service::APM::Controller apm_controller{core_timing};
|
Service::APM::Controller apm_controller{core_timing};
|
||||||
@ -533,7 +587,6 @@ struct System::Impl {
|
|||||||
/// Service State
|
/// Service State
|
||||||
Service::Glue::ARPManager arp_manager;
|
Service::Glue::ARPManager arp_manager;
|
||||||
Service::Account::ProfileManager profile_manager;
|
Service::Account::ProfileManager profile_manager;
|
||||||
Service::Time::TimeManager time_manager;
|
|
||||||
|
|
||||||
/// Service manager
|
/// Service manager
|
||||||
std::shared_ptr<Service::SM::ServiceManager> service_manager;
|
std::shared_ptr<Service::SM::ServiceManager> service_manager;
|
||||||
@ -639,8 +692,8 @@ void System::InitializeDebugger() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
|
SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
|
||||||
u64 program_id, std::size_t program_index) {
|
Service::AM::FrontendAppletParameters& params) {
|
||||||
return impl->Load(*this, emu_window, filepath, program_id, program_index);
|
return impl->Load(*this, emu_window, filepath, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool System::IsPoweredOn() const {
|
bool System::IsPoweredOn() const {
|
||||||
@ -830,19 +883,19 @@ void System::RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
|
|||||||
impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size);
|
impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set) {
|
void System::SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set) {
|
||||||
impl->applet_manager.SetAppletFrontendSet(std::move(set));
|
impl->frontend_applets.SetFrontendAppletSet(std::move(set));
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::SetDefaultAppletFrontendSet() {
|
Service::AM::Frontend::FrontendAppletHolder& System::GetFrontendAppletHolder() {
|
||||||
impl->applet_manager.SetDefaultAppletFrontendSet();
|
return impl->frontend_applets;
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::AM::Applets::AppletManager& System::GetAppletManager() {
|
const Service::AM::Frontend::FrontendAppletHolder& System::GetFrontendAppletHolder() const {
|
||||||
return impl->applet_manager;
|
return impl->frontend_applets;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Service::AM::Applets::AppletManager& System::GetAppletManager() const {
|
Service::AM::AppletManager& System::GetAppletManager() {
|
||||||
return impl->applet_manager;
|
return impl->applet_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,14 +964,6 @@ const Service::Account::ProfileManager& System::GetProfileManager() const {
|
|||||||
return impl->profile_manager;
|
return impl->profile_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::Time::TimeManager& System::GetTimeManager() {
|
|
||||||
return impl->time_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Service::Time::TimeManager& System::GetTimeManager() const {
|
|
||||||
return impl->time_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void System::SetExitLocked(bool locked) {
|
void System::SetExitLocked(bool locked) {
|
||||||
impl->exit_locked = locked;
|
impl->exit_locked = locked;
|
||||||
}
|
}
|
||||||
@ -1030,13 +1075,9 @@ void System::Exit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void System::ApplySettings() {
|
void System::ApplySettings() {
|
||||||
impl->RefreshTime();
|
impl->RefreshTime(*this);
|
||||||
|
|
||||||
if (IsPoweredOn()) {
|
if (IsPoweredOn()) {
|
||||||
if (Settings::values.custom_rtc_enabled) {
|
|
||||||
const s64 posix_time{Settings::values.custom_rtc.GetValue()};
|
|
||||||
GetTimeManager().UpdateLocalSystemClockTime(posix_time);
|
|
||||||
}
|
|
||||||
Renderer().RefreshBaseSettings();
|
Renderer().RefreshBaseSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
@ -50,10 +50,15 @@ namespace Account {
|
|||||||
class ProfileManager;
|
class ProfileManager;
|
||||||
} // namespace Account
|
} // namespace Account
|
||||||
|
|
||||||
namespace AM::Applets {
|
namespace AM {
|
||||||
struct AppletFrontendSet;
|
struct FrontendAppletParameters;
|
||||||
class AppletManager;
|
class AppletManager;
|
||||||
} // namespace AM::Applets
|
} // namespace AM
|
||||||
|
|
||||||
|
namespace AM::Frontend {
|
||||||
|
struct FrontendAppletSet;
|
||||||
|
class FrontendAppletHolder;
|
||||||
|
} // namespace AM::Frontend
|
||||||
|
|
||||||
namespace APM {
|
namespace APM {
|
||||||
class Controller;
|
class Controller;
|
||||||
@ -73,10 +78,6 @@ namespace SM {
|
|||||||
class ServiceManager;
|
class ServiceManager;
|
||||||
} // namespace SM
|
} // namespace SM
|
||||||
|
|
||||||
namespace Time {
|
|
||||||
class TimeManager;
|
|
||||||
} // namespace Time
|
|
||||||
|
|
||||||
} // namespace Service
|
} // namespace Service
|
||||||
|
|
||||||
namespace Tegra {
|
namespace Tegra {
|
||||||
@ -207,8 +208,8 @@ public:
|
|||||||
* @returns SystemResultStatus code, indicating if the operation succeeded.
|
* @returns SystemResultStatus code, indicating if the operation succeeded.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window,
|
[[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window,
|
||||||
const std::string& filepath, u64 program_id = 0,
|
const std::string& filepath,
|
||||||
std::size_t program_index = 0);
|
Service::AM::FrontendAppletParameters& params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
|
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
|
||||||
@ -348,11 +349,13 @@ public:
|
|||||||
const std::array<u8, 0x20>& build_id, u64 main_region_begin,
|
const std::array<u8, 0x20>& build_id, u64 main_region_begin,
|
||||||
u64 main_region_size);
|
u64 main_region_size);
|
||||||
|
|
||||||
void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set);
|
void SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set);
|
||||||
void SetDefaultAppletFrontendSet();
|
|
||||||
|
|
||||||
[[nodiscard]] Service::AM::Applets::AppletManager& GetAppletManager();
|
[[nodiscard]] Service::AM::Frontend::FrontendAppletHolder& GetFrontendAppletHolder();
|
||||||
[[nodiscard]] const Service::AM::Applets::AppletManager& GetAppletManager() const;
|
[[nodiscard]] const Service::AM::Frontend::FrontendAppletHolder& GetFrontendAppletHolder()
|
||||||
|
const;
|
||||||
|
|
||||||
|
[[nodiscard]] Service::AM::AppletManager& GetAppletManager();
|
||||||
|
|
||||||
void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider);
|
void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider);
|
||||||
|
|
||||||
@ -381,9 +384,6 @@ public:
|
|||||||
[[nodiscard]] Service::Account::ProfileManager& GetProfileManager();
|
[[nodiscard]] Service::Account::ProfileManager& GetProfileManager();
|
||||||
[[nodiscard]] const Service::Account::ProfileManager& GetProfileManager() const;
|
[[nodiscard]] const Service::Account::ProfileManager& GetProfileManager() const;
|
||||||
|
|
||||||
[[nodiscard]] Service::Time::TimeManager& GetTimeManager();
|
|
||||||
[[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const;
|
|
||||||
|
|
||||||
[[nodiscard]] Core::Debugger& GetDebugger();
|
[[nodiscard]] Core::Debugger& GetDebugger();
|
||||||
[[nodiscard]] const Core::Debugger& GetDebugger() const;
|
[[nodiscard]] const Core::Debugger& GetDebugger() const;
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto h : to_remove) {
|
for (auto& h : to_remove) {
|
||||||
event_queue.erase(h);
|
event_queue.erase(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <span>
|
#include <span>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace Core::Crypto {
|
namespace Core::Crypto {
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace Core::Crypto {
|
namespace Core::Crypto {
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include "core/crypto/partition_data_manager.h"
|
#include "core/crypto/partition_data_manager.h"
|
||||||
#include "core/crypto/xts_encryption_layer.h"
|
#include "core/crypto/xts_encryption_layer.h"
|
||||||
#include "core/file_sys/kernel_executable.h"
|
#include "core/file_sys/kernel_executable.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
#include "core/file_sys/vfs_vector.h"
|
#include "core/file_sys/vfs/vfs_vector.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
using Common::AsArray;
|
using Common::AsArray;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
|
|
||||||
namespace Core::Crypto {
|
namespace Core::Crypto {
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/range_mutex.h"
|
||||||
#include "common/scratch_buffer.h"
|
#include "common/scratch_buffer.h"
|
||||||
#include "common/virtual_buffer.h"
|
#include "common/virtual_buffer.h"
|
||||||
|
|
||||||
@ -204,7 +205,7 @@ private:
|
|||||||
(1ULL << (device_virtual_bits - page_bits)) / subentries;
|
(1ULL << (device_virtual_bits - page_bits)) / subentries;
|
||||||
using CachedPages = std::array<CounterEntry, num_counter_entries>;
|
using CachedPages = std::array<CounterEntry, num_counter_entries>;
|
||||||
std::unique_ptr<CachedPages> cached_pages;
|
std::unique_ptr<CachedPages> cached_pages;
|
||||||
std::mutex counter_guard;
|
Common::RangeMutex counter_guard;
|
||||||
std::mutex mapping_guard;
|
std::mutex mapping_guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -508,12 +508,7 @@ void DeviceMemoryManager<Traits>::UnregisterProcess(Asid asid) {
|
|||||||
|
|
||||||
template <typename Traits>
|
template <typename Traits>
|
||||||
void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta) {
|
void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta) {
|
||||||
std::unique_lock<std::mutex> lk(counter_guard, std::defer_lock);
|
Common::ScopedRangeLock lk(counter_guard, addr, size);
|
||||||
const auto Lock = [&] {
|
|
||||||
if (!lk) {
|
|
||||||
lk.lock();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
u64 uncache_begin = 0;
|
u64 uncache_begin = 0;
|
||||||
u64 cache_begin = 0;
|
u64 cache_begin = 0;
|
||||||
u64 uncache_bytes = 0;
|
u64 uncache_bytes = 0;
|
||||||
@ -548,7 +543,6 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
|
|||||||
}
|
}
|
||||||
uncache_bytes += Memory::YUZU_PAGESIZE;
|
uncache_bytes += Memory::YUZU_PAGESIZE;
|
||||||
} else if (uncache_bytes > 0) {
|
} else if (uncache_bytes > 0) {
|
||||||
Lock();
|
|
||||||
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
|
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
|
||||||
uncache_bytes, false);
|
uncache_bytes, false);
|
||||||
uncache_bytes = 0;
|
uncache_bytes = 0;
|
||||||
@ -559,7 +553,6 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
|
|||||||
}
|
}
|
||||||
cache_bytes += Memory::YUZU_PAGESIZE;
|
cache_bytes += Memory::YUZU_PAGESIZE;
|
||||||
} else if (cache_bytes > 0) {
|
} else if (cache_bytes > 0) {
|
||||||
Lock();
|
|
||||||
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
|
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
|
||||||
true);
|
true);
|
||||||
cache_bytes = 0;
|
cache_bytes = 0;
|
||||||
@ -567,12 +560,10 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
|
|||||||
vpage++;
|
vpage++;
|
||||||
}
|
}
|
||||||
if (uncache_bytes > 0) {
|
if (uncache_bytes > 0) {
|
||||||
Lock();
|
|
||||||
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes,
|
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
if (cache_bytes > 0) {
|
if (cache_bytes > 0) {
|
||||||
Lock();
|
|
||||||
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
|
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "core/file_sys/bis_factory.h"
|
#include "core/file_sys/bis_factory.h"
|
||||||
#include "core/file_sys/mode.h"
|
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
@ -84,7 +83,7 @@ VirtualFile BISFactory::OpenPartitionStorage(BisPartitionId id,
|
|||||||
VirtualFilesystem file_system) const {
|
VirtualFilesystem file_system) const {
|
||||||
auto& keys = Core::Crypto::KeyManager::Instance();
|
auto& keys = Core::Crypto::KeyManager::Instance();
|
||||||
Core::Crypto::PartitionDataManager pdm{file_system->OpenDirectory(
|
Core::Crypto::PartitionDataManager pdm{file_system->OpenDirectory(
|
||||||
Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir), Mode::Read)};
|
Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir), OpenMode::Read)};
|
||||||
keys.PopulateFromPartitionData(pdm);
|
keys.PopulateFromPartitionData(pdm);
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
#include "core/file_sys/nca_metadata.h"
|
#include "core/file_sys/nca_metadata.h"
|
||||||
#include "core/file_sys/partition_filesystem.h"
|
#include "core/file_sys/partition_filesystem.h"
|
||||||
#include "core/file_sys/submission_package.h"
|
#include "core/file_sys/submission_package.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
#include "core/file_sys/vfs_vector.h"
|
#include "core/file_sys/vfs/vfs_vector.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace Core::Crypto {
|
namespace Core::Crypto {
|
||||||
class KeyManager;
|
class KeyManager;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
#include "core/file_sys/partition_filesystem.h"
|
#include "core/file_sys/partition_filesystem.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
#include "core/file_sys/fssystem/fssystem_compression_configuration.h"
|
#include "core/file_sys/fssystem/fssystem_compression_configuration.h"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
enum class ResultStatus : u16;
|
enum class ResultStatus : u16;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include "common/common_funcs.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FileSys namespace
|
|
||||||
|
|
||||||
namespace FileSys {
|
|
||||||
|
|
||||||
enum class EntryType : u8 {
|
|
||||||
Directory = 0,
|
|
||||||
File = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Structure of a directory entry, from
|
|
||||||
// http://switchbrew.org/index.php?title=Filesystem_services#DirectoryEntry
|
|
||||||
struct Entry {
|
|
||||||
Entry(std::string_view view, EntryType entry_type, u64 entry_size)
|
|
||||||
: type{entry_type}, file_size{entry_size} {
|
|
||||||
const std::size_t copy_size = view.copy(filename, std::size(filename) - 1);
|
|
||||||
filename[copy_size] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
char filename[0x301];
|
|
||||||
INSERT_PADDING_BYTES(3);
|
|
||||||
EntryType type;
|
|
||||||
INSERT_PADDING_BYTES(3);
|
|
||||||
u64 file_size;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(Entry) == 0x310, "Directory Entry struct isn't exactly 0x310 bytes long!");
|
|
||||||
static_assert(offsetof(Entry, type) == 0x304, "Wrong offset for type in Entry.");
|
|
||||||
static_assert(offsetof(Entry, file_size) == 0x308, "Wrong offset for file_size in Entry.");
|
|
||||||
|
|
||||||
} // namespace FileSys
|
|
@ -7,18 +7,13 @@
|
|||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
constexpr Result ERROR_PATH_NOT_FOUND{ErrorModule::FS, 1};
|
constexpr Result ResultPathNotFound{ErrorModule::FS, 1};
|
||||||
constexpr Result ERROR_PATH_ALREADY_EXISTS{ErrorModule::FS, 2};
|
constexpr Result ResultPathAlreadyExists{ErrorModule::FS, 2};
|
||||||
constexpr Result ERROR_ENTITY_NOT_FOUND{ErrorModule::FS, 1002};
|
|
||||||
constexpr Result ERROR_SD_CARD_NOT_FOUND{ErrorModule::FS, 2001};
|
|
||||||
constexpr Result ERROR_OUT_OF_BOUNDS{ErrorModule::FS, 3005};
|
|
||||||
constexpr Result ERROR_FAILED_MOUNT_ARCHIVE{ErrorModule::FS, 3223};
|
|
||||||
constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::FS, 6001};
|
|
||||||
constexpr Result ERROR_INVALID_OFFSET{ErrorModule::FS, 6061};
|
|
||||||
constexpr Result ERROR_INVALID_SIZE{ErrorModule::FS, 6062};
|
|
||||||
|
|
||||||
constexpr Result ResultUnsupportedSdkVersion{ErrorModule::FS, 50};
|
constexpr Result ResultUnsupportedSdkVersion{ErrorModule::FS, 50};
|
||||||
constexpr Result ResultPartitionNotFound{ErrorModule::FS, 1001};
|
constexpr Result ResultPartitionNotFound{ErrorModule::FS, 1001};
|
||||||
|
constexpr Result ResultTargetNotFound{ErrorModule::FS, 1002};
|
||||||
|
constexpr Result ResultPortSdCardNoDevice{ErrorModule::FS, 2001};
|
||||||
|
constexpr Result ResultNotImplemented{ErrorModule::FS, 3001};
|
||||||
constexpr Result ResultUnsupportedVersion{ErrorModule::FS, 3002};
|
constexpr Result ResultUnsupportedVersion{ErrorModule::FS, 3002};
|
||||||
constexpr Result ResultOutOfRange{ErrorModule::FS, 3005};
|
constexpr Result ResultOutOfRange{ErrorModule::FS, 3005};
|
||||||
constexpr Result ResultAllocationMemoryFailedInFileSystemBuddyHeapA{ErrorModule::FS, 3294};
|
constexpr Result ResultAllocationMemoryFailedInFileSystemBuddyHeapA{ErrorModule::FS, 3294};
|
||||||
@ -78,10 +73,21 @@ constexpr Result ResultUnexpectedInCompressedStorageA{ErrorModule::FS, 5324};
|
|||||||
constexpr Result ResultUnexpectedInCompressedStorageB{ErrorModule::FS, 5325};
|
constexpr Result ResultUnexpectedInCompressedStorageB{ErrorModule::FS, 5325};
|
||||||
constexpr Result ResultUnexpectedInCompressedStorageC{ErrorModule::FS, 5326};
|
constexpr Result ResultUnexpectedInCompressedStorageC{ErrorModule::FS, 5326};
|
||||||
constexpr Result ResultUnexpectedInCompressedStorageD{ErrorModule::FS, 5327};
|
constexpr Result ResultUnexpectedInCompressedStorageD{ErrorModule::FS, 5327};
|
||||||
|
constexpr Result ResultUnexpectedInPathA{ErrorModule::FS, 5328};
|
||||||
constexpr Result ResultInvalidArgument{ErrorModule::FS, 6001};
|
constexpr Result ResultInvalidArgument{ErrorModule::FS, 6001};
|
||||||
|
constexpr Result ResultInvalidPath{ErrorModule::FS, 6002};
|
||||||
|
constexpr Result ResultTooLongPath{ErrorModule::FS, 6003};
|
||||||
|
constexpr Result ResultInvalidCharacter{ErrorModule::FS, 6004};
|
||||||
|
constexpr Result ResultInvalidPathFormat{ErrorModule::FS, 6005};
|
||||||
|
constexpr Result ResultDirectoryUnobtainable{ErrorModule::FS, 6006};
|
||||||
|
constexpr Result ResultNotNormalized{ErrorModule::FS, 6007};
|
||||||
constexpr Result ResultInvalidOffset{ErrorModule::FS, 6061};
|
constexpr Result ResultInvalidOffset{ErrorModule::FS, 6061};
|
||||||
constexpr Result ResultInvalidSize{ErrorModule::FS, 6062};
|
constexpr Result ResultInvalidSize{ErrorModule::FS, 6062};
|
||||||
constexpr Result ResultNullptrArgument{ErrorModule::FS, 6063};
|
constexpr Result ResultNullptrArgument{ErrorModule::FS, 6063};
|
||||||
|
constexpr Result ResultInvalidOpenMode{ErrorModule::FS, 6072};
|
||||||
|
constexpr Result ResultFileExtensionWithoutOpenModeAllowAppend{ErrorModule::FS, 6201};
|
||||||
|
constexpr Result ResultReadNotPermitted{ErrorModule::FS, 6202};
|
||||||
|
constexpr Result ResultWriteNotPermitted{ErrorModule::FS, 6203};
|
||||||
constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325};
|
constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325};
|
||||||
constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387};
|
constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387};
|
||||||
constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388};
|
constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388};
|
||||||
|
33
src/core/file_sys/fs_directory.h
Normal file
33
src/core/file_sys/fs_directory.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
constexpr inline size_t EntryNameLengthMax = 0x300;
|
||||||
|
|
||||||
|
struct DirectoryEntry {
|
||||||
|
DirectoryEntry(std::string_view view, s8 entry_type, u64 entry_size)
|
||||||
|
: type{entry_type}, file_size{static_cast<s64>(entry_size)} {
|
||||||
|
const std::size_t copy_size = view.copy(name, std::size(name) - 1);
|
||||||
|
name[copy_size] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[EntryNameLengthMax + 1];
|
||||||
|
INSERT_PADDING_BYTES(3);
|
||||||
|
s8 type;
|
||||||
|
INSERT_PADDING_BYTES(3);
|
||||||
|
s64 file_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(DirectoryEntry) == 0x310,
|
||||||
|
"Directory Entry struct isn't exactly 0x310 bytes long!");
|
||||||
|
static_assert(offsetof(DirectoryEntry, type) == 0x304, "Wrong offset for type in Entry.");
|
||||||
|
static_assert(offsetof(DirectoryEntry, file_size) == 0x308, "Wrong offset for file_size in Entry.");
|
||||||
|
|
||||||
|
struct DirectoryHandle {
|
||||||
|
void* handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
65
src/core/file_sys/fs_file.h
Normal file
65
src/core/file_sys/fs_file.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
struct ReadOption {
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
static const ReadOption None;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ReadOptionFlag : u32 {
|
||||||
|
ReadOptionFlag_None = (0 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr const ReadOption ReadOption::None = {ReadOptionFlag_None};
|
||||||
|
|
||||||
|
inline constexpr bool operator==(const ReadOption& lhs, const ReadOption& rhs) {
|
||||||
|
return lhs.value == rhs.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr bool operator!=(const ReadOption& lhs, const ReadOption& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(sizeof(ReadOption) == sizeof(u32));
|
||||||
|
|
||||||
|
enum WriteOptionFlag : u32 {
|
||||||
|
WriteOptionFlag_None = (0 << 0),
|
||||||
|
WriteOptionFlag_Flush = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WriteOption {
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
constexpr inline bool HasFlushFlag() const {
|
||||||
|
return value & WriteOptionFlag_Flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const WriteOption None;
|
||||||
|
static const WriteOption Flush;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr const WriteOption WriteOption::None = {WriteOptionFlag_None};
|
||||||
|
inline constexpr const WriteOption WriteOption::Flush = {WriteOptionFlag_Flush};
|
||||||
|
|
||||||
|
inline constexpr bool operator==(const WriteOption& lhs, const WriteOption& rhs) {
|
||||||
|
return lhs.value == rhs.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr bool operator!=(const WriteOption& lhs, const WriteOption& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(sizeof(WriteOption) == sizeof(u32));
|
||||||
|
|
||||||
|
struct FileHandle {
|
||||||
|
void* handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
39
src/core/file_sys/fs_filesystem.h
Normal file
39
src/core/file_sys/fs_filesystem.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
enum class OpenMode : u32 {
|
||||||
|
Read = (1 << 0),
|
||||||
|
Write = (1 << 1),
|
||||||
|
AllowAppend = (1 << 2),
|
||||||
|
|
||||||
|
ReadWrite = (Read | Write),
|
||||||
|
All = (ReadWrite | AllowAppend),
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OpenMode)
|
||||||
|
|
||||||
|
enum class OpenDirectoryMode : u64 {
|
||||||
|
Directory = (1 << 0),
|
||||||
|
File = (1 << 1),
|
||||||
|
|
||||||
|
All = (Directory | File),
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OpenDirectoryMode)
|
||||||
|
|
||||||
|
enum class DirectoryEntryType : u8 {
|
||||||
|
Directory = 0,
|
||||||
|
File = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CreateOption : u8 {
|
||||||
|
None = (0 << 0),
|
||||||
|
BigFile = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
40
src/core/file_sys/fs_memory_management.h
Normal file
40
src/core/file_sys/fs_memory_management.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include "common/alignment.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
constexpr size_t RequiredAlignment = alignof(u64);
|
||||||
|
|
||||||
|
void* AllocateUnsafe(size_t size) {
|
||||||
|
// Allocate
|
||||||
|
void* const ptr = ::operator new(size, std::align_val_t{RequiredAlignment});
|
||||||
|
|
||||||
|
// Check alignment
|
||||||
|
ASSERT(Common::IsAligned(reinterpret_cast<uintptr_t>(ptr), RequiredAlignment));
|
||||||
|
|
||||||
|
// Return allocated pointer
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeallocateUnsafe(void* ptr, size_t size) {
|
||||||
|
// Deallocate the pointer
|
||||||
|
::operator delete(ptr, std::align_val_t{RequiredAlignment});
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Allocate(size_t size) {
|
||||||
|
return AllocateUnsafe(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Deallocate(void* ptr, size_t size) {
|
||||||
|
// If the pointer is non-null, deallocate it
|
||||||
|
if (ptr != nullptr) {
|
||||||
|
DeallocateUnsafe(ptr, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
22
src/core/file_sys/fs_operate_range.h
Normal file
22
src/core/file_sys/fs_operate_range.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
enum class OperationId : s64 {
|
||||||
|
FillZero = 0,
|
||||||
|
DestroySignature = 1,
|
||||||
|
Invalidate = 2,
|
||||||
|
QueryRange = 3,
|
||||||
|
QueryUnpreparedRange = 4,
|
||||||
|
QueryLazyLoadCompletionRate = 5,
|
||||||
|
SetLazyLoadPriority = 6,
|
||||||
|
|
||||||
|
ReadLazyLoadFileForciblyForDebug = 10001,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
566
src/core/file_sys/fs_path.h
Normal file
566
src/core/file_sys/fs_path.h
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/alignment.h"
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "core/file_sys/errors.h"
|
||||||
|
#include "core/file_sys/fs_memory_management.h"
|
||||||
|
#include "core/file_sys/fs_path_utility.h"
|
||||||
|
#include "core/file_sys/fs_string_util.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
class DirectoryPathParser;
|
||||||
|
|
||||||
|
class Path {
|
||||||
|
YUZU_NON_COPYABLE(Path);
|
||||||
|
YUZU_NON_MOVEABLE(Path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr const char* EmptyPath = "";
|
||||||
|
static constexpr size_t WriteBufferAlignmentLength = 8;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class DirectoryPathParser;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class WriteBuffer {
|
||||||
|
YUZU_NON_COPYABLE(WriteBuffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* m_buffer;
|
||||||
|
size_t m_length_and_is_normalized;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) {}
|
||||||
|
|
||||||
|
constexpr ~WriteBuffer() {
|
||||||
|
if (m_buffer != nullptr) {
|
||||||
|
Deallocate(m_buffer, this->GetLength());
|
||||||
|
this->ResetBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr WriteBuffer(WriteBuffer&& rhs)
|
||||||
|
: m_buffer(rhs.m_buffer), m_length_and_is_normalized(rhs.m_length_and_is_normalized) {
|
||||||
|
rhs.ResetBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr WriteBuffer& operator=(WriteBuffer&& rhs) {
|
||||||
|
if (m_buffer != nullptr) {
|
||||||
|
Deallocate(m_buffer, this->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer = rhs.m_buffer;
|
||||||
|
m_length_and_is_normalized = rhs.m_length_and_is_normalized;
|
||||||
|
|
||||||
|
rhs.ResetBuffer();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void ResetBuffer() {
|
||||||
|
m_buffer = nullptr;
|
||||||
|
this->SetLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr char* Get() const {
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t GetLength() const {
|
||||||
|
return m_length_and_is_normalized >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsNormalized() const {
|
||||||
|
return static_cast<bool>(m_length_and_is_normalized & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void SetNormalized() {
|
||||||
|
m_length_and_is_normalized |= static_cast<size_t>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void SetNotNormalized() {
|
||||||
|
m_length_and_is_normalized &= ~static_cast<size_t>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
constexpr WriteBuffer(char* buffer, size_t length)
|
||||||
|
: m_buffer(buffer), m_length_and_is_normalized(0) {
|
||||||
|
this->SetLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static WriteBuffer Make(size_t length) {
|
||||||
|
if (void* alloc = Allocate(length); alloc != nullptr) {
|
||||||
|
return WriteBuffer(static_cast<char*>(alloc), length);
|
||||||
|
} else {
|
||||||
|
return WriteBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
constexpr void SetLength(size_t size) {
|
||||||
|
m_length_and_is_normalized = (m_length_and_is_normalized & 1) | (size << 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* m_str;
|
||||||
|
WriteBuffer m_write_buffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr Path() : m_str(EmptyPath), m_write_buffer() {}
|
||||||
|
|
||||||
|
constexpr Path(const char* s) : m_str(s), m_write_buffer() {
|
||||||
|
m_write_buffer.SetNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ~Path() = default;
|
||||||
|
|
||||||
|
constexpr Result SetShallowBuffer(const char* buffer) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(m_write_buffer.GetLength() == 0);
|
||||||
|
|
||||||
|
// Check the buffer is valid
|
||||||
|
R_UNLESS(buffer != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
// Set buffer
|
||||||
|
this->SetReadOnlyBuffer(buffer);
|
||||||
|
|
||||||
|
// Note that we're normalized
|
||||||
|
this->SetNormalized();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const char* GetString() const {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(this->IsNormalized());
|
||||||
|
|
||||||
|
return m_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t GetLength() const {
|
||||||
|
if (std::is_constant_evaluated()) {
|
||||||
|
return Strlen(this->GetString());
|
||||||
|
} else {
|
||||||
|
return std::strlen(this->GetString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsEmpty() const {
|
||||||
|
return *m_str == '\x00';
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsMatchHead(const char* p, size_t len) const {
|
||||||
|
return Strncmp(this->GetString(), p, len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Initialize(const Path& rhs) {
|
||||||
|
// Check the other path is normalized
|
||||||
|
const bool normalized = rhs.IsNormalized();
|
||||||
|
R_UNLESS(normalized, ResultNotNormalized);
|
||||||
|
|
||||||
|
// Allocate buffer for our path
|
||||||
|
const auto len = rhs.GetLength();
|
||||||
|
R_TRY(this->Preallocate(len + 1));
|
||||||
|
|
||||||
|
// Copy the path
|
||||||
|
const size_t copied = Strlcpy<char>(m_write_buffer.Get(), rhs.GetString(), len + 1);
|
||||||
|
R_UNLESS(copied == len, ResultUnexpectedInPathA);
|
||||||
|
|
||||||
|
// Set normalized
|
||||||
|
this->SetNormalized();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Initialize(const char* path, size_t len) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(path != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
R_TRY(this->InitializeImpl(path, len));
|
||||||
|
|
||||||
|
// Set not normalized
|
||||||
|
this->SetNotNormalized();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Initialize(const char* path) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(path != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
R_RETURN(this->Initialize(path, std::strlen(path)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result InitializeWithReplaceBackslash(const char* path) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(path != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||||
|
|
||||||
|
// Replace slashes as desired
|
||||||
|
if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) {
|
||||||
|
Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set not normalized
|
||||||
|
this->SetNotNormalized();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result InitializeWithReplaceForwardSlashes(const char* path) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(path != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||||
|
|
||||||
|
// Replace slashes as desired
|
||||||
|
if (m_write_buffer.GetLength() > 1) {
|
||||||
|
if (auto* p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') {
|
||||||
|
p[0] = '\\';
|
||||||
|
p[1] = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set not normalized
|
||||||
|
this->SetNotNormalized();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result InitializeWithNormalization(const char* path, size_t size) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(path != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
R_TRY(this->InitializeImpl(path, size));
|
||||||
|
|
||||||
|
// Set not normalized
|
||||||
|
this->SetNotNormalized();
|
||||||
|
|
||||||
|
// Perform normalization
|
||||||
|
PathFlags path_flags;
|
||||||
|
if (IsPathRelative(m_str)) {
|
||||||
|
path_flags.AllowRelativePath();
|
||||||
|
} else if (IsWindowsPath(m_str, true)) {
|
||||||
|
path_flags.AllowWindowsPath();
|
||||||
|
} else {
|
||||||
|
/* NOTE: In this case, Nintendo checks is normalized, then sets is normalized, then
|
||||||
|
* returns success. */
|
||||||
|
/* This seems like a bug. */
|
||||||
|
size_t dummy;
|
||||||
|
bool normalized;
|
||||||
|
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy),
|
||||||
|
m_str));
|
||||||
|
|
||||||
|
this->SetNormalized();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
R_TRY(this->Normalize(path_flags));
|
||||||
|
|
||||||
|
this->SetNormalized();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result InitializeWithNormalization(const char* path) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(path != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
R_RETURN(this->InitializeWithNormalization(path, std::strlen(path)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result InitializeAsEmpty() {
|
||||||
|
// Clear our buffer
|
||||||
|
this->ClearBuffer();
|
||||||
|
|
||||||
|
// Set normalized
|
||||||
|
this->SetNormalized();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result AppendChild(const char* child) {
|
||||||
|
// Check the path is valid
|
||||||
|
R_UNLESS(child != nullptr, ResultNullptrArgument);
|
||||||
|
|
||||||
|
// Basic checks. If we have a path and the child is empty, we have nothing to do
|
||||||
|
const char* c = child;
|
||||||
|
if (m_str[0]) {
|
||||||
|
// Skip an early separator
|
||||||
|
if (*c == '/') {
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED_IF(*c == '\x00');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have a string, we can just initialize
|
||||||
|
auto cur_len = std::strlen(m_str);
|
||||||
|
if (cur_len == 0) {
|
||||||
|
R_RETURN(this->Initialize(child));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a trailing separator
|
||||||
|
if (m_str[cur_len - 1] == '/' || m_str[cur_len - 1] == '\\') {
|
||||||
|
--cur_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the child path's length
|
||||||
|
auto child_len = std::strlen(c);
|
||||||
|
|
||||||
|
// Reset our write buffer
|
||||||
|
WriteBuffer old_write_buffer;
|
||||||
|
if (m_write_buffer.Get() != nullptr) {
|
||||||
|
old_write_buffer = std::move(m_write_buffer);
|
||||||
|
this->ClearBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-allocate the new buffer
|
||||||
|
R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
|
||||||
|
|
||||||
|
// Get our write buffer
|
||||||
|
auto* dst = m_write_buffer.Get();
|
||||||
|
if (old_write_buffer.Get() != nullptr && cur_len > 0) {
|
||||||
|
Strlcpy<char>(dst, old_write_buffer.Get(), cur_len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add separator
|
||||||
|
dst[cur_len] = '/';
|
||||||
|
|
||||||
|
// Copy the child path
|
||||||
|
const size_t copied = Strlcpy<char>(dst + cur_len + 1, c, child_len + 1);
|
||||||
|
R_UNLESS(copied == child_len, ResultUnexpectedInPathA);
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result AppendChild(const Path& rhs) {
|
||||||
|
R_RETURN(this->AppendChild(rhs.GetString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Combine(const Path& parent, const Path& child) {
|
||||||
|
// Get the lengths
|
||||||
|
const auto p_len = parent.GetLength();
|
||||||
|
const auto c_len = child.GetLength();
|
||||||
|
|
||||||
|
// Allocate our buffer
|
||||||
|
R_TRY(this->Preallocate(p_len + c_len + 1));
|
||||||
|
|
||||||
|
// Initialize as parent
|
||||||
|
R_TRY(this->Initialize(parent));
|
||||||
|
|
||||||
|
// If we're empty, we can just initialize as child
|
||||||
|
if (this->IsEmpty()) {
|
||||||
|
R_TRY(this->Initialize(child));
|
||||||
|
} else {
|
||||||
|
// Otherwise, we should append the child
|
||||||
|
R_TRY(this->AppendChild(child));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result RemoveChild() {
|
||||||
|
// If we don't have a write-buffer, ensure that we have one
|
||||||
|
if (m_write_buffer.Get() == nullptr) {
|
||||||
|
if (const auto len = std::strlen(m_str); len > 0) {
|
||||||
|
R_TRY(this->Preallocate(len));
|
||||||
|
Strlcpy<char>(m_write_buffer.Get(), m_str, len + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that it's possible for us to remove a child
|
||||||
|
auto* p = m_write_buffer.Get();
|
||||||
|
s32 len = std::strlen(p);
|
||||||
|
R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), ResultNotImplemented);
|
||||||
|
|
||||||
|
// Handle a trailing separator
|
||||||
|
if (len > 0 && (p[len - 1] == '\\' || p[len - 1] == '/')) {
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the child path segment
|
||||||
|
while ((--len) >= 0 && p[len]) {
|
||||||
|
if (p[len] == '/' || p[len] == '\\') {
|
||||||
|
if (len > 0) {
|
||||||
|
p[len] = 0;
|
||||||
|
} else {
|
||||||
|
p[1] = 0;
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that length remains > 0
|
||||||
|
R_UNLESS(len > 0, ResultNotImplemented);
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Normalize(const PathFlags& flags) {
|
||||||
|
// If we're already normalized, nothing to do
|
||||||
|
R_SUCCEED_IF(this->IsNormalized());
|
||||||
|
|
||||||
|
// Check if we're normalized
|
||||||
|
bool normalized;
|
||||||
|
size_t dummy;
|
||||||
|
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str,
|
||||||
|
flags));
|
||||||
|
|
||||||
|
// If we're not normalized, normalize
|
||||||
|
if (!normalized) {
|
||||||
|
// Determine necessary buffer length
|
||||||
|
auto len = m_write_buffer.GetLength();
|
||||||
|
if (flags.IsRelativePathAllowed() && IsPathRelative(m_str)) {
|
||||||
|
len += 2;
|
||||||
|
}
|
||||||
|
if (flags.IsWindowsPathAllowed() && IsWindowsPath(m_str, true)) {
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a new buffer
|
||||||
|
const size_t size = Common::AlignUp(len, WriteBufferAlignmentLength);
|
||||||
|
auto buf = WriteBuffer::Make(size);
|
||||||
|
R_UNLESS(buf.Get() != nullptr, ResultAllocationMemoryFailedMakeUnique);
|
||||||
|
|
||||||
|
// Normalize into it
|
||||||
|
R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(),
|
||||||
|
m_write_buffer.GetLength(), flags));
|
||||||
|
|
||||||
|
// Set the normalized buffer as our buffer
|
||||||
|
this->SetModifiableBuffer(std::move(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set normalized
|
||||||
|
this->SetNormalized();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ClearBuffer() {
|
||||||
|
m_write_buffer.ResetBuffer();
|
||||||
|
m_str = EmptyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetModifiableBuffer(WriteBuffer&& buffer) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(buffer.Get() != nullptr);
|
||||||
|
ASSERT(buffer.GetLength() > 0);
|
||||||
|
ASSERT(Common::IsAligned(buffer.GetLength(), WriteBufferAlignmentLength));
|
||||||
|
|
||||||
|
// Get whether we're normalized
|
||||||
|
if (m_write_buffer.IsNormalized()) {
|
||||||
|
buffer.SetNormalized();
|
||||||
|
} else {
|
||||||
|
buffer.SetNotNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set write buffer
|
||||||
|
m_write_buffer = std::move(buffer);
|
||||||
|
m_str = m_write_buffer.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void SetReadOnlyBuffer(const char* buffer) {
|
||||||
|
m_str = buffer;
|
||||||
|
m_write_buffer.ResetBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Preallocate(size_t length) {
|
||||||
|
// Allocate additional space, if needed
|
||||||
|
if (length > m_write_buffer.GetLength()) {
|
||||||
|
// Allocate buffer
|
||||||
|
const size_t size = Common::AlignUp(length, WriteBufferAlignmentLength);
|
||||||
|
auto buf = WriteBuffer::Make(size);
|
||||||
|
R_UNLESS(buf.Get() != nullptr, ResultAllocationMemoryFailedMakeUnique);
|
||||||
|
|
||||||
|
// Set write buffer
|
||||||
|
this->SetModifiableBuffer(std::move(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result InitializeImpl(const char* path, size_t size) {
|
||||||
|
if (size > 0 && path[0]) {
|
||||||
|
// Pre allocate a buffer for the path
|
||||||
|
R_TRY(this->Preallocate(size + 1));
|
||||||
|
|
||||||
|
// Copy the path
|
||||||
|
const size_t copied = Strlcpy<char>(m_write_buffer.Get(), path, size + 1);
|
||||||
|
R_UNLESS(copied >= size, ResultUnexpectedInPathA);
|
||||||
|
} else {
|
||||||
|
// We can just clear the buffer
|
||||||
|
this->ClearBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr char* GetWriteBuffer() {
|
||||||
|
ASSERT(m_write_buffer.Get() != nullptr);
|
||||||
|
return m_write_buffer.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t GetWriteBufferLength() const {
|
||||||
|
return m_write_buffer.GetLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsNormalized() const {
|
||||||
|
return m_write_buffer.IsNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void SetNormalized() {
|
||||||
|
m_write_buffer.SetNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void SetNotNormalized() {
|
||||||
|
m_write_buffer.SetNotNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool operator==(const FileSys::Path& rhs) const {
|
||||||
|
return std::strcmp(this->GetString(), rhs.GetString()) == 0;
|
||||||
|
}
|
||||||
|
bool operator!=(const FileSys::Path& rhs) const {
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
bool operator==(const char* p) const {
|
||||||
|
return std::strcmp(this->GetString(), p) == 0;
|
||||||
|
}
|
||||||
|
bool operator!=(const char* p) const {
|
||||||
|
return !(*this == p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Result SetUpFixedPath(FileSys::Path* out, const char* s) {
|
||||||
|
// Verify the path is normalized
|
||||||
|
bool normalized;
|
||||||
|
size_t dummy;
|
||||||
|
R_TRY(PathNormalizer::IsNormalized(std::addressof(normalized), std::addressof(dummy), s));
|
||||||
|
|
||||||
|
R_UNLESS(normalized, ResultInvalidPathFormat);
|
||||||
|
|
||||||
|
// Set the fixed path
|
||||||
|
R_RETURN(out->SetShallowBuffer(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline bool IsWindowsDriveRootPath(const FileSys::Path& path) {
|
||||||
|
const char* const str = path.GetString();
|
||||||
|
return IsWindowsDrive(str) &&
|
||||||
|
(str[2] == StringTraits::DirectorySeparator ||
|
||||||
|
str[2] == StringTraits::AlternateDirectorySeparator) &&
|
||||||
|
str[3] == StringTraits::NullTerminator;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
1239
src/core/file_sys/fs_path_utility.h
Normal file
1239
src/core/file_sys/fs_path_utility.h
Normal file
File diff suppressed because it is too large
Load Diff
226
src/core/file_sys/fs_string_util.h
Normal file
226
src/core/file_sys/fs_string_util.h
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr int Strlen(const T* str) {
|
||||||
|
ASSERT(str != nullptr);
|
||||||
|
|
||||||
|
int length = 0;
|
||||||
|
while (*str++) {
|
||||||
|
++length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr int Strnlen(const T* str, int count) {
|
||||||
|
ASSERT(str != nullptr);
|
||||||
|
ASSERT(count >= 0);
|
||||||
|
|
||||||
|
int length = 0;
|
||||||
|
while (count-- && *str++) {
|
||||||
|
++length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr int Strncmp(const T* lhs, const T* rhs, int count) {
|
||||||
|
ASSERT(lhs != nullptr);
|
||||||
|
ASSERT(rhs != nullptr);
|
||||||
|
ASSERT(count >= 0);
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
T l, r;
|
||||||
|
do {
|
||||||
|
l = *(lhs++);
|
||||||
|
r = *(rhs++);
|
||||||
|
} while (l && (l == r) && (--count));
|
||||||
|
|
||||||
|
return l - r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr int Strlcpy(T* dst, const T* src, int count) {
|
||||||
|
ASSERT(dst != nullptr);
|
||||||
|
ASSERT(src != nullptr);
|
||||||
|
|
||||||
|
const T* cur = src;
|
||||||
|
if (count > 0) {
|
||||||
|
while ((--count) && *cur) {
|
||||||
|
*(dst++) = *(cur++);
|
||||||
|
}
|
||||||
|
*dst = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*cur) {
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<int>(cur - src);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CharacterEncodingResult {
|
||||||
|
CharacterEncodingResult_Success = 0,
|
||||||
|
CharacterEncodingResult_InsufficientLength = 1,
|
||||||
|
CharacterEncodingResult_InvalidFormat = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
class CharacterEncodingHelper {
|
||||||
|
public:
|
||||||
|
static constexpr int8_t Utf8NBytesInnerTable[0x100 + 1] = {
|
||||||
|
-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr char GetUtf8NBytes(size_t i) {
|
||||||
|
return static_cast<char>(Utf8NBytesInnerTable[1 + i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace impl
|
||||||
|
|
||||||
|
constexpr inline CharacterEncodingResult ConvertCharacterUtf8ToUtf32(u32* dst, const char* src) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(dst != nullptr);
|
||||||
|
ASSERT(src != nullptr);
|
||||||
|
|
||||||
|
// Perform the conversion
|
||||||
|
const auto* p = src;
|
||||||
|
switch (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[0]))) {
|
||||||
|
case 1:
|
||||||
|
*dst = static_cast<u32>(p[0]);
|
||||||
|
return CharacterEncodingResult_Success;
|
||||||
|
case 2:
|
||||||
|
if ((static_cast<u32>(p[0]) & 0x1E) != 0) {
|
||||||
|
if (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[1])) ==
|
||||||
|
0) {
|
||||||
|
*dst = (static_cast<u32>(p[0] & 0x1F) << 6) | (static_cast<u32>(p[1] & 0x3F) << 0);
|
||||||
|
return CharacterEncodingResult_Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[1])) == 0 &&
|
||||||
|
impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[2])) == 0) {
|
||||||
|
const u32 c = (static_cast<u32>(p[0] & 0xF) << 12) |
|
||||||
|
(static_cast<u32>(p[1] & 0x3F) << 6) |
|
||||||
|
(static_cast<u32>(p[2] & 0x3F) << 0);
|
||||||
|
if ((c & 0xF800) != 0 && (c & 0xF800) != 0xD800) {
|
||||||
|
*dst = c;
|
||||||
|
return CharacterEncodingResult_Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
case 4:
|
||||||
|
if (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[1])) == 0 &&
|
||||||
|
impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[2])) == 0 &&
|
||||||
|
impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[3])) == 0) {
|
||||||
|
const u32 c =
|
||||||
|
(static_cast<u32>(p[0] & 0x7) << 18) | (static_cast<u32>(p[1] & 0x3F) << 12) |
|
||||||
|
(static_cast<u32>(p[2] & 0x3F) << 6) | (static_cast<u32>(p[3] & 0x3F) << 0);
|
||||||
|
if (c >= 0x10000 && c < 0x110000) {
|
||||||
|
*dst = c;
|
||||||
|
return CharacterEncodingResult_Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We failed to convert
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline CharacterEncodingResult PickOutCharacterFromUtf8String(char* dst,
|
||||||
|
const char** str) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(dst != nullptr);
|
||||||
|
ASSERT(str != nullptr);
|
||||||
|
ASSERT(*str != nullptr);
|
||||||
|
|
||||||
|
// Clear the output
|
||||||
|
dst[0] = 0;
|
||||||
|
dst[1] = 0;
|
||||||
|
dst[2] = 0;
|
||||||
|
dst[3] = 0;
|
||||||
|
|
||||||
|
// Perform the conversion
|
||||||
|
const auto* p = *str;
|
||||||
|
u32 c = static_cast<u32>(*p);
|
||||||
|
switch (impl::CharacterEncodingHelper::GetUtf8NBytes(c)) {
|
||||||
|
case 1:
|
||||||
|
dst[0] = (*str)[0];
|
||||||
|
++(*str);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if ((p[0] & 0x1E) != 0) {
|
||||||
|
if (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[1])) ==
|
||||||
|
0) {
|
||||||
|
c = (static_cast<u32>(p[0] & 0x1F) << 6) | (static_cast<u32>(p[1] & 0x3F) << 0);
|
||||||
|
dst[0] = (*str)[0];
|
||||||
|
dst[1] = (*str)[1];
|
||||||
|
(*str) += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
case 3:
|
||||||
|
if (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[1])) == 0 &&
|
||||||
|
impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[2])) == 0) {
|
||||||
|
c = (static_cast<u32>(p[0] & 0xF) << 12) | (static_cast<u32>(p[1] & 0x3F) << 6) |
|
||||||
|
(static_cast<u32>(p[2] & 0x3F) << 0);
|
||||||
|
if ((c & 0xF800) != 0 && (c & 0xF800) != 0xD800) {
|
||||||
|
dst[0] = (*str)[0];
|
||||||
|
dst[1] = (*str)[1];
|
||||||
|
dst[2] = (*str)[2];
|
||||||
|
(*str) += 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
case 4:
|
||||||
|
if (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[1])) == 0 &&
|
||||||
|
impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[2])) == 0 &&
|
||||||
|
impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[3])) == 0) {
|
||||||
|
c = (static_cast<u32>(p[0] & 0x7) << 18) | (static_cast<u32>(p[1] & 0x3F) << 12) |
|
||||||
|
(static_cast<u32>(p[2] & 0x3F) << 6) | (static_cast<u32>(p[3] & 0x3F) << 0);
|
||||||
|
if (c >= 0x10000 && c < 0x110000) {
|
||||||
|
dst[0] = (*str)[0];
|
||||||
|
dst[1] = (*str)[1];
|
||||||
|
dst[2] = (*str)[2];
|
||||||
|
dst[3] = (*str)[3];
|
||||||
|
(*str) += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
default:
|
||||||
|
return CharacterEncodingResult_InvalidFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CharacterEncodingResult_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
@ -8,8 +8,8 @@
|
|||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "core/file_sys/fsmitm_romfsbuild.h"
|
#include "core/file_sys/fsmitm_romfsbuild.h"
|
||||||
#include "core/file_sys/ips_layer.h"
|
#include "core/file_sys/ips_layer.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
#include "core/file_sys/vfs_vector.h"
|
#include "core/file_sys/vfs/vfs_vector.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "common/overflow.h"
|
#include "common/overflow.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h"
|
#include "core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h"
|
#include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_nca_header.h"
|
#include "core/file_sys/fssystem/fssystem_nca_header.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/literals.h"
|
#include "common/literals.h"
|
||||||
|
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_compression_common.h"
|
#include "core/file_sys/fssystem/fssystem_compression_common.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h"
|
#include "core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "core/file_sys/fssystem/fs_types.h"
|
#include "core/file_sys/fssystem/fs_types.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_alignment_matching_storage.h"
|
#include "core/file_sys/fssystem/fssystem_alignment_matching_storage.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_integrity_verification_storage.h"
|
#include "core/file_sys/fssystem/fssystem_integrity_verification_storage.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
||||||
#include "core/file_sys/fssystem/fssystem_bucket_tree_template_impl.h"
|
#include "core/file_sys/fssystem/fssystem_bucket_tree_template_impl.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
#include "core/file_sys/vfs_offset.h"
|
#include "core/file_sys/vfs/vfs_offset.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user