Compare commits

..

1 Commits

Author SHA1 Message Date
crueter
8c1cf35080 [cmake] initial support for static Linux builds
A LOT of things are still missing, notably:

- most distros don't package static libs, like at all
- ci target
  * qt6ct :(

Tbh this probably isn't worth it at all for the AppImage, but it's an
option I guess

Signed-off-by: crueter <crueter@eden-emu.dev>
2025-11-23 00:28:36 -05:00
143 changed files with 773 additions and 2713 deletions

View File

@@ -14,7 +14,6 @@ License: GPL-2.0-or-later
Files: dist/qt_themes/default/icons/256x256/eden.png Files: dist/qt_themes/default/icons/256x256/eden.png
dist/qt_themes/default/icons/256x256/eden_named.png dist/qt_themes/default/icons/256x256/eden_named.png
dist/Assets.car
dist/yuzu.bmp dist/yuzu.bmp
dist/eden.icns dist/eden.icns
dist/eden.ico dist/eden.ico

View File

@@ -125,11 +125,16 @@ if (YUZU_STATIC_BUILD)
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
set(BUILD_SHARED_LIBS OFF) set(BUILD_SHARED_LIBS OFF)
## find .a libs first (static, usually) if (NOT PLATFORM_LINUX)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") ## find .a libs first (static, usually)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
## some libraries use CMAKE_IMPORT_LIBRARY_SUFFIX e.g. Harfbuzz ## ## some libraries define a Library::Name_static alternative ##
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a") set(YUZU_STATIC_SUFFIX _static)
## some libraries use CMAKE_IMPORT_LIBRARY_SUFFIX e.g. Harfbuzz ##
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a")
endif()
if (MINGW) if (MINGW)
# simple hook to reject dynamic libs # simple hook to reject dynamic libs
@@ -158,22 +163,29 @@ if (YUZU_STATIC_BUILD)
set(YUZU_USE_BUNDLED_OPENSSL ON) set(YUZU_USE_BUNDLED_OPENSSL ON)
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF) set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
## some libraries define a Library::Name_static alternative ##
set(MBEDTLS_LIB_SUFFIX _static)
elseif(APPLE) elseif(APPLE)
# these libs do not properly provide static libs/let you do it with cmake
set(YUZU_USE_CPM ON) set(YUZU_USE_CPM ON)
set(YUZU_USE_BUNDLED_FFMPEG ON) set(YUZU_USE_BUNDLED_FFMPEG ON)
set(YUZU_USE_BUNDLED_SDL2 ON) set(YUZU_USE_BUNDLED_SDL2 ON)
set(YUZU_USE_BUNDLED_OPENSSL ON) set(YUZU_USE_BUNDLED_OPENSSL ON)
# these libs do not properly provide static libs/let you do it with cmake # IMPORTED_IMPLIB not set for imported target
# TODO(crueter): wtf
set(fmt_FORCE_BUNDLED ON) set(fmt_FORCE_BUNDLED ON)
set(SPIRV-Tools_FORCE_BUNDLED ON) set(SPIRV-Tools_FORCE_BUNDLED ON)
set(SPIRV-Headers_FORCE_BUNDLED ON) set(SPIRV-Headers_FORCE_BUNDLED ON)
set(zstd_FORCE_BUNDLED ON) set(zstd_FORCE_BUNDLED ON)
set(MbedTLS_FORCE_BUNDLED ON) elseif(PLATFORM_LINUX)
# Most distros don't package static libs :(
set(YUZU_USE_CPM ON)
set(CPMUTIL_FORCE_BUNDLED ON)
set(YUZU_USE_BUNDLED_FFMPEG ON)
set(YUZU_USE_BUNDLED_SDL2 ON)
set(YUZU_USE_BUNDLED_OPENSSL ON)
set(YUZU_USE_BUNDLED_SIRIT ON)
endif() endif()
endif() endif()
@@ -801,6 +813,16 @@ if (YUZU_TESTS OR DYNARMIC_TESTS)
find_package(Catch2) find_package(Catch2)
endif() endif()
# Qt expects this target
if (YUZU_STATIC_BUILD AND PLATFORM_LINUX)
get_target_property(RDOC_TARGET RenderDoc::API ALIASED_TARGET)
if (RDOC_TARGET)
add_library(RenderDoc::RenderDoc ALIAS ${RDOC_TARGET})
else()
add_library(RenderDoc::RenderDoc ALIAS RenderDoc::API)
endif()
endif()
if (ENABLE_QT) if (ENABLE_QT)
if (YUZU_USE_BUNDLED_QT) if (YUZU_USE_BUNDLED_QT)
download_qt(6.8.3) download_qt(6.8.3)

View File

@@ -16,13 +16,15 @@ function(static_qt_link target)
# NB: yes, we have to put them here twice. I have no idea why # NB: yes, we have to put them here twice. I have no idea why
# libtiff.a # libtiff.a
extra_libs(tiff jbig bz2 lzma deflate jpeg tiff) if (MINGW)
extra_libs(tiff jbig bz2 lzma deflate jpeg tiff)
# libfreetype.a # libfreetype.a
extra_libs(freetype bz2 Lerc brotlidec brotlicommon freetype) extra_libs(freetype bz2 Lerc brotlidec brotlicommon freetype)
# libharfbuzz.a # libharfbuzz.a
extra_libs(harfbuzz graphite2) extra_libs(harfbuzz graphite2)
endif()
# sijfjkfnjkdfjsbjsbsdfhvbdf # sijfjkfnjkdfjsbjsbsdfhvbdf
if (ENABLE_OPENSSL) if (ENABLE_OPENSSL)

BIN
dist/Assets.car vendored

Binary file not shown.

View File

@@ -43,12 +43,6 @@ Various graphical filters exist - each of them aimed at a specific target/image
- **Pros**: Offers decent pixel-art upscaling. - **Pros**: Offers decent pixel-art upscaling.
- **Cons**: Only works for pixel-art. - **Cons**: Only works for pixel-art.
### Anisotropy values
The anisotropy value is (value game wants + the set value); **Default** will use the native anisotropy value as it would be on hardware. **Automatic** sets it according to screen resolution. Turning off anisotropy is not recommended as it can break a myriad of games, however it is provided in the name of flexibility.
Values from x2, x4, x8, x16, x32 up to x64 values are provided. This should be enough to not need to revise those values in my lifetime ever again.
### External ### External
While stock shaders offer a basic subset of options for most users, programs such as [ReShade](https://github.com/crosire/reshade) offer a more flexible experience. In addition to that users can also seek out modifications (mods) for enhancing visual experience (60 FPS mods, HDR, etc). While stock shaders offer a basic subset of options for most users, programs such as [ReShade](https://github.com/crosire/reshade) offer a more flexible experience. In addition to that users can also seek out modifications (mods) for enhancing visual experience (60 FPS mods, HDR, etc).

View File

@@ -1,12 +0,0 @@
# User Handbook - Native Application Development
Debugging on physical hardware can get tedious and time consuming. Users are empowered with the debugging capabilities of the emulator to ensure their applications run as-is on the system. To the greatest extent possible atleast.
## Debugging
**Standard key prefix**: Allows to redirect the key manager to a file other than `prod.keys` (for example `other` would redirect to `other.keys`). This is useful for testing multiple keysets. Default is `prod`.
**Changing serial**: Very basic way to set debug values for the serial (and battery number). Developers do not need to write the full serial as it will be writen in-place (that is, it will be filled with the default serial and then overwrite the serial from the beginning).
- Battery serial: `YUZU0EMULATOR14022024`
- Board serial: `YUZ10000000001`
If the user were to set their board serial as `ABC`, then it will be written in-place and the resulting serial would be `ABC10000000001`. There are no underlying checks to ensure correctness of serials other than a hard limit of 16-characters for both.

View File

@@ -11,4 +11,3 @@ This handbook is primarily aimed at the end-user - baking useful knowledge for e
- **[Testing](Testing.md)** - **[Testing](Testing.md)**
- **[Data, savefiles and storage](Storage.md)** - **[Data, savefiles and storage](Storage.md)**
- **[Orphaned Profiles](Orphaned.md)** - **[Orphaned Profiles](Orphaned.md)**
- **[Native Application Development](Native.md)**

View File

@@ -174,7 +174,7 @@ else()
add_compile_definitions(QT_STATICPLUGIN) add_compile_definitions(QT_STATICPLUGIN)
# macos doesn't even let you make static executables... wtf? # macos doesn't even let you make static executables... wtf?
if (NOT APPLE) if (NOT APPLE AND NOT PLATFORM_LINUX)
add_compile_options(-static) add_compile_options(-static)
if (YUZU_STATIC_BUILD) if (YUZU_STATIC_BUILD)
# yuzu-cmd requires us to explicitly link libpthread, libgcc, and libstdc++ as static # yuzu-cmd requires us to explicitly link libpthread, libgcc, and libstdc++ as static

View File

@@ -72,8 +72,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
DEBUG_FLUSH_BY_LINE("flush_line"), DEBUG_FLUSH_BY_LINE("flush_line"),
USE_LRU_CACHE("use_lru_cache"), USE_LRU_CACHE("use_lru_cache"),
DONT_SHOW_DRIVER_SHADER_WARNING("dont_show_driver_shader_warning"), DONT_SHOW_DRIVER_SHADER_WARNING("dont_show_driver_shader_warning");
ENABLE_OVERLAY("enable_overlay");
// external fun isFrameSkippingEnabled(): Boolean // external fun isFrameSkippingEnabled(): Boolean

View File

@@ -61,8 +61,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
LOGIN_SHARE_APPLET("login_share_applet_mode"), LOGIN_SHARE_APPLET("login_share_applet_mode"),
WIFI_WEB_AUTH_APPLET("wifi_web_auth_applet_mode"), WIFI_WEB_AUTH_APPLET("wifi_web_auth_applet_mode"),
MY_PAGE_APPLET("my_page_applet_mode"), MY_PAGE_APPLET("my_page_applet_mode"),
INPUT_OVERLAY_AUTO_HIDE("input_overlay_auto_hide"), INPUT_OVERLAY_AUTO_HIDE("input_overlay_auto_hide")
DEBUG_KNOBS("debug_knobs")
; ;
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)

View File

@@ -788,16 +788,6 @@ abstract class SettingsItem(
descriptionId = R.string.use_auto_stub_description descriptionId = R.string.use_auto_stub_description
) )
) )
put(
SpinBoxSetting(
IntSetting.DEBUG_KNOBS,
titleId = R.string.debug_knobs,
descriptionId = R.string.debug_knobs_description,
valueHint = R.string.debug_knobs_hint,
min = 0,
max = 65535
)
)
val fastmem = object : AbstractBooleanSetting { val fastmem = object : AbstractBooleanSetting {
override fun getBoolean(needsGlobal: Boolean): Boolean = override fun getBoolean(needsGlobal: Boolean): Boolean =
@@ -849,14 +839,7 @@ abstract class SettingsItem(
descriptionId = R.string.airplane_mode_description descriptionId = R.string.airplane_mode_description
) )
) )
put(
SwitchSetting(
BooleanSetting.ENABLE_OVERLAY,
titleId = R.string.enable_overlay,
descriptionId = R.string.enable_overlay_description
)
)
} }
} }
} }

View File

@@ -186,12 +186,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
updateButtonState(isValid) updateButtonState(isValid)
} }
/*
* xbzk: these two events, along with attachRepeat feature,
* were causing spinbox buttons to respond twice per press
* cutting these out to retain accelerated press functionality
* TODO: clean this out later if no issues arise
*
spinboxBinding.buttonDecrement.setOnClickListener { spinboxBinding.buttonDecrement.setOnClickListener {
val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue
val newValue = current - 1 val newValue = current - 1
@@ -205,7 +199,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
spinboxBinding.editValue.setText(newValue.toString()) spinboxBinding.editValue.setText(newValue.toString())
updateValidity(newValue) updateValidity(newValue)
} }
*/
fun attachRepeat(button: View, delta: Int) { fun attachRepeat(button: View, delta: Int) {
val handler = Handler(Looper.getMainLooper()) val handler = Handler(Looper.getMainLooper())

View File

@@ -491,7 +491,6 @@ class SettingsFragmentPresenter(
sl.apply { sl.apply {
add(IntSetting.SWKBD_APPLET.key) add(IntSetting.SWKBD_APPLET.key)
add(BooleanSetting.AIRPLANE_MODE.key) add(BooleanSetting.AIRPLANE_MODE.key)
add(BooleanSetting.ENABLE_OVERLAY.key)
} }
} }
private fun addInputPlayer(sl: ArrayList<SettingsItem>, playerIndex: Int) { private fun addInputPlayer(sl: ArrayList<SettingsItem>, playerIndex: Int) {
@@ -1168,10 +1167,9 @@ class SettingsFragmentPresenter(
add(IntSetting.CPU_ACCURACY.key) add(IntSetting.CPU_ACCURACY.key)
add(BooleanSetting.USE_AUTO_STUB.key) add(BooleanSetting.USE_AUTO_STUB.key)
add(SettingsItem.FASTMEM_COMBINED) add(SettingsItem.FASTMEM_COMBINED)
add(HeaderSetting(R.string.log)) add(HeaderSetting(R.string.log))
add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key) add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key)
add(HeaderSetting(R.string.general))
add(IntSetting.DEBUG_KNOBS.key)
} }
} }
} }

View File

@@ -1016,13 +1016,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">خلفيات سوداء</string> <string name="use_black_backgrounds">خلفيات سوداء</string>

View File

@@ -727,13 +727,10 @@
<string name="theme_mode_dark">تاریک</string> <string name="theme_mode_dark">تاریک</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">پاشبنەمای ڕەش</string> <string name="use_black_backgrounds">پاشبنەمای ڕەش</string>

View File

@@ -693,13 +693,10 @@
<string name="theme_mode_dark">Tmavé</string> <string name="theme_mode_dark">Tmavé</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Černá pozadí</string> <string name="use_black_backgrounds">Černá pozadí</string>

View File

@@ -912,13 +912,10 @@ Wirklich fortfahren?</string>
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Schwarze Hintergründe</string> <string name="use_black_backgrounds">Schwarze Hintergründe</string>

View File

@@ -975,13 +975,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">x2</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">x4</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">x8</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">x16</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Fondos oscuros</string> <string name="use_black_backgrounds">Fondos oscuros</string>

View File

@@ -861,13 +861,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">پس‌زمینه مشکی</string> <string name="use_black_backgrounds">پس‌زمینه مشکی</string>

View File

@@ -988,13 +988,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Arrière-plan noir</string> <string name="use_black_backgrounds">Arrière-plan noir</string>

View File

@@ -776,13 +776,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">רקעים שחורים</string> <string name="use_black_backgrounds">רקעים שחורים</string>

View File

@@ -875,13 +875,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Fekete háttér</string> <string name="use_black_backgrounds">Fekete háttér</string>

View File

@@ -929,13 +929,10 @@
<string name="cubeb">Cubeb</string> <string name="cubeb">Cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Gunakan Latar Belakang Hitam</string> <string name="use_black_backgrounds">Gunakan Latar Belakang Hitam</string>

View File

@@ -988,13 +988,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Sfondi neri</string> <string name="use_black_backgrounds">Sfondi neri</string>

View File

@@ -778,13 +778,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">完全な黒を使用</string> <string name="use_black_backgrounds">完全な黒を使用</string>

View File

@@ -837,13 +837,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">검정 배경</string> <string name="use_black_backgrounds">검정 배경</string>

View File

@@ -740,13 +740,10 @@
<string name="theme_mode_dark">Mørk</string> <string name="theme_mode_dark">Mørk</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Svart bakgrunn</string> <string name="use_black_backgrounds">Svart bakgrunn</string>

View File

@@ -1012,13 +1012,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Czarne tła</string> <string name="use_black_backgrounds">Czarne tła</string>

View File

@@ -976,13 +976,10 @@ uma tentativa de mapeamento automático</string>
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Planos de fundo pretos</string> <string name="use_black_backgrounds">Planos de fundo pretos</string>

View File

@@ -890,13 +890,10 @@ uma tentativa de mapeamento automático</string>
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Plano de fundo preto</string> <string name="use_black_backgrounds">Plano de fundo preto</string>

View File

@@ -1010,13 +1010,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Чёрный фон</string> <string name="use_black_backgrounds">Чёрный фон</string>

View File

@@ -888,13 +888,10 @@
<string name="cubeb">Цубеб</string> <string name="cubeb">Цубеб</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2к</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4к</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8к</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16к</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Црна позадина</string> <string name="use_black_backgrounds">Црна позадина</string>

View File

@@ -1012,13 +1012,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Чорний фон</string> <string name="use_black_backgrounds">Чорний фон</string>

View File

@@ -740,13 +740,10 @@
<string name="theme_mode_dark">Tối</string> <string name="theme_mode_dark">Tối</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Nền tối</string> <string name="use_black_backgrounds">Nền tối</string>

View File

@@ -984,13 +984,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">使用黑色背景</string> <string name="use_black_backgrounds">使用黑色背景</string>

View File

@@ -984,13 +984,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">黑色背景</string> <string name="use_black_backgrounds">黑色背景</string>

View File

@@ -487,13 +487,10 @@
<string-array name="anisoEntries"> <string-array name="anisoEntries">
<item>@string/auto</item> <item>@string/auto</item>
<item>@string/slider_default</item> <item>@string/slider_default</item>
<item>@string/multiplier_x2</item> <item>@string/multiplier_two</item>
<item>@string/multiplier_x4</item> <item>@string/multiplier_four</item>
<item>@string/multiplier_x8</item> <item>@string/multiplier_eight</item>
<item>@string/multiplier_x16</item> <item>@string/multiplier_sixteen</item>
<item>@string/multiplier_x32</item>
<item>@string/multiplier_x64</item>
<item>@string/multiplier_none</item>
</string-array> </string-array>
<integer-array name="anisoValues"> <integer-array name="anisoValues">
<item>0</item> <item>0</item>

View File

@@ -135,9 +135,6 @@
<string name="memory_layout_description">(EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend.</string> <string name="memory_layout_description">(EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend.</string>
<string name="dma_accuracy">DMA Accuracy</string> <string name="dma_accuracy">DMA Accuracy</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string> <string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
<string name="debug_knobs">Debug knobs</string>
<string name="debug_knobs_description">For development use only.</string>
<string name="debug_knobs_hint">0 to 65535</string>
<!-- Shader Backend --> <!-- Shader Backend -->
<string name="shader_backend">Shader Backend</string> <string name="shader_backend">Shader Backend</string>
@@ -537,8 +534,6 @@
<string name="flush_by_line">Flush debug logs by line</string> <string name="flush_by_line">Flush debug logs by line</string>
<string name="flush_by_line_description">Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing.</string> <string name="flush_by_line_description">Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing.</string>
<string name="general">General</string>
<!-- Audio settings strings --> <!-- Audio settings strings -->
<string name="audio_output_engine">Output engine</string> <string name="audio_output_engine">Output engine</string>
<string name="audio_volume">Volume</string> <string name="audio_volume">Volume</string>
@@ -1055,13 +1050,10 @@
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options --> <!-- Anisotropic filtering options -->
<string name="multiplier_x2">x2</string> <string name="multiplier_two">2x</string>
<string name="multiplier_x4">x4</string> <string name="multiplier_four">4x</string>
<string name="multiplier_x8">x8</string> <string name="multiplier_eight">8x</string>
<string name="multiplier_x16">x16</string> <string name="multiplier_sixteen">16x</string>
<string name="multiplier_x32">x32</string>
<string name="multiplier_x64">x64</string>
<string name="multiplier_none">None</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Black backgrounds</string> <string name="use_black_backgrounds">Black backgrounds</string>
@@ -1125,7 +1117,7 @@
<!-- Applet Modes --> <!-- Applet Modes -->
<string name="applets_menu">Applets</string> <string name="applets_menu">Applets</string>
<string name="applets_menu_description">Change applet frontends and settings</string> <string name="applets_menu_description">(WIP) Change applet frontends and settings</string>
<string name="applet_hle">Custom Frontend</string> <string name="applet_hle">Custom Frontend</string>
<string name="applet_lle">Real Applet</string> <string name="applet_lle">Real Applet</string>
@@ -1135,9 +1127,6 @@
<string name="airplane_mode">Airplane Mode</string> <string name="airplane_mode">Airplane Mode</string>
<string name="airplane_mode_description">Passes Airplane Mode to the Switch OS</string> <string name="airplane_mode_description">Passes Airplane Mode to the Switch OS</string>
<string name="enable_overlay">Enable Overlay Applet</string>
<string name="enable_overlay_description">Enables Horizon\'s built-in overlay applet. Press and hold the home button for 1 second to show it.</string>
<!-- Licenses screen strings --> <!-- Licenses screen strings -->
<string name="licenses">Licenses</string> <string name="licenses">Licenses</string>
<string name="license_fidelityfx_fsr" translatable="false">FidelityFX-FSR</string> <string name="license_fidelityfx_fsr" translatable="false">FidelityFX-FSR</string>

View File

@@ -141,10 +141,6 @@ void LogSettings() {
log_path("DataStorage_SDMCDir", Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir)); log_path("DataStorage_SDMCDir", Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir));
} }
bool getDebugKnobAt(u8 i) {
return (values.debug_knobs.GetValue() & (1 << (i & 0xF))) != 0;
}
void UpdateGPUAccuracy() { void UpdateGPUAccuracy() {
values.current_gpu_accuracy = values.gpu_accuracy.GetValue(); values.current_gpu_accuracy = values.gpu_accuracy.GetValue();
} }

View File

@@ -739,22 +739,11 @@ struct Values {
Setting<bool> perform_vulkan_check{linkage, true, "perform_vulkan_check", Category::Debugging}; Setting<bool> perform_vulkan_check{linkage, true, "perform_vulkan_check", Category::Debugging};
Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Debugging}; Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Debugging};
SwitchableSetting<u16, true> debug_knobs{linkage,
0,
0,
65535,
"debug_knobs",
Category::Debugging,
Specialization::Countable,
true,
true};
// Miscellaneous // Miscellaneous
Setting<std::string> serial_battery{linkage, std::string(), "serial_battery", Category::Miscellaneous};
Setting<std::string> serial_unit{linkage, std::string(), "serial_unit", Category::Miscellaneous};
Setting<std::string> log_filter{linkage, "*:Info", "log_filter", Category::Miscellaneous}; Setting<std::string> log_filter{linkage, "*:Info", "log_filter", Category::Miscellaneous};
Setting<bool> log_flush_line{linkage, false, "flush_line", Category::Miscellaneous, Specialization::Default, true, true}; Setting<bool> log_flush_line{linkage, false, "flush_line", Category::Miscellaneous, Specialization::Default, true, true};
Setting<bool> censor_username{linkage, true, "censor_username", Category::Miscellaneous}; Setting<bool> censor_username{linkage, true, "censor_username", Category::Miscellaneous};
Setting<bool> use_dev_keys{linkage, false, "use_dev_keys", Category::Miscellaneous};
Setting<bool> first_launch{linkage, true, "first_launch", Category::Miscellaneous}; Setting<bool> first_launch{linkage, true, "first_launch", Category::Miscellaneous};
// Network // Network
@@ -774,14 +763,10 @@ struct Values {
// Per-game overrides // Per-game overrides
bool use_squashed_iterated_blend; bool use_squashed_iterated_blend;
Setting<bool> enable_overlay{linkage, true, "enable_overlay", Category::Core};
}; };
extern Values values; extern Values values;
bool getDebugKnobAt(u8 i);
void UpdateGPUAccuracy(); void UpdateGPUAccuracy();
bool IsGPULevelExtreme(); bool IsGPULevelExtreme();
bool IsGPULevelHigh(); bool IsGPULevelHigh();

View File

@@ -126,7 +126,7 @@ ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt
GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica, GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,
Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt, Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt,
Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu); Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu);
ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16, X32, X64, None); ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16);
ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous); ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous);
ENUM(AstcRecompression, Uncompressed, Bc1, Bc3); ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed); ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed);

View File

@@ -129,7 +129,7 @@ protected:
} else if constexpr (std::is_floating_point_v<Type>) { } else if constexpr (std::is_floating_point_v<Type>) {
return fmt::format("{:f}", value_); return fmt::format("{:f}", value_);
} else if constexpr (std::is_enum_v<Type>) { } else if constexpr (std::is_enum_v<Type>) {
return std::to_string(u32(value_)); return std::to_string(static_cast<u32>(value_));
} else { } else {
return std::to_string(value_); return std::to_string(value_);
} }
@@ -192,13 +192,15 @@ public:
if constexpr (std::is_same_v<Type, std::string>) { if constexpr (std::is_same_v<Type, std::string>) {
this->SetValue(input); this->SetValue(input);
} else if constexpr (std::is_same_v<Type, std::optional<u32>>) { } else if constexpr (std::is_same_v<Type, std::optional<u32>>) {
this->SetValue(u32(std::stoul(input))); this->SetValue(static_cast<u32>(std::stoul(input)));
} else if constexpr (std::is_same_v<Type, bool>) { } else if constexpr (std::is_same_v<Type, bool>) {
this->SetValue(input == "true"); this->SetValue(input == "true");
} else if constexpr (std::is_same_v<Type, float>) { } else if constexpr (std::is_same_v<Type, float>) {
this->SetValue(std::stof(input)); this->SetValue(std::stof(input));
} else if constexpr (std::is_same_v<Type, AudioEngine>) {
this->SetValue(ToEnum<AudioEngine>(input));
} else { } else {
this->SetValue(Type(std::stoll(input))); this->SetValue(static_cast<Type>(std::stoll(input)));
} }
} catch (std::invalid_argument&) { } catch (std::invalid_argument&) {
this->SetValue(this->GetDefault()); this->SetValue(this->GetDefault());

View File

@@ -487,10 +487,6 @@ add_library(core STATIC
hle/service/am/service/library_applet_self_accessor.h hle/service/am/service/library_applet_self_accessor.h
hle/service/am/service/lock_accessor.cpp hle/service/am/service/lock_accessor.cpp
hle/service/am/service/lock_accessor.h hle/service/am/service/lock_accessor.h
hle/service/am/service/overlay_functions.cpp
hle/service/am/service/overlay_functions.h
hle/service/am/service/overlay_applet_proxy.cpp
hle/service/am/service/overlay_applet_proxy.h
hle/service/am/service/process_winding_controller.cpp hle/service/am/service/process_winding_controller.cpp
hle/service/am/service/process_winding_controller.h hle/service/am/service/process_winding_controller.h
hle/service/am/service/self_controller.cpp hle/service/am/service/self_controller.cpp
@@ -1203,7 +1199,7 @@ else()
target_link_libraries(core PUBLIC Boost::headers) target_link_libraries(core PUBLIC Boost::headers)
endif() endif()
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto${MBEDTLS_LIB_SUFFIX} MbedTLS::mbedtls${MBEDTLS_LIB_SUFFIX}) target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto${YUZU_STATIC_SUFFIX} MbedTLS::mbedtls${YUZU_STATIC_SUFFIX})
# if (MINGW) # if (MINGW)
# target_link_libraries(core PRIVATE ws2_32 mswsock wlanapi) # target_link_libraries(core PRIVATE ws2_32 mswsock wlanapi)
# endif() # endif()

View File

@@ -580,21 +580,6 @@ struct System::Impl {
gpu_dirty_memory_managers; gpu_dirty_memory_managers;
std::deque<std::vector<u8>> user_channel; std::deque<std::vector<u8>> user_channel;
std::mutex general_channel_mutex;
std::deque<std::vector<u8>> general_channel;
std::unique_ptr<Service::KernelHelpers::ServiceContext> general_channel_context; // lazy
std::unique_ptr<Service::Event> general_channel_event; // lazy
bool general_channel_initialized{false};
void EnsureGeneralChannelInitialized(System& system) {
if (general_channel_initialized) {
return;
}
general_channel_context = std::make_unique<Service::KernelHelpers::ServiceContext>(system, "GeneralChannel");
general_channel_event = std::make_unique<Service::Event>(*general_channel_context);
general_channel_initialized = true;
}
}; };
System::System() : impl{std::make_unique<Impl>(*this)} {} System::System() : impl{std::make_unique<Impl>(*this)} {}
@@ -1008,39 +993,6 @@ std::deque<std::vector<u8>>& System::GetUserChannel() {
return impl->user_channel; return impl->user_channel;
} }
std::deque<std::vector<u8>>& System::GetGeneralChannel() {
return impl->general_channel;
}
void System::PushGeneralChannelData(std::vector<u8>&& data) {
std::scoped_lock lk{impl->general_channel_mutex};
impl->EnsureGeneralChannelInitialized(*this);
const bool was_empty = impl->general_channel.empty();
impl->general_channel.push_back(std::move(data));
if (was_empty) {
impl->general_channel_event->Signal();
}
}
bool System::TryPopGeneralChannel(std::vector<u8>& out_data) {
std::scoped_lock lk{impl->general_channel_mutex};
if (!impl->general_channel_initialized || impl->general_channel.empty()) {
return false;
}
out_data = std::move(impl->general_channel.back());
impl->general_channel.pop_back();
if (impl->general_channel.empty()) {
impl->general_channel_event->Clear();
}
return true;
}
Service::Event& System::GetGeneralChannelEvent() {
std::scoped_lock lk{impl->general_channel_mutex};
impl->EnsureGeneralChannelInitialized(*this);
return *impl->general_channel_event;
}
void System::RegisterExitCallback(ExitCallback&& callback) { void System::RegisterExitCallback(ExitCallback&& callback) {
impl->exit_callback = std::move(callback); impl->exit_callback = std::move(callback);
} }

View File

@@ -17,8 +17,6 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/file_sys/vfs/vfs_types.h" #include "core/file_sys/vfs/vfs_types.h"
#include "core/hle/service/os/event.h"
#include "core/hle/service/kernel_helpers.h"
namespace Core::Frontend { namespace Core::Frontend {
class EmuWindow; class EmuWindow;
@@ -430,11 +428,6 @@ public:
*/ */
[[nodiscard]] std::deque<std::vector<u8>>& GetUserChannel(); [[nodiscard]] std::deque<std::vector<u8>>& GetUserChannel();
[[nodiscard]] std::deque<std::vector<u8>>& GetGeneralChannel();
void PushGeneralChannelData(std::vector<u8>&& data);
bool TryPopGeneralChannel(std::vector<u8>& out_data);
[[nodiscard]] Service::Event& GetGeneralChannelEvent();
/// Type used for the frontend to designate a callback for System to exit the application. /// Type used for the frontend to designate a callback for System to exit the application.
using ExitCallback = std::function<void()>; using ExitCallback = std::function<void()>;

View File

@@ -640,20 +640,32 @@ KeyManager::KeyManager() {
void KeyManager::ReloadKeys() { void KeyManager::ReloadKeys() {
// Initialize keys // Initialize keys
const auto keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir);
if (!Common::FS::CreateDir(keys_dir))
if (!Common::FS::CreateDir(yuzu_keys_dir)) {
LOG_ERROR(Core, "Failed to create the keys directory."); LOG_ERROR(Core, "Failed to create the keys directory.");
LoadFromFile(keys_dir / "prod.keys_autogenerated", false); }
LoadFromFile(keys_dir / "prod.keys", false);
LoadFromFile(keys_dir / "title.keys_autogenerated", true); if (Settings::values.use_dev_keys) {
LoadFromFile(keys_dir / "title.keys", true); dev_mode = true;
LoadFromFile(keys_dir / "console.keys_autogenerated", false); LoadFromFile(yuzu_keys_dir / "dev.keys_autogenerated", false);
LoadFromFile(keys_dir / "console.keys", false); LoadFromFile(yuzu_keys_dir / "dev.keys", false);
} else {
dev_mode = false;
LoadFromFile(yuzu_keys_dir / "prod.keys_autogenerated", false);
LoadFromFile(yuzu_keys_dir / "prod.keys", false);
}
LoadFromFile(yuzu_keys_dir / "title.keys_autogenerated", true);
LoadFromFile(yuzu_keys_dir / "title.keys", true);
LoadFromFile(yuzu_keys_dir / "console.keys_autogenerated", false);
LoadFromFile(yuzu_keys_dir / "console.keys", false);
} }
static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_t length) { static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_t length) {
if (base.size() < begin + length) if (base.size() < begin + length) {
return false; return false;
}
return std::all_of(base.begin() + begin, base.begin() + begin + length, return std::all_of(base.begin() + begin, base.begin() + begin + length,
[](u8 c) { return std::isxdigit(c); }); [](u8 c) { return std::isxdigit(c); });
} }
@@ -838,8 +850,9 @@ void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname,
const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir);
std::string filename = "title.keys_autogenerated"; std::string filename = "title.keys_autogenerated";
if (category == KeyCategory::Standard) { if (category == KeyCategory::Standard) {
filename = "prod.keys_autogenerated"; filename = dev_mode ? "dev.keys_autogenerated" : "prod.keys_autogenerated";
} else if (category == KeyCategory::Console) { } else if (category == KeyCategory::Console) {
filename = "console.keys_autogenerated"; filename = "console.keys_autogenerated";
} }
@@ -934,10 +947,17 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) {
} }
bool KeyManager::KeyFileExists(bool title) { bool KeyManager::KeyFileExists(bool title) {
const auto keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); const auto yuzu_keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir);
if (title)
return Common::FS::Exists(keys_dir / "title.keys"); if (title) {
return Common::FS::Exists(keys_dir / "prod.keys"); return Common::FS::Exists(yuzu_keys_dir / "title.keys");
}
if (Settings::values.use_dev_keys) {
return Common::FS::Exists(yuzu_keys_dir / "dev.keys");
}
return Common::FS::Exists(yuzu_keys_dir / "prod.keys");
} }
void KeyManager::DeriveSDSeedLazy() { void KeyManager::DeriveSDSeedLazy() {

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -314,6 +311,7 @@ private:
std::array<u8, 576> eticket_extended_kek{}; std::array<u8, 576> eticket_extended_kek{};
RSAKeyPair<2048> eticket_rsa_keypair{}; RSAKeyPair<2048> eticket_rsa_keypair{};
bool dev_mode;
void LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys); void LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys);
template <size_t Size> template <size_t Size>

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,7 +5,6 @@
#include <array> #include <array>
#include <string> #include <string>
#include <vector>
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/swap.h" #include "common/swap.h"

View File

@@ -95,7 +95,7 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
case SaveDataSpaceId::System: case SaveDataSpaceId::System:
return "/system/"; return "/system/";
case SaveDataSpaceId::User: case SaveDataSpaceId::User:
case SaveDataSpaceId::SdUser: case SaveDataSpaceId::SdUser:
return "/user/"; return "/user/";
case SaveDataSpaceId::Temporary: case SaveDataSpaceId::Temporary:
return "/temp/"; return "/temp/";

View File

@@ -16,7 +16,7 @@ namespace HLE::ApiVersion {
constexpr u8 HOS_VERSION_MAJOR = 21; constexpr u8 HOS_VERSION_MAJOR = 21;
constexpr u8 HOS_VERSION_MINOR = 0; constexpr u8 HOS_VERSION_MINOR = 0;
constexpr u8 HOS_VERSION_MICRO = 1; constexpr u8 HOS_VERSION_MICRO = 0;
// NintendoSDK version constants. // NintendoSDK version constants.
@@ -24,9 +24,9 @@ constexpr u8 SDK_REVISION_MAJOR = 1;
constexpr u8 SDK_REVISION_MINOR = 0; constexpr u8 SDK_REVISION_MINOR = 0;
constexpr char PLATFORM_STRING[] = "NX"; constexpr char PLATFORM_STRING[] = "NX";
constexpr char VERSION_HASH[] = "066a75e6fab7316de34b88b60d229a0b2729e421"; constexpr char VERSION_HASH[] = "f6b2425b6888a66590db104fc734891696e0ecb3";
constexpr char DISPLAY_VERSION[] = "21.0.1"; constexpr char DISPLAY_VERSION[] = "21.0.0";
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 21.0.1-1.0"; constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 21.0.0-1.0";
// Atmosphere version constants. // Atmosphere version constants.

View File

@@ -215,7 +215,7 @@ public:
{220, nullptr, "SynchronizeProfileAsync"}, {220, nullptr, "SynchronizeProfileAsync"},
{221, nullptr, "UploadProfileAsync"}, {221, nullptr, "UploadProfileAsync"},
{222, nullptr, "SynchronizaProfileAsyncIfSecondsElapsed"}, {222, nullptr, "SynchronizaProfileAsyncIfSecondsElapsed"},
{250, &IAdministrator::IsLinkedWithNintendoAccount, "IsLinkedWithNintendoAccount"}, {250, nullptr, "IsLinkedWithNintendoAccount"},
{251, nullptr, "CreateProcedureToLinkWithNintendoAccount"}, {251, nullptr, "CreateProcedureToLinkWithNintendoAccount"},
{252, nullptr, "ResumeProcedureToLinkWithNintendoAccount"}, {252, nullptr, "ResumeProcedureToLinkWithNintendoAccount"},
{255, nullptr, "CreateProcedureToUpdateLinkageStateOfNintendoAccount"}, {255, nullptr, "CreateProcedureToUpdateLinkageStateOfNintendoAccount"},
@@ -236,13 +236,6 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
} }
private:
void IsLinkedWithNintendoAccount(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(false);
}
}; };
class IAuthorizationRequest final : public ServiceFramework<IAuthorizationRequest> { class IAuthorizationRequest final : public ServiceFramework<IAuthorizationRequest> {
@@ -503,35 +496,6 @@ protected:
rb.Push(static_cast<u32>(buffer.size())); rb.Push(static_cast<u32>(buffer.size()));
} }
void LoadIdTokenCache(HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
std::vector<u8> token_data(0x100);
std::fill(token_data.begin(), token_data.end(), u8(0));
(void)ctx.WriteBuffer(token_data);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(token_data.size()));
}
void GetNintendoAccountUserResourceCacheForApplication(HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
std::vector<u8> nas_user_base_for_application(0x68);
(void)ctx.WriteBuffer(nas_user_base_for_application);
if (ctx.CanWriteBuffer(1)) {
std::vector<u8> unknown_out_buffer(ctx.GetWriteBufferSize(1));
(void)ctx.WriteBuffer(unknown_out_buffer, 1);
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushRaw<u64>(profile_manager.GetLastOpenedUser().Hash());
}
void Store(HLERequestContext& ctx) { void Store(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto base = rp.PopRaw<ProfileBase>(); const auto base = rp.PopRaw<ProfileBase>();
@@ -743,7 +707,7 @@ private:
std::vector<u8> token_data(0x100); std::vector<u8> token_data(0x100);
std::fill(token_data.begin(), token_data.end(), u8(0)); std::fill(token_data.begin(), token_data.end(), u8(0));
ctx.WriteBuffer(token_data); ctx.WriteBuffer(token_data, 0);
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
@@ -754,7 +718,7 @@ private:
LOG_WARNING(Service_ACC, "(STUBBED) called"); LOG_WARNING(Service_ACC, "(STUBBED) called");
std::vector<u8> nas_user_base_for_application(0x68); std::vector<u8> nas_user_base_for_application(0x68);
ctx.WriteBuffer(nas_user_base_for_application); ctx.WriteBuffer(nas_user_base_for_application, 0);
if (ctx.CanWriteBuffer(1)) { if (ctx.CanWriteBuffer(1)) {
std::vector<u8> unknown_out_buffer(ctx.GetWriteBufferSize(1)); std::vector<u8> unknown_out_buffer(ctx.GetWriteBufferSize(1));
@@ -970,7 +934,6 @@ Result Module::Interface::InitializeApplicationInfoBase() {
application_info.application_type = ApplicationType::GameCard; application_info.application_type = ApplicationType::GameCard;
break; break;
case FileSys::StorageId::Host: case FileSys::StorageId::Host:
case FileSys::StorageId::NandSystem:
case FileSys::StorageId::NandUser: case FileSys::StorageId::NandUser:
case FileSys::StorageId::SdCard: case FileSys::StorageId::SdCard:
case FileSys::StorageId::None: // Yuzu specific, differs from hardware case FileSys::StorageId::None: // Yuzu specific, differs from hardware
@@ -1091,17 +1054,6 @@ void Module::Interface::GetProfileEditor(HLERequestContext& ctx) {
rb.PushIpcInterface<IProfileEditor>(system, user_id, *profile_manager); rb.PushIpcInterface<IProfileEditor>(system, user_id, *profile_manager);
} }
void Module::Interface::GetBaasAccountAdministrator(HLERequestContext &ctx) {
IPC::RequestParser rp{ctx};
const auto uuid = rp.PopRaw<Common::UUID>();
LOG_INFO(Service_ACC, "called, uuid=0x{}", uuid.RawString());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IAdministrator>(system, uuid);
}
void Module::Interface::ListQualifiedUsers(HLERequestContext& ctx) { void Module::Interface::ListQualifiedUsers(HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called"); LOG_DEBUG(Service_ACC, "called");

View File

@@ -42,7 +42,6 @@ public:
void DeleteUser(HLERequestContext& ctx); void DeleteUser(HLERequestContext& ctx);
void SetUserPosition(HLERequestContext& ctx); void SetUserPosition(HLERequestContext& ctx);
void GetProfileEditor(HLERequestContext& ctx); void GetProfileEditor(HLERequestContext& ctx);
void GetBaasAccountAdministrator(HLERequestContext &ctx);
void ListQualifiedUsers(HLERequestContext& ctx); void ListQualifiedUsers(HLERequestContext& ctx);
void ListOpenContextStoredUsers(HLERequestContext& ctx); void ListOpenContextStoredUsers(HLERequestContext& ctx);
void StoreSaveDataThumbnailApplication(HLERequestContext& ctx); void StoreSaveDataThumbnailApplication(HLERequestContext& ctx);

View File

@@ -55,7 +55,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
{230, nullptr, "AuthenticateServiceAsync"}, {230, nullptr, "AuthenticateServiceAsync"},
{250, &ACC_SU::GetBaasAccountAdministrator, "GetBaasAccountAdministrator"}, {250, nullptr, "GetBaasAccountAdministrator"},
{290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"}, {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
{299, nullptr, "SuspendBackgroundDaemon"}, {299, nullptr, "SuspendBackgroundDaemon"},

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -18,7 +15,6 @@ class FrontendApplet;
enum class AppletType { enum class AppletType {
Application, Application,
LibraryApplet, LibraryApplet,
OverlayApplet,
SystemApplet, SystemApplet,
}; };
@@ -150,7 +146,6 @@ enum class AppletMessage : u32 {
ForceHideApplicationLogo = 57, ForceHideApplicationLogo = 57,
FloatingApplicationDetected = 60, FloatingApplicationDetected = 60,
DetectShortPressingCaptureButton = 90, DetectShortPressingCaptureButton = 90,
DetectLongPressingCaptureButton = 91,
AlbumScreenShotTaken = 92, AlbumScreenShotTaken = 92,
AlbumRecordingSaved = 93, AlbumRecordingSaved = 93,
}; };

View File

@@ -12,7 +12,7 @@ namespace Service::AM {
Applet::Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_application) Applet::Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_application)
: context(system, "Applet"), lifecycle_manager(system, context, is_application), : context(system, "Applet"), lifecycle_manager(system, context, is_application),
process(std::move(process_)), hid_registration(system, *process), overlay_event(context), process(std::move(process_)), hid_registration(system, *process),
gpu_error_detected_event(context), friend_invitation_storage_channel_event(context), gpu_error_detected_event(context), friend_invitation_storage_channel_event(context),
notification_storage_channel_event(context), health_warning_disappeared_system_event(context), notification_storage_channel_event(context), health_warning_disappeared_system_event(context),
unknown_event(context), acquired_sleep_lock_event(context), pop_from_general_channel_event(context), unknown_event(context), acquired_sleep_lock_event(context), pop_from_general_channel_event(context),
@@ -63,15 +63,7 @@ void Applet::SetInteractibleLocked(bool interactible) {
is_interactible = interactible; is_interactible = interactible;
const bool exit_requested = lifecycle_manager.GetExitRequested(); hid_registration.EnableAppletToGetInput(interactible && !lifecycle_manager.GetExitRequested());
const bool input_enabled = interactible && !exit_requested;
if (applet_id == AppletId::OverlayDisplay || applet_id == AppletId::Application) {
LOG_DEBUG(Service_AM, "called, applet={} interactible={} exit_requested={} input_enabled={} overlay_in_foreground={}",
static_cast<u32>(applet_id), interactible, exit_requested, input_enabled, overlay_in_foreground);
}
hid_registration.EnableAppletToGetInput(input_enabled);
} }
void Applet::OnProcessTerminatedLocked() { void Applet::OnProcessTerminatedLocked() {

View File

@@ -122,10 +122,8 @@ struct Applet {
bool is_activity_runnable{}; bool is_activity_runnable{};
bool is_interactible{true}; bool is_interactible{true};
bool window_visible{true}; bool window_visible{true};
bool overlay_in_foreground{false};
// Events // Events
Event overlay_event;
Event gpu_error_detected_event; Event gpu_error_detected_event;
Event friend_invitation_storage_channel_event; Event friend_invitation_storage_channel_event;
Event notification_storage_channel_event; Event notification_storage_channel_event;

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -18,7 +15,6 @@
#include "core/hle/service/am/service/storage.h" #include "core/hle/service/am/service/storage.h"
#include "core/hle/service/am/window_system.h" #include "core/hle/service/am/window_system.h"
#include "hid_core/hid_types.h" #include "hid_core/hid_types.h"
#include "core/hle/service/am/process_creation.h"
namespace Service::AM { namespace Service::AM {
@@ -266,22 +262,6 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
m_cv.wait(lk, [&] { return m_pending_process != nullptr; }); m_cv.wait(lk, [&] { return m_pending_process != nullptr; });
if (Settings::values.enable_overlay) {
if (auto overlay_process = CreateProcess(m_system, static_cast<u64>(AppletProgramId::OverlayDisplay), 0, 0)) {
auto overlay_applet = std::make_shared<Applet>(m_system, std::move(overlay_process), false);
overlay_applet->program_id = static_cast<u64>(AppletProgramId::OverlayDisplay);
overlay_applet->applet_id = AppletId::OverlayDisplay;
overlay_applet->type = AppletType::OverlayApplet;
overlay_applet->library_applet_mode = LibraryAppletMode::PartialForeground;
overlay_applet->window_visible = true;
overlay_applet->home_button_short_pressed_blocked = false;
overlay_applet->home_button_long_pressed_blocked = false;
m_window_system->TrackApplet(overlay_applet, false);
overlay_applet->process->Run();
LOG_INFO(Service_AM, "called, Overlay applet launched before application (initially hidden, watching home button)");
}
}
const auto& params = m_pending_parameters; const auto& params = m_pending_parameters;
auto applet = std::make_shared<Applet>(m_system, std::move(m_pending_process), auto applet = std::make_shared<Applet>(m_system, std::move(m_pending_process),
params.applet_id == AppletId::Application); params.applet_id == AppletId::Application);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -49,7 +46,6 @@ public:
public: public:
void SetWindowSystem(WindowSystem* window_system); void SetWindowSystem(WindowSystem* window_system);
[[nodiscard]] WindowSystem* GetWindowSystem() const { return m_window_system; }
private: private:
Core::System& m_system; Core::System& m_system;

View File

@@ -1,11 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/am/am_types.h"
#include "core/hle/service/am/button_poller.h" #include "core/hle/service/am/button_poller.h"
#include "core/hle/service/am/window_system.h" #include "core/hle/service/am/window_system.h"
#include "hid_core/frontend/emulated_controller.h" #include "hid_core/frontend/emulated_controller.h"
@@ -23,9 +19,9 @@ ButtonPressDuration ClassifyPressDuration(std::chrono::steady_clock::time_point
// TODO: determine actual thresholds // TODO: determine actual thresholds
// TODO: these are likely different for each button // TODO: these are likely different for each button
if (dur < 400ms) { if (dur < 500ms) {
return ButtonPressDuration::ShortPressing; return ButtonPressDuration::ShortPressing;
} else if (dur < 800ms) { } else if (dur < 1000ms) {
return ButtonPressDuration::MiddlePressing; return ButtonPressDuration::MiddlePressing;
} else { } else {
return ButtonPressDuration::LongPressing; return ButtonPressDuration::LongPressing;
@@ -51,22 +47,14 @@ ButtonPoller::ButtonPoller(Core::System& system, WindowSystem& window_system)
m_handheld_key = m_handheld->SetCallback(engine_callback); m_handheld_key = m_handheld->SetCallback(engine_callback);
m_player1 = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); m_player1 = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
m_player1_key = m_player1->SetCallback(engine_callback); m_player1_key = m_player1->SetCallback(engine_callback);
m_thread = std::thread([this] { this->ThreadLoop(); });
} }
ButtonPoller::~ButtonPoller() { ButtonPoller::~ButtonPoller() {
m_handheld->DeleteCallback(m_handheld_key); m_handheld->DeleteCallback(m_handheld_key);
m_player1->DeleteCallback(m_player1_key); m_player1->DeleteCallback(m_player1_key);
m_stop = true;
m_cv.notify_all();
if (m_thread.joinable()) {
m_thread.join();
}
} }
void ButtonPoller::OnButtonStateChanged() { void ButtonPoller::OnButtonStateChanged() {
std::lock_guard lk{m_mutex};
const bool home_button = const bool home_button =
m_handheld->GetHomeButtons().home.Value() || m_player1->GetHomeButtons().home.Value(); m_handheld->GetHomeButtons().home.Value() || m_player1->GetHomeButtons().home.Value();
const bool capture_button = m_handheld->GetCaptureButtons().capture.Value() || const bool capture_button = m_handheld->GetCaptureButtons().capture.Value() ||
@@ -75,54 +63,22 @@ void ButtonPoller::OnButtonStateChanged() {
// Buttons pressed which were not previously pressed // Buttons pressed which were not previously pressed
if (home_button && !m_home_button_press_start) { if (home_button && !m_home_button_press_start) {
m_home_button_press_start = std::chrono::steady_clock::now(); m_home_button_press_start = std::chrono::steady_clock::now();
m_home_button_long_sent = false;
} }
if (capture_button && !m_capture_button_press_start) { if (capture_button && !m_capture_button_press_start) {
m_capture_button_press_start = std::chrono::steady_clock::now(); m_capture_button_press_start = std::chrono::steady_clock::now();
m_capture_button_long_sent = false;
} }
// if (power_button && !m_power_button_press_start) { // if (power_button && !m_power_button_press_start) {
// m_power_button_press_start = std::chrono::steady_clock::now(); // m_power_button_press_start = std::chrono::steady_clock::now();
// } // }
// While buttons are held, check whether they have crossed the long-press
// threshold and, if so, send the long-press action immediately (only once).
if (home_button && m_home_button_press_start && !m_home_button_long_sent) {
const auto duration = ClassifyPressDuration(*m_home_button_press_start);
if (duration != ButtonPressDuration::ShortPressing) {
m_window_system.OnSystemButtonPress(SystemButtonType::HomeButtonLongPressing);
m_home_button_long_sent = true;
}
}
if (capture_button && m_capture_button_press_start && !m_capture_button_long_sent) {
const auto duration = ClassifyPressDuration(*m_capture_button_press_start);
if (duration != ButtonPressDuration::ShortPressing) {
m_window_system.OnSystemButtonPress(SystemButtonType::CaptureButtonLongPressing);
m_capture_button_long_sent = true;
}
}
// Buttons released which were previously held // Buttons released which were previously held
if (!home_button && m_home_button_press_start) { if (!home_button && m_home_button_press_start) {
if(!m_home_button_long_sent) { m_window_system.OnHomeButtonPressed(ClassifyPressDuration(*m_home_button_press_start));
const auto duration = ClassifyPressDuration(*m_home_button_press_start);
m_window_system.OnSystemButtonPress(
duration == ButtonPressDuration::ShortPressing ? SystemButtonType::HomeButtonShortPressing
: SystemButtonType::HomeButtonLongPressing);
}
m_home_button_press_start = std::nullopt; m_home_button_press_start = std::nullopt;
m_home_button_long_sent = false;
} }
if (!capture_button && m_capture_button_press_start) { if (!capture_button && m_capture_button_press_start) {
if (!m_capture_button_long_sent) { // TODO
const auto duration = ClassifyPressDuration(*m_capture_button_press_start);
m_window_system.OnSystemButtonPress(
duration == ButtonPressDuration::ShortPressing ? SystemButtonType::CaptureButtonShortPressing
: SystemButtonType::CaptureButtonLongPressing);
}
m_capture_button_press_start = std::nullopt; m_capture_button_press_start = std::nullopt;
m_capture_button_long_sent = false;
} }
// if (!power_button && m_power_button_press_start) { // if (!power_button && m_power_button_press_start) {
// // TODO // // TODO
@@ -130,16 +86,4 @@ void ButtonPoller::OnButtonStateChanged() {
// } // }
} }
void ButtonPoller::ThreadLoop() {
using namespace std::chrono_literals;
std::unique_lock lk{m_mutex};
while (!m_stop) {
m_cv.wait_for(lk, 50ms);
if (m_stop) break;
lk.unlock();
OnButtonStateChanged();
lk.lock();
}
}
} // namespace Service::AM } // namespace Service::AM

View File

@@ -1,17 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <atomic>
#include <chrono> #include <chrono>
#include <condition_variable>
#include <mutex>
#include <optional> #include <optional>
#include <thread>
#include "hid_core/frontend/emulated_controller.h" #include "hid_core/frontend/emulated_controller.h"
namespace Core { namespace Core {
@@ -33,7 +26,6 @@ public:
private: private:
void OnButtonStateChanged(); void OnButtonStateChanged();
void ThreadLoop();
private: private:
WindowSystem& m_window_system; WindowSystem& m_window_system;
@@ -46,15 +38,6 @@ private:
std::optional<std::chrono::steady_clock::time_point> m_home_button_press_start{}; std::optional<std::chrono::steady_clock::time_point> m_home_button_press_start{};
std::optional<std::chrono::steady_clock::time_point> m_capture_button_press_start{}; std::optional<std::chrono::steady_clock::time_point> m_capture_button_press_start{};
std::optional<std::chrono::steady_clock::time_point> m_power_button_press_start{}; std::optional<std::chrono::steady_clock::time_point> m_power_button_press_start{};
bool m_home_button_long_sent{};
bool m_capture_button_long_sent{};
bool m_power_button_long_sent{};
std::thread m_thread;
std::atomic<bool> m_stop{false};
std::condition_variable m_cv;
std::mutex m_mutex;
}; };
} // namespace Service::AM } // namespace Service::AM

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -36,10 +33,6 @@ void DisplayLayerManager::Initialize(Core::System& system, Kernel::KProcess* pro
m_buffer_sharing_enabled = false; m_buffer_sharing_enabled = false;
m_blending_enabled = mode == LibraryAppletMode::PartialForeground || m_blending_enabled = mode == LibraryAppletMode::PartialForeground ||
mode == LibraryAppletMode::PartialForegroundIndirectDisplay; mode == LibraryAppletMode::PartialForegroundIndirectDisplay;
if (m_applet_id != AppletId::Application) {
(void)this->IsSystemBufferSharingEnabled();
}
} }
void DisplayLayerManager::Finalize() { void DisplayLayerManager::Finalize() {
@@ -76,18 +69,6 @@ Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer_id) {
out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()})); out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()}));
m_manager_display_service->SetLayerVisibility(m_visible, *out_layer_id); m_manager_display_service->SetLayerVisibility(m_visible, *out_layer_id);
if (m_applet_id != AppletId::Application) {
(void)m_manager_display_service->SetLayerBlending(m_blending_enabled, *out_layer_id);
if (m_applet_id == AppletId::OverlayDisplay) {
static constexpr s32 kOverlayBackgroundZ = -1;
(void)m_manager_display_service->SetLayerZIndex(kOverlayBackgroundZ, *out_layer_id);
} else {
static constexpr s32 kOverlayZ = 3;
(void)m_manager_display_service->SetLayerZIndex(kOverlayZ, *out_layer_id);
}
}
m_managed_display_layers.emplace(*out_layer_id); m_managed_display_layers.emplace(*out_layer_id);
R_SUCCEED(); R_SUCCEED();
@@ -124,15 +105,7 @@ Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
// We succeeded, so set up remaining state. // We succeeded, so set up remaining state.
m_buffer_sharing_enabled = true; m_buffer_sharing_enabled = true;
// Ensure the overlay layer is visible
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id); m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
m_manager_display_service->SetLayerBlending(m_blending_enabled, m_system_shared_layer_id);
s32 initial_z = 1;
if (m_applet_id == AppletId::OverlayDisplay) {
initial_z = -1;
}
m_manager_display_service->SetLayerZIndex(initial_z, m_system_shared_layer_id);
R_SUCCEED(); R_SUCCEED();
} }
@@ -155,14 +128,10 @@ void DisplayLayerManager::SetWindowVisibility(bool visible) {
if (m_manager_display_service) { if (m_manager_display_service) {
if (m_system_shared_layer_id) { if (m_system_shared_layer_id) {
LOG_INFO(Service_VI, "shared_layer={} visible={} applet_id={}",
m_system_shared_layer_id, m_visible, static_cast<u32>(m_applet_id));
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id); m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
} }
for (const auto layer_id : m_managed_display_layers) { for (const auto layer_id : m_managed_display_layers) {
LOG_INFO(Service_VI, "managed_layer={} visible={} applet_id={}",
layer_id, m_visible, static_cast<u32>(m_applet_id));
m_manager_display_service->SetLayerVisibility(m_visible, layer_id); m_manager_display_service->SetLayerVisibility(m_visible, layer_id);
} }
} }
@@ -172,22 +141,6 @@ bool DisplayLayerManager::GetWindowVisibility() const {
return m_visible; return m_visible;
} }
void DisplayLayerManager::SetOverlayZIndex(s32 z_index) {
if (!m_manager_display_service) {
return;
}
if (m_system_shared_layer_id) {
m_manager_display_service->SetLayerZIndex(z_index, m_system_shared_layer_id);
LOG_INFO(Service_VI, "called, shared_layer={} z={}", m_system_shared_layer_id, z_index);
}
for (const auto layer_id : m_managed_display_layers) {
m_manager_display_service->SetLayerZIndex(z_index, layer_id);
LOG_INFO(Service_VI, "called, managed_layer={} z={}", layer_id, z_index);
}
}
Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written, Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written,
s32* out_fbshare_layer_index) { s32* out_fbshare_layer_index) {
R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied); R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -46,8 +43,6 @@ public:
void SetWindowVisibility(bool visible); void SetWindowVisibility(bool visible);
bool GetWindowVisibility() const; bool GetWindowVisibility() const;
void SetOverlayZIndex(s32 z_index);
Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index); Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
private: private:

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -10,7 +7,6 @@
#include "core/hle/service/am/service/application_proxy.h" #include "core/hle/service/am/service/application_proxy.h"
#include "core/hle/service/am/service/library_applet_proxy.h" #include "core/hle/service/am/service/library_applet_proxy.h"
#include "core/hle/service/am/service/system_applet_proxy.h" #include "core/hle/service/am/service/system_applet_proxy.h"
#include "core/hle/service/am/service/overlay_applet_proxy.h"
#include "core/hle/service/am/window_system.h" #include "core/hle/service/am/window_system.h"
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
@@ -25,7 +21,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys
{110, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxyEx"}, {110, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxyEx"},
{200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"}, {200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"},
{201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"}, {201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"},
{300, D<&IAllSystemAppletProxiesService::OpenOverlayAppletProxy>, "OpenOverlayAppletProxy"}, {300, nullptr, "OpenOverlayAppletProxy"},
{350, D<&IAllSystemAppletProxiesService::OpenSystemApplicationProxy>, "OpenSystemApplicationProxy"}, {350, D<&IAllSystemAppletProxiesService::OpenSystemApplicationProxy>, "OpenSystemApplicationProxy"},
{400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
{410, nullptr, "GetSystemAppletControllerForDebug"}, {410, nullptr, "GetSystemAppletControllerForDebug"},
@@ -71,22 +67,6 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
} }
} }
Result IAllSystemAppletProxiesService::OpenOverlayAppletProxy(
Out<SharedPointer<IOverlayAppletProxy>> out_overlay_applet_proxy, ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle,
InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute) {
LOG_WARNING(Service_AM, "called");
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
*out_overlay_applet_proxy = std::make_shared<IOverlayAppletProxy>(
system, applet, process_handle.Get(), m_window_system);
R_SUCCEED();
} else {
UNIMPLEMENTED();
R_THROW(ResultUnknown);
}
}
Result IAllSystemAppletProxiesService::OpenSystemApplicationProxy( Result IAllSystemAppletProxiesService::OpenSystemApplicationProxy(
Out<SharedPointer<IApplicationProxy>> out_system_application_proxy, ClientProcessId pid, Out<SharedPointer<IApplicationProxy>> out_system_application_proxy, ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle, InCopyHandle<Kernel::KProcess> process_handle,

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,7 +5,6 @@
#include "core/hle/service/cmif_types.h" #include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "core/hle/service/am/service/overlay_applet_proxy.h"
namespace Service { namespace Service {
@@ -35,9 +31,6 @@ private:
ClientProcessId pid, ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle, InCopyHandle<Kernel::KProcess> process_handle,
InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute); InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute);
Result OpenOverlayAppletProxy(Out<SharedPointer<IOverlayAppletProxy>> out_overlay_applet_proxy,
ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle,
InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute);
Result OpenLibraryAppletProxyOld( Result OpenLibraryAppletProxyOld(
Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle); InCopyHandle<Kernel::KProcess> process_handle);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -21,7 +18,7 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
{20, nullptr, "PushToAppletBoundChannel"}, {20, nullptr, "PushToAppletBoundChannel"},
{21, nullptr, "TryPopFromAppletBoundChannel"}, {21, nullptr, "TryPopFromAppletBoundChannel"},
{40, nullptr, "GetDisplayLogicalResolution"}, {40, nullptr, "GetDisplayLogicalResolution"},
{42, D<&IAppletCommonFunctions::SetDisplayMagnification>, "SetDisplayMagnification"}, {42, nullptr, "SetDisplayMagnification"},
{50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"}, {50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"},
{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"}, {51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
{52, nullptr, "IsHomeButtonShortPressedBlocked"}, {52, nullptr, "IsHomeButtonShortPressedBlocked"},
@@ -61,14 +58,6 @@ Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled(
R_SUCCEED(); R_SUCCEED();
} }
Result IAppletCommonFunctions::SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height) {
LOG_DEBUG(Service_AM, "(STUBBED) called, x={}, y={}, width={}, height={}", x, y, width,
height);
std::scoped_lock lk{applet->lock};
applet->display_magnification = Common::Rectangle<f32>{x, y, x + width, y + height};
R_SUCCEED();
}
Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) { Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
std::scoped_lock lk{applet->lock}; std::scoped_lock lk{applet->lock};

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -21,7 +18,6 @@ public:
private: private:
Result SetHomeButtonDoubleClickEnabled(bool home_button_double_click_enabled); Result SetHomeButtonDoubleClickEnabled(bool home_button_double_click_enabled);
Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled); Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled);
Result SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height);
Result SetCpuBoostRequestPriority(s32 priority); Result SetCpuBoostRequestPriority(s32 priority);
Result GetCurrentApplicationId(Out<u64> out_application_id); Result GetCurrentApplicationId(Out<u64> out_application_id);
Result Unknown350(Out<u16> out_unknown); Result Unknown350(Out<u16> out_unknown);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -59,7 +56,7 @@ IApplicationCreator::IApplicationCreator(Core::System& system_, WindowSystem& wi
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"}, {0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"},
{1, nullptr, "PopLaunchRequestedApplication"}, {1, nullptr, "PopLaunchRequestedApplication"},
{10, D<&IApplicationCreator::CreateSystemApplication>, "CreateSystemApplication"}, {10, nullptr, "CreateSystemApplication"},
{100, nullptr, "PopFloatingApplicationForDevelopment"}, {100, nullptr, "PopFloatingApplicationForDevelopment"},
}; };
// clang-format on // clang-format on
@@ -76,34 +73,4 @@ Result IApplicationCreator::CreateApplication(
CreateGuestApplication(out_application_accessor, system, m_window_system, application_id)); CreateGuestApplication(out_application_accessor, system, m_window_system, application_id));
} }
Result IApplicationCreator::CreateSystemApplication(
Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) {
FileSys::VirtualFile nca_raw{};
auto& storage = system.GetContentProviderUnion();
nca_raw = storage.GetEntryRaw(application_id, FileSys::ContentRecordType::Program);
R_UNLESS(nca_raw != nullptr, ResultUnknown);
std::vector<u8> control;
std::unique_ptr<Loader::AppLoader> loader;
auto process =
CreateProcess(system, application_id, 1, 21);
R_UNLESS(process != nullptr, ResultUnknown);
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
applet->program_id = application_id;
applet->applet_id = AppletId::Starter;
applet->type = AppletType::LibraryApplet;
applet->library_applet_mode = LibraryAppletMode::AllForeground;
m_window_system.TrackApplet(applet, true);
*out_application_accessor =
std::make_shared<IApplicationAccessor>(system, applet, m_window_system);
R_SUCCEED();
}
} // namespace Service::AM } // namespace Service::AM

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -22,7 +19,6 @@ public:
private: private:
Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id); Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
Result CreateSystemApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
WindowSystem& m_window_system; WindowSystem& m_window_system;
}; };

View File

@@ -9,11 +9,11 @@
#include "core/hle/service/am/applet.h" #include "core/hle/service/am/applet.h"
#include "core/hle/service/am/service/common_state_getter.h" #include "core/hle/service/am/service/common_state_getter.h"
#include "core/hle/service/am/service/lock_accessor.h" #include "core/hle/service/am/service/lock_accessor.h"
#include "core/hle/service/am/service/storage.h"
#include "core/hle/service/apm/apm_interface.h" #include "core/hle/service/apm/apm_interface.h"
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/pm/pm.h" #include "core/hle/service/pm/pm.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_types.h" #include "core/hle/service/vi/vi_types.h"
namespace Service::AM { namespace Service::AM {
@@ -37,7 +37,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Ap
{12, D<&ICommonStateGetter::ReleaseSleepLockTransiently>, "ReleaseSleepLockTransiently"}, {12, D<&ICommonStateGetter::ReleaseSleepLockTransiently>, "ReleaseSleepLockTransiently"},
{13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"}, {13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"},
{14, nullptr, "GetWakeupCount"}, {14, nullptr, "GetWakeupCount"},
{20, D<&ICommonStateGetter::PushToGeneralChannel>, "PushToGeneralChannel"}, {20, nullptr, "PushToGeneralChannel"},
{30, nullptr, "GetHomeButtonReaderLockAccessor"}, {30, nullptr, "GetHomeButtonReaderLockAccessor"},
{31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"}, {31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"},
{32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"}, {32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"},
@@ -61,7 +61,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Ap
{80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"}, {80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"},
{90, nullptr, "SetPerformanceConfigurationChangedNotification"}, {90, nullptr, "SetPerformanceConfigurationChangedNotification"},
{91, nullptr, "GetCurrentPerformanceConfiguration"}, {91, nullptr, "GetCurrentPerformanceConfiguration"},
{100, D<&ICommonStateGetter::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"}, {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
{110, nullptr, "OpenMyGpuErrorHandler"}, {110, nullptr, "OpenMyGpuErrorHandler"},
{120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory"}, {120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory"},
{200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"}, {200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"},
@@ -95,9 +95,6 @@ Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message)
R_THROW(AM::ResultNoMessages); R_THROW(AM::ResultNoMessages);
} }
LOG_DEBUG(Service_AM, "called, returning message={} to applet_id={}",
static_cast<u32>(*out_applet_message), static_cast<u32>(m_applet->applet_id));
R_SUCCEED(); R_SUCCEED();
} }
@@ -265,40 +262,7 @@ Result ICommonStateGetter::GetBuiltInDisplayType(Out<s32> out_display_type) {
} }
Result ICommonStateGetter::PerformSystemButtonPressingIfInFocus(SystemButtonType type) { Result ICommonStateGetter::PerformSystemButtonPressingIfInFocus(SystemButtonType type) {
LOG_DEBUG(Service_AM, "called, type={}", type); LOG_WARNING(Service_AM, "(STUBBED) called, type={}", type);
std::scoped_lock lk{m_applet->lock};
switch (type) {
case SystemButtonType::HomeButtonShortPressing:
if (!m_applet->home_button_short_pressed_blocked) {
m_applet->lifecycle_manager.PushUnorderedMessage(
AppletMessage::DetectShortPressingHomeButton);
}
break;
case SystemButtonType::HomeButtonLongPressing:
if (!m_applet->home_button_long_pressed_blocked) {
m_applet->lifecycle_manager.PushUnorderedMessage(
AppletMessage::DetectLongPressingHomeButton);
}
break;
case SystemButtonType::CaptureButtonShortPressing:
if (m_applet->handling_capture_button_short_pressed_message_enabled_for_applet) {
m_applet->lifecycle_manager.PushUnorderedMessage(
AppletMessage::DetectShortPressingCaptureButton);
}
break;
case SystemButtonType::CaptureButtonLongPressing:
if (m_applet->handling_capture_button_long_pressed_message_enabled_for_applet) {
m_applet->lifecycle_manager.PushUnorderedMessage(
AppletMessage::DetectLongPressingCaptureButton);
}
break;
default:
// Other buttons ignored for now
break;
}
R_SUCCEED(); R_SUCCEED();
} }
@@ -340,18 +304,4 @@ Result ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnab
R_SUCCEED(); R_SUCCEED();
} }
Result ICommonStateGetter::PushToGeneralChannel(SharedPointer<IStorage> storage) {
LOG_DEBUG(Service_AM, "called");
system.PushGeneralChannelData(storage->GetData());
R_SUCCEED();
}
Result ICommonStateGetter::SetHandlingHomeButtonShortPressedEnabled(bool enabled) {
LOG_DEBUG(Service_AM, "called, enabled={} applet_id={}", enabled, m_applet->applet_id);
std::scoped_lock lk{m_applet->lock};
m_applet->home_button_short_pressed_blocked = !enabled;
R_SUCCEED();
}
} // namespace Service::AM } // namespace Service::AM

View File

@@ -21,7 +21,6 @@ namespace Service::AM {
struct Applet; struct Applet;
class ILockAccessor; class ILockAccessor;
class IStorage;
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
public: public:
@@ -61,8 +60,6 @@ private:
OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids); OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids);
Result GetSettingsPlatformRegion(Out<Set::PlatformRegion> out_settings_platform_region); Result GetSettingsPlatformRegion(Out<Set::PlatformRegion> out_settings_platform_region);
Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled();
Result PushToGeneralChannel(SharedPointer<IStorage> storage); // cmd 20
Result SetHandlingHomeButtonShortPressedEnabled(bool enabled);
void SetCpuBoostMode(HLERequestContext& ctx); void SetCpuBoostMode(HLERequestContext& ctx);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,21 +6,20 @@
#include "core/hle/service/am/service/home_menu_functions.h" #include "core/hle/service/am/service/home_menu_functions.h"
#include "core/hle/service/am/window_system.h" #include "core/hle/service/am/window_system.h"
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/am/am_results.h"
#include "core/hle/service/am/service/storage.h"
namespace Service::AM { namespace Service::AM {
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet, IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet,
WindowSystem& window_system) WindowSystem& window_system)
: ServiceFramework{system_, "IHomeMenuFunctions"}, m_window_system{window_system}, : ServiceFramework{system_, "IHomeMenuFunctions"}, m_window_system{window_system},
m_applet{std::move(applet)}, m_context{system, "IHomeMenuFunctions"} { m_applet{std::move(applet)}, m_context{system, "IHomeMenuFunctions"},
m_pop_from_general_channel_event{m_context} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
{11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"}, {11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"},
{12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"}, {12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"},
{20, D<&IHomeMenuFunctions::PopFromGeneralChannel>, "PopFromGeneralChannel"}, {20, nullptr, "PopFromGeneralChannel"},
{21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"}, {21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"},
{30, nullptr, "GetHomeButtonWriterLockAccessor"}, {30, nullptr, "GetHomeButtonWriterLockAccessor"},
{31, nullptr, "GetWriterLockAccessorEx"}, {31, nullptr, "GetWriterLockAccessorEx"},
@@ -61,22 +57,10 @@ Result IHomeMenuFunctions::UnlockForeground() {
R_SUCCEED(); R_SUCCEED();
} }
Result IHomeMenuFunctions::PopFromGeneralChannel(Out<SharedPointer<IStorage>> out_storage) {
LOG_DEBUG(Service_AM, "called");
std::vector<u8> data;
if (!system.TryPopGeneralChannel(data)) {
R_THROW(AM::ResultNoDataInChannel);
}
*out_storage = std::make_shared<IStorage>(system, std::move(data));
R_SUCCEED();
}
Result IHomeMenuFunctions::GetPopFromGeneralChannelEvent( Result IHomeMenuFunctions::GetPopFromGeneralChannelEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) { OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_INFO(Service_AM, "called"); LOG_INFO(Service_AM, "called");
*out_event = system.GetGeneralChannelEvent().GetHandle(); *out_event = m_pop_from_general_channel_event.GetHandle();
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -15,7 +12,6 @@ namespace Service::AM {
struct Applet; struct Applet;
class WindowSystem; class WindowSystem;
class IStorage;
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
public: public:
@@ -27,7 +23,6 @@ private:
Result RequestToGetForeground(); Result RequestToGetForeground();
Result LockForeground(); Result LockForeground();
Result UnlockForeground(); Result UnlockForeground();
Result PopFromGeneralChannel(Out<SharedPointer<IStorage>> out_storage);
Result GetPopFromGeneralChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); Result GetPopFromGeneralChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsRebootEnabled(Out<bool> out_is_reboot_enbaled); Result IsRebootEnabled(Out<bool> out_is_reboot_enbaled);
Result IsForceTerminateApplicationDisabledForDebug( Result IsForceTerminateApplicationDisabledForDebug(
@@ -36,6 +31,7 @@ private:
WindowSystem& m_window_system; WindowSystem& m_window_system;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
KernelHelpers::ServiceContext m_context; KernelHelpers::ServiceContext m_context;
Event m_pop_from_general_channel_event;
}; };
} // namespace Service::AM } // namespace Service::AM

View File

@@ -1,120 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/am/service/common_state_getter.h"
#include "core/hle/service/am/service/display_controller.h"
#include "core/hle/service/am/service/global_state_controller.h"
#include "core/hle/service/am/service/audio_controller.h"
#include "core/hle/service/am/service/applet_common_functions.h"
#include "core/hle/service/am/service/overlay_applet_proxy.h"
#include "core/hle/service/am/service/library_applet_creator.h"
#include "core/hle/service/am/service/process_winding_controller.h"
#include "core/hle/service/am/service/self_controller.h"
#include "core/hle/service/am/service/window_controller.h"
#include "core/hle/service/am/service/debug_functions.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::AM {
IOverlayAppletProxy::IOverlayAppletProxy(Core::System &system_, std::shared_ptr<Applet> applet,
Kernel::KProcess *process, WindowSystem &window_system)
: ServiceFramework{system_, "IOverlayAppletProxy"},
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IOverlayAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
{1, D<&IOverlayAppletProxy::GetSelfController>, "GetSelfController"},
{2, D<&IOverlayAppletProxy::GetWindowController>, "GetWindowController"},
{3, D<&IOverlayAppletProxy::GetAudioController>, "GetAudioController"},
{4, D<&IOverlayAppletProxy::GetDisplayController>, "GetDisplayController"},
{10, D<&IOverlayAppletProxy::GetProcessWindingController>, "GetProcessWindingController"},
{11, D<&IOverlayAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
{20, D<&IOverlayAppletProxy::GetOverlayFunctions>, "GetOverlayFunctions"},
{21, D<&IOverlayAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"},
{23, D<&IOverlayAppletProxy::GetGlobalStateController>, "GetGlobalStateController"},
{1000, D<&IOverlayAppletProxy::GetDebugFunctions>, "GetDebugFunctions"},
};
// clang-format on
RegisterHandlers(functions);
}
IOverlayAppletProxy::~IOverlayAppletProxy() = default;
Result IOverlayAppletProxy::GetCommonStateGetter(
Out<SharedPointer<ICommonStateGetter> > out_common_state_getter) {
LOG_DEBUG(Service_AM, "called");
*out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetSelfController(
Out<SharedPointer<ISelfController> > out_self_controller) {
LOG_DEBUG(Service_AM, "called");
*out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetWindowController(
Out<SharedPointer<IWindowController> > out_window_controller) {
LOG_DEBUG(Service_AM, "called");
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetAudioController(
Out<SharedPointer<IAudioController> > out_audio_controller) {
LOG_DEBUG(Service_AM, "called");
*out_audio_controller = std::make_shared<IAudioController>(system);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetDisplayController(
Out<SharedPointer<IDisplayController> > out_display_controller) {
LOG_DEBUG(Service_AM, "called");
*out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetProcessWindingController(
Out<SharedPointer<IProcessWindingController> > out_process_winding_controller) {
LOG_DEBUG(Service_AM, "called");
*out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetLibraryAppletCreator(
Out<SharedPointer<ILibraryAppletCreator> > out_library_applet_creator) {
LOG_DEBUG(Service_AM, "called");
*out_library_applet_creator =
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetOverlayFunctions(
Out<SharedPointer<IOverlayFunctions> > out_overlay_functions) {
LOG_DEBUG(Service_AM, "called");
*out_overlay_functions = std::make_shared<IOverlayFunctions>(system, m_applet);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetAppletCommonFunctions(
Out<SharedPointer<IAppletCommonFunctions> > out_applet_common_functions) {
LOG_DEBUG(Service_AM, "called");
*out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetGlobalStateController(
Out<SharedPointer<IGlobalStateController> > out_global_state_controller) {
LOG_DEBUG(Service_AM, "called");
*out_global_state_controller = std::make_shared<IGlobalStateController>(system);
R_SUCCEED();
}
Result IOverlayAppletProxy::GetDebugFunctions(
Out<SharedPointer<IDebugFunctions> > out_debug_functions) {
LOG_DEBUG(Service_AM, "called");
*out_debug_functions = std::make_shared<IDebugFunctions>(system);
R_SUCCEED();
}
} // namespace Service::AM

View File

@@ -1,55 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
#include "core/hle/service/am/service/overlay_functions.h"
namespace Service::AM {
struct Applet;
class IAppletCommonFunctions;
class IAudioController;
class ICommonStateGetter;
class IDebugFunctions;
class IDisplayController;
class IHomeMenuFunctions;
class IGlobalStateController;
class ILibraryAppletCreator;
class ILibraryAppletSelfAccessor;
class IProcessWindingController;
class ISelfController;
class IWindowController;
class WindowSystem;
class IOverlayAppletProxy final : public ServiceFramework<IOverlayAppletProxy> {
public:
explicit IOverlayAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, WindowSystem& window_system);
~IOverlayAppletProxy();
private:
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
Result GetProcessWindingController(
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
Result GetLibraryAppletCreator(
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
Result GetOverlayFunctions(Out<SharedPointer<IOverlayFunctions>> out_overlay_functions);
Result GetAppletCommonFunctions(
Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions);
Result GetGlobalStateController(
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
WindowSystem& m_window_system;
Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet;
};
} // namespace Service::AM

View File

@@ -1,100 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/am/applet.h"
#include "core/hle/service/am/service/overlay_functions.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/am/applet_manager.h"
#include "core/hle/service/am/window_system.h"
namespace Service::AM {
IOverlayFunctions::IOverlayFunctions(Core::System &system_, std::shared_ptr<Applet> applet)
: ServiceFramework{system_, "IOverlayFunctions"}, m_applet{std::move(applet)} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IOverlayFunctions::BeginToWatchShortHomeButtonMessage>, "BeginToWatchShortHomeButtonMessage"},
{1, D<&IOverlayFunctions::EndToWatchShortHomeButtonMessage>, "EndToWatchShortHomeButtonMessage"},
{2, D<&IOverlayFunctions::GetApplicationIdForLogo>, "GetApplicationIdForLogo"},
{3, nullptr, "SetGpuTimeSliceBoost"},
{4, D<&IOverlayFunctions::SetAutoSleepTimeAndDimmingTimeEnabled>, "SetAutoSleepTimeAndDimmingTimeEnabled"},
{5, nullptr, "TerminateApplicationAndSetReason"},
{6, nullptr, "SetScreenShotPermissionGlobally"},
{10, nullptr, "StartShutdownSequenceForOverlay"},
{11, nullptr, "StartRebootSequenceForOverlay"},
{20, D<&IOverlayFunctions::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"},
{21, nullptr, "SetHandlingTouchScreenInputEnabled"},
{30, nullptr, "SetHealthWarningShowingState"},
{31, nullptr, "IsHealthWarningRequired"},
{40, nullptr, "GetApplicationNintendoLogo"},
{41, nullptr, "GetApplicationStartupMovie"},
{50, nullptr, "SetGpuTimeSliceBoostForApplication"},
{60, nullptr, "Unknown60"},
{70, D<&IOverlayFunctions::Unknown70>, "Unknown70"},
{90, nullptr, "SetRequiresGpuResourceUse"},
{101, nullptr, "BeginToObserveHidInputForDevelop"},
};
// clang-format on
RegisterHandlers(functions);
}
IOverlayFunctions::~IOverlayFunctions() = default;
Result IOverlayFunctions::BeginToWatchShortHomeButtonMessage() {
LOG_DEBUG(Service_AM, "called");
m_applet->overlay_in_foreground = true;
m_applet->home_button_short_pressed_blocked = false;
if (auto *window_system = system.GetAppletManager().GetWindowSystem()) {
window_system->RequestUpdate();
}
R_SUCCEED();
}
Result IOverlayFunctions::EndToWatchShortHomeButtonMessage() {
LOG_DEBUG(Service_AM, "called");
m_applet->overlay_in_foreground = false;
m_applet->home_button_short_pressed_blocked = false;
if (auto *window_system = system.GetAppletManager().GetWindowSystem()) {
window_system->RequestUpdate();
}
R_SUCCEED();
}
Result IOverlayFunctions::GetApplicationIdForLogo(Out<u64> out_application_id) {
LOG_DEBUG(Service_AM, "called");
// Prefer explicit application_id if available, else fall back to program_id
std::scoped_lock lk{m_applet->lock};
u64 id = m_applet->screen_shot_identity.application_id;
if (id == 0) {
id = m_applet->program_id;
}
*out_application_id = id;
R_SUCCEED();
}
Result IOverlayFunctions::SetAutoSleepTimeAndDimmingTimeEnabled(bool enabled) {
LOG_WARNING(Service_AM, "(STUBBED) called, enabled={}", enabled);
std::scoped_lock lk{m_applet->lock};
m_applet->auto_sleep_disabled = !enabled;
R_SUCCEED();
}
Result IOverlayFunctions::SetHandlingHomeButtonShortPressedEnabled(bool enabled) {
LOG_DEBUG(Service_AM, "called, enabled={}", enabled);
std::scoped_lock lk{m_applet->lock};
m_applet->home_button_short_pressed_blocked = !enabled;
R_SUCCEED();
}
Result IOverlayFunctions::Unknown70() {
LOG_DEBUG(Service_AM, "called");
R_SUCCEED();
}
} // namespace Service::AM

View File

@@ -1,27 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::AM {
struct Applet;
class IOverlayFunctions final : public ServiceFramework<IOverlayFunctions> {
public:
explicit IOverlayFunctions(Core::System &system_, std::shared_ptr<Applet> applet);
~IOverlayFunctions() override;
private:
Result BeginToWatchShortHomeButtonMessage();
Result EndToWatchShortHomeButtonMessage();
Result GetApplicationIdForLogo(Out<u64> out_application_id);
Result SetAutoSleepTimeAndDimmingTimeEnabled(bool enabled);
Result SetHandlingHomeButtonShortPressedEnabled(bool enabled);
Result Unknown70();
private:
const std::shared_ptr<Applet> m_applet;
};
} // namespace Service::AM

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -33,14 +30,14 @@ public:
~ISystemAppletProxy(); ~ISystemAppletProxy();
private: private:
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
Result GetProcessWindingController( Result GetProcessWindingController(
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
Result GetLibraryAppletCreator( Result GetLibraryAppletCreator(
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
Result GetApplicationCreator(Out<SharedPointer<IApplicationCreator>> out_application_creator); Result GetApplicationCreator(Out<SharedPointer<IApplicationCreator>> out_application_creator);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -24,18 +21,9 @@ void WindowSystem::SetEventObserver(EventObserver* observer) {
m_system.GetAppletManager().SetWindowSystem(this); m_system.GetAppletManager().SetWindowSystem(this);
} }
void WindowSystem::RequestUpdate() {
if (m_event_observer) {
m_event_observer->RequestUpdate();
}
}
void WindowSystem::Update() { void WindowSystem::Update() {
std::scoped_lock lk{m_lock}; std::scoped_lock lk{m_lock};
LOG_DEBUG(Service_AM, "called, home_menu={} application={} overlay={}",
m_home_menu != nullptr, m_application != nullptr, m_overlay_display != nullptr);
// Loop through all applets and remove terminated applets. // Loop through all applets and remove terminated applets.
this->PruneTerminatedAppletsLocked(); this->PruneTerminatedAppletsLocked();
@@ -44,16 +32,9 @@ void WindowSystem::Update() {
return; return;
} }
bool overlay_blocks_input = false;
if (m_overlay_display) {
std::scoped_lock lk_overlay{m_overlay_display->lock};
overlay_blocks_input = m_overlay_display->overlay_in_foreground;
}
// Recursively update each applet root. // Recursively update each applet root.
this->UpdateAppletStateLocked(m_home_menu, m_foreground_requested_applet == m_home_menu, overlay_blocks_input); this->UpdateAppletStateLocked(m_home_menu, m_foreground_requested_applet == m_home_menu);
this->UpdateAppletStateLocked(m_application, m_foreground_requested_applet == m_application, overlay_blocks_input); this->UpdateAppletStateLocked(m_application, m_foreground_requested_applet == m_application);
this->UpdateAppletStateLocked(m_overlay_display, true, false); // overlay is always updated, never blocked
} }
void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) { void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) {
@@ -62,8 +43,6 @@ void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_applicati
if (applet->applet_id == AppletId::QLaunch) { if (applet->applet_id == AppletId::QLaunch) {
ASSERT(m_home_menu == nullptr); ASSERT(m_home_menu == nullptr);
m_home_menu = applet.get(); m_home_menu = applet.get();
} else if (applet->applet_id == AppletId::OverlayDisplay) {
m_overlay_display = applet.get();
} else if (is_application) { } else if (is_application) {
ASSERT(m_application == nullptr); ASSERT(m_application == nullptr);
m_application = applet.get(); m_application = applet.get();
@@ -157,66 +136,21 @@ void WindowSystem::OnExitRequested() {
} }
} }
void WindowSystem::SendButtonAppletMessageLocked(AppletMessage message) {
if (m_home_menu) {
std::scoped_lock lk_home{m_home_menu->lock};
m_home_menu->lifecycle_manager.PushUnorderedMessage(message);
}
if (m_overlay_display) {
std::scoped_lock lk_overlay{m_overlay_display->lock};
m_overlay_display->lifecycle_manager.PushUnorderedMessage(message);
}
if (m_application) {
std::scoped_lock lk_application{m_application->lock};
m_application->lifecycle_manager.PushUnorderedMessage(message);
}
if (m_event_observer) {
m_event_observer->RequestUpdate();
}
}
void WindowSystem::OnSystemButtonPress(SystemButtonType type) {
std::scoped_lock lk{m_lock};
switch (type) {
case SystemButtonType::HomeButtonShortPressing:
SendButtonAppletMessageLocked(AppletMessage::DetectShortPressingHomeButton);
break;
case SystemButtonType::HomeButtonLongPressing: {
// Toggle overlay foreground visibility on long home press
if (m_overlay_display) {
std::scoped_lock lk_overlay{m_overlay_display->lock};
m_overlay_display->overlay_in_foreground = !m_overlay_display->overlay_in_foreground;
// Tie window visibility to foreground state so hidden when not active
m_overlay_display->window_visible = m_overlay_display->overlay_in_foreground;
LOG_INFO(Service_AM, "Overlay long-press toggle: overlay_in_foreground={} window_visible={}", m_overlay_display->overlay_in_foreground, m_overlay_display->window_visible);
}
SendButtonAppletMessageLocked(AppletMessage::DetectLongPressingHomeButton);
// Force a state update after toggling overlay
if (m_event_observer) {
m_event_observer->RequestUpdate();
}
break; }
case SystemButtonType::CaptureButtonShortPressing:
SendButtonAppletMessageLocked(AppletMessage::DetectShortPressingCaptureButton);
break;
case SystemButtonType::CaptureButtonLongPressing:
SendButtonAppletMessageLocked(AppletMessage::DetectLongPressingCaptureButton);
break;
default:
break;
}
}
void WindowSystem::OnHomeButtonPressed(ButtonPressDuration type) { void WindowSystem::OnHomeButtonPressed(ButtonPressDuration type) {
// Map duration to SystemButtonType for legacy callers std::scoped_lock lk{m_lock};
switch (type) {
case ButtonPressDuration::ShortPressing: // If we don't have a home menu, nothing to do.
OnSystemButtonPress(SystemButtonType::HomeButtonShortPressing); if (!m_home_menu) {
break; return;
case ButtonPressDuration::MiddlePressing: }
case ButtonPressDuration::LongPressing:
OnSystemButtonPress(SystemButtonType::HomeButtonLongPressing); // Lock.
break; std::scoped_lock lk2{m_home_menu->lock};
// Send home button press event to home menu.
if (type == ButtonPressDuration::ShortPressing) {
m_home_menu->lifecycle_manager.PushUnorderedMessage(
AppletMessage::DetectShortPressingHomeButton);
} }
} }
@@ -274,10 +208,6 @@ void WindowSystem::PruneTerminatedAppletsLocked() {
} }
} }
if (applet.get() == m_overlay_display) {
m_overlay_display = nullptr;
}
// Finalize applet. // Finalize applet.
applet->OnProcessTerminatedLocked(); applet->OnProcessTerminatedLocked();
@@ -328,7 +258,7 @@ void WindowSystem::TerminateChildAppletsLocked(Applet* applet) {
applet->lock.lock(); applet->lock.lock();
} }
void WindowSystem::UpdateAppletStateLocked(Applet* applet, bool is_foreground, bool overlay_blocking) { void WindowSystem::UpdateAppletStateLocked(Applet* applet, bool is_foreground) {
// With no applet, we don't have anything to do. // With no applet, we don't have anything to do.
if (!applet) { if (!applet) {
return; return;
@@ -357,23 +287,10 @@ void WindowSystem::UpdateAppletStateLocked(Applet* applet, bool is_foreground, b
}(); }();
// Update visibility state. // Update visibility state.
// Overlay applets should always be visible when window_visible is true, regardless of foreground state applet->display_layer_manager.SetWindowVisibility(is_foreground && applet->window_visible);
const bool should_be_visible = (applet->applet_id == AppletId::OverlayDisplay)
? applet->window_visible
: (is_foreground && applet->window_visible);
applet->display_layer_manager.SetWindowVisibility(should_be_visible);
// Update interactibility state.
const bool should_be_interactible = (applet->applet_id == AppletId::OverlayDisplay) applet->SetInteractibleLocked(is_foreground && applet->window_visible);
? applet->overlay_in_foreground
: (is_foreground && applet->window_visible && !overlay_blocking);
if (applet->applet_id == AppletId::OverlayDisplay || applet->applet_id == AppletId::Application) {
LOG_DEBUG(Service_AM, "UpdateAppletStateLocked: applet={} overlay_in_foreground={} is_foreground={} window_visible={} overlay_blocking={} should_be_interactible={}",
static_cast<u32>(applet->applet_id), applet->overlay_in_foreground, is_foreground, applet->window_visible, overlay_blocking, should_be_interactible);
}
applet->SetInteractibleLocked(should_be_interactible);
// Update focus state and suspension. // Update focus state and suspension.
const bool is_obscured = has_obscuring_child_applets || !applet->window_visible; const bool is_obscured = has_obscuring_child_applets || !applet->window_visible;
@@ -389,23 +306,9 @@ void WindowSystem::UpdateAppletStateLocked(Applet* applet, bool is_foreground, b
applet->UpdateSuspensionStateLocked(true); applet->UpdateSuspensionStateLocked(true);
} }
// Z-index logic like in reference C# implementation (tuned for overlay extremes)
s32 z_index = 0;
const bool now_foreground = inherited_foreground;
if (applet->applet_id == AppletId::OverlayDisplay) {
z_index = applet->overlay_in_foreground ? 100000 : -100000;
} else if (now_foreground && !is_obscured) {
z_index = 2;
} else if (now_foreground) {
z_index = 1;
} else {
z_index = 0;
}
applet->display_layer_manager.SetOverlayZIndex(z_index);
// Recurse into child applets. // Recurse into child applets.
for (const auto& child_applet : applet->child_applets) { for (const auto& child_applet : applet->child_applets) {
this->UpdateAppletStateLocked(child_applet.get(), is_foreground, overlay_blocking); this->UpdateAppletStateLocked(child_applet.get(), is_foreground);
} }
} }

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -11,7 +8,6 @@
#include <mutex> #include <mutex>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/am/am_types.h"
namespace Core { namespace Core {
class System; class System;
@@ -36,7 +32,6 @@ public:
public: public:
void SetEventObserver(EventObserver* event_observer); void SetEventObserver(EventObserver* event_observer);
void Update(); void Update();
void RequestUpdate();
public: public:
void TrackApplet(std::shared_ptr<Applet> applet, bool is_application); void TrackApplet(std::shared_ptr<Applet> applet, bool is_application);
@@ -54,7 +49,6 @@ public:
void OnOperationModeChanged(); void OnOperationModeChanged();
void OnExitRequested(); void OnExitRequested();
void OnHomeButtonPressed(ButtonPressDuration type); void OnHomeButtonPressed(ButtonPressDuration type);
void OnSystemButtonPress(SystemButtonType type);
void OnCaptureButtonPressed(ButtonPressDuration type) {} void OnCaptureButtonPressed(ButtonPressDuration type) {}
void OnPowerButtonPressed(ButtonPressDuration type) {} void OnPowerButtonPressed(ButtonPressDuration type) {}
@@ -62,8 +56,7 @@ private:
void PruneTerminatedAppletsLocked(); void PruneTerminatedAppletsLocked();
bool LockHomeMenuIntoForegroundLocked(); bool LockHomeMenuIntoForegroundLocked();
void TerminateChildAppletsLocked(Applet* applet); void TerminateChildAppletsLocked(Applet* applet);
void UpdateAppletStateLocked(Applet* applet, bool is_foreground, bool overlay_blocking = false); void UpdateAppletStateLocked(Applet* applet, bool is_foreground);
void SendButtonAppletMessageLocked(AppletMessage message);
private: private:
// System reference. // System reference.
@@ -82,7 +75,6 @@ private:
// Foreground roots. // Foreground roots.
Applet* m_home_menu{}; Applet* m_home_menu{};
Applet* m_application{}; Applet* m_application{};
Applet* m_overlay_display{};
// Applet map by aruid. // Applet map by aruid.
std::map<u64, std::shared_ptr<Applet>> m_applets{}; std::map<u64, std::shared_ptr<Applet>> m_applets{};

View File

@@ -1,22 +1,15 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "audio_core/audio_core.h" #include "common/logging/log.h"
#include "core/hle/service/audio/audio_controller.h" #include "core/hle/service/audio/audio_controller.h"
#include "core/hle/service/audio/audio_out_manager.h"
#include "core/core.h"
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/set/system_settings_server.h" #include "core/hle/service/set/system_settings_server.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include "common/settings.h"
#include <algorithm>
namespace Service::Audio { namespace Service::Audio {
@@ -24,12 +17,12 @@ IAudioController::IAudioController(Core::System& system_)
: ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} { : ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IAudioController::GetTargetVolume>, "GetTargetVolume"}, {0, nullptr, "GetTargetVolume"},
{1, D<&IAudioController::SetTargetVolume>, "SetTargetVolume"}, {1, nullptr, "SetTargetVolume"},
{2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"}, {2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"},
{3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"}, {3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"},
{4, D<&IAudioController::IsTargetMute>, "IsTargetMute"}, {4, nullptr, "IsTargetMute"},
{5, D<&IAudioController::SetTargetMute>, "SetTargetMute"}, {5, nullptr, "SetTargetMute"},
{6, nullptr, "IsTargetConnected"}, {6, nullptr, "IsTargetConnected"},
{7, nullptr, "SetDefaultTarget"}, {7, nullptr, "SetDefaultTarget"},
{8, nullptr, "GetDefaultTarget"}, {8, nullptr, "GetDefaultTarget"},
@@ -56,7 +49,7 @@ IAudioController::IAudioController(Core::System& system_)
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"}, {30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"},
{31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"}, {31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"},
{32, D<&IAudioController::GetActiveOutputTarget>, "GetActiveOutputTarget"}, {32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"}, {33, nullptr, "GetTargetDeviceInfo"},
{34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"}, {34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"},
{35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
@@ -91,38 +84,6 @@ IAudioController::IAudioController(Core::System& system_)
m_set_sys = m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
notification_event = service_context.CreateEvent("IAudioController:NotificationEvent"); notification_event = service_context.CreateEvent("IAudioController:NotificationEvent");
// Probably shouldn't do this in constructor?
try {
const int ui_volume = Settings::values.volume.GetValue();
const int mapped = static_cast<int>(std::lround((static_cast<double>(ui_volume) / 100.0) * 15.0));
const auto active_idx = static_cast<size_t>(m_active_target);
if (active_idx < m_target_volumes.size()) {
m_target_volumes[active_idx] = std::clamp(mapped, 0, 15);
}
const bool muted = Settings::values.audio_muted.GetValue();
for (auto& m : m_target_muted) {
m = muted;
}
if (!muted && active_idx < m_target_volumes.size()) {
const float vol_f = static_cast<float>(m_target_volumes[active_idx]) / 15.0f;
try {
auto& sink = system.AudioCore().GetOutputSink();
sink.SetSystemVolume(vol_f);
sink.SetDeviceVolume(vol_f);
} catch (...) {
LOG_WARNING(Audio, "Failed to apply initial sink volume from settings");
}
if (auto audout_mgr = system.ServiceManager().GetService<Service::Audio::IAudioOutManager>("audout:u")) {
audout_mgr->SetAllAudioOutVolume(static_cast<float>(m_target_volumes[active_idx]) / 15.0f);
}
}
} catch (...) {
// Catch if something fails, since this is constructor
}
} }
IAudioController::~IAudioController() { IAudioController::~IAudioController() {
@@ -230,120 +191,4 @@ Result IAudioController::Unknown5000(Out<SharedPointer<IAudioController>> out_au
R_SUCCEED(); R_SUCCEED();
} }
Result IAudioController::GetTargetVolume(Out<s32> out_target_volume, Set::AudioOutputModeTarget target) {
LOG_DEBUG(Audio, "GetTargetVolume called, target={}", target);
const auto idx = static_cast<size_t>(target);
if (idx >= m_target_volumes.size()) {
LOG_ERROR(Audio, "GetTargetVolume invalid target {}", idx);
R_THROW(ResultInvalidArgument);
}
*out_target_volume = m_target_volumes[idx];
R_SUCCEED();
}
Result IAudioController::SetTargetVolume(Set::AudioOutputModeTarget target, s32 target_volume) {
LOG_INFO(Audio, "SetTargetVolume called, target={}, volume={}", target, target_volume);
const auto idx = static_cast<size_t>(target);
if (idx >= m_target_volumes.size()) {
LOG_ERROR(Audio, "SetTargetVolume invalid target {}", idx);
R_THROW(ResultInvalidArgument);
}
if (target_volume < 0) {
target_volume = 0;
} else if (target_volume > 15) {
target_volume = 15;
}
m_target_volumes[idx] = target_volume;
if (m_active_target == target && !m_target_muted[idx]) {
const float vol = static_cast<float>(target_volume) / 15.0f;
// try catch this, as we don't know how it handles it when no output is set.
// we already have audio issues when no output is set, so catch.
try {
auto& sink = system.AudioCore().GetOutputSink();
sink.SetSystemVolume(vol);
sink.SetDeviceVolume(vol);
} catch (...) {
LOG_WARNING(Audio, "Failed to set sink system volume");
}
if (auto audout_mgr = system.ServiceManager().GetService<IAudioOutManager>("audout:u")) {
audout_mgr->SetAllAudioOutVolume(vol);
}
}
if (m_active_target == target) {
const int ui_volume = static_cast<int>(std::lround((static_cast<double>(target_volume) / 15.0) * 100.0));
Settings::values.volume.SetValue(static_cast<u8>(std::clamp(ui_volume, 0, 100)));
}
R_SUCCEED();
}
Result IAudioController::IsTargetMute(Out<bool> out_is_target_muted, Set::AudioOutputModeTarget target) {
LOG_DEBUG(Audio, "called, target={}", target);
const auto idx = static_cast<size_t>(target);
if (idx >= m_target_muted.size()) {
LOG_ERROR(Audio, "invalid target {}", idx);
R_THROW(ResultInvalidArgument);
}
*out_is_target_muted = m_target_muted[idx];
R_SUCCEED();
}
Result IAudioController::SetTargetMute(bool is_muted, Set::AudioOutputModeTarget target) {
LOG_INFO(Audio, "called, target={}, muted={}", target, is_muted);
const auto idx = static_cast<size_t>(target);
if (idx >= m_target_muted.size()) {
LOG_ERROR(Audio, "invalid target {}", idx);
R_THROW(ResultInvalidArgument);
}
m_target_muted[idx] = is_muted;
if (m_active_target == target) {
try {
auto& sink = system.AudioCore().GetOutputSink();
if (is_muted) {
sink.SetSystemVolume(0.0f);
sink.SetDeviceVolume(0.0f);
} else {
const float vol = static_cast<float>(m_target_volumes[idx]) / 15.0f;
sink.SetSystemVolume(vol);
sink.SetDeviceVolume(vol);
}
} catch (...) {
LOG_WARNING(Audio, "Failed to set sink system volume on mute change");
}
// Also update any open audout sessions via the audout:u service.
if (auto audout_mgr = system.ServiceManager().GetService<IAudioOutManager>("audout:u")) {
if (is_muted) {
audout_mgr->SetAllAudioOutVolume(0.0f);
} else {
const float vol = static_cast<float>(m_target_volumes[idx]) / 15.0f;
audout_mgr->SetAllAudioOutVolume(vol);
}
}
}
Settings::values.audio_muted.SetValue(is_muted);
R_SUCCEED();
}
Result IAudioController::GetActiveOutputTarget(Out<Set::AudioOutputModeTarget> out_active_target) {
LOG_DEBUG(Audio, "GetActiveOutputTarget called");
*out_active_target = m_active_target;
R_SUCCEED();
}
} // namespace Service::Audio } // namespace Service::Audio

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -38,11 +35,6 @@ private:
Result GetTargetVolumeMin(Out<s32> out_target_min_volume); Result GetTargetVolumeMin(Out<s32> out_target_min_volume);
Result GetTargetVolumeMax(Out<s32> out_target_max_volume); Result GetTargetVolumeMax(Out<s32> out_target_max_volume);
Result GetTargetVolume(Out<s32> out_target_volume, Set::AudioOutputModeTarget target);
Result SetTargetVolume(Set::AudioOutputModeTarget target, s32 target_volume);
Result IsTargetMute(Out<bool> out_is_target_muted, Set::AudioOutputModeTarget target);
Result SetTargetMute(bool is_muted, Set::AudioOutputModeTarget target);
Result GetActiveOutputTarget(Out<Set::AudioOutputModeTarget> out_active_target);
Result GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode, Result GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode,
Set::AudioOutputModeTarget target); Set::AudioOutputModeTarget target);
Result SetAudioOutputMode(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode); Result SetAudioOutputMode(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode);
@@ -63,9 +55,6 @@ private:
Kernel::KEvent* notification_event; Kernel::KEvent* notification_event;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
std::array<s32, 6> m_target_volumes{{15, 15, 15, 15, 15, 15}};
std::array<bool, 6> m_target_muted{{false, false, false, false, false, false}};
Set::AudioOutputModeTarget m_active_target{Set::AudioOutputModeTarget::Speaker};
}; };
} // namespace Service::Audio } // namespace Service::Audio

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -101,15 +98,4 @@ Result IAudioOutManager::OpenAudioOutAuto(
R_SUCCEED(); R_SUCCEED();
} }
Result IAudioOutManager::SetAllAudioOutVolume(f32 volume) {
std::scoped_lock l{impl->mutex};
for (auto& session : impl->sessions) {
if (session) {
session->GetSystem().SetVolume(volume);
}
}
R_SUCCEED();
}
} // namespace Service::Audio } // namespace Service::Audio

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -21,8 +18,6 @@ public:
explicit IAudioOutManager(Core::System& system_); explicit IAudioOutManager(Core::System& system_);
~IAudioOutManager() override; ~IAudioOutManager() override;
Result SetAllAudioOutVolume(f32 volume);
private: private:
Result ListAudioOuts(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_outs, Result ListAudioOuts(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_outs,
Out<u32> out_count); Out<u32> out_count);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -22,7 +19,6 @@ constexpr Result ResultInvalidAddressInfo{ErrorModule::Audio, 42};
constexpr Result ResultNotSupported{ErrorModule::Audio, 513}; constexpr Result ResultNotSupported{ErrorModule::Audio, 513};
constexpr Result ResultInvalidHandle{ErrorModule::Audio, 1536}; constexpr Result ResultInvalidHandle{ErrorModule::Audio, 1536};
constexpr Result ResultInvalidRevision{ErrorModule::Audio, 1537}; constexpr Result ResultInvalidRevision{ErrorModule::Audio, 1537};
constexpr Result ResultInvalidArgument{ErrorModule::Audio, 900};
constexpr Result ResultLibOpusAllocFail{ErrorModule::HwOpus, 7}; constexpr Result ResultLibOpusAllocFail{ErrorModule::HwOpus, 7};
constexpr Result ResultInputDataTooSmall{ErrorModule::HwOpus, 8}; constexpr Result ResultInputDataTooSmall{ErrorModule::HwOpus, 8};

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -56,7 +53,6 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
{8021, nullptr, "GetAlbumEntryFromApplicationAlbumEntryAruid"}, {8021, nullptr, "GetAlbumEntryFromApplicationAlbumEntryAruid"},
{10011, nullptr, "SetInternalErrorConversionEnabled"}, {10011, nullptr, "SetInternalErrorConversionEnabled"},
{50000, nullptr, "LoadMakerNoteInfoForDebug"}, {50000, nullptr, "LoadMakerNoteInfoForDebug"},
{50011, C<&IAlbumAccessorService::GetAlbumAccessResultForDebug>, "GetAlbumAccessResultForDebug"},
{60002, nullptr, "OpenAccessorSession"}, {60002, nullptr, "OpenAccessorSession"},
}; };
// clang-format on // clang-format on
@@ -201,11 +197,4 @@ Result IAlbumAccessorService::TranslateResult(Result in_result) {
return in_result; return in_result;
} }
Result IAlbumAccessorService::GetAlbumAccessResultForDebug(Out<Result> out_result) {
LOG_WARNING(Service_Capture, "(STUBBED) called");
*out_result = ResultSuccess;
R_SUCCEED();
}
} // namespace Service::Capture } // namespace Service::Capture

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -55,8 +52,6 @@ private:
Result TranslateResult(Result in_result); Result TranslateResult(Result in_result);
Result GetAlbumAccessResultForDebug(Out<Result> out_result);
std::shared_ptr<AlbumManager> manager = nullptr; std::shared_ptr<AlbumManager> manager = nullptr;
}; };

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -153,17 +150,16 @@ private:
class INpnsUser final : public ServiceFramework<INpnsUser> { class INpnsUser final : public ServiceFramework<INpnsUser> {
public: public:
explicit INpnsUser(Core::System& system_) explicit INpnsUser(Core::System& system_) : ServiceFramework{system_, "npns:u"} {
: ServiceFramework{system_, "npns:u"}, service_context{system, "npns:u"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{1, nullptr, "ListenAll"}, {1, nullptr, "ListenAll"},
{2, nullptr, "ListenTo"}, {2, nullptr, "ListenTo"},
{3, nullptr, "Receive"}, {3, nullptr, "Receive"},
{4, nullptr, "ReceiveRaw"}, {4, nullptr, "ReceiveRaw"},
{5, C<&INpnsUser::GetReceiveEvent>, "GetReceiveEvent"}, {5, nullptr, "GetReceiveEvent"},
{7, nullptr, "GetStateChangeEvent"}, {7, nullptr, "GetStateChangeEvent"},
{8, C<&INpnsUser::ListenToByName>, "ListenToByName"}, // 18.0.0+ {8, nullptr, "ListenToByName"}, // 18.0.0+
{21, nullptr, "CreateToken"}, {21, nullptr, "CreateToken"},
{23, nullptr, "DestroyToken"}, {23, nullptr, "DestroyToken"},
{25, nullptr, "QueryIsTokenValid"}, {25, nullptr, "QueryIsTokenValid"},
@@ -182,33 +178,7 @@ public:
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
get_receive_event = service_context.CreateEvent("npns:u:GetReceiveEvent");
} }
~INpnsUser() override {
service_context.CloseEvent(get_receive_event);
}
private:
Result ListenToByName(InBuffer<BufferAttr_HipcMapAlias> name_buffer) {
const std::string name(reinterpret_cast<const char*>(name_buffer.data()), name_buffer.size());
LOG_DEBUG(Service_NPNS, "called, name={}", name);
// Store the name for future use if needed
// For now, just acknowledge the registration
R_SUCCEED();
}
Result GetReceiveEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_DEBUG(Service_NPNS, "called");
*out_event = &get_receive_event->GetReadableEvent();
R_SUCCEED();
}
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* get_receive_event;
}; };
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {

View File

@@ -4,7 +4,6 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/nca_metadata.h" #include "core/file_sys/nca_metadata.h"
#include "core/file_sys/registered_cache.h" #include "core/file_sys/registered_cache.h"
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
@@ -12,7 +11,6 @@
#include "core/hle/service/ns/application_manager_interface.h" #include "core/hle/service/ns/application_manager_interface.h"
#include "core/hle/service/ns/content_management_interface.h" #include "core/hle/service/ns/content_management_interface.h"
#include "core/hle/service/ns/read_only_application_control_data_interface.h" #include "core/hle/service/ns/read_only_application_control_data_interface.h"
#include "core/file_sys/patch_manager.h"
namespace Service::NS { namespace Service::NS {
@@ -21,8 +19,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
service_context{system, "IApplicationManagerInterface"}, service_context{system, "IApplicationManagerInterface"},
record_update_system_event{service_context}, sd_card_mount_status_event{service_context}, record_update_system_event{service_context}, sd_card_mount_status_event{service_context},
gamecard_update_detection_event{service_context}, gamecard_update_detection_event{service_context},
gamecard_mount_status_event{service_context}, gamecard_mount_failure_event{service_context}, gamecard_mount_status_event{service_context}, gamecard_mount_failure_event{service_context} {
gamecard_waken_ready_event{service_context}, unknown_event{service_context} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IApplicationManagerInterface::ListApplicationRecord>, "ListApplicationRecord"}, {0, D<&IApplicationManagerInterface::ListApplicationRecord>, "ListApplicationRecord"},
@@ -45,7 +42,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{26, nullptr, "BeginInstallApplication"}, {26, nullptr, "BeginInstallApplication"},
{27, nullptr, "DeleteApplicationRecord"}, {27, nullptr, "DeleteApplicationRecord"},
{30, nullptr, "RequestApplicationUpdateInfo"}, {30, nullptr, "RequestApplicationUpdateInfo"},
{31, nullptr, "RequestUpdateApplication"}, {31, nullptr, "Unknown31"},
{32, nullptr, "CancelApplicationDownload"}, {32, nullptr, "CancelApplicationDownload"},
{33, nullptr, "ResumeApplicationDownload"}, {33, nullptr, "ResumeApplicationDownload"},
{35, nullptr, "UpdateVersionList"}, {35, nullptr, "UpdateVersionList"},
@@ -141,8 +138,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{508, nullptr, "GetLastGameCardMountFailureResult"}, {508, nullptr, "GetLastGameCardMountFailureResult"},
{509, nullptr, "ListApplicationIdOnGameCard"}, {509, nullptr, "ListApplicationIdOnGameCard"},
{510, nullptr, "GetGameCardPlatformRegion"}, {510, nullptr, "GetGameCardPlatformRegion"},
{511, D<&IApplicationManagerInterface::GetGameCardWakenReadyEvent>, "GetGameCardWakenReadyEvent"},
{512, D<&IApplicationManagerInterface::IsGameCardApplicationRunning>, "IsGameCardApplicationRunning"},
{600, nullptr, "CountApplicationContentMeta"}, {600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"}, {601, nullptr, "ListApplicationContentMetaStatus"},
{602, nullptr, "ListAvailableAddOnContent"}, {602, nullptr, "ListAvailableAddOnContent"},
@@ -167,7 +162,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{901, nullptr, "GetApplicationRecordProperty"}, {901, nullptr, "GetApplicationRecordProperty"},
{902, nullptr, "EnableApplicationAutoUpdate"}, {902, nullptr, "EnableApplicationAutoUpdate"},
{903, nullptr, "DisableApplicationAutoUpdate"}, {903, nullptr, "DisableApplicationAutoUpdate"},
{904, D<&IApplicationManagerInterface::TouchApplication>, "TouchApplication"}, {904, nullptr, "TouchApplication"},
{905, nullptr, "RequestApplicationUpdate"}, {905, nullptr, "RequestApplicationUpdate"},
{906, D<&IApplicationManagerInterface::IsApplicationUpdateRequested>, "IsApplicationUpdateRequested"}, {906, D<&IApplicationManagerInterface::IsApplicationUpdateRequested>, "IsApplicationUpdateRequested"},
{907, nullptr, "WithdrawApplicationUpdateRequest"}, {907, nullptr, "WithdrawApplicationUpdateRequest"},
@@ -334,7 +329,7 @@ Result IApplicationManagerInterface::GetApplicationControlData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) { ApplicationControlSource application_control_source, u64 application_id) {
LOG_DEBUG(Service_NS, "called"); LOG_DEBUG(Service_NS, "called");
R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationControlData( R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationControlDataOld(
out_buffer, out_actual_size, application_control_source, application_id)); out_buffer, out_actual_size, application_control_source, application_id));
} }
@@ -408,19 +403,6 @@ Result IApplicationManagerInterface::GetGameCardMountFailureEvent(
R_SUCCEED(); R_SUCCEED();
} }
Result IApplicationManagerInterface::GetGameCardWakenReadyEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_event = gamecard_waken_ready_event.GetHandle();
R_SUCCEED();
}
Result IApplicationManagerInterface::IsGameCardApplicationRunning(Out<bool> out_is_running) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_is_running = false;
R_SUCCEED();
}
Result IApplicationManagerInterface::IsAnyApplicationEntityInstalled( Result IApplicationManagerInterface::IsAnyApplicationEntityInstalled(
Out<bool> out_is_any_application_entity_installed) { Out<bool> out_is_any_application_entity_installed) {
LOG_WARNING(Service_NS, "(STUBBED) called"); LOG_WARNING(Service_NS, "(STUBBED) called");
@@ -544,11 +526,6 @@ Result IApplicationManagerInterface::GetStorageSize(Out<s64> out_total_space_siz
R_SUCCEED(); R_SUCCEED();
} }
Result IApplicationManagerInterface::TouchApplication(u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id);
R_SUCCEED();
}
Result IApplicationManagerInterface::IsApplicationUpdateRequested(Out<bool> out_update_required, Result IApplicationManagerInterface::IsApplicationUpdateRequested(Out<bool> out_update_required,
Out<u32> out_update_version, Out<u32> out_update_version,
u64 application_id) { u64 application_id) {
@@ -572,18 +549,14 @@ Result IApplicationManagerInterface::GetApplicationTerminateResult(Out<Result> o
Result IApplicationManagerInterface::RequestDownloadApplicationControlDataInBackground( Result IApplicationManagerInterface::RequestDownloadApplicationControlDataInBackground(
u64 control_source, u64 application_id) { u64 control_source, u64 application_id) {
LOG_INFO(Service_NS, "called, control_source={} app={:016X}", LOG_WARNING(Service_NS, "(STUBBED), control_source={} app={:016X}", control_source, application_id);
control_source, application_id);
unknown_event.Signal();
R_SUCCEED(); R_SUCCEED();
} }
Result IApplicationManagerInterface::Unknown4022( Result IApplicationManagerInterface::Unknown4022(
OutCopyHandle<Kernel::KReadableEvent> out_event) { OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called"); LOG_WARNING(Service_NS, "(STUBBED) called");
unknown_event.Signal(); *out_event = gamecard_update_detection_event.GetHandle();
*out_event = unknown_event.GetHandle();
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -32,8 +32,6 @@ public:
Out<s32> out_count, s32 offset); Out<s32> out_count, s32 offset);
Result GetApplicationRecordUpdateSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); Result GetApplicationRecordUpdateSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetGameCardMountFailureEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); Result GetGameCardMountFailureEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetGameCardWakenReadyEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsGameCardApplicationRunning(Out<bool> out_is_running);
Result IsAnyApplicationEntityInstalled(Out<bool> out_is_any_application_entity_installed); Result IsAnyApplicationEntityInstalled(Out<bool> out_is_any_application_entity_installed);
Result GetApplicationViewDeprecated( Result GetApplicationViewDeprecated(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views, OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
@@ -54,7 +52,6 @@ public:
Result ResumeAll(); Result ResumeAll();
Result GetStorageSize(Out<s64> out_total_space_size, Out<s64> out_free_space_size, Result GetStorageSize(Out<s64> out_total_space_size, Out<s64> out_free_space_size,
FileSys::StorageId storage_id); FileSys::StorageId storage_id);
Result TouchApplication(u64 application_id);
Result IsApplicationUpdateRequested(Out<bool> out_update_required, Out<u32> out_update_version, Result IsApplicationUpdateRequested(Out<bool> out_update_required, Out<u32> out_update_version,
u64 application_id); u64 application_id);
Result CheckApplicationLaunchVersion(u64 application_id); Result CheckApplicationLaunchVersion(u64 application_id);
@@ -63,7 +60,7 @@ public:
Result Unknown4023(Out<u64> out_result); Result Unknown4023(Out<u64> out_result);
Result Unknown4053(); Result Unknown4053();
Result RequestDownloadApplicationControlDataInBackground(u64 control_source, Result RequestDownloadApplicationControlDataInBackground(u64 unk,
u64 application_id); u64 application_id);
private: private:
@@ -73,8 +70,6 @@ private:
Event gamecard_update_detection_event; Event gamecard_update_detection_event;
Event gamecard_mount_status_event; Event gamecard_mount_status_event;
Event gamecard_mount_failure_event; Event gamecard_mount_failure_event;
Event gamecard_waken_ready_event;
Event unknown_event;
}; };
} // namespace Service::NS } // namespace Service::NS

View File

@@ -22,13 +22,13 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
: ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlData>, "GetApplicationControlData"}, {0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataOld>, "GetApplicationControlDataOld"},
{1, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"}, {1, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"},
{2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"}, {2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{4, nullptr, "SelectApplicationDesiredLanguage"}, {4, nullptr, "SelectApplicationDesiredLanguage"},
{5, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithoutIcon>, "GetApplicationControlDataWithoutIcon"}, {5, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithoutIcon>, "GetApplicationControlDataWithIconSize"},
{19, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithoutIcon>, "GetApplicationControlDataWithoutIcon"}, {19, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithoutIcon>, "GetApplicationControlDataWithIconSize"},
}; };
// clang-format on // clang-format on
@@ -37,7 +37,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData( Result IReadOnlyApplicationControlDataInterface::GetApplicationControlDataOld(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) { ApplicationControlSource application_control_source, u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}", LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
@@ -125,8 +125,8 @@ Result IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLan
R_SUCCEED(); R_SUCCEED();
} }
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithoutIcon( Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u64> out_total_size, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) { ApplicationControlSource application_control_source, u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}", LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
application_control_source, application_id); application_control_source, application_id);
@@ -136,44 +136,57 @@ Result IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithou
const auto control = pm.GetControlMetadata(); const auto control = pm.GetControlMetadata();
const auto size = out_buffer.size(); const auto size = out_buffer.size();
const auto nacp_size = sizeof(FileSys::RawNACP); const auto icon_size = control.second ? control.second->GetSize() : 0;
const auto total_size = sizeof(FileSys::RawNACP) + icon_size;
if (size < nacp_size) { if (size < total_size) {
LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min={:08X})", LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)",
size, nacp_size); size);
R_THROW(ResultUnknown); R_THROW(ResultUnknown);
} }
if (control.first != nullptr) { if (control.first != nullptr) {
const auto bytes = control.first->GetRawBytes(); const auto bytes = control.first->GetRawBytes();
const auto copy_len = (std::min)(static_cast<size_t>(bytes.size()), static_cast<size_t>(nacp_size)); std::memcpy(out_buffer.data(), bytes.data(), bytes.size());
std::memcpy(out_buffer.data(), bytes.data(), copy_len);
if (copy_len < nacp_size) {
std::memset(out_buffer.data() + copy_len, 0, nacp_size - copy_len);
}
} else { } else {
LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero", LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero",
application_id); application_id);
std::memset(out_buffer.data(), 0, nacp_size); std::memset(out_buffer.data(), 0, sizeof(FileSys::RawNACP));
} }
const auto icon_area_size = size - nacp_size; if (control.second != nullptr) {
if (icon_area_size > 0) { control.second->Read(out_buffer.data() + sizeof(FileSys::RawNACP), icon_size);
if (control.second != nullptr) { } else {
const auto icon_size = control.second->GetSize(); LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id);
const auto to_copy = static_cast<size_t>((std::min)(icon_size, icon_area_size));
control.second->Read(out_buffer.data() + nacp_size, to_copy);
if (to_copy < icon_area_size) {
std::memset(out_buffer.data() + nacp_size + to_copy, 0, icon_area_size - to_copy);
}
} else {
std::memset(out_buffer.data() + nacp_size, 0, icon_area_size);
LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}, zero-filling icon area",
application_id);
}
} }
*out_total_size = static_cast<u64>(size); *out_actual_size = static_cast<u32>(total_size);
R_SUCCEED();
}
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithoutIcon(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u64> out_total_size,
ApplicationControlSource application_control_source,
u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
application_control_source, application_id);
constexpr size_t kExpectedBufferSize = 0x14000;
constexpr size_t kNACPSize = sizeof(FileSys::RawNACP);
const FileSys::PatchManager pm{application_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
if (control.first != nullptr) {
const auto bytes = control.first->GetRawBytes();
std::memcpy(out_buffer.data(), bytes.data(), bytes.size());
} else {
std::memset(out_buffer.data(), 0, kNACPSize);
}
*out_total_size = kExpectedBufferSize;
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -19,7 +19,7 @@ public:
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
~IReadOnlyApplicationControlDataInterface() override; ~IReadOnlyApplicationControlDataInterface() override;
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Result GetApplicationControlDataOld(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u32> out_actual_size, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, ApplicationControlSource application_control_source,
u64 application_id); u64 application_id);
@@ -27,6 +27,10 @@ public:
u32 supported_languages); u32 supported_languages);
Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code, Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code,
ApplicationLanguage application_language); ApplicationLanguage application_language);
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u32> out_actual_size,
ApplicationControlSource application_control_source,
u64 application_id);
Result GetApplicationControlDataWithoutIcon( Result GetApplicationControlDataWithoutIcon(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u64> out_total_size, Out<u64> out_total_size,

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -15,7 +12,7 @@ struct Layer {
explicit Layer(std::shared_ptr<android::BufferItemConsumer> buffer_item_consumer_, explicit Layer(std::shared_ptr<android::BufferItemConsumer> buffer_item_consumer_,
s32 consumer_id_) s32 consumer_id_)
: buffer_item_consumer(std::move(buffer_item_consumer_)), consumer_id(consumer_id_), : buffer_item_consumer(std::move(buffer_item_consumer_)), consumer_id(consumer_id_),
blending(LayerBlending::None), visible(true), z_index(0) {} blending(LayerBlending::None), visible(true) {}
~Layer() { ~Layer() {
buffer_item_consumer->Abandon(); buffer_item_consumer->Abandon();
} }
@@ -24,7 +21,6 @@ struct Layer {
s32 consumer_id; s32 consumer_id;
LayerBlending blending; LayerBlending blending;
bool visible; bool visible;
s32 z_index;
}; };
struct LayerStack { struct LayerStack {

View File

@@ -95,6 +95,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
const auto& item = buffer.item; const auto& item = buffer.item;
const auto& igbp_buffer = *item.graphic_buffer; const auto& igbp_buffer = *item.graphic_buffer;
// TODO: get proper Z-index from layer
if (layer->visible) { if (layer->visible) {
composition_stack.emplace_back(HwcLayer{ composition_stack.emplace_back(HwcLayer{
.buffer_handle = igbp_buffer.BufferId(), .buffer_handle = igbp_buffer.BufferId(),
@@ -103,7 +104,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
.width = igbp_buffer.Width(), .width = igbp_buffer.Width(),
.height = igbp_buffer.Height(), .height = igbp_buffer.Height(),
.stride = igbp_buffer.Stride(), .stride = igbp_buffer.Stride(),
.z_index = layer->z_index, .z_index = 0,
.blending = layer->blending, .blending = layer->blending,
.transform = static_cast<android::BufferTransformFlags>(item.transform), .transform = static_cast<android::BufferTransformFlags>(item.transform),
.crop_rect = item.crop, .crop_rect = item.crop,
@@ -127,9 +128,9 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
// If any new buffers were acquired, we can present. // If any new buffers were acquired, we can present.
if (has_acquired_buffer && !composition_stack.empty()) { if (has_acquired_buffer && !composition_stack.empty()) {
// Sort back-to-front: lower z first, higher z last so top-most draws last (on top). // Sort by Z-index.
std::stable_sort(composition_stack.begin(), composition_stack.end(), std::stable_sort(composition_stack.begin(), composition_stack.end(),
[&](const HwcLayer& l, const HwcLayer& r) { return l.z_index < r.z_index; }); [&](auto& l, auto& r) { return l.z_index < r.z_index; });
// Composite. // Composite.
nvdisp.Composite(composition_stack); nvdisp.Composite(composition_stack);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -48,10 +45,9 @@ public:
void SetLayerVisibility(s32 consumer_binder_id, bool visible); void SetLayerVisibility(s32 consumer_binder_id, bool visible);
void SetLayerBlending(s32 consumer_binder_id, LayerBlending blending); void SetLayerBlending(s32 consumer_binder_id, LayerBlending blending);
std::shared_ptr<Layer> FindLayer(s32 consumer_binder_id);
private: private:
Display* FindDisplay(u64 display_id); Display* FindDisplay(u64 display_id);
std::shared_ptr<Layer> FindLayer(s32 consumer_binder_id);
public: public:
// TODO: these don't belong here // TODO: these don't belong here

View File

@@ -13,17 +13,16 @@ IDaemonController::IDaemonController(Core::System& system_)
: ServiceFramework{system_, "IDaemonController"} { : ServiceFramework{system_, "IDaemonController"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IDaemonController::GetApplicationAutoTransferSetting>, "GetApplicationAutoTransferSetting"}, {0, D<&IDaemonController::GetAutoTransferEnabledForAccountAndApplication>, "GetAutoTransferEnabledForAccountAndApplication"},
{1, D<&IDaemonController::SetApplicationAutoTransferSetting>, "SetApplicationAutoTransferSetting"}, {1, nullptr, "SetAutoTransferEnabledForAccountAndApplication"},
{2, D<&IDaemonController::GetGlobalAutoUploadSetting>, "GetGlobalAutoUploadSetting"}, {2, nullptr, "GetGlobalUploadEnabledForAccount"},
{3, D<&IDaemonController::SetGlobalAutoUploadSetting>, "SetGlobalAutoUploadSetting"}, {3, nullptr, "SetGlobalUploadEnabledForAccount"},
{4, D<&IDaemonController::RunTransferTaskAutonomyRegistration>, "RunTransferTaskAutonomyRegistration"}, {4, nullptr, "TouchAccount"},
{5, D<&IDaemonController::GetGlobalAutoDownloadSetting>, "GetGlobalAutoDownloadSetting"}, // 11.0.0+ {5, nullptr, "GetGlobalDownloadEnabledForAccount"},
{6, D<&IDaemonController::SetGlobalAutoDownloadSetting>, "SetGlobalAutoDownloadSetting"}, // 11.0.0+ {6, nullptr, "SetGlobalDownloadEnabledForAccount"},
{10, nullptr, "CreateForbiddenSaveDataInidication"}, {10, nullptr, "GetForbiddenSaveDataIndication"},
{11, nullptr, "StopAutonomyTaskExecution"}, {11, nullptr, "GetStopperObject"},
{12, D<&IDaemonController::GetAutonomyTaskStatus>, "GetAutonomyTaskStatus"}, {12, D<&IDaemonController::GetState>, "GetState"},
{13, nullptr, "Unknown13_20_0_0_Plus"}, // 20.0.0+
}; };
// clang-format on // clang-format on
@@ -32,73 +31,19 @@ IDaemonController::IDaemonController(Core::System& system_)
IDaemonController::~IDaemonController() = default; IDaemonController::~IDaemonController() = default;
Result IDaemonController::GetApplicationAutoTransferSetting(Out<bool> out_is_enabled, Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
Common::UUID user_id, Common::UUID user_id,
u64 application_id) { u64 application_id) {
LOG_INFO(Service_OLSC, "called, user_id={} application_id={:016X}", user_id.FormattedString(), LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}",
application_id); user_id.FormattedString(), application_id);
AppKey key{user_id, application_id}; *out_is_enabled = false;
const auto it = app_auto_transfer_.find(key);
*out_is_enabled = (it != app_auto_transfer_.end()) ? it->second : false;
R_SUCCEED(); R_SUCCEED();
} }
Result IDaemonController::SetApplicationAutoTransferSetting(bool is_enabled, Common::UUID user_id, Result IDaemonController::GetState(Out<u8> state, Common::UUID user_id, u64 application_id) {
u64 application_id) { LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}",
LOG_INFO(Service_OLSC, "called, user_id={} application_id={:016X} is_enabled={}", user_id.FormattedString(), application_id);
user_id.FormattedString(), application_id, is_enabled); *state = 0;
AppKey key{user_id, application_id};
app_auto_transfer_[key] = is_enabled;
R_SUCCEED();
}
Result IDaemonController::GetGlobalAutoUploadSetting(Out<bool> out_is_enabled,
Common::UUID user_id) {
LOG_INFO(Service_OLSC, "called, user_id={}", user_id.FormattedString());
const auto it = global_auto_upload_.find(user_id);
*out_is_enabled = (it != global_auto_upload_.end()) ? it->second : false;
R_SUCCEED();
}
Result IDaemonController::SetGlobalAutoUploadSetting(bool is_enabled, Common::UUID user_id) {
LOG_INFO(Service_OLSC, "called, user_id={} is_enabled={}", user_id.FormattedString(), is_enabled);
global_auto_upload_[user_id] = is_enabled;
R_SUCCEED();
}
Result IDaemonController::RunTransferTaskAutonomyRegistration(Common::UUID user_id,
u64 application_id) {
LOG_INFO(Service_OLSC, "called, user_id={} application_id={:016X}", user_id.FormattedString(),
application_id);
// Simulate starting an autonomy task: set status to 1 (running) then back to 0 (idle)
AppKey key{user_id, application_id};
autonomy_task_status_[key] = 1; // running
// TODO: In a real implementation this would be asynchronous. We'll immediately set to idle.
autonomy_task_status_[key] = 0; // idle
R_SUCCEED();
}
Result IDaemonController::GetGlobalAutoDownloadSetting(Out<bool> out_is_enabled,
Common::UUID user_id) {
LOG_INFO(Service_OLSC, "called, user_id={}", user_id.FormattedString());
const auto it = global_auto_download_.find(user_id);
*out_is_enabled = (it != global_auto_download_.end()) ? it->second : false;
R_SUCCEED();
}
Result IDaemonController::SetGlobalAutoDownloadSetting(bool is_enabled, Common::UUID user_id) {
LOG_INFO(Service_OLSC, "called, user_id={} is_enabled={}", user_id.FormattedString(), is_enabled);
global_auto_download_[user_id] = is_enabled;
R_SUCCEED();
}
Result IDaemonController::GetAutonomyTaskStatus(Out<u8> out_state, Common::UUID user_id,
u64 application_id) {
LOG_INFO(Service_OLSC, "called, user_id={} application_id={:016X}", user_id.FormattedString(),
application_id);
AppKey key{user_id, application_id};
const auto it = autonomy_task_status_.find(key);
*out_state = (it != autonomy_task_status_.end()) ? it->second : 0; // default idle
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -1,12 +1,9 @@
#pragma once
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <unordered_map>
#include "common/uuid.h" #include "common/uuid.h"
#include "core/hle/service/cmif_types.h" #include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
@@ -19,43 +16,9 @@ public:
~IDaemonController() override; ~IDaemonController() override;
private: private:
Result GetApplicationAutoTransferSetting(Out<bool> out_is_enabled, Common::UUID user_id, Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
u64 application_id); Common::UUID user_id, u64 application_id);
Result SetApplicationAutoTransferSetting(bool is_enabled, Common::UUID user_id, Result GetState(Out<u8> state, Common::UUID user_id, u64 application_id);
u64 application_id);
Result GetGlobalAutoUploadSetting(Out<bool> out_is_enabled, Common::UUID user_id);
Result SetGlobalAutoUploadSetting(bool is_enabled, Common::UUID user_id);
Result RunTransferTaskAutonomyRegistration(Common::UUID user_id, u64 application_id);
Result GetGlobalAutoDownloadSetting(Out<bool> out_is_enabled, Common::UUID user_id);
Result SetGlobalAutoDownloadSetting(bool is_enabled, Common::UUID user_id);
Result GetAutonomyTaskStatus(Out<u8> out_state, Common::UUID user_id, u64 application_id);
// Internal in-memory state to back the above APIs
struct AppKey {
Common::UUID user_id;
u64 application_id{};
friend constexpr bool operator==(const AppKey& a, const AppKey& b) {
return a.user_id == b.user_id && a.application_id == b.application_id;
}
};
struct AppKeyHash {
size_t operator()(const AppKey& k) const noexcept {
// Combine UUID hash and application_id
size_t h1 = std::hash<Common::UUID>{}(k.user_id);
size_t h2 = std::hash<u64>{}(k.application_id);
// Simple hash combine
return h1 ^ (h2 + 0x9e3779b97f4a7c15ULL + (h1 << 6) + (h1 >> 2));
}
};
std::unordered_map<AppKey, bool, AppKeyHash> app_auto_transfer_{};
std::unordered_map<Common::UUID, bool> global_auto_upload_{};
std::unordered_map<Common::UUID, bool> global_auto_download_{};
std::unordered_map<AppKey, u8, AppKeyHash> autonomy_task_status_{};
}; };
} // namespace Service::OLSC } // namespace Service::OLSC

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -21,13 +18,4 @@ union MessageFlags {
}; };
static_assert(sizeof(MessageFlags) == 0x8, "MessageFlags has incorrect size"); static_assert(sizeof(MessageFlags) == 0x8, "MessageFlags has incorrect size");
struct SourceName {
char name[0x16];
const char* GetString() const {
return name;
}
};
;
} // namespace Service::PSC } // namespace Service::PSC

View File

@@ -1,118 +1,24 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/psc/ovln/receiver.h" #include "core/hle/service/psc/ovln/receiver.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::PSC { namespace Service::PSC {
IReceiver::IReceiver(Core::System& system_) IReceiver::IReceiver(Core::System& system_) : ServiceFramework{system_, "IReceiver"} {
: ServiceFramework{system_, "IReceiver"}, service_context{system_, "IReceiver"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IReceiver::AddSource>, "AddSource"}, {0, nullptr, "AddSource"},
{1, D<&IReceiver::RemoveSource>, "RemoveSource"}, {1, nullptr, "RemoveSource"},
{2, D<&IReceiver::GetReceiveEventHandle>, "GetReceiveEventHandle"}, {2, nullptr, "GetReceiveEventHandle"},
{3, D<&IReceiver::Receive>, "Receive"}, {3, nullptr, "Receive"},
{4, D<&IReceiver::ReceiveWithTick>, "ReceiveWithTick"}, {4, nullptr, "ReceiveWithTick"},
}; };
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
receive_event = service_context.CreateEvent("IReceiver::ReceiveEvent");
} }
IReceiver::~IReceiver() { IReceiver::~IReceiver() = default;
service_context.CloseEvent(receive_event);
}
Result IReceiver::AddSource(SourceName source_name) {
const std::string name = source_name.GetString();
LOG_INFO(Service_PSC, "called: source_name={}", name);
// Add source if it doesn't already exist
if (message_sources.find(name) == message_sources.end()) {
message_sources[name] = {};
}
R_SUCCEED();
}
Result IReceiver::RemoveSource(SourceName source_name) {
const std::string name = source_name.GetString();
LOG_INFO(Service_PSC, "called: source_name={}", name);
// Remove source if it exists
message_sources.erase(name);
R_SUCCEED();
}
Result IReceiver::GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_INFO(Service_PSC, "called");
*out_event = &receive_event->GetReadableEvent();
R_SUCCEED();
}
Result IReceiver::Receive(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags) {
u64 tick;
return ReceiveWithTick(out_notification, out_flags, Out<u64>(&tick));
}
Result IReceiver::ReceiveWithTick(Out<OverlayNotification> out_notification,
Out<MessageFlags> out_flags, Out<u64> out_tick) {
LOG_DEBUG(Service_PSC, "called");
// Find the message with the lowest ID across all sources
const std::string* target_source = nullptr;
size_t target_index = 0;
for (const auto& [source_name, messages] : message_sources) {
if (!messages.empty()) {
if (target_source == nullptr) {
target_source = &source_name;
target_index = 0;
}
// Note: In the real implementation, we would track message IDs
// For now, just use FIFO order
}
}
if (target_source != nullptr) {
auto& messages = message_sources[*target_source];
*out_notification = messages[target_index].first;
*out_flags = messages[target_index].second;
*out_tick = 0; // TODO: Implement tick tracking
// Remove the message
messages.erase(messages.begin() + target_index);
// Clear event if no more messages
bool has_messages = false;
for (const auto& [_, msgs] : message_sources) {
if (!msgs.empty()) {
has_messages = true;
break;
}
}
if (!has_messages) {
receive_event->Clear();
}
R_SUCCEED();
}
// No messages available
*out_notification = {};
*out_flags = {};
*out_tick = 0;
LOG_WARNING(Service_PSC, "No messages available");
R_THROW(ResultUnknown); // TODO: Use proper OvlnResult::NoMessages when available
}
} // namespace Service::PSC } // namespace Service::PSC

View File

@@ -1,23 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <map>
#include <memory>
#include <string>
#include "core/hle/result.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "core/hle/service/psc/ovln/ovln_types.h"
namespace Kernel {
class KReadableEvent;
}
namespace Service::PSC { namespace Service::PSC {
@@ -25,22 +11,6 @@ class IReceiver final : public ServiceFramework<IReceiver> {
public: public:
explicit IReceiver(Core::System& system_); explicit IReceiver(Core::System& system_);
~IReceiver() override; ~IReceiver() override;
IReceiver(const IReceiver&) = delete;
IReceiver& operator=(const IReceiver&) = delete;
private:
Result AddSource(SourceName source_name);
Result RemoveSource(SourceName source_name);
Result GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result Receive(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags);
Result ReceiveWithTick(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags,
Out<u64> out_tick);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* receive_event;
std::map<std::string, std::vector<std::pair<OverlayNotification, MessageFlags>>> message_sources;
}; };
} // namespace Service::PSC } // namespace Service::PSC

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -24,7 +21,7 @@ IReceiverService::~IReceiverService() = default;
Result IReceiverService::OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver) { Result IReceiverService::OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver) {
LOG_DEBUG(Service_PSC, "called"); LOG_DEBUG(Service_PSC, "called");
*out_receiver = std::shared_ptr<IReceiver>(new IReceiver(system)); *out_receiver = std::make_shared<IReceiver>(system);
R_SUCCEED(); R_SUCCEED();
} }

Some files were not shown because too many files have changed in this diff Show More