Compare commits
1 Commits
android-18
...
android-17
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2403bf5d7 |
@@ -3,33 +3,38 @@
|
||||
# SPDX-FileCopyrightText: 2019 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
shopt -s nullglob globstar
|
||||
|
||||
if grep -nrI '\s$' src **/*.yml **/*.txt **/*.md Doxyfile .gitignore .gitmodules .ci* dist/*.desktop \
|
||||
if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dist/*.desktop \
|
||||
dist/*.svg dist/*.xml; then
|
||||
echo Trailing whitespace found, aborting
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Default clang-format points to default 3.5 version one
|
||||
CLANG_FORMAT="${CLANG_FORMAT:-clang-format-15}"
|
||||
"$CLANG_FORMAT" --version
|
||||
CLANG_FORMAT=${CLANG_FORMAT:-clang-format-15}
|
||||
$CLANG_FORMAT --version
|
||||
|
||||
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
|
||||
# Get list of every file modified in this pull request
|
||||
files_to_lint="$(git diff --name-only --diff-filter=ACMRTUXB $TRAVIS_COMMIT_RANGE | grep '^src/[^.]*[.]\(cpp\|h\)$' || true)"
|
||||
else
|
||||
# Check everything for branch pushes
|
||||
files_to_lint="$(find src/ -name '*.cpp' -or -name '*.h')"
|
||||
fi
|
||||
|
||||
# Turn off tracing for this because it's too verbose
|
||||
set +x
|
||||
|
||||
# Check everything for branch pushes
|
||||
FILES_TO_LINT="$(find src/ -name '*.cpp' -or -name '*.h')"
|
||||
|
||||
for f in $FILES_TO_LINT; do
|
||||
echo "$f"
|
||||
"$CLANG_FORMAT" -i "$f"
|
||||
for f in $files_to_lint; do
|
||||
d=$(diff -u "$f" <($CLANG_FORMAT "$f") || true)
|
||||
if ! [ -z "$d" ]; then
|
||||
echo "!!! $f not compliant to coding style, here is the fix:"
|
||||
echo "$d"
|
||||
fail=1
|
||||
fi
|
||||
done
|
||||
|
||||
DIFF=$(git diff)
|
||||
set -x
|
||||
|
||||
if [ ! -z "$DIFF" ]; then
|
||||
echo "!!! Not compliant to coding style, here is the fix:"
|
||||
echo "$DIFF"
|
||||
if [ "$fail" = 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -9,7 +9,7 @@ chmod a+x ./.ci/scripts/linux/docker.sh
|
||||
sudo chown -R 1027 ./
|
||||
|
||||
# The environment variables listed below:
|
||||
# AZURECIREPO TITLEBARFORMATIDLE TITLEBARFORMATRUNNING DISPLAYVERSION
|
||||
# AZURECIREPO TITLEBARFORMATIDLE TITLEBARFORMATRUNNING DISPLAYVERSION
|
||||
# are requested in src/common/CMakeLists.txt and appear to be provided somewhere in Azure DevOps
|
||||
|
||||
docker run -e AZURECIREPO -e TITLEBARFORMATIDLE -e TITLEBARFORMATRUNNING -e DISPLAYVERSION -e ENABLE_COMPATIBILITY_REPORTING -e CCACHE_DIR=/yuzu/ccache -v "$(pwd):/yuzu" -w /yuzu yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.ci/scripts/linux/docker.sh "$1"
|
||||
|
||||
49
.github/workflows/android-merge.js
vendored
49
.github/workflows/android-merge.js
vendored
@@ -10,7 +10,7 @@ const CHANGE_LABEL = 'android-merge';
|
||||
// how far back in time should we consider the changes are "recent"? (default: 24 hours)
|
||||
const DETECTION_TIME_FRAME = (parseInt(process.env.DETECTION_TIME_FRAME)) || (24 * 3600 * 1000);
|
||||
|
||||
async function checkBaseChanges(github) {
|
||||
async function checkBaseChanges(github, context) {
|
||||
// query the commit date of the latest commit on this branch
|
||||
const query = `query($owner:String!, $name:String!, $ref:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
@@ -22,8 +22,8 @@ async function checkBaseChanges(github) {
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
owner: 'yuzu-emu',
|
||||
name: 'yuzu',
|
||||
owner: context.repo.owner,
|
||||
name: context.repo.repo,
|
||||
ref: 'refs/heads/master',
|
||||
};
|
||||
const result = await github.graphql(query, variables);
|
||||
@@ -38,8 +38,8 @@ async function checkBaseChanges(github) {
|
||||
return false;
|
||||
}
|
||||
|
||||
async function checkAndroidChanges(github) {
|
||||
if (checkBaseChanges(github)) return true;
|
||||
async function checkAndroidChanges(github, context) {
|
||||
if (checkBaseChanges(github, context)) return true;
|
||||
const query = `query($owner:String!, $name:String!, $label:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
pullRequests(labels: [$label], states: OPEN, first: 100) {
|
||||
@@ -48,8 +48,8 @@ async function checkAndroidChanges(github) {
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
owner: 'yuzu-emu',
|
||||
name: 'yuzu',
|
||||
owner: context.repo.owner,
|
||||
name: context.repo.repo,
|
||||
label: CHANGE_LABEL,
|
||||
};
|
||||
const result = await github.graphql(query, variables);
|
||||
@@ -90,8 +90,8 @@ async function tagAndPush(github, owner, repo, execa, commit=false) {
|
||||
console.log(`New tag: ${newTag}`);
|
||||
if (commit) {
|
||||
let channelName = channel[0].toUpperCase() + channel.slice(1);
|
||||
console.info(`Committing pending commit as ${channelName} ${tagNumber + 1}`);
|
||||
await execa("git", ['commit', '-m', `${channelName} ${tagNumber + 1}`]);
|
||||
console.info(`Committing pending commit as ${channelName} #${tagNumber + 1}`);
|
||||
await execa("git", ['commit', '-m', `${channelName} #${tagNumber + 1}`]);
|
||||
}
|
||||
console.info('Pushing tags to GitHub ...');
|
||||
await execa("git", ['tag', newTag]);
|
||||
@@ -157,7 +157,7 @@ async function mergePullRequests(pulls, execa) {
|
||||
process1.stdout.pipe(process.stdout);
|
||||
await process1;
|
||||
|
||||
const process2 = execa("git", ["commit", "-m", `Merge yuzu-emu#${pr}`]);
|
||||
const process2 = execa("git", ["commit", "-m", `Merge PR ${pr}`]);
|
||||
process2.stdout.pipe(process.stdout);
|
||||
await process2;
|
||||
|
||||
@@ -182,30 +182,7 @@ async function mergePullRequests(pulls, execa) {
|
||||
return mergeResults;
|
||||
}
|
||||
|
||||
async function resetBranch(execa) {
|
||||
console.log("::group::Reset master branch");
|
||||
let hasFailed = false;
|
||||
try {
|
||||
await execa("git", ["remote", "add", "source", "https://github.com/yuzu-emu/yuzu.git"]);
|
||||
await execa("git", ["fetch", "source"]);
|
||||
const process1 = await execa("git", ["rev-parse", "source/master"]);
|
||||
const headCommit = process1.stdout;
|
||||
|
||||
await execa("git", ["reset", "--hard", headCommit]);
|
||||
} catch (err) {
|
||||
console.log(`::error title=Failed to reset master branch`);
|
||||
hasFailed = true;
|
||||
}
|
||||
console.log("::endgroup::");
|
||||
if (hasFailed) {
|
||||
throw 'Failed to reset the master branch. Aborting!';
|
||||
}
|
||||
}
|
||||
|
||||
async function mergebot(github, context, execa) {
|
||||
// Reset our local copy of master to what appears on yuzu-emu/yuzu - master
|
||||
await resetBranch(execa);
|
||||
|
||||
const query = `query ($owner:String!, $name:String!, $label:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
pullRequests(labels: [$label], states: OPEN, first: 100) {
|
||||
@@ -216,8 +193,8 @@ async function mergebot(github, context, execa) {
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
owner: 'yuzu-emu',
|
||||
name: 'yuzu',
|
||||
owner: context.repo.owner,
|
||||
name: context.repo.repo,
|
||||
label: CHANGE_LABEL,
|
||||
};
|
||||
const result = await github.graphql(query, variables);
|
||||
@@ -232,7 +209,7 @@ async function mergebot(github, context, execa) {
|
||||
await fetchPullRequests(pulls, "https://github.com/yuzu-emu/yuzu", execa);
|
||||
const mergeResults = await mergePullRequests(pulls, execa);
|
||||
await generateReadme(pulls, context, mergeResults, execa);
|
||||
await tagAndPush(github, 'yuzu-emu', `yuzu-android`, execa, true);
|
||||
await tagAndPush(github, context.repo.owner, `${context.repo.repo}-android`, execa, true);
|
||||
}
|
||||
|
||||
module.exports.mergebot = mergebot;
|
||||
|
||||
4
.github/workflows/android-publish.yml
vendored
4
.github/workflows/android-publish.yml
vendored
@@ -16,7 +16,7 @@ on:
|
||||
jobs:
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu-android' }}
|
||||
if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu' }}
|
||||
steps:
|
||||
# this checkout is required to make sure the GitHub Actions scripts are available
|
||||
- uses: actions/checkout@v3
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
script: |
|
||||
if (context.payload.inputs && context.payload.inputs.android === 'true') return true;
|
||||
const checkAndroidChanges = require('./.github/workflows/android-merge.js').checkAndroidChanges;
|
||||
return checkAndroidChanges(github);
|
||||
return checkAndroidChanges(github, context);
|
||||
- run: npm install execa@5
|
||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) <year> <owner>
|
||||
Copyright (c) <year> <owner>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) <year> <owner>.
|
||||
Copyright (c) <year> <owner>.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Mozilla Public License Version 2.0
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
| Pull Request | Commit | Title | Author | Merged? |
|
||||
|----|----|----|----|----|
|
||||
| [12579](https://github.com/yuzu-emu/yuzu-android//pull/12579) | [`66ae60a9e`](https://github.com/yuzu-emu/yuzu-android//pull/12579/files) | Core: Implement Device Mapping & GPU SMMU | [FernandoS27](https://github.com/FernandoS27/) | Yes |
|
||||
|
||||
|
||||
End of merge log. You can find the original README.md below the break.
|
||||
|
||||
2
externals/ffmpeg/CMakeLists.txt
vendored
2
externals/ffmpeg/CMakeLists.txt
vendored
@@ -138,7 +138,7 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
--cross-prefix=${TOOLCHAIN}/bin/aarch64-linux-android-
|
||||
--sysroot=${SYSROOT}
|
||||
--target-os=android
|
||||
--extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
|
||||
--extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
|
||||
--extra-ldflags="-nostdlib"
|
||||
)
|
||||
endif()
|
||||
|
||||
2
externals/nx_tzdb/tzdb_to_nx
vendored
2
externals/nx_tzdb/tzdb_to_nx
vendored
Submodule externals/nx_tzdb/tzdb_to_nx updated: 404d390045...f6680093bc
@@ -185,7 +185,6 @@ add_subdirectory(common)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(audio_core)
|
||||
add_subdirectory(video_core)
|
||||
add_subdirectory(hid_core)
|
||||
add_subdirectory(network)
|
||||
add_subdirectory(input_common)
|
||||
add_subdirectory(frontend_common)
|
||||
|
||||
@@ -31,9 +31,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
android:dataExtractionRules="@xml/data_extraction_rules_api_31"
|
||||
android:enableOnBackInvokedCallback="true">
|
||||
|
||||
<meta-data android:name="android.game_mode_config"
|
||||
android:resource="@xml/game_mode_config" />
|
||||
|
||||
<activity
|
||||
android:name="org.yuzu.yuzu_emu.ui.main.MainActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -547,15 +547,6 @@ object NativeLibrary {
|
||||
*/
|
||||
external fun getSavePath(programId: String): String
|
||||
|
||||
/**
|
||||
* Gets the root save directory for the default profile as either
|
||||
* /user/save/account/<user id raw string> or /user/save/000...000/<user id>
|
||||
*
|
||||
* @param future If true, returns the /user/save/account/... directory
|
||||
* @return Save data path that may not exist yet
|
||||
*/
|
||||
external fun getDefaultProfileSaveDataRoot(future: Boolean): String
|
||||
|
||||
/**
|
||||
* Adds a file to the manual filesystem provider in our EmulationSession instance
|
||||
* @param path Path to the file we're adding. Can be a string representation of a [Uri] or
|
||||
|
||||
@@ -79,18 +79,7 @@ object Settings {
|
||||
const val PREF_THEME_MODE = "ThemeMode"
|
||||
const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds"
|
||||
|
||||
enum class EmulationOrientation(val int: Int) {
|
||||
Unspecified(0),
|
||||
SensorLandscape(5),
|
||||
Landscape(1),
|
||||
ReverseLandscape(2),
|
||||
SensorPortrait(6),
|
||||
Portrait(4),
|
||||
ReversePortrait(3);
|
||||
|
||||
companion object {
|
||||
fun from(int: Int): EmulationOrientation =
|
||||
entries.firstOrNull { it.int == int } ?: Unspecified
|
||||
}
|
||||
}
|
||||
const val LayoutOption_Unspecified = 0
|
||||
const val LayoutOption_MobilePortrait = 4
|
||||
const val LayoutOption_MobileLandscape = 5
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ class AddonsFragment : Fragment() {
|
||||
}
|
||||
|
||||
val isValid = externalAddonDirectory.listFiles()
|
||||
.any { AddonUtil.validAddonDirectories.contains(it.name?.lowercase()) }
|
||||
.any { AddonUtil.validAddonDirectories.contains(it.name) }
|
||||
val errorMessage = MessageDialogFragment.newInstance(
|
||||
requireActivity(),
|
||||
titleId = R.string.invalid_directory,
|
||||
|
||||
@@ -50,7 +50,6 @@ import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation
|
||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||
import org.yuzu.yuzu_emu.model.Game
|
||||
@@ -100,7 +99,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
updateOrientation()
|
||||
|
||||
val intentUri: Uri? = requireActivity().intent.data
|
||||
var intentGame: Game? = null
|
||||
@@ -460,23 +458,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
private fun updateOrientation() {
|
||||
emulationActivity?.let {
|
||||
val orientationSetting =
|
||||
EmulationOrientation.from(IntSetting.RENDERER_SCREEN_LAYOUT.getInt())
|
||||
it.requestedOrientation = when (orientationSetting) {
|
||||
EmulationOrientation.Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
EmulationOrientation.SensorLandscape ->
|
||||
it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.getInt()) {
|
||||
Settings.LayoutOption_MobileLandscape ->
|
||||
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||
|
||||
EmulationOrientation.Landscape -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||
EmulationOrientation.ReverseLandscape ->
|
||||
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
|
||||
|
||||
EmulationOrientation.SensorPortrait ->
|
||||
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
|
||||
|
||||
EmulationOrientation.Portrait -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||
EmulationOrientation.ReversePortrait ->
|
||||
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
|
||||
Settings.LayoutOption_MobilePortrait ->
|
||||
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
||||
Settings.LayoutOption_Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
else -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -663,7 +651,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
private fun startConfiguringControls() {
|
||||
// Lock the current orientation to prevent editing inconsistencies
|
||||
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {
|
||||
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) {
|
||||
emulationActivity?.let {
|
||||
it.requestedOrientation =
|
||||
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
@@ -681,7 +669,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
binding.doneControlConfig.visibility = View.GONE
|
||||
binding.surfaceInputOverlay.setIsInEditMode(false)
|
||||
// Unlock the orientation if it was locked for editing
|
||||
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {
|
||||
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) {
|
||||
emulationActivity?.let {
|
||||
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
}
|
||||
|
||||
@@ -445,8 +445,7 @@ class GamePropertiesFragment : Fragment() {
|
||||
val zipResult = FileUtil.zipFromInternalStorage(
|
||||
File(saveLocation),
|
||||
saveLocation.replaceAfterLast("/", ""),
|
||||
BufferedOutputStream(requireContext().contentResolver.openOutputStream(result)),
|
||||
compression = false
|
||||
BufferedOutputStream(requireContext().contentResolver.openOutputStream(result))
|
||||
)
|
||||
return@newInstance when (zipResult) {
|
||||
TaskState.Completed -> getString(R.string.export_success)
|
||||
|
||||
@@ -7,39 +7,20 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.YuzuApplication
|
||||
import org.yuzu.yuzu_emu.adapters.InstallableAdapter
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentInstallablesBinding
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||
import org.yuzu.yuzu_emu.model.Installable
|
||||
import org.yuzu.yuzu_emu.model.TaskState
|
||||
import org.yuzu.yuzu_emu.ui.main.MainActivity
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.math.BigInteger
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class InstallableFragment : Fragment() {
|
||||
private var _binding: FragmentInstallablesBinding? = null
|
||||
@@ -75,17 +56,6 @@ class InstallableFragment : Fragment() {
|
||||
binding.root.findNavController().popBackStack()
|
||||
}
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||
homeViewModel.openImportSaves.collect {
|
||||
if (it) {
|
||||
importSaves.launch(arrayOf("application/zip"))
|
||||
homeViewModel.setOpenImportSaves(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installables = listOf(
|
||||
Installable(
|
||||
R.string.user_data,
|
||||
@@ -93,43 +63,6 @@ class InstallableFragment : Fragment() {
|
||||
install = { mainActivity.importUserData.launch(arrayOf("application/zip")) },
|
||||
export = { mainActivity.exportUserData.launch("export.zip") }
|
||||
),
|
||||
Installable(
|
||||
R.string.manage_save_data,
|
||||
R.string.manage_save_data_description,
|
||||
install = {
|
||||
MessageDialogFragment.newInstance(
|
||||
requireActivity(),
|
||||
titleId = R.string.import_save_warning,
|
||||
descriptionId = R.string.import_save_warning_description,
|
||||
positiveAction = { homeViewModel.setOpenImportSaves(true) }
|
||||
).show(parentFragmentManager, MessageDialogFragment.TAG)
|
||||
},
|
||||
export = {
|
||||
val oldSaveDataFolder = File(
|
||||
"${DirectoryInitialization.userDirectory}/nand" +
|
||||
NativeLibrary.getDefaultProfileSaveDataRoot(false)
|
||||
)
|
||||
val futureSaveDataFolder = File(
|
||||
"${DirectoryInitialization.userDirectory}/nand" +
|
||||
NativeLibrary.getDefaultProfileSaveDataRoot(true)
|
||||
)
|
||||
if (!oldSaveDataFolder.exists() && !futureSaveDataFolder.exists()) {
|
||||
Toast.makeText(
|
||||
YuzuApplication.appContext,
|
||||
R.string.no_save_data_found,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return@Installable
|
||||
} else {
|
||||
exportSaves.launch(
|
||||
"${getString(R.string.save_data)} " +
|
||||
LocalDateTime.now().format(
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
),
|
||||
Installable(
|
||||
R.string.install_game_content,
|
||||
R.string.install_game_content_description,
|
||||
@@ -188,156 +121,4 @@ class InstallableFragment : Fragment() {
|
||||
|
||||
windowInsets
|
||||
}
|
||||
|
||||
private val importSaves =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result == null) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
val inputZip = requireContext().contentResolver.openInputStream(result)
|
||||
val cacheSaveDir = File("${requireContext().cacheDir.path}/saves/")
|
||||
cacheSaveDir.mkdir()
|
||||
|
||||
if (inputZip == null) {
|
||||
Toast.makeText(
|
||||
YuzuApplication.appContext,
|
||||
getString(R.string.fatal_error),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
IndeterminateProgressDialogFragment.newInstance(
|
||||
requireActivity(),
|
||||
R.string.save_files_importing,
|
||||
false
|
||||
) {
|
||||
try {
|
||||
FileUtil.unzipToInternalStorage(BufferedInputStream(inputZip), cacheSaveDir)
|
||||
val files = cacheSaveDir.listFiles()
|
||||
var successfulImports = 0
|
||||
var failedImports = 0
|
||||
if (files != null) {
|
||||
for (file in files) {
|
||||
if (file.isDirectory) {
|
||||
val baseSaveDir =
|
||||
NativeLibrary.getSavePath(BigInteger(file.name, 16).toString())
|
||||
if (baseSaveDir.isEmpty()) {
|
||||
failedImports++
|
||||
continue
|
||||
}
|
||||
|
||||
val internalSaveFolder = File(
|
||||
"${DirectoryInitialization.userDirectory}/nand$baseSaveDir"
|
||||
)
|
||||
internalSaveFolder.deleteRecursively()
|
||||
internalSaveFolder.mkdir()
|
||||
file.copyRecursively(target = internalSaveFolder, overwrite = true)
|
||||
successfulImports++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (successfulImports == 0) {
|
||||
MessageDialogFragment.newInstance(
|
||||
requireActivity(),
|
||||
titleId = R.string.save_file_invalid_zip_structure,
|
||||
descriptionId = R.string.save_file_invalid_zip_structure_description
|
||||
).show(parentFragmentManager, MessageDialogFragment.TAG)
|
||||
return@withContext
|
||||
}
|
||||
val successString = if (failedImports > 0) {
|
||||
"""
|
||||
${
|
||||
requireContext().resources.getQuantityString(
|
||||
R.plurals.saves_import_success,
|
||||
successfulImports,
|
||||
successfulImports
|
||||
)
|
||||
}
|
||||
${
|
||||
requireContext().resources.getQuantityString(
|
||||
R.plurals.saves_import_failed,
|
||||
failedImports,
|
||||
failedImports
|
||||
)
|
||||
}
|
||||
"""
|
||||
} else {
|
||||
requireContext().resources.getQuantityString(
|
||||
R.plurals.saves_import_success,
|
||||
successfulImports,
|
||||
successfulImports
|
||||
)
|
||||
}
|
||||
MessageDialogFragment.newInstance(
|
||||
requireActivity(),
|
||||
titleId = R.string.import_complete,
|
||||
descriptionString = successString
|
||||
).show(parentFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
|
||||
cacheSaveDir.deleteRecursively()
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(
|
||||
YuzuApplication.appContext,
|
||||
getString(R.string.fatal_error),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}.show(parentFragmentManager, IndeterminateProgressDialogFragment.TAG)
|
||||
}
|
||||
|
||||
private val exportSaves = registerForActivityResult(
|
||||
ActivityResultContracts.CreateDocument("application/zip")
|
||||
) { result ->
|
||||
if (result == null) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
IndeterminateProgressDialogFragment.newInstance(
|
||||
requireActivity(),
|
||||
R.string.save_files_exporting,
|
||||
false
|
||||
) {
|
||||
val cacheSaveDir = File("${requireContext().cacheDir.path}/saves/")
|
||||
cacheSaveDir.mkdir()
|
||||
|
||||
val oldSaveDataFolder = File(
|
||||
"${DirectoryInitialization.userDirectory}/nand" +
|
||||
NativeLibrary.getDefaultProfileSaveDataRoot(false)
|
||||
)
|
||||
if (oldSaveDataFolder.exists()) {
|
||||
oldSaveDataFolder.copyRecursively(cacheSaveDir)
|
||||
}
|
||||
|
||||
val futureSaveDataFolder = File(
|
||||
"${DirectoryInitialization.userDirectory}/nand" +
|
||||
NativeLibrary.getDefaultProfileSaveDataRoot(true)
|
||||
)
|
||||
if (futureSaveDataFolder.exists()) {
|
||||
futureSaveDataFolder.copyRecursively(cacheSaveDir)
|
||||
}
|
||||
|
||||
val saveFilesTotal = cacheSaveDir.listFiles()?.size ?: 0
|
||||
if (saveFilesTotal == 0) {
|
||||
cacheSaveDir.deleteRecursively()
|
||||
return@newInstance getString(R.string.no_save_data_found)
|
||||
}
|
||||
|
||||
val zipResult = FileUtil.zipFromInternalStorage(
|
||||
cacheSaveDir,
|
||||
cacheSaveDir.path,
|
||||
BufferedOutputStream(requireContext().contentResolver.openOutputStream(result))
|
||||
)
|
||||
cacheSaveDir.deleteRecursively()
|
||||
|
||||
return@newInstance when (zipResult) {
|
||||
TaskState.Completed -> getString(R.string.export_success)
|
||||
TaskState.Cancelled, TaskState.Failed -> getString(R.string.export_failed)
|
||||
}
|
||||
}.show(parentFragmentManager, IndeterminateProgressDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,14 +167,13 @@ class GamesViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun onCloseGameFoldersFragment() {
|
||||
NativeConfig.saveGlobalConfig()
|
||||
fun onCloseGameFoldersFragment() =
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
NativeConfig.saveGlobalConfig()
|
||||
getGameDirs(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGameDirs(reloadList: Boolean = false) {
|
||||
val gameDirs = NativeConfig.getGameDirs()
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.yuzu.yuzu_emu.NativeLibrary.StickType
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.overlay.model.OverlayControl
|
||||
import org.yuzu.yuzu_emu.overlay.model.OverlayControlData
|
||||
import org.yuzu.yuzu_emu.overlay.model.OverlayLayout
|
||||
@@ -301,7 +302,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
||||
MotionEvent.ACTION_POINTER_UP -> if (dpadBeingConfigured === dpad) {
|
||||
// Persist button position by saving new place.
|
||||
saveControlPosition(
|
||||
OverlayControl.COMBINED_DPAD.id,
|
||||
Settings.PREF_BUTTON_DPAD,
|
||||
dpadBeingConfigured!!.bounds.centerX(),
|
||||
dpadBeingConfigured!!.bounds.centerY(),
|
||||
layout
|
||||
|
||||
@@ -625,8 +625,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
File(DirectoryInitialization.userDirectory!!),
|
||||
DirectoryInitialization.userDirectory!!,
|
||||
BufferedOutputStream(contentResolver.openOutputStream(result)),
|
||||
taskViewModel.cancelled,
|
||||
compression = false
|
||||
taskViewModel.cancelled
|
||||
)
|
||||
return@newInstance when (zipResult) {
|
||||
TaskState.Completed -> getString(R.string.user_data_export_success)
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.yuzu.yuzu_emu.model.TaskState
|
||||
import java.io.BufferedOutputStream
|
||||
import java.lang.NullPointerException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.Deflater
|
||||
import java.util.zip.ZipOutputStream
|
||||
import kotlin.IllegalStateException
|
||||
|
||||
@@ -313,23 +312,15 @@ object FileUtil {
|
||||
* @param inputFile File representation of the item that will be zipped
|
||||
* @param rootDir Directory containing the inputFile
|
||||
* @param outputStream Stream where the zip file will be output
|
||||
* @param cancelled [StateFlow] that reports whether this process has been cancelled
|
||||
* @param compression Disables compression if true
|
||||
*/
|
||||
fun zipFromInternalStorage(
|
||||
inputFile: File,
|
||||
rootDir: String,
|
||||
outputStream: BufferedOutputStream,
|
||||
cancelled: StateFlow<Boolean>? = null,
|
||||
compression: Boolean = true
|
||||
cancelled: StateFlow<Boolean>? = null
|
||||
): TaskState {
|
||||
try {
|
||||
ZipOutputStream(outputStream).use { zos ->
|
||||
if (!compression) {
|
||||
zos.setMethod(ZipOutputStream.DEFLATED)
|
||||
zos.setLevel(Deflater.NO_COMPRESSION)
|
||||
}
|
||||
|
||||
inputFile.walkTopDown().forEach { file ->
|
||||
if (cancelled?.value == true) {
|
||||
return TaskState.Cancelled
|
||||
@@ -347,7 +338,6 @@ object FileUtil {
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.error("[FileUtil] Failed creating zip file - ${e.message}")
|
||||
return TaskState.Failed
|
||||
}
|
||||
return TaskState.Completed
|
||||
|
||||
@@ -14,6 +14,12 @@ AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_t
|
||||
}
|
||||
}
|
||||
|
||||
AndroidConfig::~AndroidConfig() {
|
||||
if (global) {
|
||||
AndroidConfig::SaveAllValues();
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidConfig::ReloadAllValues() {
|
||||
Reload();
|
||||
ReadAndroidValues();
|
||||
|
||||
@@ -9,6 +9,7 @@ class AndroidConfig final : public Config {
|
||||
public:
|
||||
explicit AndroidConfig(const std::string& config_name = "config",
|
||||
ConfigType config_type = ConfigType::GlobalConfig);
|
||||
~AndroidConfig() override;
|
||||
|
||||
void ReloadAllValues() override;
|
||||
void SaveAllValues() override;
|
||||
|
||||
@@ -45,15 +45,15 @@
|
||||
#include "core/frontend/applets/profile_select.h"
|
||||
#include "core/frontend/applets/software_keyboard.h"
|
||||
#include "core/frontend/applets/web_browser.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/service/am/applet_ae.h"
|
||||
#include "core/hle/service/am/applet_oe.h"
|
||||
#include "core/hle/service/am/applets/applets.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "frontend_common/config.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "jni/android_common/android_common.h"
|
||||
#include "jni/id_cache.h"
|
||||
#include "jni/native.h"
|
||||
@@ -862,9 +862,6 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAddonsForFile(JNIEnv* env,
|
||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
|
||||
jstring jprogramId) {
|
||||
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||
if (program_id == 0) {
|
||||
return ToJString(env, "");
|
||||
}
|
||||
|
||||
auto& system = EmulationSession::GetInstance().System();
|
||||
|
||||
@@ -883,19 +880,6 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
|
||||
return ToJString(env, user_save_data_path);
|
||||
}
|
||||
|
||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIEnv* env,
|
||||
jobject jobj,
|
||||
jboolean jfuture) {
|
||||
Service::Account::ProfileManager manager;
|
||||
// TODO: Pass in a selected user once we get the relevant UI working
|
||||
const auto user_id = manager.GetUser(static_cast<std::size_t>(0));
|
||||
ASSERT(user_id);
|
||||
|
||||
const auto user_save_data_root =
|
||||
FileSys::SaveDataFactory::GetUserGameSaveDataRoot(user_id->AsU128(), jfuture);
|
||||
return ToJString(env, user_save_data_root);
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj,
|
||||
jstring jpath) {
|
||||
EmulationSession::GetInstance().ConfigureFilesystemProvider(GetJString(env, jpath));
|
||||
|
||||
@@ -118,23 +118,15 @@
|
||||
</integer-array>
|
||||
|
||||
<string-array name="rendererScreenLayoutNames">
|
||||
<item>@string/screen_layout_auto</item>
|
||||
<item>@string/screen_layout_sensor_landscape</item>
|
||||
<item>@string/screen_layout_landscape</item>
|
||||
<item>@string/screen_layout_reverse_landscape</item>
|
||||
<item>@string/screen_layout_sensor_portrait</item>
|
||||
<item>@string/screen_layout_portrait</item>
|
||||
<item>@string/screen_layout_reverse_portrait</item>
|
||||
<item>@string/screen_layout_auto</item>
|
||||
</string-array>
|
||||
|
||||
<integer-array name="rendererScreenLayoutValues">
|
||||
<item>0</item>
|
||||
<item>5</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>6</item>
|
||||
<item>4</item>
|
||||
<item>3</item>
|
||||
<item>0</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="rendererAspectRatioNames">
|
||||
|
||||
@@ -133,15 +133,6 @@
|
||||
<string name="add_game_folder">Add game folder</string>
|
||||
<string name="folder_already_added">This folder was already added!</string>
|
||||
<string name="game_folder_properties">Game folder properties</string>
|
||||
<plurals name="saves_import_failed">
|
||||
<item quantity="one">Failed to import %d save</item>
|
||||
<item quantity="other">Failed to import %d saves</item>
|
||||
</plurals>
|
||||
<plurals name="saves_import_success">
|
||||
<item quantity="one">Successfully imported %d save</item>
|
||||
<item quantity="other">Successfully imported %d saves</item>
|
||||
</plurals>
|
||||
<string name="no_save_data_found">No save data found</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="applets">Applet launcher</string>
|
||||
@@ -285,7 +276,6 @@
|
||||
<string name="global">Global</string>
|
||||
<string name="custom">Custom</string>
|
||||
<string name="notice">Notice</string>
|
||||
<string name="import_complete">Import complete</string>
|
||||
|
||||
<!-- GPU driver installation -->
|
||||
<string name="select_gpu_driver">Select GPU driver</string>
|
||||
@@ -473,13 +463,9 @@
|
||||
<string name="anti_aliasing_smaa">SMAA</string>
|
||||
|
||||
<!-- Screen Layouts -->
|
||||
<string name="screen_layout_auto">Auto</string>
|
||||
<string name="screen_layout_sensor_landscape">Sensor landscape</string>
|
||||
<string name="screen_layout_landscape">Landscape</string>
|
||||
<string name="screen_layout_reverse_landscape">Reverse landscape</string>
|
||||
<string name="screen_layout_sensor_portrait">Sensor portrait</string>
|
||||
<string name="screen_layout_portrait">Portrait</string>
|
||||
<string name="screen_layout_reverse_portrait">Reverse portrait</string>
|
||||
<string name="screen_layout_auto">Auto</string>
|
||||
|
||||
<!-- Aspect Ratios -->
|
||||
<string name="ratio_default">Default (16:9)</string>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<game-mode-config
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:supportsBatteryGameMode="true"
|
||||
android:supportsPerformanceGameMode="true"
|
||||
android:allowGameDownscaling="false"
|
||||
android:allowGameFpsOverride="false"/>
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "audio_core/sink/sink_stream.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/guest_memory.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "common/fixed_point.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/scratch_buffer.h"
|
||||
#include "core/guest_memory.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace AudioCore::Renderer {
|
||||
|
||||
@@ -45,7 +45,6 @@ using f32 = float; ///< 32-bit floating point
|
||||
using f64 = double; ///< 64-bit floating point
|
||||
|
||||
using VAddr = u64; ///< Represents a pointer in the userspace virtual address space.
|
||||
using DAddr = u64; ///< Represents a pointer in the device specific virtual address space.
|
||||
using PAddr = u64; ///< Represents a pointer in the ARM11 physical address space.
|
||||
using GPUVAddr = u64; ///< Represents a pointer in the GPU virtual address space.
|
||||
|
||||
|
||||
@@ -37,8 +37,6 @@ add_library(core STATIC
|
||||
debugger/gdbstub_arch.h
|
||||
debugger/gdbstub.cpp
|
||||
debugger/gdbstub.h
|
||||
device_memory_manager.h
|
||||
device_memory_manager.inc
|
||||
device_memory.cpp
|
||||
device_memory.h
|
||||
file_sys/fssystem/fs_i_storage.h
|
||||
@@ -185,6 +183,22 @@ add_library(core STATIC
|
||||
frontend/framebuffer_layout.cpp
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/graphics_context.h
|
||||
hid/emulated_console.cpp
|
||||
hid/emulated_console.h
|
||||
hid/emulated_controller.cpp
|
||||
hid/emulated_controller.h
|
||||
hid/emulated_devices.cpp
|
||||
hid/emulated_devices.h
|
||||
hid/hid_core.cpp
|
||||
hid/hid_core.h
|
||||
hid/hid_types.h
|
||||
hid/input_converter.cpp
|
||||
hid/input_converter.h
|
||||
hid/input_interpreter.cpp
|
||||
hid/input_interpreter.h
|
||||
hid/irs_types.h
|
||||
hid/motion_input.cpp
|
||||
hid/motion_input.h
|
||||
hle/api_version.h
|
||||
hle/ipc.h
|
||||
hle/kernel/board/nintendo/nx/k_memory_layout.cpp
|
||||
@@ -517,16 +531,90 @@ add_library(core STATIC
|
||||
hle/service/hid/hid.h
|
||||
hle/service/hid/hid_debug_server.cpp
|
||||
hle/service/hid/hid_debug_server.h
|
||||
hle/service/hid/hid_firmware_settings.cpp
|
||||
hle/service/hid/hid_firmware_settings.h
|
||||
hle/service/hid/hid_server.cpp
|
||||
hle/service/hid/hid_server.h
|
||||
hle/service/hid/hid_system_server.cpp
|
||||
hle/service/hid/hid_system_server.h
|
||||
hle/service/hid/hid_util.h
|
||||
hle/service/hid/hidbus.cpp
|
||||
hle/service/hid/hidbus.h
|
||||
hle/service/hid/irs.cpp
|
||||
hle/service/hid/irs.h
|
||||
hle/service/hid/irs_ring_lifo.h
|
||||
hle/service/hid/resource_manager.cpp
|
||||
hle/service/hid/resource_manager.h
|
||||
hle/service/hid/ring_lifo.h
|
||||
hle/service/hid/xcd.cpp
|
||||
hle/service/hid/xcd.h
|
||||
hle/service/hid/errors.h
|
||||
hle/service/hid/controllers/types/debug_pad_types.h
|
||||
hle/service/hid/controllers/types/keyboard_types.h
|
||||
hle/service/hid/controllers/types/mouse_types.h
|
||||
hle/service/hid/controllers/types/npad_types.h
|
||||
hle/service/hid/controllers/types/shared_memory_format.h
|
||||
hle/service/hid/controllers/types/touch_types.h
|
||||
hle/service/hid/controllers/applet_resource.cpp
|
||||
hle/service/hid/controllers/applet_resource.h
|
||||
hle/service/hid/controllers/capture_button.cpp
|
||||
hle/service/hid/controllers/capture_button.h
|
||||
hle/service/hid/controllers/console_six_axis.cpp
|
||||
hle/service/hid/controllers/console_six_axis.h
|
||||
hle/service/hid/controllers/controller_base.cpp
|
||||
hle/service/hid/controllers/controller_base.h
|
||||
hle/service/hid/controllers/debug_mouse.cpp
|
||||
hle/service/hid/controllers/debug_mouse.h
|
||||
hle/service/hid/controllers/debug_pad.cpp
|
||||
hle/service/hid/controllers/debug_pad.h
|
||||
hle/service/hid/controllers/digitizer.cpp
|
||||
hle/service/hid/controllers/digitizer.h
|
||||
hle/service/hid/controllers/gesture.cpp
|
||||
hle/service/hid/controllers/gesture.h
|
||||
hle/service/hid/controllers/home_button.cpp
|
||||
hle/service/hid/controllers/home_button.h
|
||||
hle/service/hid/controllers/keyboard.cpp
|
||||
hle/service/hid/controllers/keyboard.h
|
||||
hle/service/hid/controllers/mouse.cpp
|
||||
hle/service/hid/controllers/mouse.h
|
||||
hle/service/hid/controllers/npad.cpp
|
||||
hle/service/hid/controllers/npad.h
|
||||
hle/service/hid/controllers/palma.cpp
|
||||
hle/service/hid/controllers/palma.h
|
||||
hle/service/hid/controllers/seven_six_axis.cpp
|
||||
hle/service/hid/controllers/seven_six_axis.h
|
||||
hle/service/hid/controllers/shared_memory_holder.cpp
|
||||
hle/service/hid/controllers/shared_memory_holder.h
|
||||
hle/service/hid/controllers/six_axis.cpp
|
||||
hle/service/hid/controllers/six_axis.h
|
||||
hle/service/hid/controllers/sleep_button.cpp
|
||||
hle/service/hid/controllers/sleep_button.h
|
||||
hle/service/hid/controllers/touchscreen.cpp
|
||||
hle/service/hid/controllers/touchscreen.h
|
||||
hle/service/hid/controllers/unique_pad.cpp
|
||||
hle/service/hid/controllers/unique_pad.h
|
||||
hle/service/hid/hidbus/hidbus_base.cpp
|
||||
hle/service/hid/hidbus/hidbus_base.h
|
||||
hle/service/hid/hidbus/ringcon.cpp
|
||||
hle/service/hid/hidbus/ringcon.h
|
||||
hle/service/hid/hidbus/starlink.cpp
|
||||
hle/service/hid/hidbus/starlink.h
|
||||
hle/service/hid/hidbus/stubbed.cpp
|
||||
hle/service/hid/hidbus/stubbed.h
|
||||
hle/service/hid/irsensor/clustering_processor.cpp
|
||||
hle/service/hid/irsensor/clustering_processor.h
|
||||
hle/service/hid/irsensor/image_transfer_processor.cpp
|
||||
hle/service/hid/irsensor/image_transfer_processor.h
|
||||
hle/service/hid/irsensor/ir_led_processor.cpp
|
||||
hle/service/hid/irsensor/ir_led_processor.h
|
||||
hle/service/hid/irsensor/moment_processor.cpp
|
||||
hle/service/hid/irsensor/moment_processor.h
|
||||
hle/service/hid/irsensor/pointing_processor.cpp
|
||||
hle/service/hid/irsensor/pointing_processor.h
|
||||
hle/service/hid/irsensor/processor_base.cpp
|
||||
hle/service/hid/irsensor/processor_base.h
|
||||
hle/service/hid/irsensor/tera_plugin_processor.cpp
|
||||
hle/service/hid/irsensor/tera_plugin_processor.h
|
||||
hle/service/lbl/lbl.cpp
|
||||
hle/service/lbl/lbl.h
|
||||
hle/service/ldn/lan_discovery.cpp
|
||||
@@ -607,8 +695,6 @@ add_library(core STATIC
|
||||
hle/service/ns/pdm_qry.h
|
||||
hle/service/nvdrv/core/container.cpp
|
||||
hle/service/nvdrv/core/container.h
|
||||
hle/service/nvdrv/core/heap_mapper.cpp
|
||||
hle/service/nvdrv/core/heap_mapper.h
|
||||
hle/service/nvdrv/core/nvmap.cpp
|
||||
hle/service/nvdrv/core/nvmap.h
|
||||
hle/service/nvdrv/core/syncpoint_manager.cpp
|
||||
@@ -712,24 +798,24 @@ add_library(core STATIC
|
||||
hle/service/server_manager.h
|
||||
hle/service/service.cpp
|
||||
hle/service/service.h
|
||||
hle/service/set/set.cpp
|
||||
hle/service/set/set.h
|
||||
hle/service/set/appln_settings.cpp
|
||||
hle/service/set/appln_settings.h
|
||||
hle/service/set/device_settings.cpp
|
||||
hle/service/set/device_settings.h
|
||||
hle/service/set/factory_settings_server.cpp
|
||||
hle/service/set/factory_settings_server.h
|
||||
hle/service/set/firmware_debug_settings_server.cpp
|
||||
hle/service/set/firmware_debug_settings_server.h
|
||||
hle/service/set/private_settings.cpp
|
||||
hle/service/set/private_settings.h
|
||||
hle/service/set/set_cal.cpp
|
||||
hle/service/set/set_cal.h
|
||||
hle/service/set/set_fd.cpp
|
||||
hle/service/set/set_fd.h
|
||||
hle/service/set/set_sys.cpp
|
||||
hle/service/set/set_sys.h
|
||||
hle/service/set/settings.cpp
|
||||
hle/service/set/settings.h
|
||||
hle/service/set/settings_server.cpp
|
||||
hle/service/set/settings_server.h
|
||||
hle/service/set/system_settings.cpp
|
||||
hle/service/set/system_settings.h
|
||||
hle/service/set/system_settings_server.cpp
|
||||
hle/service/set/system_settings_server.h
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/sm/sm.h
|
||||
hle/service/sm/sm_controller.cpp
|
||||
@@ -869,7 +955,7 @@ endif()
|
||||
|
||||
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 network video_core nx_tzdb)
|
||||
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
|
||||
if (MINGW)
|
||||
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/file_sys/vfs_concat.h"
|
||||
#include "core/file_sys/vfs_real.h"
|
||||
#include "core/gpu_dirty_memory_manager.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/kernel/k_memory_manager.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_resource_limit.h"
|
||||
@@ -52,7 +52,6 @@
|
||||
#include "core/telemetry_session.h"
|
||||
#include "core/tools/freezer.h"
|
||||
#include "core/tools/renderdoc.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "network/network.h"
|
||||
#include "video_core/host1x/host1x.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
@@ -565,9 +564,6 @@ struct System::Impl {
|
||||
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
|
||||
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{};
|
||||
|
||||
std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES>
|
||||
gpu_dirty_memory_managers;
|
||||
|
||||
std::deque<std::vector<u8>> user_channel;
|
||||
};
|
||||
|
||||
@@ -654,14 +650,8 @@ size_t System::GetCurrentHostThreadID() const {
|
||||
return impl->kernel.GetCurrentHostThreadID();
|
||||
}
|
||||
|
||||
std::span<GPUDirtyMemoryManager> System::GetGPUDirtyMemoryManager() {
|
||||
return impl->gpu_dirty_memory_managers;
|
||||
}
|
||||
|
||||
void System::GatherGPUDirtyMemory(std::function<void(PAddr, size_t)>& callback) {
|
||||
for (auto& manager : impl->gpu_dirty_memory_managers) {
|
||||
manager.Gather(callback);
|
||||
}
|
||||
void System::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) {
|
||||
return this->ApplicationProcess()->GatherGPUDirtyMemory(callback);
|
||||
}
|
||||
|
||||
PerfStatsResults System::GetAndResetPerfStats() {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -117,7 +116,6 @@ class CpuManager;
|
||||
class Debugger;
|
||||
class DeviceMemory;
|
||||
class ExclusiveMonitor;
|
||||
class GPUDirtyMemoryManager;
|
||||
class PerfStats;
|
||||
class Reporter;
|
||||
class SpeedLimiter;
|
||||
@@ -226,9 +224,7 @@ public:
|
||||
/// Prepare the core emulation for a reschedule
|
||||
void PrepareReschedule(u32 core_index);
|
||||
|
||||
std::span<GPUDirtyMemoryManager> GetGPUDirtyMemoryManager();
|
||||
|
||||
void GatherGPUDirtyMemory(std::function<void(PAddr, size_t)>& callback);
|
||||
void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback);
|
||||
|
||||
[[nodiscard]] size_t GetCurrentHostThreadID() const;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
return [this] { ShutdownThreadFunction(); };
|
||||
}
|
||||
|
||||
void PreemptSingleCore(bool from_running_environment = true);
|
||||
void PreemptSingleCore(bool from_running_enviroment = true);
|
||||
|
||||
std::size_t CurrentCore() const {
|
||||
return current_core.load();
|
||||
|
||||
@@ -559,28 +559,28 @@ void GDBStub::HandleVCont(std::string_view command, std::vector<DebuggerAction>&
|
||||
}
|
||||
|
||||
constexpr std::array<std::pair<const char*, Kernel::Svc::MemoryState>, 22> MemoryStateNames{{
|
||||
{"----- Free ------", Kernel::Svc::MemoryState::Free},
|
||||
{"Io ", Kernel::Svc::MemoryState::Io},
|
||||
{"Static ", Kernel::Svc::MemoryState::Static},
|
||||
{"Code ", Kernel::Svc::MemoryState::Code},
|
||||
{"CodeData ", Kernel::Svc::MemoryState::CodeData},
|
||||
{"Normal ", Kernel::Svc::MemoryState::Normal},
|
||||
{"Shared ", Kernel::Svc::MemoryState::Shared},
|
||||
{"AliasCode ", Kernel::Svc::MemoryState::AliasCode},
|
||||
{"AliasCodeData ", Kernel::Svc::MemoryState::AliasCodeData},
|
||||
{"Ipc ", Kernel::Svc::MemoryState::Ipc},
|
||||
{"Stack ", Kernel::Svc::MemoryState::Stack},
|
||||
{"ThreadLocal ", Kernel::Svc::MemoryState::ThreadLocal},
|
||||
{"Transferred ", Kernel::Svc::MemoryState::Transferred},
|
||||
{"SharedTransferred", Kernel::Svc::MemoryState::SharedTransferred},
|
||||
{"SharedCode ", Kernel::Svc::MemoryState::SharedCode},
|
||||
{"Inaccessible ", Kernel::Svc::MemoryState::Inaccessible},
|
||||
{"NonSecureIpc ", Kernel::Svc::MemoryState::NonSecureIpc},
|
||||
{"NonDeviceIpc ", Kernel::Svc::MemoryState::NonDeviceIpc},
|
||||
{"Kernel ", Kernel::Svc::MemoryState::Kernel},
|
||||
{"GeneratedCode ", Kernel::Svc::MemoryState::GeneratedCode},
|
||||
{"CodeOut ", Kernel::Svc::MemoryState::CodeOut},
|
||||
{"Coverage ", Kernel::Svc::MemoryState::Coverage},
|
||||
{"----- Free -----", Kernel::Svc::MemoryState::Free},
|
||||
{"Io ", Kernel::Svc::MemoryState::Io},
|
||||
{"Static ", Kernel::Svc::MemoryState::Static},
|
||||
{"Code ", Kernel::Svc::MemoryState::Code},
|
||||
{"CodeData ", Kernel::Svc::MemoryState::CodeData},
|
||||
{"Normal ", Kernel::Svc::MemoryState::Normal},
|
||||
{"Shared ", Kernel::Svc::MemoryState::Shared},
|
||||
{"AliasCode ", Kernel::Svc::MemoryState::AliasCode},
|
||||
{"AliasCodeData ", Kernel::Svc::MemoryState::AliasCodeData},
|
||||
{"Ipc ", Kernel::Svc::MemoryState::Ipc},
|
||||
{"Stack ", Kernel::Svc::MemoryState::Stack},
|
||||
{"ThreadLocal ", Kernel::Svc::MemoryState::ThreadLocal},
|
||||
{"Transfered ", Kernel::Svc::MemoryState::Transfered},
|
||||
{"SharedTransfered", Kernel::Svc::MemoryState::SharedTransfered},
|
||||
{"SharedCode ", Kernel::Svc::MemoryState::SharedCode},
|
||||
{"Inaccessible ", Kernel::Svc::MemoryState::Inaccessible},
|
||||
{"NonSecureIpc ", Kernel::Svc::MemoryState::NonSecureIpc},
|
||||
{"NonDeviceIpc ", Kernel::Svc::MemoryState::NonDeviceIpc},
|
||||
{"Kernel ", Kernel::Svc::MemoryState::Kernel},
|
||||
{"GeneratedCode ", Kernel::Svc::MemoryState::GeneratedCode},
|
||||
{"CodeOut ", Kernel::Svc::MemoryState::CodeOut},
|
||||
{"Coverage ", Kernel::Svc::MemoryState::Coverage},
|
||||
}};
|
||||
|
||||
static constexpr const char* GetMemoryStateName(Kernel::Svc::MemoryState state) {
|
||||
|
||||
@@ -31,12 +31,6 @@ public:
|
||||
DramMemoryMap::Base;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PAddr GetRawPhysicalAddr(const T* ptr) const {
|
||||
return static_cast<PAddr>(reinterpret_cast<uintptr_t>(ptr) -
|
||||
reinterpret_cast<uintptr_t>(buffer.BackingBasePointer()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* GetPointer(Common::PhysicalAddress addr) {
|
||||
return reinterpret_cast<T*>(buffer.BackingBasePointer() +
|
||||
@@ -49,16 +43,6 @@ public:
|
||||
(GetInteger(addr) - DramMemoryMap::Base));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* GetPointerFromRaw(PAddr addr) {
|
||||
return reinterpret_cast<T*>(buffer.BackingBasePointer() + addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* GetPointerFromRaw(PAddr addr) const {
|
||||
return reinterpret_cast<T*>(buffer.BackingBasePointer() + addr);
|
||||
}
|
||||
|
||||
Common::HostMemory buffer;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/scratch_buffer.h"
|
||||
#include "common/virtual_buffer.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
constexpr size_t DEVICE_PAGEBITS = 12ULL;
|
||||
constexpr size_t DEVICE_PAGESIZE = 1ULL << DEVICE_PAGEBITS;
|
||||
constexpr size_t DEVICE_PAGEMASK = DEVICE_PAGESIZE - 1ULL;
|
||||
|
||||
class DeviceMemory;
|
||||
|
||||
namespace Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
template <typename DTraits>
|
||||
struct DeviceMemoryManagerAllocator;
|
||||
|
||||
template <typename Traits>
|
||||
class DeviceMemoryManager {
|
||||
using DeviceInterface = typename Traits::DeviceInterface;
|
||||
using DeviceMethods = typename Traits::DeviceMethods;
|
||||
|
||||
public:
|
||||
DeviceMemoryManager(const DeviceMemory& device_memory);
|
||||
~DeviceMemoryManager();
|
||||
|
||||
void BindInterface(DeviceInterface* device_inter);
|
||||
|
||||
DAddr Allocate(size_t size);
|
||||
void AllocateFixed(DAddr start, size_t size);
|
||||
void Free(DAddr start, size_t size);
|
||||
|
||||
void Map(DAddr address, VAddr virtual_address, size_t size, size_t process_id,
|
||||
bool track = false);
|
||||
|
||||
void Unmap(DAddr address, size_t size);
|
||||
|
||||
void TrackContinuityImpl(DAddr address, VAddr virtual_address, size_t size, size_t process_id);
|
||||
void TrackContinuity(DAddr address, VAddr virtual_address, size_t size, size_t process_id) {
|
||||
std::scoped_lock lk(mapping_guard);
|
||||
TrackContinuityImpl(address, virtual_address, size, process_id);
|
||||
}
|
||||
|
||||
// Write / Read
|
||||
template <typename T>
|
||||
T* GetPointer(DAddr address);
|
||||
|
||||
template <typename T>
|
||||
const T* GetPointer(DAddr address) const;
|
||||
|
||||
template <typename Func>
|
||||
void ApplyOpOnPAddr(PAddr address, Common::ScratchBuffer<u32>& buffer, Func&& operation) {
|
||||
DAddr subbits = static_cast<DAddr>(address & page_mask);
|
||||
const u32 base = compressed_device_addr[(address >> page_bits)];
|
||||
if ((base >> MULTI_FLAG_BITS) == 0) [[likely]] {
|
||||
const DAddr d_address = (static_cast<DAddr>(base) << page_bits) + subbits;
|
||||
operation(d_address);
|
||||
return;
|
||||
}
|
||||
InnerGatherDeviceAddresses(buffer, address);
|
||||
for (u32 value : buffer) {
|
||||
operation((static_cast<DAddr>(value) << page_bits) + subbits);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
void ApplyOpOnPointer(const u8* p, Common::ScratchBuffer<u32>& buffer, Func&& operation) {
|
||||
PAddr address = GetRawPhysicalAddr<u8>(p);
|
||||
ApplyOpOnPAddr(address, buffer, operation);
|
||||
}
|
||||
|
||||
PAddr GetPhysicalRawAddressFromDAddr(DAddr address) const {
|
||||
PAddr subbits = static_cast<PAddr>(address & page_mask);
|
||||
auto paddr = compressed_physical_ptr[(address >> page_bits)];
|
||||
if (paddr == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (static_cast<PAddr>(paddr - 1) << page_bits) + subbits;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Write(DAddr address, T value);
|
||||
|
||||
template <typename T>
|
||||
T Read(DAddr address) const;
|
||||
|
||||
u8* GetSpan(const DAddr src_addr, const std::size_t size);
|
||||
const u8* GetSpan(const DAddr src_addr, const std::size_t size) const;
|
||||
|
||||
void ReadBlock(DAddr address, void* dest_pointer, size_t size);
|
||||
void ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size);
|
||||
void WriteBlock(DAddr address, const void* src_pointer, size_t size);
|
||||
void WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size);
|
||||
|
||||
size_t RegisterProcess(Memory::Memory* memory);
|
||||
void UnregisterProcess(size_t id);
|
||||
|
||||
void UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta);
|
||||
|
||||
static constexpr size_t AS_BITS = Traits::device_virtual_bits;
|
||||
|
||||
private:
|
||||
static constexpr size_t device_virtual_bits = Traits::device_virtual_bits;
|
||||
static constexpr size_t device_as_size = 1ULL << device_virtual_bits;
|
||||
static constexpr size_t physical_min_bits = 32;
|
||||
static constexpr size_t physical_max_bits = 33;
|
||||
static constexpr size_t page_bits = 12;
|
||||
static constexpr size_t page_size = 1ULL << page_bits;
|
||||
static constexpr size_t page_mask = page_size - 1ULL;
|
||||
static constexpr u32 physical_address_base = 1U << page_bits;
|
||||
static constexpr u32 MULTI_FLAG_BITS = 31;
|
||||
static constexpr u32 MULTI_FLAG = 1U << MULTI_FLAG_BITS;
|
||||
static constexpr u32 MULTI_MASK = ~MULTI_FLAG;
|
||||
|
||||
template <typename T>
|
||||
T* GetPointerFromRaw(PAddr addr) {
|
||||
return reinterpret_cast<T*>(physical_base + addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* GetPointerFromRaw(PAddr addr) const {
|
||||
return reinterpret_cast<T*>(physical_base + addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PAddr GetRawPhysicalAddr(const T* ptr) const {
|
||||
return static_cast<PAddr>(reinterpret_cast<uintptr_t>(ptr) - physical_base);
|
||||
}
|
||||
|
||||
void WalkBlock(const DAddr addr, const std::size_t size, auto on_unmapped, auto on_memory,
|
||||
auto increment);
|
||||
|
||||
void InnerGatherDeviceAddresses(Common::ScratchBuffer<u32>& buffer, PAddr address);
|
||||
|
||||
std::unique_ptr<DeviceMemoryManagerAllocator<Traits>> impl;
|
||||
|
||||
const uintptr_t physical_base;
|
||||
DeviceInterface* device_inter;
|
||||
Common::VirtualBuffer<u32> compressed_physical_ptr;
|
||||
Common::VirtualBuffer<u32> compressed_device_addr;
|
||||
Common::VirtualBuffer<u32> continuity_tracker;
|
||||
|
||||
// Process memory interfaces
|
||||
|
||||
std::deque<size_t> id_pool;
|
||||
std::deque<Memory::Memory*> registered_processes;
|
||||
|
||||
// Memory protection management
|
||||
|
||||
static constexpr size_t guest_max_as_bits = 39;
|
||||
static constexpr size_t guest_as_size = 1ULL << guest_max_as_bits;
|
||||
static constexpr size_t guest_mask = guest_as_size - 1ULL;
|
||||
static constexpr size_t process_id_start_bit = guest_max_as_bits;
|
||||
|
||||
std::pair<size_t, VAddr> ExtractCPUBacking(size_t page_index) {
|
||||
auto content = cpu_backing_address[page_index];
|
||||
const VAddr address = content & guest_mask;
|
||||
const size_t process_id = static_cast<size_t>(content >> process_id_start_bit);
|
||||
return std::make_pair(process_id, address);
|
||||
}
|
||||
|
||||
void InsertCPUBacking(size_t page_index, VAddr address, size_t process_id) {
|
||||
cpu_backing_address[page_index] = address | (process_id << process_id_start_bit);
|
||||
}
|
||||
|
||||
Common::VirtualBuffer<VAddr> cpu_backing_address;
|
||||
static constexpr size_t subentries = 8 / sizeof(u8);
|
||||
static constexpr size_t subentries_mask = subentries - 1;
|
||||
class CounterEntry final {
|
||||
public:
|
||||
CounterEntry() = default;
|
||||
|
||||
std::atomic_uint8_t& Count(std::size_t page) {
|
||||
return values[page & subentries_mask];
|
||||
}
|
||||
|
||||
const std::atomic_uint8_t& Count(std::size_t page) const {
|
||||
return values[page & subentries_mask];
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<std::atomic_uint8_t, subentries> values{};
|
||||
};
|
||||
static_assert(sizeof(CounterEntry) == subentries * sizeof(u8),
|
||||
"CounterEntry should be 8 bytes!");
|
||||
|
||||
static constexpr size_t num_counter_entries =
|
||||
(1ULL << (device_virtual_bits - page_bits)) / subentries;
|
||||
using CachedPages = std::array<CounterEntry, num_counter_entries>;
|
||||
std::unique_ptr<CachedPages> cached_pages;
|
||||
std::mutex counter_guard;
|
||||
std::mutex mapping_guard;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
@@ -1,588 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include "common/address_space.h"
|
||||
#include "common/address_space.inc"
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/div_ceil.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/device_memory.h"
|
||||
#include "core/device_memory_manager.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace {
|
||||
|
||||
class MultiAddressContainer {
|
||||
public:
|
||||
MultiAddressContainer() = default;
|
||||
~MultiAddressContainer() = default;
|
||||
|
||||
void GatherValues(u32 start_entry, Common::ScratchBuffer<u32>& buffer) {
|
||||
buffer.resize(8);
|
||||
buffer.resize(0);
|
||||
size_t index = 0;
|
||||
const auto add_value = [&](u32 value) {
|
||||
buffer[index] = value;
|
||||
index++;
|
||||
buffer.resize(index);
|
||||
};
|
||||
|
||||
u32 iter_entry = start_entry;
|
||||
Entry* current = &storage[iter_entry - 1];
|
||||
add_value(current->value);
|
||||
while (current->next_entry != 0) {
|
||||
iter_entry = current->next_entry;
|
||||
current = &storage[iter_entry - 1];
|
||||
add_value(current->value);
|
||||
}
|
||||
}
|
||||
|
||||
u32 Register(u32 value) {
|
||||
return RegisterImplementation(value);
|
||||
}
|
||||
|
||||
void Register(u32 value, u32 start_entry) {
|
||||
auto entry_id = RegisterImplementation(value);
|
||||
u32 iter_entry = start_entry;
|
||||
Entry* current = &storage[iter_entry - 1];
|
||||
while (current->next_entry != 0) {
|
||||
iter_entry = current->next_entry;
|
||||
current = &storage[iter_entry - 1];
|
||||
}
|
||||
current->next_entry = entry_id;
|
||||
}
|
||||
|
||||
std::pair<bool, u32> Unregister(u32 value, u32 start_entry) {
|
||||
u32 iter_entry = start_entry;
|
||||
Entry* previous{};
|
||||
Entry* current = &storage[iter_entry - 1];
|
||||
Entry* next{};
|
||||
bool more_than_one_remaining = false;
|
||||
u32 result_start{start_entry};
|
||||
size_t count = 0;
|
||||
while (current->value != value) {
|
||||
count++;
|
||||
previous = current;
|
||||
iter_entry = current->next_entry;
|
||||
current = &storage[iter_entry - 1];
|
||||
}
|
||||
// Find next
|
||||
u32 next_entry = current->next_entry;
|
||||
if (next_entry != 0) {
|
||||
next = &storage[next_entry - 1];
|
||||
more_than_one_remaining = next->next_entry != 0 || previous != nullptr;
|
||||
}
|
||||
if (previous) {
|
||||
previous->next_entry = next_entry;
|
||||
} else {
|
||||
result_start = next_entry;
|
||||
}
|
||||
free_entries.emplace_back(iter_entry);
|
||||
return std::make_pair(more_than_one_remaining || count > 1, result_start);
|
||||
}
|
||||
|
||||
u32 ReleaseEntry(u32 start_entry) {
|
||||
Entry* current = &storage[start_entry - 1];
|
||||
free_entries.emplace_back(start_entry);
|
||||
return current->value;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 RegisterImplementation(u32 value) {
|
||||
auto entry_id = GetNewEntry();
|
||||
auto& entry = storage[entry_id - 1];
|
||||
entry.next_entry = 0;
|
||||
entry.value = value;
|
||||
return entry_id;
|
||||
}
|
||||
u32 GetNewEntry() {
|
||||
if (!free_entries.empty()) {
|
||||
u32 result = free_entries.front();
|
||||
free_entries.pop_front();
|
||||
return result;
|
||||
}
|
||||
storage.emplace_back();
|
||||
u32 new_entry = static_cast<u32>(storage.size());
|
||||
return new_entry;
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
u32 next_entry{};
|
||||
u32 value{};
|
||||
};
|
||||
|
||||
std::deque<Entry> storage;
|
||||
std::deque<u32> free_entries;
|
||||
};
|
||||
|
||||
struct EmptyAllocator {
|
||||
EmptyAllocator([[maybe_unused]] DAddr address) {}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename DTraits>
|
||||
struct DeviceMemoryManagerAllocator {
|
||||
static constexpr size_t device_virtual_bits = DTraits::device_virtual_bits;
|
||||
static constexpr DAddr first_address = 1ULL << Memory::YUZU_PAGEBITS;
|
||||
static constexpr DAddr max_device_area = 1ULL << device_virtual_bits;
|
||||
|
||||
DeviceMemoryManagerAllocator() : main_allocator(first_address) {}
|
||||
|
||||
Common::FlatAllocator<DAddr, 0, device_virtual_bits> main_allocator;
|
||||
MultiAddressContainer multi_dev_address;
|
||||
|
||||
/// Returns true when vaddr -> vaddr+size is fully contained in the buffer
|
||||
template <bool pin_area>
|
||||
[[nodiscard]] bool IsInBounds(VAddr addr, u64 size) const noexcept {
|
||||
return addr >= 0 && addr + size <= max_device_area;
|
||||
}
|
||||
|
||||
DAddr Allocate(size_t size) {
|
||||
return main_allocator.Allocate(size);
|
||||
}
|
||||
|
||||
void AllocateFixed(DAddr b_address, size_t b_size) {
|
||||
main_allocator.AllocateFixed(b_address, b_size);
|
||||
}
|
||||
|
||||
void Free(DAddr b_address, size_t b_size) {
|
||||
main_allocator.Free(b_address, b_size);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Traits>
|
||||
DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memory_)
|
||||
: physical_base{reinterpret_cast<const uintptr_t>(device_memory_.buffer.BackingBasePointer())},
|
||||
device_inter{nullptr}, compressed_physical_ptr(device_as_size >> Memory::YUZU_PAGEBITS),
|
||||
compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() ==
|
||||
Settings::MemoryLayout::Memory_4Gb
|
||||
? physical_min_bits
|
||||
: physical_max_bits) -
|
||||
Memory::YUZU_PAGEBITS)),
|
||||
continuity_tracker(device_as_size >> Memory::YUZU_PAGEBITS),
|
||||
cpu_backing_address(device_as_size >> Memory::YUZU_PAGEBITS) {
|
||||
impl = std::make_unique<DeviceMemoryManagerAllocator<Traits>>();
|
||||
cached_pages = std::make_unique<CachedPages>();
|
||||
|
||||
const size_t total_virtual = device_as_size >> Memory::YUZU_PAGEBITS;
|
||||
for (size_t i = 0; i < total_virtual; i++) {
|
||||
compressed_physical_ptr[i] = 0;
|
||||
continuity_tracker[i] = 1;
|
||||
cpu_backing_address[i] = 0;
|
||||
}
|
||||
const size_t total_phys = 1ULL << ((Settings::values.memory_layout_mode.GetValue() ==
|
||||
Settings::MemoryLayout::Memory_4Gb
|
||||
? physical_min_bits
|
||||
: physical_max_bits) -
|
||||
Memory::YUZU_PAGEBITS);
|
||||
for (size_t i = 0; i < total_phys; i++) {
|
||||
compressed_device_addr[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
DeviceMemoryManager<Traits>::~DeviceMemoryManager() = default;
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::BindInterface(DeviceInterface* device_inter_) {
|
||||
device_inter = device_inter_;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
DAddr DeviceMemoryManager<Traits>::Allocate(size_t size) {
|
||||
return impl->Allocate(size);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::AllocateFixed(DAddr start, size_t size) {
|
||||
return impl->AllocateFixed(start, size);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::Free(DAddr start, size_t size) {
|
||||
impl->Free(start, size);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size,
|
||||
size_t process_id, bool track) {
|
||||
Core::Memory::Memory* process_memory = registered_processes[process_id];
|
||||
size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
|
||||
size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
|
||||
std::scoped_lock lk(mapping_guard);
|
||||
for (size_t i = 0; i < num_pages; i++) {
|
||||
const VAddr new_vaddress = virtual_address + i * Memory::YUZU_PAGESIZE;
|
||||
auto* ptr = process_memory->GetPointerSilent(Common::ProcessAddress(new_vaddress));
|
||||
if (ptr == nullptr) [[unlikely]] {
|
||||
compressed_physical_ptr[start_page_d + i] = 0;
|
||||
continue;
|
||||
}
|
||||
auto phys_addr = static_cast<u32>(GetRawPhysicalAddr(ptr) >> Memory::YUZU_PAGEBITS) + 1U;
|
||||
compressed_physical_ptr[start_page_d + i] = phys_addr;
|
||||
InsertCPUBacking(start_page_d + i, new_vaddress, process_id);
|
||||
const u32 base_dev = compressed_device_addr[phys_addr - 1U];
|
||||
const u32 new_dev = static_cast<u32>(start_page_d + i);
|
||||
if (base_dev == 0) [[likely]] {
|
||||
compressed_device_addr[phys_addr - 1U] = new_dev;
|
||||
continue;
|
||||
}
|
||||
u32 start_id = base_dev & MULTI_MASK;
|
||||
if ((base_dev >> MULTI_FLAG_BITS) == 0) {
|
||||
start_id = impl->multi_dev_address.Register(base_dev);
|
||||
compressed_device_addr[phys_addr - 1U] = MULTI_FLAG | start_id;
|
||||
}
|
||||
impl->multi_dev_address.Register(new_dev, start_id);
|
||||
}
|
||||
if (track) {
|
||||
TrackContinuityImpl(address, virtual_address, size, process_id);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) {
|
||||
size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
|
||||
size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
|
||||
device_inter->InvalidateRegion(address, size);
|
||||
std::scoped_lock lk(mapping_guard);
|
||||
for (size_t i = 0; i < num_pages; i++) {
|
||||
auto phys_addr = compressed_physical_ptr[start_page_d + i];
|
||||
compressed_physical_ptr[start_page_d + i] = 0;
|
||||
cpu_backing_address[start_page_d + i] = 0;
|
||||
if (phys_addr != 0) [[likely]] {
|
||||
const u32 base_dev = compressed_device_addr[phys_addr - 1U];
|
||||
if ((base_dev >> MULTI_FLAG_BITS) == 0) [[likely]] {
|
||||
compressed_device_addr[phys_addr - 1] = 0;
|
||||
continue;
|
||||
}
|
||||
const auto [more_entries, new_start] = impl->multi_dev_address.Unregister(
|
||||
static_cast<u32>(start_page_d + i), base_dev & MULTI_MASK);
|
||||
if (!more_entries) {
|
||||
compressed_device_addr[phys_addr - 1] =
|
||||
impl->multi_dev_address.ReleaseEntry(new_start);
|
||||
continue;
|
||||
}
|
||||
compressed_device_addr[phys_addr - 1] = new_start | MULTI_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address,
|
||||
size_t size, size_t process_id) {
|
||||
Core::Memory::Memory* process_memory = registered_processes[process_id];
|
||||
size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
|
||||
size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
|
||||
uintptr_t last_ptr = 0;
|
||||
size_t page_count = 1;
|
||||
for (size_t i = num_pages; i > 0; i--) {
|
||||
size_t index = i - 1;
|
||||
const VAddr new_vaddress = virtual_address + index * Memory::YUZU_PAGESIZE;
|
||||
const uintptr_t new_ptr = reinterpret_cast<uintptr_t>(
|
||||
process_memory->GetPointerSilent(Common::ProcessAddress(new_vaddress)));
|
||||
if (new_ptr + page_size == last_ptr) {
|
||||
page_count++;
|
||||
} else {
|
||||
page_count = 1;
|
||||
}
|
||||
last_ptr = new_ptr;
|
||||
continuity_tracker[start_page_d + index] = static_cast<u32>(page_count);
|
||||
}
|
||||
}
|
||||
template <typename Traits>
|
||||
u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::size_t size) {
|
||||
size_t page_index = src_addr >> page_bits;
|
||||
size_t subbits = src_addr & page_mask;
|
||||
if ((static_cast<size_t>(continuity_tracker[page_index]) << page_bits) >= size + subbits) {
|
||||
return GetPointer<u8>(src_addr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
const u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::size_t size) const {
|
||||
size_t page_index = src_addr >> page_bits;
|
||||
size_t subbits = src_addr & page_mask;
|
||||
if ((static_cast<size_t>(continuity_tracker[page_index]) << page_bits) >= size + subbits) {
|
||||
return GetPointer<u8>(src_addr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::InnerGatherDeviceAddresses(Common::ScratchBuffer<u32>& buffer,
|
||||
PAddr address) {
|
||||
size_t phys_addr = address >> page_bits;
|
||||
std::scoped_lock lk(mapping_guard);
|
||||
u32 backing = compressed_device_addr[phys_addr];
|
||||
if ((backing >> MULTI_FLAG_BITS) != 0) {
|
||||
impl->multi_dev_address.GatherValues(backing & MULTI_MASK, buffer);
|
||||
return;
|
||||
}
|
||||
buffer.resize(1);
|
||||
buffer[0] = backing;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
template <typename T>
|
||||
T* DeviceMemoryManager<Traits>::GetPointer(DAddr address) {
|
||||
const size_t index = address >> Memory::YUZU_PAGEBITS;
|
||||
const size_t offset = address & Memory::YUZU_PAGEMASK;
|
||||
auto phys_addr = compressed_physical_ptr[index];
|
||||
if (phys_addr == 0) [[unlikely]] {
|
||||
return nullptr;
|
||||
}
|
||||
return GetPointerFromRaw<T>((static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS) +
|
||||
offset);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
template <typename T>
|
||||
const T* DeviceMemoryManager<Traits>::GetPointer(DAddr address) const {
|
||||
const size_t index = address >> Memory::YUZU_PAGEBITS;
|
||||
const size_t offset = address & Memory::YUZU_PAGEMASK;
|
||||
auto phys_addr = compressed_physical_ptr[index];
|
||||
if (phys_addr == 0) [[unlikely]] {
|
||||
return nullptr;
|
||||
}
|
||||
return GetPointerFromRaw<T>((static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS) +
|
||||
offset);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
template <typename T>
|
||||
void DeviceMemoryManager<Traits>::Write(DAddr address, T value) {
|
||||
T* ptr = GetPointer<T>(address);
|
||||
if (!ptr) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
std::memcpy(ptr, &value, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
template <typename T>
|
||||
T DeviceMemoryManager<Traits>::Read(DAddr address) const {
|
||||
const T* ptr = GetPointer<T>(address);
|
||||
T result{};
|
||||
if (!ptr) [[unlikely]] {
|
||||
return result;
|
||||
}
|
||||
std::memcpy(&result, ptr, sizeof(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto on_unmapped,
|
||||
auto on_memory, auto increment) {
|
||||
std::size_t remaining_size = size;
|
||||
std::size_t page_index = addr >> Memory::YUZU_PAGEBITS;
|
||||
std::size_t page_offset = addr & Memory::YUZU_PAGEMASK;
|
||||
|
||||
while (remaining_size) {
|
||||
const size_t next_pages = static_cast<std::size_t>(continuity_tracker[page_index]);
|
||||
const std::size_t copy_amount =
|
||||
std::min((next_pages << Memory::YUZU_PAGEBITS) - page_offset, remaining_size);
|
||||
const auto current_vaddr =
|
||||
static_cast<u64>((page_index << Memory::YUZU_PAGEBITS) + page_offset);
|
||||
SCOPE_EXIT({
|
||||
page_index += next_pages;
|
||||
page_offset = 0;
|
||||
increment(copy_amount);
|
||||
remaining_size -= copy_amount;
|
||||
});
|
||||
|
||||
auto phys_addr = compressed_physical_ptr[page_index];
|
||||
if (phys_addr == 0) {
|
||||
on_unmapped(copy_amount, current_vaddr);
|
||||
continue;
|
||||
}
|
||||
auto* mem_ptr = GetPointerFromRaw<u8>(
|
||||
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS) + page_offset);
|
||||
on_memory(copy_amount, mem_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::ReadBlock(DAddr address, void* dest_pointer, size_t size) {
|
||||
device_inter->FlushRegion(address, size);
|
||||
WalkBlock(
|
||||
address, size,
|
||||
[&](size_t copy_amount, DAddr current_vaddr) {
|
||||
LOG_ERROR(
|
||||
HW_Memory,
|
||||
"Unmapped Device ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
|
||||
current_vaddr, address, size);
|
||||
std::memset(dest_pointer, 0, copy_amount);
|
||||
},
|
||||
[&](size_t copy_amount, const u8* const src_ptr) {
|
||||
std::memcpy(dest_pointer, src_ptr, copy_amount);
|
||||
},
|
||||
[&](const std::size_t copy_amount) {
|
||||
dest_pointer = static_cast<u8*>(dest_pointer) + copy_amount;
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::WriteBlock(DAddr address, const void* src_pointer, size_t size) {
|
||||
WalkBlock(
|
||||
address, size,
|
||||
[&](size_t copy_amount, DAddr current_vaddr) {
|
||||
LOG_ERROR(
|
||||
HW_Memory,
|
||||
"Unmapped Device WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
|
||||
current_vaddr, address, size);
|
||||
},
|
||||
[&](size_t copy_amount, u8* const dst_ptr) {
|
||||
std::memcpy(dst_ptr, src_pointer, copy_amount);
|
||||
},
|
||||
[&](const std::size_t copy_amount) {
|
||||
src_pointer = static_cast<const u8*>(src_pointer) + copy_amount;
|
||||
});
|
||||
device_inter->InvalidateRegion(address, size);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size) {
|
||||
WalkBlock(
|
||||
address, size,
|
||||
[&](size_t copy_amount, DAddr current_vaddr) {
|
||||
LOG_ERROR(
|
||||
HW_Memory,
|
||||
"Unmapped Device ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
|
||||
current_vaddr, address, size);
|
||||
std::memset(dest_pointer, 0, copy_amount);
|
||||
},
|
||||
[&](size_t copy_amount, const u8* const src_ptr) {
|
||||
std::memcpy(dest_pointer, src_ptr, copy_amount);
|
||||
},
|
||||
[&](const std::size_t copy_amount) {
|
||||
dest_pointer = static_cast<u8*>(dest_pointer) + copy_amount;
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::WriteBlockUnsafe(DAddr address, const void* src_pointer,
|
||||
size_t size) {
|
||||
WalkBlock(
|
||||
address, size,
|
||||
[&](size_t copy_amount, DAddr current_vaddr) {
|
||||
LOG_ERROR(
|
||||
HW_Memory,
|
||||
"Unmapped Device WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
|
||||
current_vaddr, address, size);
|
||||
},
|
||||
[&](size_t copy_amount, u8* const dst_ptr) {
|
||||
std::memcpy(dst_ptr, src_pointer, copy_amount);
|
||||
},
|
||||
[&](const std::size_t copy_amount) {
|
||||
src_pointer = static_cast<const u8*>(src_pointer) + copy_amount;
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
size_t DeviceMemoryManager<Traits>::RegisterProcess(Memory::Memory* memory_device_inter) {
|
||||
size_t new_id;
|
||||
if (!id_pool.empty()) {
|
||||
new_id = id_pool.front();
|
||||
id_pool.pop_front();
|
||||
registered_processes[new_id] = memory_device_inter;
|
||||
} else {
|
||||
registered_processes.emplace_back(memory_device_inter);
|
||||
new_id = registered_processes.size() - 1U;
|
||||
}
|
||||
return new_id;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::UnregisterProcess(size_t id) {
|
||||
registered_processes[id] = nullptr;
|
||||
id_pool.push_front(id);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta) {
|
||||
bool locked = false;
|
||||
auto lock = [&] {
|
||||
if (!locked) {
|
||||
counter_guard.lock();
|
||||
locked = true;
|
||||
}
|
||||
};
|
||||
SCOPE_EXIT({
|
||||
if (locked) {
|
||||
counter_guard.unlock();
|
||||
}
|
||||
});
|
||||
u64 uncache_begin = 0;
|
||||
u64 cache_begin = 0;
|
||||
u64 uncache_bytes = 0;
|
||||
u64 cache_bytes = 0;
|
||||
const auto MarkRegionCaching = &DeviceMemoryManager<Traits>::DeviceMethods::MarkRegionCaching;
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
|
||||
size_t page = addr >> Memory::YUZU_PAGEBITS;
|
||||
auto [process_id, base_vaddress] = ExtractCPUBacking(page);
|
||||
size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS;
|
||||
auto* memory_device_inter = registered_processes[process_id];
|
||||
for (; page != page_end; ++page) {
|
||||
std::atomic_uint8_t& count = cached_pages->at(page >> 3).Count(page);
|
||||
|
||||
if (delta > 0) {
|
||||
ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<u8>::max(),
|
||||
"Count may overflow!");
|
||||
} else if (delta < 0) {
|
||||
ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!");
|
||||
} else {
|
||||
ASSERT_MSG(false, "Delta must be non-zero!");
|
||||
}
|
||||
|
||||
// Adds or subtracts 1, as count is a unsigned 8-bit value
|
||||
count.fetch_add(static_cast<u8>(delta), std::memory_order_release);
|
||||
|
||||
// Assume delta is either -1 or 1
|
||||
if (count.load(std::memory_order::relaxed) == 0) {
|
||||
if (uncache_bytes == 0) {
|
||||
uncache_begin = vpage;
|
||||
}
|
||||
uncache_bytes += Memory::YUZU_PAGESIZE;
|
||||
} else if (uncache_bytes > 0) {
|
||||
lock();
|
||||
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
|
||||
uncache_bytes, false);
|
||||
uncache_bytes = 0;
|
||||
}
|
||||
if (count.load(std::memory_order::relaxed) == 1 && delta > 0) {
|
||||
if (cache_bytes == 0) {
|
||||
cache_begin = vpage;
|
||||
}
|
||||
cache_bytes += Memory::YUZU_PAGESIZE;
|
||||
} else if (cache_bytes > 0) {
|
||||
lock();
|
||||
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
|
||||
true);
|
||||
cache_bytes = 0;
|
||||
}
|
||||
vpage++;
|
||||
}
|
||||
if (uncache_bytes > 0) {
|
||||
lock();
|
||||
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes,
|
||||
false);
|
||||
}
|
||||
if (cache_bytes > 0) {
|
||||
lock();
|
||||
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "core/file_sys/vfs_vector.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/ns/language.h"
|
||||
#include "core/hle/service/set/settings_server.h"
|
||||
#include "core/hle/service/set/set.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/loader/nso.h"
|
||||
#include "core/memory/cheat_engine.h"
|
||||
|
||||
@@ -189,15 +189,6 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
|
||||
}
|
||||
}
|
||||
|
||||
std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future) {
|
||||
if (future) {
|
||||
Common::UUID uuid;
|
||||
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
|
||||
return fmt::format("/user/save/account/{}", uuid.RawString());
|
||||
}
|
||||
return fmt::format("/user/save/{:016X}/{:016X}{:016X}", 0, user_id[1], user_id[0]);
|
||||
}
|
||||
|
||||
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
u128 user_id) const {
|
||||
const auto path =
|
||||
|
||||
@@ -101,7 +101,6 @@ public:
|
||||
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
|
||||
static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,
|
||||
SaveDataType type, u64 title_id, u128 user_id, u64 save_id);
|
||||
static std::string GetUserGameSaveDataRoot(u128 user_id, bool future);
|
||||
|
||||
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
|
||||
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "core/device_memory_manager.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
|
||||
~GPUDirtyMemoryManager() = default;
|
||||
|
||||
void Collect(PAddr address, size_t size) {
|
||||
void Collect(VAddr address, size_t size) {
|
||||
TransformAddress t = BuildTransform(address, size);
|
||||
TransformAddress tmp, original;
|
||||
do {
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
void Gather(std::function<void(PAddr, size_t)>& callback) {
|
||||
void Gather(std::function<void(VAddr, size_t)>& callback) {
|
||||
{
|
||||
std::scoped_lock lk(guard);
|
||||
TransformAddress t = current.exchange(default_transform, std::memory_order_relaxed);
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
mask = mask >> empty_bits;
|
||||
|
||||
const size_t continuous_bits = std::countr_one(mask);
|
||||
callback((static_cast<PAddr>(transform.address) << page_bits) + offset,
|
||||
callback((static_cast<VAddr>(transform.address) << page_bits) + offset,
|
||||
continuous_bits << align_bits);
|
||||
mask = continuous_bits < align_size ? (mask >> continuous_bits) : 0;
|
||||
offset += continuous_bits << align_bits;
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
constexpr static size_t page_bits = DEVICE_PAGEBITS - 1;
|
||||
constexpr static size_t page_bits = Memory::YUZU_PAGEBITS - 1;
|
||||
constexpr static size_t page_size = 1ULL << page_bits;
|
||||
constexpr static size_t page_mask = page_size - 1;
|
||||
|
||||
@@ -89,7 +89,7 @@ private:
|
||||
constexpr static size_t align_mask = align_size - 1;
|
||||
constexpr static TransformAddress default_transform = {.address = ~0U, .mask = 0U};
|
||||
|
||||
bool IsValid(PAddr address) {
|
||||
bool IsValid(VAddr address) {
|
||||
return address < (1ULL << 39);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ private:
|
||||
return mask;
|
||||
}
|
||||
|
||||
TransformAddress BuildTransform(PAddr address, size_t size) {
|
||||
TransformAddress BuildTransform(VAddr address, size_t size) {
|
||||
const size_t minor_address = address & page_mask;
|
||||
const size_t minor_bit = minor_address >> align_bits;
|
||||
const size_t top_bit = (minor_address + size + align_mask) >> align_bits;
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/scratch_buffer.h"
|
||||
|
||||
namespace Core::Memory {
|
||||
|
||||
enum GuestMemoryFlags : u32 {
|
||||
Read = 1 << 0,
|
||||
Write = 1 << 1,
|
||||
Safe = 1 << 2,
|
||||
Cached = 1 << 3,
|
||||
|
||||
SafeRead = Read | Safe,
|
||||
SafeWrite = Write | Safe,
|
||||
SafeReadWrite = SafeRead | SafeWrite,
|
||||
SafeReadCachedWrite = SafeReadWrite | Cached,
|
||||
|
||||
UnsafeRead = Read,
|
||||
UnsafeWrite = Write,
|
||||
UnsafeReadWrite = UnsafeRead | UnsafeWrite,
|
||||
UnsafeReadCachedWrite = UnsafeReadWrite | Cached,
|
||||
};
|
||||
|
||||
namespace {
|
||||
template <typename M, typename T, GuestMemoryFlags FLAGS>
|
||||
class GuestMemory {
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
using value_type = T;
|
||||
using element_type = T;
|
||||
using iterator_category = std::contiguous_iterator_tag;
|
||||
|
||||
public:
|
||||
GuestMemory() = delete;
|
||||
explicit GuestMemory(M& memory, u64 addr, std::size_t size,
|
||||
Common::ScratchBuffer<T>* backup = nullptr)
|
||||
: m_memory{memory}, m_addr{addr}, m_size{size} {
|
||||
static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
|
||||
if constexpr (FLAGS & GuestMemoryFlags::Read) {
|
||||
Read(addr, size, backup);
|
||||
}
|
||||
}
|
||||
|
||||
~GuestMemory() = default;
|
||||
|
||||
T* data() noexcept {
|
||||
return m_data_span.data();
|
||||
}
|
||||
|
||||
const T* data() const noexcept {
|
||||
return m_data_span.data();
|
||||
}
|
||||
|
||||
size_t size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_t size_bytes() const noexcept {
|
||||
return this->size() * sizeof(T);
|
||||
}
|
||||
|
||||
[[nodiscard]] T* begin() noexcept {
|
||||
return this->data();
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* begin() const noexcept {
|
||||
return this->data();
|
||||
}
|
||||
|
||||
[[nodiscard]] T* end() noexcept {
|
||||
return this->data() + this->size();
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* end() const noexcept {
|
||||
return this->data() + this->size();
|
||||
}
|
||||
|
||||
T& operator[](size_t index) noexcept {
|
||||
return m_data_span[index];
|
||||
}
|
||||
|
||||
const T& operator[](size_t index) const noexcept {
|
||||
return m_data_span[index];
|
||||
}
|
||||
|
||||
void SetAddressAndSize(u64 addr, std::size_t size) noexcept {
|
||||
m_addr = addr;
|
||||
m_size = size;
|
||||
m_addr_changed = true;
|
||||
}
|
||||
|
||||
std::span<T> Read(u64 addr, std::size_t size,
|
||||
Common::ScratchBuffer<T>* backup = nullptr) noexcept {
|
||||
m_addr = addr;
|
||||
m_size = size;
|
||||
if (m_size == 0) {
|
||||
m_is_data_copy = true;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (this->TrySetSpan()) {
|
||||
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
|
||||
m_memory.FlushRegion(m_addr, this->size_bytes());
|
||||
}
|
||||
} else {
|
||||
if (backup) {
|
||||
backup->resize_destructive(this->size());
|
||||
m_data_span = *backup;
|
||||
} else {
|
||||
m_data_copy.resize(this->size());
|
||||
m_data_span = std::span(m_data_copy);
|
||||
}
|
||||
m_is_data_copy = true;
|
||||
m_span_valid = true;
|
||||
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
|
||||
m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
|
||||
} else {
|
||||
m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
|
||||
}
|
||||
}
|
||||
return m_data_span;
|
||||
}
|
||||
|
||||
void Write(std::span<T> write_data) noexcept {
|
||||
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
|
||||
m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
|
||||
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
|
||||
m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
|
||||
} else {
|
||||
m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
bool TrySetSpan() noexcept {
|
||||
if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) {
|
||||
m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
|
||||
m_span_valid = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool IsDataCopy() const noexcept {
|
||||
return m_is_data_copy;
|
||||
}
|
||||
|
||||
bool AddressChanged() const noexcept {
|
||||
return m_addr_changed;
|
||||
}
|
||||
|
||||
M& m_memory;
|
||||
u64 m_addr{};
|
||||
size_t m_size{};
|
||||
std::span<T> m_data_span{};
|
||||
std::vector<T> m_data_copy{};
|
||||
bool m_span_valid{false};
|
||||
bool m_is_data_copy{false};
|
||||
bool m_addr_changed{false};
|
||||
};
|
||||
|
||||
template <typename M, typename T, GuestMemoryFlags FLAGS>
|
||||
class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> {
|
||||
public:
|
||||
GuestMemoryScoped() = delete;
|
||||
explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
|
||||
Common::ScratchBuffer<T>* backup = nullptr)
|
||||
: GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
|
||||
if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
|
||||
if (!this->TrySetSpan()) {
|
||||
if (backup) {
|
||||
this->m_data_span = *backup;
|
||||
this->m_span_valid = true;
|
||||
this->m_is_data_copy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~GuestMemoryScoped() {
|
||||
if constexpr (FLAGS & GuestMemoryFlags::Write) {
|
||||
if (this->size() == 0) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->AddressChanged() || this->IsDataCopy()) {
|
||||
ASSERT(this->m_span_valid);
|
||||
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
|
||||
this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
|
||||
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
|
||||
this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes());
|
||||
} else {
|
||||
this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
|
||||
}
|
||||
} else if constexpr ((FLAGS & GuestMemoryFlags::Safe) ||
|
||||
(FLAGS & GuestMemoryFlags::Cached)) {
|
||||
this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
} // namespace Core::Memory
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "hid_core/frontend/emulated_console.h"
|
||||
#include "hid_core/frontend/input_converter.h"
|
||||
#include "core/hid/emulated_console.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
|
||||
namespace Core::HID {
|
||||
EmulatedConsole::EmulatedConsole() = default;
|
||||
@@ -17,8 +17,8 @@
|
||||
#include "common/point.h"
|
||||
#include "common/quaternion.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "hid_core/frontend/motion_input.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hid/motion_input.h"
|
||||
|
||||
namespace Core::HID {
|
||||
static constexpr std::size_t MaxTouchDevices = 32;
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
#include "common/polyfill_ranges.h"
|
||||
#include "common/thread.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/frontend/input_converter.h"
|
||||
#include "hid_core/hid_util.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
#include "core/hle/service/hid/hid_util.h"
|
||||
|
||||
namespace Core::HID {
|
||||
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
|
||||
@@ -15,9 +15,9 @@
|
||||
#include "common/param_package.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "hid_core/frontend/motion_input.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/irsensor/irs_types.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hid/irs_types.h"
|
||||
#include "core/hid/motion_input.h"
|
||||
|
||||
namespace Core::HID {
|
||||
const std::size_t max_emulated_controllers = 2;
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <algorithm>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "hid_core/frontend/emulated_devices.h"
|
||||
#include "hid_core/frontend/input_converter.h"
|
||||
#include "core/hid/emulated_devices.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
|
||||
namespace Core::HID {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "common/input.h"
|
||||
#include "common/param_package.h"
|
||||
#include "common/settings.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
|
||||
namespace Core::HID {
|
||||
using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
|
||||
@@ -2,11 +2,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "hid_core/frontend/emulated_console.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/frontend/emulated_devices.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_util.h"
|
||||
#include "core/hid/emulated_console.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/emulated_devices.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/hid/hid_util.h"
|
||||
|
||||
namespace Core::HID {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class EmulatedConsole;
|
||||
@@ -267,7 +267,6 @@ enum class NpadStyleSet : u32 {
|
||||
All = 0xFFFFFFFFU,
|
||||
};
|
||||
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
||||
DECLARE_ENUM_FLAG_OPERATORS(NpadStyleSet)
|
||||
|
||||
// This is nn::hid::VibrationDevicePosition
|
||||
enum class VibrationDevicePosition : u32 {
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <random>
|
||||
|
||||
#include "common/input.h"
|
||||
#include "hid_core/frontend/input_converter.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
|
||||
namespace Core::HID {
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hid/input_interpreter.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/hid_server.h"
|
||||
#include "core/hle/service/hid/resource_manager.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "hid_core/frontend/input_interpreter.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/resource_manager.h"
|
||||
#include "hid_core/resources/npad/npad.h"
|
||||
|
||||
InputInterpreter::InputInterpreter(Core::System& system)
|
||||
: npad{system.ServiceManager()
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
|
||||
namespace Core::IrSensor {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "common/math_util.h"
|
||||
#include "hid_core/frontend/motion_input.h"
|
||||
#include "core/hid/motion_input.h"
|
||||
|
||||
namespace Core::HID {
|
||||
|
||||
@@ -81,12 +81,12 @@ enum class KMemoryState : u32 {
|
||||
|
||||
ThreadLocal = static_cast<u32>(Svc::MemoryState::ThreadLocal) | FlagLinearMapped,
|
||||
|
||||
Transferred = static_cast<u32>(Svc::MemoryState::Transferred) | FlagsMisc |
|
||||
FlagCanAlignedDeviceMap | FlagCanChangeAttribute | FlagCanUseIpc |
|
||||
FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
||||
Transfered = static_cast<u32>(Svc::MemoryState::Transfered) | FlagsMisc |
|
||||
FlagCanAlignedDeviceMap | FlagCanChangeAttribute | FlagCanUseIpc |
|
||||
FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
||||
|
||||
SharedTransferred = static_cast<u32>(Svc::MemoryState::SharedTransferred) | FlagsMisc |
|
||||
FlagCanAlignedDeviceMap | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
||||
SharedTransfered = static_cast<u32>(Svc::MemoryState::SharedTransfered) | FlagsMisc |
|
||||
FlagCanAlignedDeviceMap | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
||||
|
||||
SharedCode = static_cast<u32>(Svc::MemoryState::SharedCode) | FlagMapped |
|
||||
FlagReferenceCounted | FlagLinearMapped | FlagCanUseNonSecureIpc |
|
||||
@@ -130,8 +130,8 @@ static_assert(static_cast<u32>(KMemoryState::AliasCodeData) == 0x0FFFBD09);
|
||||
static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x045C3C0A);
|
||||
static_assert(static_cast<u32>(KMemoryState::Stack) == 0x045C3C0B);
|
||||
static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0400000C);
|
||||
static_assert(static_cast<u32>(KMemoryState::Transferred) == 0x055C3C0D);
|
||||
static_assert(static_cast<u32>(KMemoryState::SharedTransferred) == 0x045C380E);
|
||||
static_assert(static_cast<u32>(KMemoryState::Transfered) == 0x055C3C0D);
|
||||
static_assert(static_cast<u32>(KMemoryState::SharedTransfered) == 0x045C380E);
|
||||
static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0440380F);
|
||||
static_assert(static_cast<u32>(KMemoryState::Inaccessible) == 0x00000010);
|
||||
static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x045C3811);
|
||||
|
||||
@@ -486,8 +486,8 @@ KProcessAddress KPageTableBase::GetRegionAddress(Svc::MemoryState state) const {
|
||||
case Svc::MemoryState::Shared:
|
||||
case Svc::MemoryState::AliasCode:
|
||||
case Svc::MemoryState::AliasCodeData:
|
||||
case Svc::MemoryState::Transferred:
|
||||
case Svc::MemoryState::SharedTransferred:
|
||||
case Svc::MemoryState::Transfered:
|
||||
case Svc::MemoryState::SharedTransfered:
|
||||
case Svc::MemoryState::SharedCode:
|
||||
case Svc::MemoryState::GeneratedCode:
|
||||
case Svc::MemoryState::CodeOut:
|
||||
@@ -522,8 +522,8 @@ size_t KPageTableBase::GetRegionSize(Svc::MemoryState state) const {
|
||||
case Svc::MemoryState::Shared:
|
||||
case Svc::MemoryState::AliasCode:
|
||||
case Svc::MemoryState::AliasCodeData:
|
||||
case Svc::MemoryState::Transferred:
|
||||
case Svc::MemoryState::SharedTransferred:
|
||||
case Svc::MemoryState::Transfered:
|
||||
case Svc::MemoryState::SharedTransfered:
|
||||
case Svc::MemoryState::SharedCode:
|
||||
case Svc::MemoryState::GeneratedCode:
|
||||
case Svc::MemoryState::CodeOut:
|
||||
@@ -564,8 +564,8 @@ bool KPageTableBase::CanContain(KProcessAddress addr, size_t size, Svc::MemorySt
|
||||
case Svc::MemoryState::AliasCodeData:
|
||||
case Svc::MemoryState::Stack:
|
||||
case Svc::MemoryState::ThreadLocal:
|
||||
case Svc::MemoryState::Transferred:
|
||||
case Svc::MemoryState::SharedTransferred:
|
||||
case Svc::MemoryState::Transfered:
|
||||
case Svc::MemoryState::SharedTransfered:
|
||||
case Svc::MemoryState::SharedCode:
|
||||
case Svc::MemoryState::GeneratedCode:
|
||||
case Svc::MemoryState::CodeOut:
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/gpu_dirty_memory_manager.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
@@ -315,7 +314,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
|
||||
|
||||
// Ensure our memory is initialized.
|
||||
m_memory.SetCurrentPageTable(*this);
|
||||
m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager());
|
||||
m_memory.SetGPUDirtyManagers(m_dirty_memory_managers);
|
||||
|
||||
// Ensure we can insert the code region.
|
||||
R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize,
|
||||
@@ -412,7 +411,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
|
||||
|
||||
// Ensure our memory is initialized.
|
||||
m_memory.SetCurrentPageTable(*this);
|
||||
m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager());
|
||||
m_memory.SetGPUDirtyManagers(m_dirty_memory_managers);
|
||||
|
||||
// Ensure we can insert the code region.
|
||||
R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code),
|
||||
@@ -1136,7 +1135,8 @@ void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
|
||||
KProcess::KProcess(KernelCore& kernel)
|
||||
: KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
|
||||
m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
|
||||
m_handle_table{kernel}, m_exclusive_monitor{}, m_memory{kernel.System()} {}
|
||||
m_handle_table{kernel}, m_dirty_memory_managers{},
|
||||
m_exclusive_monitor{}, m_memory{kernel.System()} {}
|
||||
KProcess::~KProcess() = default;
|
||||
|
||||
Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
|
||||
@@ -1318,4 +1318,10 @@ bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointT
|
||||
return true;
|
||||
}
|
||||
|
||||
void KProcess::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) {
|
||||
for (auto& manager : m_dirty_memory_managers) {
|
||||
manager.Gather(callback);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/file_sys/program_metadata.h"
|
||||
#include "core/gpu_dirty_memory_manager.h"
|
||||
#include "core/hle/kernel/code_set.h"
|
||||
#include "core/hle/kernel/k_address_arbiter.h"
|
||||
#include "core/hle/kernel/k_capabilities.h"
|
||||
@@ -127,6 +128,7 @@ private:
|
||||
#ifdef HAS_NCE
|
||||
std::unordered_map<u64, u64> m_post_handlers{};
|
||||
#endif
|
||||
std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> m_dirty_memory_managers;
|
||||
std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
|
||||
Core::Memory::Memory m_memory;
|
||||
|
||||
@@ -509,6 +511,8 @@ public:
|
||||
return m_memory;
|
||||
}
|
||||
|
||||
void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback);
|
||||
|
||||
Core::ExclusiveMonitor& GetExclusiveMonitor() const {
|
||||
return *m_exclusive_monitor;
|
||||
}
|
||||
|
||||
@@ -1258,11 +1258,11 @@ ThreadState KThread::RequestTerminate() {
|
||||
// Change the thread's priority to be higher than any system thread's.
|
||||
this->IncreaseBasePriority(TerminatingThreadPriority);
|
||||
|
||||
// If the thread is runnable, send a termination interrupt to cores it may be running on.
|
||||
// If the thread is runnable, send a termination interrupt to other cores.
|
||||
if (this->GetState() == ThreadState::Runnable) {
|
||||
// NOTE: We do not mask the "current core", because this code may not actually be
|
||||
// executing from the thread representing the "current core".
|
||||
if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask(); core_mask != 0) {
|
||||
if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask() &
|
||||
~(1ULL << GetCurrentCoreId(m_kernel));
|
||||
core_mask != 0) {
|
||||
Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ Result KTransferMemory::Map(KProcessAddress address, size_t size, Svc::MemoryPer
|
||||
|
||||
// Map the memory.
|
||||
const KMemoryState state = (m_owner_perm == Svc::MemoryPermission::None)
|
||||
? KMemoryState::Transferred
|
||||
: KMemoryState::SharedTransferred;
|
||||
? KMemoryState::Transfered
|
||||
: KMemoryState::SharedTransfered;
|
||||
R_TRY(GetCurrentProcess(m_kernel).GetPageTable().MapPageGroup(
|
||||
address, *m_page_group, state, KMemoryPermission::UserReadWrite));
|
||||
|
||||
@@ -96,8 +96,8 @@ Result KTransferMemory::Unmap(KProcessAddress address, size_t size) {
|
||||
|
||||
// Unmap the memory.
|
||||
const KMemoryState state = (m_owner_perm == Svc::MemoryPermission::None)
|
||||
? KMemoryState::Transferred
|
||||
: KMemoryState::SharedTransferred;
|
||||
? KMemoryState::Transfered
|
||||
: KMemoryState::SharedTransfered;
|
||||
R_TRY(GetCurrentProcess(m_kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, state));
|
||||
|
||||
// Mark ourselves as unmapped.
|
||||
|
||||
@@ -90,7 +90,7 @@ Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t add
|
||||
// Verify that the mapping is in range.
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel())
|
||||
.GetPageTable()
|
||||
.CanContain(address, size, KMemoryState::Transferred),
|
||||
.CanContain(address, size, KMemoryState::Transfered),
|
||||
ResultInvalidMemoryRegion);
|
||||
|
||||
// Map the transfer memory.
|
||||
@@ -117,7 +117,7 @@ Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t a
|
||||
// Verify that the mapping is in range.
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel())
|
||||
.GetPageTable()
|
||||
.CanContain(address, size, KMemoryState::Transferred),
|
||||
.CanContain(address, size, KMemoryState::Transfered),
|
||||
ResultInvalidMemoryRegion);
|
||||
|
||||
// Unmap the transfer memory.
|
||||
|
||||
@@ -27,8 +27,8 @@ enum class MemoryState : u32 {
|
||||
Ipc = 0x0A,
|
||||
Stack = 0x0B,
|
||||
ThreadLocal = 0x0C,
|
||||
Transferred = 0x0D,
|
||||
SharedTransferred = 0x0E,
|
||||
Transfered = 0x0D,
|
||||
SharedTransfered = 0x0E,
|
||||
SharedCode = 0x0F,
|
||||
Inaccessible = 0x10,
|
||||
NonSecureIpc = 0x11,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/result.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#include "core/hle/service/caps/caps_su.h"
|
||||
#include "core/hle/service/caps/caps_types.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/ipc_helpers.h"
|
||||
#include "core/hle/service/ns/ns.h"
|
||||
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
|
||||
@@ -46,8 +48,6 @@
|
||||
#include "core/hle/service/vi/vi.h"
|
||||
#include "core/hle/service/vi/vi_results.h"
|
||||
#include "core/memory.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/resources/npad/npad.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/applets/cabinet.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/am/applets/applet_cabinet.h"
|
||||
#include "core/hle/service/mii/mii_manager.h"
|
||||
#include "core/hle/service/nfc/common/device.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
|
||||
namespace Service::AM::Applets {
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/am/applets/applet_controller.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/resources/npad/npad.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
|
||||
namespace Service::AM::Applets {
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ struct UiSettingsDisplayOptions {
|
||||
bool is_system_or_launcher;
|
||||
bool is_registration_permitted;
|
||||
bool show_skip_button;
|
||||
bool additional_select;
|
||||
bool aditional_select;
|
||||
bool show_user_selector;
|
||||
bool is_unqualified_user_selectable;
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@ Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, Albu
|
||||
}
|
||||
|
||||
Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries,
|
||||
ContentType content_type, s64 start_posix_time,
|
||||
ContentType contex_type, s64 start_posix_time,
|
||||
s64 end_posix_time, u64 aruid) const {
|
||||
if (!is_mounted) {
|
||||
return ResultIsNotMounted;
|
||||
@@ -94,7 +94,7 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& ou
|
||||
std::vector<ApplicationAlbumEntry> album_entries;
|
||||
const auto start_date = ConvertToAlbumDateTime(start_posix_time);
|
||||
const auto end_date = ConvertToAlbumDateTime(end_posix_time);
|
||||
const auto result = GetAlbumFileList(album_entries, content_type, start_date, end_date, aruid);
|
||||
const auto result = GetAlbumFileList(album_entries, contex_type, start_date, end_date, aruid);
|
||||
|
||||
if (result.IsError()) {
|
||||
return result;
|
||||
@@ -113,14 +113,14 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& ou
|
||||
}
|
||||
|
||||
Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries,
|
||||
ContentType content_type, AlbumFileDateTime start_date,
|
||||
ContentType contex_type, AlbumFileDateTime start_date,
|
||||
AlbumFileDateTime end_date, u64 aruid) const {
|
||||
if (!is_mounted) {
|
||||
return ResultIsNotMounted;
|
||||
}
|
||||
|
||||
for (auto& [file_id, path] : album_files) {
|
||||
if (file_id.type != content_type) {
|
||||
if (file_id.type != contex_type) {
|
||||
continue;
|
||||
}
|
||||
if (file_id.date > start_date) {
|
||||
@@ -139,7 +139,7 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
|
||||
.hash{},
|
||||
.datetime = file_id.date,
|
||||
.storage = file_id.storage,
|
||||
.content = content_type,
|
||||
.content = contex_type,
|
||||
.unknown = 1,
|
||||
};
|
||||
out_entries.push_back(entry);
|
||||
|
||||
@@ -45,10 +45,10 @@ public:
|
||||
Result GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage,
|
||||
u8 flags) const;
|
||||
Result GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries,
|
||||
ContentType content_type, s64 start_posix_time, s64 end_posix_time,
|
||||
ContentType contex_type, s64 start_posix_time, s64 end_posix_time,
|
||||
u64 aruid) const;
|
||||
Result GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries,
|
||||
ContentType content_type, AlbumFileDateTime start_date,
|
||||
ContentType contex_type, AlbumFileDateTime start_date,
|
||||
AlbumFileDateTime end_date, u64 aruid) const;
|
||||
Result GetAutoSavingStorage(bool& out_is_autosaving) const;
|
||||
Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
|
||||
|
||||
@@ -12,7 +12,7 @@ constexpr Result ResultUnknown5(ErrorModule::Capture, 5);
|
||||
constexpr Result ResultUnknown6(ErrorModule::Capture, 6);
|
||||
constexpr Result ResultUnknown7(ErrorModule::Capture, 7);
|
||||
constexpr Result ResultOutOfRange(ErrorModule::Capture, 8);
|
||||
constexpr Result ResultInvalidTimestamp(ErrorModule::Capture, 12);
|
||||
constexpr Result ResulInvalidTimestamp(ErrorModule::Capture, 12);
|
||||
constexpr Result ResultInvalidStorage(ErrorModule::Capture, 13);
|
||||
constexpr Result ResultInvalidFileContents(ErrorModule::Capture, 14);
|
||||
constexpr Result ResultIsNotMounted(ErrorModule::Capture, 21);
|
||||
|
||||
@@ -131,7 +131,7 @@ private:
|
||||
u8 is_favorite;
|
||||
u8 same_app;
|
||||
u8 same_app_played;
|
||||
u8 arbitrary_app_played;
|
||||
u8 arbitary_app_played;
|
||||
u64 group_id;
|
||||
};
|
||||
static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size");
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
#include "hid_core/hid_result.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
#include "core/hle/service/hid/errors.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -87,9 +87,7 @@ Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input
|
||||
data_index = i;
|
||||
break;
|
||||
}
|
||||
// TODO: Don't Handle pending delete here
|
||||
if (registration_list.flag[i] == RegistrationStatus::None ||
|
||||
registration_list.flag[i] == RegistrationStatus::PendingDelete) {
|
||||
if (registration_list.flag[i] == RegistrationStatus::None) {
|
||||
data_index = i;
|
||||
break;
|
||||
}
|
||||
@@ -106,22 +104,30 @@ Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input
|
||||
}
|
||||
|
||||
void AppletResource::UnregisterAppletResourceUserId(u64 aruid) {
|
||||
const u64 index = GetIndexFromAruid(aruid);
|
||||
u64 index = GetIndexFromAruid(aruid);
|
||||
|
||||
if (index >= AruidIndexMax) {
|
||||
return;
|
||||
if (index < AruidIndexMax) {
|
||||
if (data[index].flag.is_assigned) {
|
||||
data[index].shared_memory_format = nullptr;
|
||||
data[index].flag.is_assigned.Assign(false);
|
||||
}
|
||||
}
|
||||
|
||||
FreeAppletResourceId(aruid);
|
||||
DestroySevenSixAxisTransferMemory();
|
||||
data[index].flag.raw = 0;
|
||||
data[index].aruid = 0;
|
||||
index = GetIndexFromAruid(aruid);
|
||||
if (index < AruidIndexMax) {
|
||||
DestroySevenSixAxisTransferMemory();
|
||||
data[index].flag.raw = 0;
|
||||
data[index].aruid = 0;
|
||||
|
||||
registration_list.flag[index] = RegistrationStatus::PendingDelete;
|
||||
index = GetIndexFromAruid(aruid);
|
||||
if (index < AruidIndexMax) {
|
||||
registration_list.flag[index] = RegistrationStatus::PendingDelete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppletResource::FreeAppletResourceId(u64 aruid) {
|
||||
const u64 index = GetIndexFromAruid(aruid);
|
||||
u64 index = GetIndexFromAruid(aruid);
|
||||
if (index >= AruidIndexMax) {
|
||||
return;
|
||||
}
|
||||
@@ -130,7 +136,6 @@ void AppletResource::FreeAppletResourceId(u64 aruid) {
|
||||
if (aruid_data.flag.is_assigned) {
|
||||
aruid_data.shared_memory_format = nullptr;
|
||||
aruid_data.flag.is_assigned.Assign(false);
|
||||
shared_memory_holder[index].Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +144,7 @@ u64 AppletResource::GetActiveAruid() {
|
||||
}
|
||||
|
||||
Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
|
||||
const u64 index = GetIndexFromAruid(aruid);
|
||||
u64 index = GetIndexFromAruid(aruid);
|
||||
if (index >= AruidIndexMax) {
|
||||
return ResultAruidNotRegistered;
|
||||
}
|
||||
@@ -150,7 +155,7 @@ Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle,
|
||||
|
||||
Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format,
|
||||
u64 aruid) {
|
||||
const u64 index = GetIndexFromAruid(aruid);
|
||||
u64 index = GetIndexFromAruid(aruid);
|
||||
if (index >= AruidIndexMax) {
|
||||
return ResultAruidNotRegistered;
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "hid_core/resources/shared_memory_holder.h"
|
||||
#include "core/hle/service/hid/controllers/shared_memory_holder.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
@@ -25,7 +25,6 @@ class AppletResource;
|
||||
class NPadResource;
|
||||
|
||||
static constexpr std::size_t AruidIndexMax = 0x20;
|
||||
static constexpr u64 SystemAruid = 0;
|
||||
|
||||
enum class RegistrationStatus : u32 {
|
||||
None,
|
||||
@@ -2,9 +2,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "hid_core/resources/system_buttons/capture_button.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/capture_button.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -21,11 +21,10 @@ void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/frontend/emulated_console.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "hid_core/resources/six_axis/console_six_axis.h"
|
||||
#include "core/hid/emulated_console.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/hid/controllers/console_six_axis.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -20,11 +20,10 @@ void ConsoleSixAxis::OnInit() {}
|
||||
void ConsoleSixAxis::OnRelease() {}
|
||||
|
||||
void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class EmulatedConsole;
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -32,10 +32,8 @@ bool ControllerBase::IsControllerActivated() const {
|
||||
return is_activated;
|
||||
}
|
||||
|
||||
void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource,
|
||||
std::recursive_mutex* resource_mutex) {
|
||||
void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource) {
|
||||
applet_resource = resource;
|
||||
shared_mutex = resource_mutex;
|
||||
}
|
||||
|
||||
} // namespace Service::HID
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
|
||||
namespace Core::Timing {
|
||||
class CoreTiming;
|
||||
@@ -42,13 +42,11 @@ public:
|
||||
|
||||
bool IsControllerActivated() const;
|
||||
|
||||
void SetAppletResource(std::shared_ptr<AppletResource> resource,
|
||||
std::recursive_mutex* resource_mutex);
|
||||
void SetAppletResource(std::shared_ptr<AppletResource> resource);
|
||||
|
||||
protected:
|
||||
bool is_activated{false};
|
||||
std::shared_ptr<AppletResource> applet_resource{nullptr};
|
||||
std::recursive_mutex* shared_mutex{nullptr};
|
||||
|
||||
Core::HID::HIDCore& hid_core;
|
||||
};
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "hid_core/frontend/emulated_devices.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/mouse/debug_mouse.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "core/hid/emulated_devices.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/debug_mouse.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -21,11 +21,10 @@ void DebugMouse::OnInit() {}
|
||||
void DebugMouse::OnRelease() {}
|
||||
|
||||
void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
class EmulatedDevices;
|
||||
struct MouseState;
|
||||
struct AnalogStickState;
|
||||
} // namespace Core::HID
|
||||
|
||||
namespace Service::HID {
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/debug_pad/debug_pad.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/debug_pad.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -23,11 +23,10 @@ void DebugPad::OnInit() {}
|
||||
void DebugPad::OnRelease() {}
|
||||
|
||||
void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "hid_core/resources/debug_pad/debug_pad_types.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/types/debug_pad_types.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
class EmulatedController;
|
||||
} // namespace Core::HID
|
||||
}
|
||||
|
||||
namespace Core::Timing {
|
||||
class CoreTiming;
|
||||
@@ -2,9 +2,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/digitizer/digitizer.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/digitizer.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -21,11 +21,10 @@ void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#include "common/math_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "hid_core/frontend/emulated_console.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "hid_core/resources/touch_screen/gesture.h"
|
||||
#include "core/hid/emulated_console.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/gesture.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
// HW is around 700, value is set to 400 to make it easier to trigger with mouse
|
||||
@@ -28,11 +28,10 @@ Gesture::Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) {
|
||||
Gesture::~Gesture() = default;
|
||||
|
||||
void Gesture::OnInit() {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,11 +44,10 @@ void Gesture::OnInit() {
|
||||
void Gesture::OnRelease() {}
|
||||
|
||||
void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <array>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "hid_core/resources/touch_screen/touch_types.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/types/touch_types.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class EmulatedConsole;
|
||||
@@ -2,9 +2,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "hid_core/resources/system_buttons/home_button.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/home_button.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -21,11 +21,10 @@ void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/frontend/emulated_devices.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/keyboard/keyboard.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "core/hid/emulated_devices.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/keyboard.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -22,11 +22,10 @@ void Keyboard::OnInit() {}
|
||||
void Keyboard::OnRelease() {}
|
||||
|
||||
void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "hid_core/resources/keyboard/keyboard_types.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
class EmulatedDevices;
|
||||
} // namespace Core::HID
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/types/keyboard_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Keyboard final : public ControllerBase {
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "hid_core/frontend/emulated_devices.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/mouse/mouse.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "core/hid/emulated_devices.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||
#include "core/hle/service/hid/controllers/mouse.h"
|
||||
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -21,11 +21,10 @@ void Mouse::OnInit() {}
|
||||
void Mouse::OnRelease() {}
|
||||
|
||||
void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
if (data == nullptr || !data->flag.is_assigned) {
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
class EmulatedDevices;
|
||||
struct MouseState;
|
||||
struct AnalogStickState;
|
||||
} // namespace Core::HID
|
||||
|
||||
namespace Service::HID {
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user