early-access version 4090

This commit is contained in:
pineappleEA 2024-01-26 07:10:49 +01:00
parent a98e552724
commit 07632da5b9
65 changed files with 1327 additions and 2852 deletions

View file

@ -2,18 +2,20 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
find_path(SimpleIni_INCLUDE_DIR SimpleIni.h)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SimpleIni
REQUIRED_VARS SimpleIni_INCLUDE_DIR
)
if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
add_library(SimpleIni::SimpleIni INTERFACE IMPORTED)
set_target_properties(SimpleIni::SimpleIni PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SimpleIni_INCLUDE_DIR}"
find_package(SimpleIni QUIET CONFIG)
if (SimpleIni_CONSIDERED_CONFIGS)
find_package_handle_standard_args(SimpleIni CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
pkg_search_module(SIMPLEINI QUIET IMPORTED_TARGET simpleini)
find_package_handle_standard_args(SimpleIni
REQUIRED_VARS SIMPLEINI_INCLUDEDIR
VERSION_VAR SIMPLEINI_VERSION
)
endif()
mark_as_advanced(SimpleIni_INCLUDE_DIR)
if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
add_library(SimpleIni::SimpleIni ALIAS PkgConfig::SIMPLEINI)
endif()

View file

@ -1,7 +1,7 @@
yuzu emulator early access
=============
This is the source code for early-access 4089.
This is the source code for early-access 4090.
## Legal Notice

View file

@ -193,6 +193,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
return super.dispatchKeyEvent(event)
}
if (emulationViewModel.drawerOpen.value) {
return super.dispatchKeyEvent(event)
}
return InputHandler.dispatchKeyEvent(event)
}
@ -203,6 +207,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
return super.dispatchGenericMotionEvent(event)
}
if (emulationViewModel.drawerOpen.value) {
return super.dispatchGenericMotionEvent(event)
}
// Don't attempt to do anything if we are disconnecting a device.
if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
return true

View file

@ -77,7 +77,7 @@ class AboutFragment : Fragment() {
}
binding.textVersionName.text = BuildConfig.VERSION_NAME
binding.textVersionName.setOnClickListener {
binding.buttonVersionName.setOnClickListener {
val clipBoard =
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(getString(R.string.build), BuildConfig.GIT_HASH)

View file

@ -38,6 +38,7 @@ import androidx.window.layout.WindowLayoutInfo
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.slider.Slider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.yuzu.yuzu_emu.HomeNavigationDirections
@ -184,10 +185,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
override fun onDrawerOpened(drawerView: View) {
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
binding.inGameMenu.requestFocus()
emulationViewModel.setDrawerOpen(true)
}
override fun onDrawerClosed(drawerView: View) {
binding.drawerLayout.setDrawerLockMode(IntSetting.LOCK_DRAWER.getInt())
emulationViewModel.setDrawerOpen(false)
}
override fun onDrawerStateChanged(newState: Int) {
@ -239,6 +243,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
requireContext().theme
)
}
binding.inGameMenu.requestFocus()
true
}
@ -247,6 +252,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
null,
Settings.MenuTag.SECTION_ROOT
)
binding.inGameMenu.requestFocus()
binding.root.findNavController().navigate(action)
true
}
@ -256,6 +262,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
args.game,
Settings.MenuTag.SECTION_ROOT
)
binding.inGameMenu.requestFocus()
binding.root.findNavController().navigate(action)
true
}
@ -287,6 +294,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
)
}
}
binding.inGameMenu.requestFocus()
NativeConfig.saveGlobalConfig()
true
}
@ -295,7 +303,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
emulationState.stop()
emulationViewModel.setIsEmulationStopping(true)
binding.drawerLayout.close()
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
binding.inGameMenu.requestFocus()
true
}
@ -312,12 +320,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (!NativeLibrary.isRunning()) {
return
}
if (binding.drawerLayout.isOpen) {
binding.drawerLayout.close()
} else {
binding.drawerLayout.open()
}
emulationViewModel.setDrawerOpen(!binding.drawerLayout.isOpen)
}
}
)
@ -408,6 +411,18 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
}
launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
emulationViewModel.drawerOpen.collect {
if (it) {
binding.drawerLayout.open()
binding.inGameMenu.requestFocus()
} else {
binding.drawerLayout.close()
}
}
}
}
}
}

View file

@ -6,6 +6,7 @@ package org.yuzu.yuzu_emu.model
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
class EmulationViewModel : ViewModel() {
val emulationStarted: StateFlow<Boolean> get() = _emulationStarted
@ -23,6 +24,9 @@ class EmulationViewModel : ViewModel() {
val shaderMessage: StateFlow<String> get() = _shaderMessage
private val _shaderMessage = MutableStateFlow("")
private val _drawerOpen = MutableStateFlow(false)
val drawerOpen = _drawerOpen.asStateFlow()
fun setEmulationStarted(started: Boolean) {
_emulationStarted.value = started
}
@ -49,6 +53,10 @@ class EmulationViewModel : ViewModel() {
setTotalShaders(max)
}
fun setDrawerOpen(value: Boolean) {
_drawerOpen.value = value
}
fun clear() {
setEmulationStarted(false)
setIsEmulationStopping(false)

View file

@ -11,12 +11,14 @@
android:id="@+id/appbar_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_about"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back"
app:title="@string/about" />
@ -28,6 +30,7 @@
android:layout_height="match_parent"
android:fadeScrollbars="false"
android:scrollbars="vertical"
android:defaultFocusHighlightEnabled="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout

View file

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinator_about"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_info"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:defaultFocusHighlightEnabled="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/content_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:baselineAligned="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="3"
android:gravity="top|center_horizontal"
android:paddingHorizontal="16dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/button_copy"
style="@style/Widget.Material3.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/copy_details" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_verify_integrity"
style="@style/Widget.Material3.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/verify_integrity" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/path_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:importantForAutofill="no"
android:inputType="none"
android:minHeight="48dp"
android:textAlignment="viewStart"
tools:text="1.0.0" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/program_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/program_id_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:importantForAutofill="no"
android:inputType="none"
android:minHeight="48dp"
android:textAlignment="viewStart"
tools:text="1.0.0" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/developer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/developer_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:importantForAutofill="no"
android:inputType="none"
android:minHeight="48dp"
android:textAlignment="viewStart"
tools:text="1.0.0" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/version_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:importantForAutofill="no"
android:inputType="none"
android:minHeight="48dp"
android:textAlignment="viewStart"
tools:text="1.0.0" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -14,6 +14,7 @@
android:clipToPadding="false"
android:fadeScrollbars="false"
android:scrollbars="vertical"
android:defaultFocusHighlightEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/icon_layout"
app:layout_constraintTop_toTopOf="parent">

View file

@ -23,6 +23,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:clickable="false"
android:checked="false" />

View file

@ -6,16 +6,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="12dp"
android:focusable="true">
android:layout_marginVertical="12dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:layout_gravity="center_vertical"
android:animateLayoutChanges="true">
android:layout_gravity="center_vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/path"

View file

@ -11,12 +11,14 @@
android:id="@+id/appbar_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_about"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:title="@string/about"
app:navigationIcon="@drawable/ic_back" />
@ -28,6 +30,7 @@
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:defaultFocusHighlightEnabled="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout

View file

@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -19,6 +20,7 @@
android:id="@+id/toolbar_addons"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back" />
</com.google.android.material.appbar.AppBarLayout>
@ -28,6 +30,8 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
android:defaultFocusHighlightEnabled="false"
android:nextFocusDown="@id/button_install"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -10,12 +10,14 @@
android:id="@+id/appbar_applets"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_applets"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back"
app:title="@string/applets" />

View file

@ -15,12 +15,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false"
app:liftOnScrollTargetViewId="@id/list_drivers">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_drivers"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back"
app:title="@string/gpu_driver_manager" />

View file

@ -11,12 +11,14 @@
android:id="@+id/appbar_ea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_about"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back"
app:title="@string/early_access" />
@ -30,6 +32,7 @@
android:paddingBottom="20dp"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:defaultFocusHighlightEnabled="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout

View file

@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:defaultFocusHighlightEnabled="false"
tools:context="org.yuzu.yuzu_emu.fragments.EmulationFragment"
tools:openDrawer="start">
@ -24,7 +25,8 @@
android:layout_height="match_parent"
android:layout_gravity="center"
android:focusable="false"
android:focusableInTouchMode="false" />
android:focusableInTouchMode="false"
android:defaultFocusHighlightEnabled="false" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/loading_indicator"
@ -32,7 +34,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:focusable="false"
android:defaultFocusHighlightEnabled="false"
android:clickable="false">
<androidx.constraintlayout.widget.ConstraintLayout
@ -118,6 +120,7 @@
android:layout_gravity="center"
android:focusable="true"
android:focusableInTouchMode="true"
android:defaultFocusHighlightEnabled="false"
android:visibility="invisible" />
<Button
@ -160,6 +163,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:focusedByDefault="true"
app:headerLayout="@layout/header_in_game"
app:menu="@menu/menu_in_game"
tools:visibility="gone" />

View file

@ -15,12 +15,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false"
app:liftOnScrollTargetViewId="@id/list_folders">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_folders"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back"
app:title="@string/game_folders" />
@ -31,6 +33,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:defaultFocusHighlightEnabled="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -11,12 +11,14 @@
android:id="@+id/appbar_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:touchscreenBlocksFocus="false"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_info"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back" />
</com.google.android.material.appbar.AppBarLayout>
@ -25,6 +27,7 @@
android:id="@+id/scroll_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:defaultFocusHighlightEnabled="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout

View file

@ -12,7 +12,8 @@
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:clipToPadding="false">
android:clipToPadding="false"
android:defaultFocusHighlightEnabled="false">
<LinearLayout
android:id="@+id/layout_all"
@ -86,7 +87,7 @@
android:id="@+id/list_properties"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/card_simple_outlined" />
android:defaultFocusHighlightEnabled="false" />
</LinearLayout>

View file

@ -27,6 +27,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:defaultFocusHighlightEnabled="false"
tools:listitem="@layout/card_game" />
</RelativeLayout>

View file

@ -7,7 +7,8 @@
android:background="?attr/colorSurface"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:clipToPadding="false">
android:clipToPadding="false"
android:defaultFocusHighlightEnabled="false">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/linear_layout_settings"

View file

@ -10,12 +10,14 @@
android:id="@+id/appbar_installables"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_installables"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:title="@string/manage_yuzu_data"
app:navigationIcon="@drawable/ic_back" />

View file

@ -10,12 +10,14 @@
android:id="@+id/appbar_licenses"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_licenses"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:title="@string/licenses"
app:navigationIcon="@drawable/ic_back" />

View file

@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false"
app:elevation="0dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
@ -24,6 +25,7 @@
android:id="@+id/toolbar_settings"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/ic_back" />

View file

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:focusable="true"
android:focusable="false"
android:paddingHorizontal="20dp"
android:paddingVertical="16dp">

View file

@ -12,4 +12,5 @@
android:textAlignment="viewStart"
android:textColor="?attr/colorPrimary"
android:textStyle="bold"
android:focusable="false"
tools:text="CPU Settings" />

View file

@ -42,8 +42,6 @@ public:
DeviceMemoryManager(const DeviceMemory& device_memory);
~DeviceMemoryManager();
static constexpr bool HAS_FLUSH_INVALIDATION = true;
void BindInterface(DeviceInterface* device_inter);
DAddr Allocate(size_t size);

View file

@ -44,32 +44,15 @@ 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} {
: m_memory{memory}, m_addr{addr}, m_size{size} {
static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
if (!this->TrySetSpan()) {
if (backup) {
backup->resize_destructive(this->size());
m_data_span = *backup;
m_span_valid = true;
m_is_data_copy = true;
} else {
m_data_copy.resize(this->size());
m_data_span = std::span(m_data_copy);
m_span_valid = true;
m_is_data_copy = true;
}
}
} else if constexpr (FLAGS & GuestMemoryFlags::Read) {
if constexpr (FLAGS & GuestMemoryFlags::Read) {
Read(addr, size, backup);
}
}
~GuestMemory() = default;
GuestMemory(GuestMemory&& rhs) = default;
GuestMemory& operator=(GuestMemory&& rhs) = default;
T* data() noexcept {
return m_data_span.data();
}
@ -126,8 +109,8 @@ public:
}
if (this->TrySetSpan()) {
if constexpr (FLAGS & GuestMemoryFlags::Safe && M::HAS_FLUSH_INVALIDATION) {
m_memory->FlushRegion(m_addr, this->size_bytes());
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
m_memory.FlushRegion(m_addr, this->size_bytes());
}
} else {
if (backup) {
@ -140,9 +123,9 @@ public:
m_is_data_copy = true;
m_span_valid = true;
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
m_memory->ReadBlock(m_addr, this->data(), this->size_bytes());
m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
} else {
m_memory->ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
}
}
return m_data_span;
@ -150,19 +133,18 @@ public:
void Write(std::span<T> write_data) noexcept {
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
m_memory->WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
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());
m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
} else {
m_memory->WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
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) {
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;
m_is_data_copy = false;
return true;
}
return false;
@ -177,7 +159,7 @@ protected:
return m_addr_changed;
}
M* m_memory;
M& m_memory;
u64 m_addr{};
size_t m_size{};
std::span<T> m_data_span{};
@ -193,7 +175,17 @@ 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) {}
: 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) {
@ -204,17 +196,15 @@ public:
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());
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());
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());
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());
this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
}
}
}

View file

@ -97,20 +97,20 @@ constexpr RequestLayout GetDomainReplyOutLayout() {
};
}
template <bool Domain, typename MethodArguments>
constexpr RequestLayout GetReplyInLayout() {
return Domain ? GetDomainReplyInLayout<MethodArguments>() : GetNonDomainReplyInLayout<MethodArguments>();
template <typename MethodArguments>
constexpr RequestLayout GetReplyInLayout(bool is_domain) {
return is_domain ? GetDomainReplyInLayout<MethodArguments>() : GetNonDomainReplyInLayout<MethodArguments>();
}
template <bool Domain, typename MethodArguments>
constexpr RequestLayout GetReplyOutLayout() {
return Domain ? GetDomainReplyOutLayout<MethodArguments>() : GetNonDomainReplyOutLayout<MethodArguments>();
template <typename MethodArguments>
constexpr RequestLayout GetReplyOutLayout(bool is_domain) {
return is_domain ? GetDomainReplyOutLayout<MethodArguments>() : GetNonDomainReplyOutLayout<MethodArguments>();
}
using OutTemporaryBuffers = std::array<Common::ScratchBuffer<u8>, 3>;
template <bool Domain, typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t HandleIndex = 0, size_t InBufferIndex = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0>
void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) {
template <typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t HandleIndex = 0, size_t InBufferIndex = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0>
void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) {
if constexpr (ArgIndex >= std::tuple_size_v<CallArguments>) {
return;
} else {
@ -134,25 +134,25 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
std::memcpy(&std::get<ArgIndex>(args), raw_data + ArgOffset, ArgSize);
}
return ReadInArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, false, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, false, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InInterface) {
constexpr size_t ArgAlign = alignof(u32);
constexpr size_t ArgSize = sizeof(u32);
constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
constexpr size_t ArgEnd = ArgOffset + ArgSize;
static_assert(Domain);
ASSERT(is_domain);
ASSERT(ctx.GetDomainMessageHeader().input_object_count > 0);
u32 value{};
std::memcpy(&value, raw_data + ArgOffset, ArgSize);
std::get<ArgIndex>(args) = ctx.GetDomainHandler<ArgType::Type>(value - 1);
return ReadInArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, true, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InCopyHandle) {
std::get<ArgIndex>(args) = std::move(ctx.GetObjectFromHandle<typename ArgType::Type>(ctx.GetCopyHandle(HandleIndex)));
std::get<ArgIndex>(args) = ctx.GetObjectFromHandle<typename ArgType::Type>(ctx.GetCopyHandle(HandleIndex)).GetPointerUnsafe();
return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) {
constexpr size_t BufferSize = sizeof(ArgType);
@ -172,7 +172,7 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
std::memcpy(&std::get<ArgIndex>(args), buffer.data(), std::min(BufferSize, buffer.size()));
return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InBuffer) {
using ElementType = typename ArgType::Type;
@ -193,14 +193,14 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
std::get<ArgIndex>(args) = std::span(ptr, size);
return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
constexpr size_t BufferSize = sizeof(ArgType);
// Clear the existing data.
std::memset(&std::get<ArgIndex>(args), 0, BufferSize);
return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) {
using ElementType = typename ArgType::Type;
@ -217,15 +217,15 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
std::get<ArgIndex>(args) = std::span(ptr, size);
return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else {
return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
}
}
}
template <bool Domain, typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0>
void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) {
template <typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0>
void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) {
if constexpr (ArgIndex >= std::tuple_size_v<CallArguments>) {
return;
} else {
@ -243,23 +243,23 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args), ArgSize);
return WriteOutArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, OutBufferIndex, false, ArgIndex + 1>(args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, OutBufferIndex, false, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutInterface) {
if constexpr (Domain) {
if (is_domain) {
ctx.AddDomainObject(std::get<ArgIndex>(args));
} else {
ctx.AddMoveInterface(std::get<ArgIndex>(args));
}
return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) {
ctx.AddCopyObject(std::get<ArgIndex>(args).GetPointerUnsafe());
ctx.AddCopyObject(std::get<ArgIndex>(args));
return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) {
ctx.AddMoveObject(std::get<ArgIndex>(args).GetPointerUnsafe());
ctx.AddMoveObject(std::get<ArgIndex>(args));
return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
constexpr size_t BufferSize = sizeof(ArgType);
@ -272,7 +272,7 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
ctx.WriteBufferC(&std::get<ArgIndex>(args), BufferSize, OutBufferIndex);
}
return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) {
auto& buffer = temp[OutBufferIndex];
const size_t size = buffer.size();
@ -287,9 +287,9 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
}
}
return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>( args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else {
return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
}
}
}
@ -297,11 +297,10 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
template <bool Domain, typename T, typename... A>
void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
// Verify domain state.
if constexpr (Domain) {
ASSERT_MSG(ctx.GetManager()->IsDomain(), "Domain reply used on non-domain session");
} else {
if constexpr (!Domain) {
ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Non-domain reply used on domain session");
}
const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false;
using MethodArguments = std::tuple<std::remove_reference_t<A>...>;
@ -310,7 +309,7 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
// Read inputs.
const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2;
ReadInArgument<Domain, MethodArguments>(call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + offset_plus_command_id), ctx, buffers);
ReadInArgument<MethodArguments>(is_domain, call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + offset_plus_command_id), ctx, buffers);
// Call.
const auto Callable = [&]<typename... CallArgs>(CallArgs&... args) {
@ -319,12 +318,12 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
const Result res = std::apply(Callable, call_arguments);
// Write result.
constexpr RequestLayout layout = GetReplyOutLayout<Domain, MethodArguments>();
const RequestLayout layout = GetReplyOutLayout<MethodArguments>(is_domain);
IPC::ResponseBuilder rb{ctx, 2 + Common::DivCeil(layout.cmif_raw_data_size, sizeof(u32)), layout.copy_handle_count, layout.move_handle_count + layout.domain_interface_count};
rb.Push(res);
// Write out arguments.
WriteOutArgument<Domain, MethodArguments>(call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + rb.GetCurrentOffset()), ctx, buffers);
WriteOutArgument<MethodArguments>(is_domain, call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + rb.GetCurrentOffset()), ctx, buffers);
}
// clang-format on

View file

@ -15,19 +15,21 @@ namespace Service {
template <typename T>
class Out {
public:
/* implicit */ Out(T& t) : raw(&t) {}
using Type = T;
/* implicit */ Out(Type& t) : raw(&t) {}
~Out() = default;
T* Get() const {
Type* Get() const {
return raw;
}
T& operator*() {
Type& operator*() {
return *raw;
}
private:
T* raw;
Type* raw;
};
template <typename T>
@ -45,51 +47,93 @@ struct ClientProcessId {
u64 pid;
};
struct ProcessId {
explicit operator bool() const {
return pid != 0;
}
const u64& operator*() const {
return pid;
}
u64 pid;
};
using ClientAppletResourceUserId = ClientProcessId;
using AppletResourceUserId = ProcessId;
template <typename T>
class InCopyHandle : public Kernel::KScopedAutoObject<T> {
class InCopyHandle {
public:
using Type = T;
template <typename... Args>
/* implicit */ InCopyHandle(Args&&... args) : Kernel::KScopedAutoObject<T>(std::forward<Args...>(args)...) {}
/* implicit */ InCopyHandle(Type* t) : raw(t) {}
/* implicit */ InCopyHandle() : raw() {}
~InCopyHandle() = default;
InCopyHandle& operator=(InCopyHandle&& rhs) {
Kernel::KScopedAutoObject<T>::operator=(std::move(rhs));
InCopyHandle& operator=(Type* rhs) {
raw = rhs;
return *this;
}
Type* Get() const {
return raw;
}
Type& operator*() const {
return *raw;
}
Type* operator->() const {
return raw;
}
explicit operator bool() const {
return raw != nullptr;
}
private:
Type* raw;
};
template <typename T>
class OutCopyHandle : public Kernel::KScopedAutoObject<T> {
class OutCopyHandle {
public:
using Type = T;
using Type = T*;
template <typename... Args>
/* implicit */ OutCopyHandle(Args&&... args) : Kernel::KScopedAutoObject<T>(std::forward<Args...>(args)...) {}
/* implicit */ OutCopyHandle(Type& t) : raw(&t) {}
~OutCopyHandle() = default;
OutCopyHandle& operator=(OutCopyHandle&& rhs) {
Kernel::KScopedAutoObject<T>::operator=(std::move(rhs));
return *this;
Type* Get() const {
return raw;