Compare commits

..

2 Commits

Author SHA1 Message Date
crueter bddb51bf1a Oopsies
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-06-11 02:57:50 -04:00
crueter 308c7ebb7a [ci] Fix update-deps workflow
me when spaces

Signed-off-by: crueter <crueter@eden-emu.dev>
2026-06-11 02:57:37 -04:00
74 changed files with 437 additions and 1213 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
}
EOF
curl -X 'POST' \
curl -XPOST \
'https://git.eden-emu.dev/api/v1/repos/eden-emu/eden/pulls' \
-H 'accept: application/json' \
-H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \
+8 -5
View File
@@ -1,4 +1,4 @@
name: update-deps
name: Update Dependencies
on:
# saturday at noon
@@ -7,7 +7,7 @@ on:
workflow_dispatch:
jobs:
tx-update:
update-deps:
runs-on: source
steps:
- uses: actions/checkout@v4
@@ -24,18 +24,21 @@ jobs:
git remote set-url origin ci:eden-emu/eden.git
DATE=$(date +"%b %d")
TIMESTAMP=$(date +"%s")
echo "DATE=$DATE" >> "$GITHUB_ENV"
echo "TIMESTAMP=$TIMESTAMP" >> "$GITHUB_ENV"
git switch -c update-deps-$DATE
git switch -c update-deps-$TIMESTAMP
tools/cpmutil.sh package update -ac
git push
- name: Create PR
run: |
set -x
TITLE="[externals] Dependency update for $DATE"
BODY="$(git show -s --format='%b')"
BASE=master
HEAD=update-deps-$DATE
HEAD=update-deps-$TIMESTAMP
cat << EOF > data.json
{
@@ -46,7 +49,7 @@ jobs:
}
EOF
curl -X 'POST' \
curl -XPOST \
'https://git.eden-emu.dev/api/v1/repos/eden-emu/eden/pulls' \
-H 'accept: application/json' \
-H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \
+38 -28
View File
@@ -128,7 +128,8 @@ function(AddDependentPackages)
message(FATAL_ERROR "Partial dependency installation detected "
"for the following packages:\n${package_names}\n"
"You can solve this in one of two ways:\n"
"1. Install the following packages to your system if available:"
"1. Install or upgrade the following packages "
"to your system if available:"
"\n\t${bundled_names}\n"
"2. Set the following variables to ON:"
"\n\t${system_names}\n"
@@ -247,9 +248,9 @@ function(AddJsonPackage)
set(multiValueArgs OPTIONS)
set(options MODULE)
set(optionArgs MODULE)
cmake_parse_arguments(JSON "${options}" "${oneValueArgs}" "${multiValueArgs}"
cmake_parse_arguments(JSON "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}"
"${ARGN}")
list(LENGTH ARGN argnLength)
@@ -278,11 +279,11 @@ function(AddJsonPackage)
parse_object(${object})
if(ci)
if (JSON_MODULE)
set(EXTRA_ARGS MODULE)
endif()
if (JSON_MODULE)
set(EXTRA_ARGS MODULE)
endif()
if(ci)
AddCIPackage(
VERSION ${version}
NAME ${name}
@@ -313,23 +314,24 @@ function(AddJsonPackage)
FORCE_BUNDLED_PACKAGE "${JSON_FORCE_BUNDLED_PACKAGE}"
SOURCE_SUBDIR "${source_subdir}"
GIT_VERSION ${git_version}
GIT_HOST ${git_host}
GIT_VERSION "${git_version}"
GIT_HOST "${git_host}"
ARTIFACT ${artifact}
TAG ${tag})
ARTIFACT "${artifact}"
TAG "${tag}"
${EXTRA_ARGS})
endif()
# pass stuff to parent scope
Propagate(${package}_ADDED)
Propagate(${package}_SOURCE_DIR)
Propagate(${package}_BINARY_DIR)
Propagate(CMAKE_PREFIX_PATH)
endfunction()
function(AddPackage)
cpm_set_policies()
# TODO(crueter): git clone?
set(EXTRA_ARGS "")
#[[
URL configurations, descending order of precedence:
@@ -374,7 +376,9 @@ function(AddPackage)
set(multiValueArgs OPTIONS PATCHES)
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "${multiValueArgs}"
set(optionArgs MODULE)
cmake_parse_arguments(PKG_ARGS "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}"
"${ARGN}")
if(NOT DEFINED PKG_ARGS_NAME)
@@ -558,6 +562,12 @@ function(AddPackage)
VERSION ${PKG_ARGS_VERSION})
endif()
if (PKG_ARGS_MODULE)
set(PKG_ARGS_DOWNLOAD_ONLY ON)
elseif (NOT DEFINED PKG_ARGS_DOWNLOAD_ONLY)
set(PKG_ARGS_DOWNLOAD_ONLY OFF)
endif()
CPMAddPackage(
NAME ${PKG_ARGS_NAME}
URL ${pkg_url}
@@ -607,13 +617,14 @@ function(AddPackage)
endif()
# pass stuff to parent scope
set(${PKG_ARGS_NAME}_ADDED "${${PKG_ARGS_NAME}_ADDED}"
PARENT_SCOPE)
set(${PKG_ARGS_NAME}_SOURCE_DIR "${${PKG_ARGS_NAME}_SOURCE_DIR}"
PARENT_SCOPE)
set(${PKG_ARGS_NAME}_BINARY_DIR "${${PKG_ARGS_NAME}_BINARY_DIR}"
PARENT_SCOPE)
Propagate(${PKG_ARGS_NAME}_ADDED)
Propagate(${PKG_ARGS_NAME}_SOURCE_DIR)
Propagate(${PKG_ARGS_NAME}_BINARY_DIR)
if (PKG_ARGS_MODULE)
list(PREPEND CMAKE_PREFIX_PATH "${${ARTIFACT_PACKAGE}_SOURCE_DIR}")
Propagate(CMAKE_PREFIX_PATH)
endif()
endfunction()
# TODO(crueter): we could do an AddMultiArchPackage, multiplatformpackage?
@@ -706,6 +717,10 @@ function(AddCIPackage)
set(ARTIFACT
"${ARTIFACT_NAME}-${pkgname}-${ARTIFACT_VERSION}.${ARTIFACT_EXT}")
if (PKG_ARGS_MODULE)
set(EXTRA_ARGS MODULE)
endif()
AddPackage(
NAME ${ARTIFACT_PACKAGE}
REPO ${ARTIFACT_REPO}
@@ -716,16 +731,11 @@ function(AddCIPackage)
KEY "${pkgname}-${ARTIFACT_VERSION}"
HASH_SUFFIX sha512sum
FORCE_BUNDLED_PACKAGE ON
DOWNLOAD_ONLY ${PKG_ARGS_MODULE})
${EXTRA_ARGS})
set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE)
set(${ARTIFACT_PACKAGE}_SOURCE_DIR
"${${ARTIFACT_PACKAGE}_SOURCE_DIR}" PARENT_SCOPE)
if (PKG_ARGS_MODULE)
list(PREPEND CMAKE_PREFIX_PATH "${${ARTIFACT_PACKAGE}_SOURCE_DIR}")
Propagate(CMAKE_PREFIX_PATH)
endif()
Propagate(${ARTIFACT_PACKAGE}_SOURCE_DIR)
Propagate(CMAKE_PREFIX_PATH)
else()
find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED)
endif()
-184
View File
@@ -1,184 +0,0 @@
; SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
; SPDX-License-Identifier: GPL-3.0-or-later
; Usage:
; get the latest nsis: https://nsis.sourceforge.io/Download
; Require these for makensis.
!ifndef PRODUCT_VERSION
!error "PRODUCT_VERSION must be defined"
!endif
!ifndef ARCH
!error "ARCH must be defined"
!endif
!ifndef VARIANT
!error "VARIANT must be defined"
!endif
Unicode true
ManifestDPIAware true
!define PRODUCT_NAME "Eden"
!define PRODUCT_PUBLISHER "Utopia LLC"
!define PRODUCT_WEB_SITE "https://git.eden-emu.dev"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_NAME}.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define BINARY_SOURCE_DIR "..\bin"
Name "${PRODUCT_NAME}"
OutFile "${PRODUCT_NAME}-Windows-${PRODUCT_VERSION}-${ARCH}-${VARIANT}-installer.exe"
SetCompressor /SOLID lzma
InstallDir "$LOCALAPPDATA\$(^Name)"
ShowInstDetails show
ShowUnInstDetails show
!include "MUI2.nsh"
; Custom page plugin
!include "nsDialogs.nsh"
; MUI Settings
!define MUI_ICON "eden.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
; License page
!insertmacro MUI_PAGE_LICENSE "..\LICENSE.txt"
; Desktop Shortcut page
Page custom desktopShortcutPageCreate desktopShortcutPageLeave
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_RUN "$INSTDIR\eden.exe"
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES
; Variables
Var DesktopShortcutPageDialog
Var DesktopShortcutCheckbox
Var DesktopShortcut
; Language files
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "TradChinese"
!insertmacro MUI_LANGUAGE "Danish"
!insertmacro MUI_LANGUAGE "Dutch"
!insertmacro MUI_LANGUAGE "French"
!insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Hungarian"
!insertmacro MUI_LANGUAGE "Italian"
!insertmacro MUI_LANGUAGE "Japanese"
!insertmacro MUI_LANGUAGE "Korean"
!insertmacro MUI_LANGUAGE "Lithuanian"
!insertmacro MUI_LANGUAGE "Norwegian"
!insertmacro MUI_LANGUAGE "Polish"
!insertmacro MUI_LANGUAGE "PortugueseBR"
!insertmacro MUI_LANGUAGE "Romanian"
!insertmacro MUI_LANGUAGE "Russian"
!insertmacro MUI_LANGUAGE "Spanish"
!insertmacro MUI_LANGUAGE "Swedish"
!insertmacro MUI_LANGUAGE "Turkish"
!insertmacro MUI_LANGUAGE "Vietnamese"
; MUI end ------
Function .onInit
StrCpy $DesktopShortcut 1
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
Function desktopShortcutPageCreate
!insertmacro MUI_HEADER_TEXT "Create Desktop Shortcut" "Would you like to create a desktop shortcut?"
nsDialogs::Create 1018
Pop $DesktopShortcutPageDialog
${If} $DesktopShortcutPageDialog == error
Abort
${EndIf}
${NSD_CreateCheckbox} 0u 0u 100% 12u "Create a desktop shortcut"
Pop $DesktopShortcutCheckbox
${NSD_SetState} $DesktopShortcutCheckbox $DesktopShortcut
nsDialogs::Show
FunctionEnd
Function desktopShortcutPageLeave
${NSD_GetState} $DesktopShortcutCheckbox $DesktopShortcut
FunctionEnd
Section "Base"
ExecWait '"$INSTDIR\uninst.exe" /S _?=$INSTDIR'
SectionIn RO
SetOutPath "$INSTDIR"
; The binplaced build output will be included verbatim.
File /r "${BINARY_SOURCE_DIR}\*"
; Create start menu and desktop shortcuts
CreateShortCut "$SMPROGRAMS\$(^Name).lnk" "$INSTDIR\eden.exe"
${If} $DesktopShortcut == 1
CreateShortCut "$DESKTOP\$(^Name).lnk" "$INSTDIR\eden.exe"
${EndIf}
SectionEnd
!include "FileFunc.nsh"
Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKCU "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\eden.exe"
; Write metadata for add/remove programs applet
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\eden.exe"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "EstimatedSize" "$0"
WriteRegStr HKCU "Software\Classes\.nsp" "" "$(^Name)"
WriteRegStr HKCU "Software\Classes\.xci" "" "$(^Name)"
WriteRegStr HKCU "Software\Classes\.nro" "" "$(^Name)"
WriteRegStr HKCU "Software\Classes\.kip" "" "$(^Name)"
WriteRegStr HKCU "Software\Classes\$(^Name)\DefaultIcon" "" "$INSTDIR\eden.exe,0"
WriteRegStr HKCU "Software\Classes\$(^Name)\Shell\open\command" "" '"$INSTDIR\eden.exe" %1'
SectionEnd
Section Uninstall
Delete "$DESKTOP\$(^Name).lnk"
Delete "$SMPROGRAMS\$(^Name).lnk"
; Be a bit careful to not delete files a user may have put into the install directory.
Delete "$INSTDIR\eden.exe"
Delete "$INSTDIR\eden-cli.exe"
Delete "$INSTDIR\uninst.exe"
Delete "$INSTDIR\LICENSE.txt"
Delete "$INSTDIR\README.md"
RMDir /r "$INSTDIR\LICENSES"
RMDir "$INSTDIR"
DeleteRegKey HKCU "Software\Classes\.nsp"
DeleteRegKey HKCU "Software\Classes\.xci"
DeleteRegKey HKCU "Software\Classes\.nro"
DeleteRegKey HKCU "Software\Classes\.kip"
DeleteRegKey HKCU "Software\Classes\$(^Name)"
DeleteRegKey HKCU "Software\Classes\discord-1397286652128264252"
DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}"
SetAutoClose true
SectionEnd
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
@@ -11,7 +11,6 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
enum class StringSetting(override val key: String) : AbstractStringSetting {
DRIVER_PATH("driver_path"),
DEVICE_NAME("device_name"),
PROGRAM_ARGS("program_args"),
WEB_TOKEN("eden_token"),
WEB_USERNAME("eden_username")
@@ -125,13 +125,6 @@ abstract class SettingsItem(
// List of all general
val settingsItems = HashMap<String, SettingsItem>().apply {
put(StringInputSetting(StringSetting.DEVICE_NAME, titleId = R.string.device_name))
put(
StringInputSetting(
StringSetting.PROGRAM_ARGS,
titleId = R.string.program_args,
descriptionId = R.string.program_args_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_USE_SPEED_LIMIT,
@@ -1286,7 +1286,6 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.general))
add(ShortSetting.DEBUG_KNOBS.key)
add(StringSetting.PROGRAM_ARGS.key)
add(HeaderSetting(R.string.gpu_logging_header))
add(BooleanSetting.GPU_LOGGING_ENABLED.key)
@@ -29,8 +29,8 @@
<string name="overlay_auto_hide">触控叠加层自动隐藏</string>
<string name="overlay_auto_hide_description">在指定时间内未进行任何操作后,自动隐藏触控叠加层。</string>
<string name="enable_input_overlay_auto_hide">启用触控叠加层自动隐藏</string>
<string name="hide_overlay_on_controller_input">使用控制器控制输入时隐藏触控叠加层</string>
<string name="hide_overlay_on_controller_input_description">在使用实体控制器时自动隐藏触控叠加层,而当控制器断开连接时,触控叠加层则会重新显现。</string>
<string name="hide_overlay_on_controller_input">使用控制器时隐藏触控叠加层</string>
<string name="hide_overlay_on_controller_input_description">在使用实体控制器时自动隐藏触控叠加层,而当控制器断开触控叠加层则会重新显现。</string>
<string name="invert_confirm_back_controller_buttons">切换“确认/返回”控制器按钮功能</string>
<string name="invert_confirm_back_controller_buttons_description">在与本应用的界面交互时,交换 Android 的“确认”与“返回”按钮的处理方式,以匹配 Switch 和 Xbox 的风格。</string>
@@ -432,7 +432,7 @@
<!-- CPU -->
<string name="fast_cpu_time">CPU 超频</string>
<string name="fast_cpu_time_description">强制模拟的 CPU 以更高的时钟频率运行,从而除某些帧率限制。使用“升频”(1700MHz)以在 Switch 的最高原生时钟频率运行,或使用“快速”(2000MHz以 2 倍时钟频率运行。</string>
<string name="fast_cpu_time_description">强制模拟的 CPU 以更高的时钟频率运行,从而除某些 FPS 限制。使用 Boost (1700MHz) 可让游戏以 Switch 的最高原生时钟运行,或使用 Fast (2000MHz) 以 2 倍时钟运行。</string>
<string name="custom_cpu_ticks">自定义CPU时钟</string>
<string name="custom_cpu_ticks_description">设置自定义的CPU时钟值。更高的值可能提高性能,但也可能导致游戏卡顿。建议范围为77-21000。</string>
<string name="cpu_ticks">时钟</string>
@@ -460,15 +460,15 @@
<string name="advanced">高级</string>
<string name="renderer_accuracy">GPU 模式</string>
<string name="renderer_accuracy_description">控制 GPU 模拟模式。大多数游戏在“快速”或“平衡模式下都能正常渲染,但有些游戏仍需使用“精确”模式。粒子效果通常只有在精确模式下才能正确渲染</string>
<string name="renderer_accuracy_description">控制 GPU 模拟的精确度。大部分游戏在性能或平衡模式下可以正常渲染,但部分游戏需要设置为精确。粒子效果通常只有在精确模式下才能正确显示</string>
<string name="dma_accuracy">DMA 精度</string>
<string name="dma_accuracy_description">控制 DMA 的精准度。安全精度可以修复存在于某些游戏中的问题,但在某些情况下也会对性能造成影响。如不确定,请保“默认”。</string>
<string name="dma_accuracy_description">控制 DMA 度。安全精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如不确定,请保留为“默认”。</string>
<string name="anisotropic_filtering">各向异性过滤</string>
<string name="anisotropic_filtering_description">提高斜角的纹理质量</string>
<string name="vram_usage_mode">显存使用模式</string>
<string name="vram_usage_mode_description">控制显存分配策略</string>
<string name="accelerate_astc">ASTC解码方式</string>
<string name="accelerate_astc_description">选择渲染时使用的 ASTC 压缩纹理解码方式:CPU缓慢,安全)GPU(快速推荐),或 CPU 异步(无卡顿,可能导致问题)</string>
<string name="accelerate_astc_description">选择ASTC压缩纹理解码方式:CPU慢速、安全)GPU(快速推荐)CPU异步(无卡顿,可能导致问题)</string>
<string name="sync_memory_operations">同步内存操作</string>
<string name="sync_memory_operations_description">确保计算和内存操作之间的数据一致性。 此选项应能修复某些游戏中的问题,但在某些情况下可能会降低性能。 使用Unreal Engine 4的游戏似乎受影响最大。</string>
@@ -477,11 +477,11 @@
<string name="renderer_force_max_clock">强制最大时钟 (仅限 Adreno)</string>
<string name="renderer_force_max_clock_description">强制 GPU 以最大时钟运行 (温控依然生效)。</string>
<string name="renderer_asynchronous_gpu_emulation">GPU 异步模拟</string>
<string name="renderer_asynchronous_gpu_emulation_description">此技巧可通过异步运行 GPU 模拟来提升性能,但在执行与时序相关的操作时,可能带来图形显示问题以及增加崩溃概率。</string>
<string name="renderer_asynchronous_gpu_emulation_description">此技巧可通过异步运行 GPU 模拟来提升性能,但在执行与时序相关的操作时,可能引入图形问题和增加崩溃概率。</string>
<string name="renderer_async_presentation">异步呈现</string>
<string name="renderer_async_presentation_description">此技巧通过将图形呈现移至独立的 CPU 线程来提升性能,但可能会带来图形显示问题。</string>
<string name="renderer_async_presentation_description">此技巧通过将图形呈现移至独立的 CPU 线程来提升性能,但可能会引入图形显示问题。</string>
<string name="renderer_reactive_flushing">启用反应性刷新</string>
<string name="renderer_reactive_flushing_description">通过牺牲性能来提某些游戏的渲染精度。</string>
<string name="renderer_reactive_flushing_description">通过牺牲性能来提某些游戏的渲染精度。</string>
<string name="enable_buffer_history">启用缓冲区历史</string>
<string name="enable_buffer_history_description">启用对先前缓冲区状态的访问。此选项可在某些游戏中提升渲染质量并保持性能的一致性。</string>
<string name="use_optimized_vertex_buffers">优化顶点缓冲区</string>
@@ -489,10 +489,10 @@
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">快速 GPU 时间</string>
<string name="fast_gpu_time">GPU 超频频率</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 可获得最佳性能,设置为 512 可获得最佳画面保真度。</string>
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
<string name="skip_cpu_inner_invalidation_description">更新内存时跳过某些 CPU 端的缓存失效操作,从而降低 CPU用率并提性能。可能会某些游戏中引发故障或崩溃。</string>
<string name="skip_cpu_inner_invalidation_description">内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
<string name="antiflicker">防闪烁</string>
<string name="antiflicker_description">强制 GPU 围栏回调等待已提交的 GPU 任务。配合“快速 GPU 模式”一起使用,以避免画面闪烁现象,仅会牺牲少量性能。</string>
<string name="fix_bloom_effects">修复 Bloom 效果</string>
@@ -502,16 +502,16 @@
<string name="rescale_hack">启用旧版缩放处理</string>
<string name="rescale_hack_description">启用通过使用快速缩放路径,来为游戏提供缩放配置处理的传统处理方式</string>
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
<string name="renderer_asynchronous_shaders_description">异步方式编译着色器。采用此方式或可减少卡顿,但也可能引入故障点</string>
<string name="gpu_unswizzle_settings">GPU Unswizzle 设置</string>
<string name="gpu_unswizzle_settings_description">配置基于 GPU 的纹理 unswizzling 参数,或完全禁用该功能。通过调整这些设置,以尝试在性能与纹理加载质量之间取得平衡</string>
<string name="gpu_unswizzle_enable">启用 GPU Unswizzle</string>
<string name="renderer_asynchronous_shaders_description">异步编译着色器。这可能会减少卡顿,但也可能会导致图形错误</string>
<string name="gpu_unswizzle_settings">GPU 还原设置</string>
<string name="gpu_unswizzle_settings_description">配置基于 GPU 的纹理还原参数,或将其完全禁用调整这些设置以平衡性能与纹理加载质量。</string>
<string name="gpu_unswizzle_enable">启用 GPU 还原</string>
<string name="gpu_unswizzle_disabled">禁用</string>
<string name="gpu_unswizzle_texture_size">GPU Unswizzle 最大纹理尺寸</string>
<string name="gpu_unswizzle_texture_size_description">设置基于 GPU 的纹理 unswizzling 的最大尺寸(MB)。虽然 GPU 处理中和大型纹理速度更快,但对于非常小的纹理,CPU 可能更为高效。通过调节此项设置,以尝试在 GPU 加速 CPU 开销之间找到平衡。</string>
<string name="gpu_unswizzle_stream_size">GPU Unswizzle 流大小</string>
<string name="gpu_unswizzle_stream_size_description">设置用于 unswizzling 大型纹理时的每帧数据限制。较高的数值可以加纹理的加载过程,但会带来更高的帧延迟。而较低的数值可以降低 GPU 的开销,但可能会导致可见的纹理闪现。</string>
<string name="gpu_unswizzle_chunk_size">GPU Unswizzle 块大小</string>
<string name="gpu_unswizzle_texture_size">GPU 还原最大纹理尺寸</string>
<string name="gpu_unswizzle_texture_size_description">设置基于 GPU 的纹理还原的最大尺寸(单位:MiB)。\n虽然 GPU 处理中和大型纹理速度更快,但对于非常小的纹理,CPU 的效率可能更高。\n调整此设置,以便在 GPU 加速 CPU 开销之间找到最佳平衡</string>
<string name="gpu_unswizzle_stream_size">GPU 还原流大小</string>
<string name="gpu_unswizzle_stream_size_description">设置用于 unswizzling 大型纹理时的每帧数据限制。较高的数值可以加纹理的加载速度,但会增加帧延迟。而较低的数值可以降低 GPU 的开销,但可能会导致可见的纹理 闪现。</string>
<string name="gpu_unswizzle_chunk_size">GPU 还原块大小</string>
<string name="gpu_unswizzle_chunk_size_description">定义了 3D 纹理每批次处理的深度切片数量。增加此数值可在高性能 GPU 上提升吞吐效率,但在性能较弱的硬件上可能会导致卡顿或驱动超时。</string>
<string name="gpu_unswizzle_default_button">默认</string>
@@ -524,7 +524,7 @@
<string name="vertex_input_dynamic_state">顶点输入动态状态</string>
<string name="vertex_input_dynamic_state_description">启用此功能可实现更灵活的顶点输入处理,可能减少顶点/缓冲区的管线编译时间。</string>
<string name="sample_shading_fraction">采样着色</string>
<string name="sample_shading_fraction_description">允许片段着色器在多采样片段中每个采样点执行一次操作,而非对每个片段执行一次。在提升图形显示质量的同时,会牺牲一部分性能</string>
<string name="sample_shading_fraction_description">允许片段着色器在多采样片段中每个样本执行一次,而不是每个片段执行一次。以提高性能为代价改善图形质量</string>
<string name="display">显示</string>
@@ -548,7 +548,7 @@
<string name="renderer_debug_description">将图形 API 设置为较慢的调试模式。</string>
<string name="patch_old_qcom_drivers">BCn 纹理补丁</string>
<string name="patch_old_qcom_drivers_description">在 Adreno GPU 上覆盖自动 BCn 纹理格式检测。通常根据 Android 版本自动检测(在 API 28 及以上启用)。</string>
<string name="fastmem">Fastmem</string>
<string name="fastmem">Fastmem 内存访问</string>
<string name="log">日志记录</string>
<string name="flush_by_line">按行刷新调试日志</string>
@@ -615,7 +615,7 @@
<string name="unused">未使用</string>
<string name="input_mapping_filter">输入映射过滤器</string>
<string name="input_mapping_filter_description">选择一个设备过滤输入映射</string>
<string name="auto_map">自动映射控制器键位</string>
<string name="auto_map">控制器自动映射</string>
<string name="auto_map_description">选择一个设备以尝试自动映射</string>
<string name="attempted_auto_map">尝试为 %1$s 自动映射</string>
<string name="controller_type">控制器类型</string>
@@ -731,10 +731,10 @@
<string name="preferences_audio">声音</string>
<string name="preferences_audio_description">输出引擎及音量</string>
<string name="preferences_controls">控制</string>
<string name="preferences_controls_description">映射控制器键位输入</string>
<string name="preferences_controls_description">使用控制器来映射输入</string>
<string name="preferences_player">玩家 %d</string>
<string name="preferences_debug">调试</string>
<string name="preferences_debug_description">CPU/GPU 调试、图形 API 及 fastmem</string>
<string name="preferences_debug_description">CPU/GPU 调试、图形 API 及 fastmem 内存访问</string>
<string name="preferences_custom_paths">自定义路径</string>
<string name="preferences_custom_paths_description">存档目录</string>
@@ -878,15 +878,15 @@
<string name="emulation_rel_stick_center">相对摇杆中心</string>
<string name="emulation_dpad_slide">十字方向键滑动</string>
<string name="emulation_haptics">触觉反馈</string>
<string name="emulation_show_overlay">显示触控叠加层</string>
<string name="emulation_hide_overlay">隐藏触控叠加层</string>
<string name="emulation_show_overlay">显示控制器</string>
<string name="emulation_hide_overlay">隐藏控制器</string>
<string name="emulation_toggle_all">全部切换</string>
<string name="emulation_control_adjust">调整触控叠加层</string>
<string name="emulation_control_scale">缩放</string>
<string name="emulation_control_opacity">不透明度</string>
<string name="emulation_touch_overlay_reset">重置触控叠加层</string>
<string name="emulation_touch_overlay_edit">编辑触控叠加层</string>
<string name="emulation_snap_to_grid">对齐到网格</string>
<string name="emulation_snap_to_grid">截图到网格</string>
<string name="emulation_pause">暂停模拟</string>
<string name="emulation_unpause">继续模拟</string>
<string name="emulation_input_overlay">触控叠加层选项</string>
@@ -982,7 +982,7 @@
<string name="renderer_none"></string>
<!-- Renderer Accuracy -->
<string name="renderer_accuracy_low">快速</string>
<string name="renderer_accuracy_low">性能</string>
<string name="renderer_accuracy_medium">平衡</string>
<string name="renderer_accuracy_high">精确</string>
@@ -434,9 +434,6 @@
<string name="cpu_accuracy">CPU accuracy</string>
<string name="value_with_units">%1$s%2$s</string>
<string name="program_args">Homebrew Args</string>
<string name="program_args_description">Command-line arguments passed to homebrew at launch (e.g. -noglsl).</string>
<!-- System settings strings -->
<string name="device_name">Device name</string>
<string name="use_docked_mode">Docked Mode</string>
+75 -26
View File
@@ -409,62 +409,107 @@ bool RenameDir(const fs::path& old_path, const fs::path& new_path) {
return true;
}
void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable& callback, DirEntryFilter filter) {
void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable& callback,
DirEntryFilter filter) {
if (!ValidatePath(path)) {
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
return;
}
if (!Exists(path)) {
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} does not exist", PathToUTF8String(path));
return;
}
if (!IsDir(path)) {
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a directory", PathToUTF8String(path));
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} does not exist",
PathToUTF8String(path));
return;
}
if (!IsDir(path)) {
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a directory",
PathToUTF8String(path));
return;
}
std::error_code ec;
bool callback_error = false;
for (auto const& entry : fs::directory_iterator(path, ec)) {
if ((True(filter & DirEntryFilter::File) && entry.status().type() == fs::file_type::regular)
|| (True(filter & DirEntryFilter::Directory) && entry.status().type() == fs::file_type::directory)) {
std::error_code ec;
for (const auto& entry : fs::directory_iterator(path, ec)) {
if (ec) {
break;
}
if (True(filter & DirEntryFilter::File) &&
entry.status().type() == fs::file_type::regular) {
if (!callback(entry)) {
callback_error = true;
break;
}
}
if (True(filter & DirEntryFilter::Directory) &&
entry.status().type() == fs::file_type::directory) {
if (!callback(entry)) {
callback_error = true;
break;
}
}
}
if (callback_error || ec) {
LOG_ERROR(Common_Filesystem, "Failed to visit all the directory entries of path={}, ec_message={}, callback_error={}", PathToUTF8String(path), ec.message(), callback_error);
} else {
LOG_DEBUG(Common_Filesystem, "Visited all the directory entries of path={}", PathToUTF8String(path));
LOG_ERROR(Common_Filesystem,
"Failed to visit all the directory entries of path={}, ec_message={}",
PathToUTF8String(path), ec.message());
return;
}
LOG_DEBUG(Common_Filesystem, "Successfully visited all the directory entries of path={}",
PathToUTF8String(path));
}
void IterateDirEntriesRecursively(const std::filesystem::path& path, const DirEntryCallable& callback, DirEntryFilter filter) {
void IterateDirEntriesRecursively(const std::filesystem::path& path,
const DirEntryCallable& callback, DirEntryFilter filter) {
if (!ValidatePath(path)) {
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
return;
}
if (!Exists(path)) {
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} does not exist", PathToUTF8String(path));
return;
}
if (!IsDir(path)) {
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a directory", PathToUTF8String(path));
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} does not exist",
PathToUTF8String(path));
return;
}
if (!IsDir(path)) {
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a directory",
PathToUTF8String(path));
return;
}
// TODO (Morph): Replace this with recursive_directory_iterator once it's fixed in MSVC.
std::error_code ec;
bool callback_error = false;
std::error_code ec;
// TODO (Morph): Replace this with recursive_directory_iterator once it's fixed in MSVC.
for (const auto& entry : fs::directory_iterator(path, ec)) {
if ((True(filter & DirEntryFilter::File) && entry.status().type() == fs::file_type::regular)
|| (True(filter & DirEntryFilter::Directory) && entry.status().type() == fs::file_type::directory)) {
if (ec) {
break;
}
if (True(filter & DirEntryFilter::File) &&
entry.status().type() == fs::file_type::regular) {
if (!callback(entry)) {
callback_error = true;
break;
}
}
if (True(filter & DirEntryFilter::Directory) &&
entry.status().type() == fs::file_type::directory) {
if (!callback(entry)) {
callback_error = true;
break;
}
}
// TODO (Morph): Remove this when MSVC fixes recursive_directory_iterator.
// recursive_directory_iterator throws an exception despite passing in a std::error_code.
if (entry.status().type() == fs::file_type::directory) {
@@ -473,10 +518,14 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path, const DirEn
}
if (callback_error || ec) {
LOG_ERROR(Common_Filesystem, "Failed to visit all the directory entries of path={}, ec_message={}, callback_error={}", PathToUTF8String(path), ec.message(), callback_error);
} else {
LOG_DEBUG(Common_Filesystem, "Visited all the directory entries of path={}", PathToUTF8String(path));
LOG_ERROR(Common_Filesystem,
"Failed to visit all the directory entries of path={}, ec_message={}",
PathToUTF8String(path), ec.message());
return;
}
LOG_DEBUG(Common_Filesystem, "Successfully visited all the directory entries of path={}",
PathToUTF8String(path));
}
// Generic Filesystem Operations
+5 -7
View File
@@ -90,7 +90,7 @@ public:
void CreateEdenPaths() {
std::for_each(eden_paths.begin(), eden_paths.end(), [](auto &path) {
void(FS::CreateDirs(path.second));
void(FS::CreateDir(path.second));
});
}
@@ -149,9 +149,10 @@ public:
LEGACY_PATH(Suyu, SUYU)
#undef LEGACY_PATH
#endif
// data
GenerateEdenPath(EdenPath::EdenDir, eden_path);
GenerateEdenPath(EdenPath::AmiiboDir, eden_path / AMIIBO_DIR);
GenerateEdenPath(EdenPath::CacheDir, eden_path_cache);
GenerateEdenPath(EdenPath::ConfigDir, eden_path_config);
GenerateEdenPath(EdenPath::CrashDumpsDir, eden_path / CRASH_DUMPS_DIR);
GenerateEdenPath(EdenPath::DumpDir, eden_path / DUMP_DIR);
GenerateEdenPath(EdenPath::KeysDir, eden_path / KEYS_DIR);
@@ -162,13 +163,10 @@ public:
GenerateEdenPath(EdenPath::SaveDir, eden_path / NAND_DIR);
GenerateEdenPath(EdenPath::ScreenshotsDir, eden_path / SCREENSHOTS_DIR);
GenerateEdenPath(EdenPath::SDMCDir, eden_path / SDMC_DIR);
GenerateEdenPath(EdenPath::ShaderDir, eden_path / SHADER_DIR);
GenerateEdenPath(EdenPath::TASDir, eden_path / TAS_DIR);
GenerateEdenPath(EdenPath::IconsDir, eden_path / ICONS_DIR);
// config
GenerateEdenPath(EdenPath::ConfigDir, eden_path_config);
// cache
GenerateEdenPath(EdenPath::CacheDir, eden_path_cache);
GenerateEdenPath(EdenPath::ShaderDir, eden_path_cache / SHADER_DIR);
#ifdef _WIN32
GenerateLegacyPath(EmuPath::RyujinxDir, GetAppDataRoamingDirectory() / RYUJINX_DIR);
#else
+40 -110
View File
@@ -22,7 +22,6 @@
#include <sys/mman.h>
#include <unistd.h>
#include "common/scope_exit.h"
#include "common/literals.h"
#if defined(__linux__)
#include <sys/random.h>
@@ -33,8 +32,6 @@
#include <mach/mach.h>
#elif defined(__FreeBSD__)
#include <sys/shm.h>
#elif defined(__OPENORBIS__)
#include <orbis/libkernel.h>
#endif
// FreeBSD
@@ -125,55 +122,54 @@ static void GetFuncAddress(Common::DynamicLibrary& dll, const char* name, T& pfn
class HostMemory::Impl {
public:
explicit Impl(size_t backing_size_, size_t virtual_size_)
: backing_size{backing_size_}
, virtual_size{virtual_size_}
, process{GetCurrentProcess()}
, kernelbase_dll("Kernelbase")
{}
bool Init() {
: backing_size{backing_size_}, virtual_size{virtual_size_}, process{GetCurrentProcess()},
kernelbase_dll("Kernelbase") {
if (!kernelbase_dll.IsOpen()) {
LOG_CRITICAL(HW_Memory, "Failed to load Kernelbase.dll");
return false;
throw std::bad_alloc{};
}
GetFuncAddress(kernelbase_dll, "CreateFileMapping2", pfn_CreateFileMapping2);
GetFuncAddress(kernelbase_dll, "VirtualAlloc2", pfn_VirtualAlloc2);
GetFuncAddress(kernelbase_dll, "MapViewOfFile3", pfn_MapViewOfFile3);
GetFuncAddress(kernelbase_dll, "UnmapViewOfFile2", pfn_UnmapViewOfFile2);
if (!pfn_CreateFileMapping2 || !pfn_VirtualAlloc2 || !pfn_MapViewOfFile3 || !pfn_UnmapViewOfFile2) {
LOG_CRITICAL(HW_Memory, "Failed to find functions for virtual allocs");
return false;
}
// Allocate backing file map
backing_handle = pfn_CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ, PAGE_READWRITE, SEC_COMMIT, backing_size, nullptr, nullptr, 0);
backing_handle =
pfn_CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ,
PAGE_READWRITE, SEC_COMMIT, backing_size, nullptr, nullptr, 0);
if (!backing_handle) {
LOG_CRITICAL(HW_Memory, "Failed to allocate {} MiB of backing memory", backing_size >> 20);
return false;
LOG_CRITICAL(HW_Memory, "Failed to allocate {} MiB of backing memory",
backing_size >> 20);
throw std::bad_alloc{};
}
// Allocate a virtual memory for the backing file map as placeholder
backing_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, backing_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS, nullptr, 0));
backing_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, backing_size,
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, nullptr, 0));
if (!backing_base) {
Release();
LOG_CRITICAL(HW_Memory, "Failed to reserve {} MiB of virtual memory", backing_size >> 20);
return false;
LOG_CRITICAL(HW_Memory, "Failed to reserve {} MiB of virtual memory",
backing_size >> 20);
throw std::bad_alloc{};
}
// Map backing placeholder
void* const ret = pfn_MapViewOfFile3(backing_handle, process, backing_base, 0, backing_size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
void* const ret = pfn_MapViewOfFile3(backing_handle, process, backing_base, 0, backing_size,
MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
if (ret != backing_base) {
Release();
LOG_CRITICAL(HW_Memory, "Failed to map {} MiB of virtual memory", backing_size >> 20);
return false;
throw std::bad_alloc{};
}
// Allocate virtual address placeholder
virtual_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, virtual_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS, nullptr, 0));
virtual_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, virtual_size,
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, nullptr, 0));
if (!virtual_base) {
Release();
LOG_CRITICAL(HW_Memory, "Failed to reserve {} GiB of virtual memory", virtual_size >> 30);
return false;
LOG_CRITICAL(HW_Memory, "Failed to reserve {} GiB of virtual memory",
virtual_size >> 30);
throw std::bad_alloc{};
}
return true;
}
~Impl() {
@@ -395,9 +391,6 @@ private:
ankerl::unordered_dense::map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
};
#elif defined(__OPENORBIS__) || defined(__managarm__)
// None of the luxuries of POSIX, all of the suffering
// For managarm: see https://github.com/managarm/managarm/issues/1370
#else // ^^^ Windows ^^^ vvv POSIX vvv
#ifdef ARCHITECTURE_arm64
@@ -503,44 +496,18 @@ static int shm_open_anon(int flags, mode_t mode) {
class HostMemory::Impl {
public:
explicit Impl(size_t backing_size_, size_t virtual_size_)
: backing_size{backing_size_}
, virtual_size{virtual_size_}
{}
bool Init() {
: backing_size{backing_size_}, virtual_size{virtual_size_} {
long page_size = sysconf(_SC_PAGESIZE);
ASSERT_MSG(page_size == 0x1000, "page size {:#x} is incompatible with 4K paging", page_size);
ASSERT_MSG(page_size == 0x1000, "page size {:#x} is incompatible with 4K paging",
page_size);
// Backing memory initialization
#if defined(__sun__) || defined(__HAIKU__) || defined(__NetBSD__) || defined(__DragonFly__)
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
#elif defined(__OpenBSD__)
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
#elif defined(__FreeBSD__)
int n_page_sizes = getpagesizes(nullptr, 0);
if (n_page_sizes > 0) {
std::vector<size_t> page_sizes(n_page_sizes);
if (getpagesizes(page_sizes.data(), n_page_sizes) > 0) {
size_t max_size = page_sizes[0];
size_t max_index = 0;
for (size_t i = 0; i < page_sizes.size(); ++i) {
using namespace Common::Literals;
if (page_sizes[i] <= 4_GiB) {
max_size = (std::max)(max_size, page_sizes[i]);
max_index = i;
}
}
LOG_WARNING(Common_Memory, "using largepage of size {} #{}", max_size, max_index);
// Do not use SHM_LARGEPAGE_ALLOC_HARD, yknow what will happen when you do?
// the entire Eden process will hang for eternity! that's what will happen
// Want to fuck around and find out? Go ahead, I tempt you change the "default" to "hard"
fd = shm_create_largepage(SHM_ANON, O_RDWR, max_index, SHM_LARGEPAGE_ALLOC_DEFAULT, 0600);
}
}
if (fd < 0) {
LOG_WARNING(Common_Memory, "unable to force largepage: {}", strerror(errno));
fd = shm_open(SHM_ANON, O_RDWR, 0600);
}
#elif defined(__APPLE__) || defined(__managarm__)
fd = shm_open(SHM_ANON, O_RDWR, 0600);
#elif defined(__APPLE__)
// macOS doesn't have memfd_create, use anonymous temporary file
char template_path[] = "/tmp/eden_mem_XXXXXX";
fd = mkstemp(template_path);
@@ -571,29 +538,17 @@ public:
close(fd);
}
} else {
#ifdef __FreeBSD__
// Prevent dirty tracking of memfd
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NOSYNC, fd, 0));
#else
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
#endif
}
if (backing_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
return false;
}
ASSERT_MSG(backing_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
// Virtual memory initialization
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
if (virtual_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
return false;
}
ASSERT_MSG(virtual_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
#if defined(__linux__)
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
#endif
free_manager.SetAddressSpace(virtual_base, virtual_size);
return true;
}
~Impl() {
@@ -714,35 +669,17 @@ private:
#endif // ^^^ POSIX ^^^
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
: backing_size(backing_size_)
, virtual_size(virtual_size_)
{
#if defined(__OPENORBIS__) || defined(__managarm__)
LOG_WARNING(HW_Memory, "Platform doesn't support fastmem");
fallback_buffer.emplace(backing_size);
backing_base = fallback_buffer->data();
virtual_base = nullptr;
#else
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) : backing_size(backing_size_), virtual_size(virtual_size_) {
// Try to allocate a fastmem arena.
// The implementation will fail with std::bad_alloc on errors.
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize);
if (impl->Init()) {
backing_base = impl->backing_base;
virtual_base = impl->virtual_base;
if (virtual_base) {
// Ensure the virtual base is aligned to the L2 block size.
virtual_base = reinterpret_cast<u8*>(Common::AlignUp(uintptr_t(virtual_base), HugePageSize));
virtual_base_offset = virtual_base - impl->virtual_base;
}
} else {
impl.reset();
LOG_WARNING(HW_Memory, "Platform can support fastmem, but can't create it");
fallback_buffer.emplace(backing_size);
backing_base = fallback_buffer->data();
virtual_base = nullptr;
backing_base = impl->backing_base;
virtual_base = impl->virtual_base;
if (virtual_base) {
// Ensure the virtual base is aligned to the L2 block size.
virtual_base = reinterpret_cast<u8*>(Common::AlignUp(uintptr_t(virtual_base), HugePageSize));
virtual_base_offset = virtual_base - impl->virtual_base;
}
#endif
}
HostMemory::~HostMemory() = default;
@@ -751,8 +688,8 @@ HostMemory::HostMemory(HostMemory&&) noexcept = default;
HostMemory& HostMemory::operator=(HostMemory&&) noexcept = default;
void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms, bool separate_heap) {
#if !(defined(__OPENORBIS__) || defined(__managarm__))
void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
MemoryPermission perms, bool separate_heap) {
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(host_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
@@ -762,11 +699,9 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length, M
return;
}
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
#endif
}
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
#if !(defined(__OPENORBIS__) || defined(__managarm__))
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
@@ -774,11 +709,9 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap)
return;
}
impl->Unmap(virtual_offset + virtual_base_offset, length);
#endif
}
void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission perm) {
#if !(defined(__OPENORBIS__) || defined(__managarm__))
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
@@ -789,7 +722,6 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission
const bool write = True(perm & MemoryPermission::Write);
const bool execute = True(perm & MemoryPermission::Execute);
impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute);
#endif
}
void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) {
@@ -797,12 +729,10 @@ void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 f
}
void HostMemory::EnableDirectMappedAddress() {
#if !(defined(__OPENORBIS__) || defined(__managarm__))
if (impl) {
impl->EnableDirectMappedAddress();
virtual_size += reinterpret_cast<uintptr_t>(virtual_base);
}
#endif
}
} // namespace Common
+1 -6
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
@@ -7,7 +7,6 @@
#pragma once
#include <memory>
#include <optional>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/virtual_buffer.h"
@@ -77,16 +76,12 @@ private:
size_t backing_size{};
size_t virtual_size{};
#if !(defined(__OPENORBIS__) || defined(__managarm__))
// Low level handler for the platform dependent memory routines
class Impl;
std::unique_ptr<Impl> impl;
#endif
u8* backing_base{};
u8* virtual_base{};
size_t virtual_base_offset{};
// Windows requires it for kernels whom lack proper support for some functions!
std::optional<Common::VirtualBuffer<u8>> fallback_buffer;
};
} // namespace Common
+5 -11
View File
@@ -336,7 +336,7 @@ struct Values {
RendererBackend::Vulkan,
#endif
"backend", Category::Renderer};
SwitchableSetting<u32> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, Specialization::RuntimeList};
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, Specialization::RuntimeList};
// Graphics Settings
ResolutionScalingInfo resolution_info{};
@@ -661,8 +661,8 @@ struct Values {
false, true, &custom_rtc_enabled};
SwitchableSetting<s64, true> custom_rtc_offset{linkage,
0,
(std::numeric_limits<s64>::min)(),
(std::numeric_limits<s64>::max)(),
(std::numeric_limits<int>::min)(),
(std::numeric_limits<int>::max)(),
"custom_rtc_offset",
Category::System,
Specialization::Countable,
@@ -751,7 +751,7 @@ struct Values {
Setting<std::string> touch_device{linkage, "min_x:100,min_y:50,max_x:1800,max_y:850",
"touch_device", Category::Controls};
Setting<u32> touch_from_button_map_index{linkage, 0, "touch_from_button_map",
Setting<int> touch_from_button_map_index{linkage, 0, "touch_from_button_map",
Category::Controls};
std::vector<TouchFromButtonMap> touch_from_button_maps;
@@ -779,13 +779,7 @@ struct Values {
bool record_frame_times;
Setting<bool> use_gdbstub{linkage, false, "use_gdbstub", Category::Debugging};
Setting<u16> gdbstub_port{linkage, 6543, "gdbstub_port", Category::Debugging};
SwitchableSetting<std::string> program_args{linkage,
std::string(),
"program_args",
Category::System,
Specialization::Default,
true, // save_ — persist in config file
false}; // runtime_modifiable_ — startup-only
Setting<std::string> program_args{linkage, std::string(), "program_args", Category::Debugging};
Setting<bool> dump_exefs{linkage, false, "dump_exefs", Category::Debugging};
Setting<bool> dump_nso{linkage, false, "dump_nso", Category::Debugging};
Setting<bool> dump_shaders{
+2 -2
View File
@@ -145,8 +145,8 @@ ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
ENUM(FullscreenMode, Borderless, Exclusive);
ENUM(NvdecEmulation, Off, Cpu, Gpu);
ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X);
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, Lanczos, ScaleForce, Fsr, Area, ZeroTangent, BSpline, Mitchell, Spline1, Mmpx, Sgsr, SgsrEdge);
ENUM(AntiAliasing, None, Fxaa, Smaa);
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, Lanczos, ScaleForce, Fsr, Area, ZeroTangent, BSpline, Mitchell, Spline1, Mmpx, Sgsr, SgsrEdge, MaxEnum);
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
ENUM(ConsoleMode, Handheld, Docked);
ENUM(AppletMode, HLE, LLE);
+3 -20
View File
@@ -11,7 +11,6 @@
#include <optional>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <fmt/core.h>
@@ -102,15 +101,7 @@ public:
* @param val The desired value
*/
virtual void SetValue(const Type& val) {
// Enums have a maximal range which they're allowed
Type temp{};
if constexpr (std::is_enum_v<Type>) {
auto const r_min = std::underlying_type_t<Type>(0);
auto const r_max = std::underlying_type_t<Type>(EnumMetadata<Type>::GetLast());
temp = Type(std::clamp(std::underlying_type_t<Type>(val), r_min, r_max));
} else {
temp = ranged ? std::clamp(val, this->minimum, this->maximum) : val;
}
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
std::swap(value, temp);
}
@@ -138,7 +129,7 @@ protected:
} else if constexpr (std::is_floating_point_v<Type>) {
return fmt::format("{:f}", value_);
} else if constexpr (std::is_enum_v<Type>) {
return std::to_string(std::underlying_type_t<Type>(value_));
return std::to_string(u32(value_));
} else {
return std::to_string(value_);
}
@@ -380,15 +371,7 @@ public:
* @param val The new value
*/
void SetValue(const Type& val) override final {
// Enums have a maximal range which they're allowed
Type temp{};
if constexpr (std::is_enum_v<Type>) {
auto const r_min = std::underlying_type_t<Type>(0);
auto const r_max = std::underlying_type_t<Type>(EnumMetadata<Type>::GetLast());
temp = Type(std::clamp(std::underlying_type_t<Type>(val), r_min, r_max));
} else {
temp = ranged ? std::clamp(val, this->minimum, this->maximum) : val;
}
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
if (use_global) {
std::swap(this->value, temp);
} else {
-4
View File
@@ -1121,10 +1121,6 @@ add_library(core STATIC
hle/service/vi/vi_types.h
hle/service/vi/vsync_manager.cpp
hle/service/vi/vsync_manager.h
hle/service/gpio/gpio.cpp
hle/service/gpio/gpio.h
hle/service/i2c/i2c.cpp
hle/service/i2c/i2c.h
internal_network/emu_net_state.cpp
internal_network/emu_net_state.h
internal_network/network.cpp
+6 -25
View File
@@ -211,9 +211,6 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, KResource
m_version = params.version;
m_program_id = params.program_id;
m_code_address = params.code_address;
m_arg_pointer = 0;
m_arg_return_address = 0;
m_main_thread_handle_addr = 0;
m_code_size = params.code_num_pages * PageSize;
m_is_application = True(params.flags & Svc::CreateProcessFlag::IsApplication);
@@ -998,27 +995,9 @@ Result KProcess::Run(s32 priority, size_t stack_size) {
Handle thread_handle;
R_TRY(m_handle_table.Add(std::addressof(thread_handle), main_thread));
// Set the thread arguments. Two distinct entry conventions:
// * Kernel/NSO entry (no homebrew ABI): x0 = 0, x1 = thread_handle
// * Homebrew/NRO ABI (loader set arg ptr): x0 = ConfigEntry ptr, x1 = -1ULL
// libnx's switch_crt0.s tests `x0==0 || x1==0xFFFFFFFFFFFFFFFF` to take
// its normal init path; any other combination is interpreted as a user
// exception handler entry.
if (GetInteger(m_arg_pointer) != 0) {
main_thread->GetContext().r[0] = GetInteger(m_arg_pointer);
main_thread->GetContext().r[1] = UINT64_MAX;
main_thread->GetContext().lr = GetInteger(m_arg_return_address);
// Patch the MainThreadHandle entry in the ConfigEntry table now that
// the actual handle exists. libnx stores this verbatim and uses it
// for thread-control SVCs later; a pseudo-handle wouldn't survive
// svcCloseHandle on exit.
if (GetInteger(m_main_thread_handle_addr) != 0) {
this->GetMemory().Write32(m_main_thread_handle_addr, thread_handle);
}
} else {
main_thread->GetContext().r[0] = 0;
main_thread->GetContext().r[1] = thread_handle;
}
// Set the thread arguments.
main_thread->GetContext().r[0] = 0;
main_thread->GetContext().r[1] = thread_handle;
// Pass the thread handle to the thread local region.
this->GetMemory().Write32(GetInteger(main_thread->GetTlsAddress()) + 0x110, thread_handle);
@@ -1195,7 +1174,8 @@ KProcess::KProcess(KernelCore& kernel)
KProcess::~KProcess() = default;
Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset) {
Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl) {
// Create a resource limit for the process.
const auto pool = static_cast<KMemoryManager::Pool>(metadata.GetPoolPartition());
const auto physical_memory_size = m_kernel.MemoryManager().GetSize(pool);
@@ -1267,6 +1247,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
aslr_space_start));
// Assign remaining properties.
m_is_hbl = is_hbl;
m_ideal_core_id = metadata.GetMainThreadCore();
// Set up emulation context.
+7 -14
View File
@@ -84,9 +84,6 @@ private:
Core::Memory::Memory m_memory;
KCapabilities m_capabilities{};
KProcessAddress m_code_address{};
KProcessAddress m_arg_pointer{};
KProcessAddress m_arg_return_address{};
KProcessAddress m_main_thread_handle_addr{};
KHandleTable m_handle_table;
KProcessAddress m_plr_address{};
ThreadList m_thread_list{};
@@ -136,6 +133,7 @@ private:
bool m_is_initialized : 1 = false;
bool m_is_application : 1 = false;
bool m_is_default_application_system_resource : 1 = false;
bool m_is_hbl : 1 = false;
bool m_is_suspended : 1 = false;
bool m_is_immortal : 1 = false;
bool m_is_handle_table_initialized : 1 = false;
@@ -222,16 +220,6 @@ public:
return m_code_address;
}
void SetArgPointer(KProcessAddress addr) {
m_arg_pointer = addr;
}
void SetArgReturnAddress(KProcessAddress addr) {
m_arg_return_address = addr;
}
void SetMainThreadHandleAddr(KProcessAddress addr) {
m_main_thread_handle_addr = addr;
}
size_t GetMainStackSize() const {
return m_main_thread_stack_size;
}
@@ -289,6 +277,10 @@ public:
return m_capabilities.CanForceDebug();
}
bool IsHbl() const {
return m_is_hbl;
}
u32 GetAllocateOption() const {
return m_page_table.GetAllocateOption();
}
@@ -522,7 +514,8 @@ public:
}
public:
Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset);
Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl);
void LoadModule(CodeSet code_set, KProcessAddress base_addr);
+3 -4
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -109,7 +106,9 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
system.CurrentPhysicalCore().LogBacktrace();
}
const bool should_break = !notification_only;
const bool is_hbl = GetCurrentProcess(system.Kernel()).IsHbl();
const bool should_break = is_hbl || !notification_only;
if (system.DebuggerEnabled() && should_break) {
auto* thread = system.Kernel().GetCurrentEmuThread();
system.GetDebugger().NotifyThreadStopped(thread);
+1 -2
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -83,7 +83,6 @@ struct Applet {
// Application functions
bool game_play_recording_supported{};
bool media_playback_state{};
GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled};
bool jit_service_launched{};
bool application_crash_report_enabled{};
@@ -11,7 +11,6 @@
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/savedata_factory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
#include "core/hle/service/am/am_results.h"
#include "core/hle/service/am/applet.h"
#include "core/hle/service/am/service/application_functions.h"
@@ -57,7 +56,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_
{37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
{40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"},
{50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"},
{60, D<&IApplicationFunctions::SetMediaPlaybackStateForApplication>, "SetMediaPlaybackStateForApplication"},
{60, nullptr, "SetMediaPlaybackStateForApplication"},
{65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"},
{66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"},
{67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"},
@@ -365,13 +364,6 @@ Result IApplicationFunctions::InitializeGamePlayRecording(
R_SUCCEED();
}
Result IApplicationFunctions::SetMediaPlaybackStateForApplication(bool enabled) {
LOG_WARNING(Service_AM, "(stubbed) {}", enabled);
std::scoped_lock lk{m_applet->lock};
m_applet->media_playback_state = enabled;
R_SUCCEED();
}
Result IApplicationFunctions::SetGamePlayRecordingState(
GamePlayRecordingState game_play_recording_state) {
LOG_WARNING(Service_AM, "(STUBBED) called");
@@ -53,7 +53,6 @@ private:
Result IsGamePlayRecordingSupported(Out<bool> out_is_game_play_recording_supported);
Result InitializeGamePlayRecording(
u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
Result SetMediaPlaybackStateForApplication(bool enabled);
Result SetGamePlayRecordingState(GamePlayRecordingState game_play_recording_state);
Result EnableApplicationCrashReport(bool enabled);
Result InitializeApplicationCopyrightFrameBuffer(
+1 -6
View File
@@ -29,7 +29,7 @@ IBtmSystemCore::IBtmSystemCore(Core::System& system_)
{10, nullptr, "StartAudioDeviceDiscovery"},
{11, nullptr, "StopAudioDeviceDiscovery"},
{12, nullptr, "IsDiscoveryingAudioDevice"},
{13, C<&IBtmSystemCore::GetDiscoveredAudioDevice>, "GetDiscoveredAudioDevice"},
{13, nullptr, "GetDiscoveredAudioDevice"},
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
@@ -93,11 +93,6 @@ Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid,
R_SUCCEED();
}
Result IBtmSystemCore::GetDiscoveredAudioDevice(OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out<s32> out_total) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
R_SUCCEED();
}
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
+3 -5
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -37,8 +34,9 @@ private:
Result DisableRadio();
Result IsRadioEnabled(Out<bool> out_is_enabled);
Result AcquireRadioEvent(Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetDiscoveredAudioDevice(OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out<s32> out_total);
Result AcquireRadioEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetConnectedAudioDevices(
@@ -151,7 +151,7 @@ Result IFileSystem::GetTotalSpaceSize(
Result IFileSystem::GetFileTimeStampRaw(
Out<FileSys::FileTimeStampRaw> out_timestamp,
const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) {
LOG_DEBUG(Service_FS, "(Partial Implementation) called. file={}", path->str);
LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", path->str);
FileSys::FileTimeStampRaw vfs_timestamp{};
R_TRY(backend->GetFileTimeStampRaw(&vfs_timestamp, FileSys::Path(path->str)));
@@ -284,17 +284,9 @@ Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface,
id = FileSys::StorageId::NandSystem;
break;
case FileSys::SaveDataSpaceId::Temporary:
// ok this is definitely wrong. ASSERT(false) here just kills the whole game the first
// time it opens cache storage, and plenty of games do that (TOTK for one). there is
// user-space scratch storage so it belongs on user nand. map it, do not crash.
id = FileSys::StorageId::NandUser;
break;
case FileSys::SaveDataSpaceId::ProperSystem:
case FileSys::SaveDataSpaceId::SafeMode:
// same deal for these two. they are system-level spaces so they go on system nand.
// way better than nuking the title over a save-space id we just did not list out.
id = FileSys::StorageId::NandSystem;
break;
ASSERT(false);
}
*out_interface =
@@ -332,15 +324,9 @@ Result FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(OutInterface<IFileSyste
id = FileSys::StorageId::NandSystem;
break;
case FileSys::SaveDataSpaceId::Temporary:
// same broken switch as OpenSaveDataFileSystem above. do not ASSERT(false) and kill the
// game over a save-space id, just map Temporary to user nand like it should be.
id = FileSys::StorageId::NandUser;
break;
case FileSys::SaveDataSpaceId::ProperSystem:
case FileSys::SaveDataSpaceId::SafeMode:
// system spaces -> system nand. handled, not crashed.
id = FileSys::StorageId::NandSystem;
break;
ASSERT(false);
}
*out_interface =
-33
View File
@@ -1,33 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/service/gpio/gpio.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/service.h"
namespace Service::GPIO {
class GPIO final : public ServiceFramework<GPIO> {
public:
explicit GPIO(Core::System& system_)
: ServiceFramework{system_, "gpio"}
{
static const FunctionInfo functions[] = {
{0, nullptr, "Cmd0"},
};
RegisterHandlers(functions);
}
~GPIO() override = default;
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("gpio", std::make_shared<GPIO>(system));
ServerManager::RunServer(std::move(server_manager));
}
} // namespace Service::GPIO
-15
View File
@@ -1,15 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
namespace Core {
class System;
}
namespace Service::GPIO {
void LoopProcess(Core::System& system);
} // namespace Service::GPIO
-76
View File
@@ -1,76 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/result.h"
#include "core/hle/service/i2c/i2c.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
#include "core/hle/service/server_manager.h"
namespace Service::I2C {
class I2CSession final : public ServiceFramework<I2CSession> {
public:
explicit I2CSession(Core::System& system_)
: ServiceFramework{system_, "I2CSession"}
{
static const FunctionInfo functions[] = {
{0, nullptr, "SendOld"},
{1, nullptr, "ReceiveOld"},
{2, nullptr, "ExecuteCommandListOld"},
{10, C<&I2CSession::Send>, "Send"},
{11, nullptr, "Receive"},
{12, nullptr, "ExecuteCommandList"},
{13, nullptr, "SetRetryPolicy"},
};
RegisterHandlers(functions);
}
~I2CSession() override = default;
Result Send(InBuffer<BufferAttr_HipcMapAlias> in_data, u32 transaction_option) {
LOG_WARNING(Service, "(stubbed) topt={}", transaction_option);
R_THROW(ResultUnknown);
}
};
enum class I2CDevice : u32 {
ClassicController,
Ftm3bd56,
};
class I2C final : public ServiceFramework<I2C> {
public:
explicit I2C(Core::System& system_)
: ServiceFramework{system_, "i2c"}
{
static const FunctionInfo functions[] = {
{0, nullptr, "OpenSessionForDev"},
{1, C<&I2C::OpenSession>, "OpenSession"},
{2, nullptr, "HasDevice"},
{3, nullptr, "HasDeviceForDev"},
{4, nullptr, "OpenSession2"},
};
RegisterHandlers(functions);
}
~I2C() override = default;
Result OpenSession(I2CDevice device, OutInterface<I2CSession> out_session) {
LOG_DEBUG(Service, "(stubbed)");
*out_session = std::make_shared<I2CSession>(system);
R_SUCCEED();
}
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("i2c", std::make_shared<I2C>(system));
ServerManager::RunServer(std::move(server_manager));
}
} // namespace Service::I2C
-15
View File
@@ -1,15 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
namespace Core {
class System;
}
namespace Service::I2C {
void LoopProcess(Core::System& system);
} // namespace Service::I2C
@@ -47,8 +47,6 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output);
case 0x14:
return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output);
case 0x15:
return WrapFixed(this, &nvhost_ctrl_gpu::PmuGetGpuLoad, input, output);
case 0x1c:
return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output);
default:
@@ -236,12 +234,6 @@ NvResult nvhost_ctrl_gpu::GetActiveSlotMask(IoctlActiveSlotMask& params) {
return NvResult::Success;
}
NvResult nvhost_ctrl_gpu::PmuGetGpuLoad(IoctlPmuGetLoad& params) {
LOG_WARNING(Service_NVDRV, "(stubbed) called");
params.pmu_gpu_load = 100;
return NvResult::Success;
}
NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(IoctlZcullGetCtxSize& params) {
LOG_DEBUG(Service_NVDRV, "called");
params.size = 0x1;
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -184,11 +184,6 @@ private:
};
static_assert(sizeof(IoctlGetCpuTimeCorrelationInfo) == 264);
struct IoctlPmuGetLoad {
u32 pmu_gpu_load;
};
static_assert(sizeof(IoctlPmuGetLoad) == 4);
NvResult GetCharacteristics1(IoctlCharacteristics& params);
NvResult GetCharacteristics3(IoctlCharacteristics& params,
std::span<IoctlGpuCharacteristics> gpu_characteristics);
@@ -197,7 +192,6 @@ private:
NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask);
NvResult GetActiveSlotMask(IoctlActiveSlotMask& params);
NvResult PmuGetGpuLoad(IoctlPmuGetLoad& params);
NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params);
NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params);
NvResult ZBCSetTable(IoctlZbcSetTable& params);
@@ -25,20 +25,18 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
switch (command.group) {
case 0x0:
switch (command.cmd) {
case 0x01:
case 0x1:
return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd);
case 0x02:
case 0x2:
return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output);
case 0x03:
case 0x3:
return WrapFixed(this, &nvhost_nvdec::GetWaitbase, input, output);
case 0x07:
case 0x7:
return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output);
case 0x09:
case 0x9:
return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output, fd);
case 0x0a:
case 0xa:
return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output);
case 0x23:
return WrapFixed(this, &nvhost_nvdec::GetClkRate, input, output);
default:
break;
}
@@ -168,13 +168,6 @@ NvResult nvhost_nvdec_common::SetSubmitTimeout(u32 timeout) {
return NvResult::Success;
}
NvResult nvhost_nvdec_common::GetClkRate(IoctlGetClkRate& params) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
params.clk_rate = 614400000;
params.module_id = 0;
return NvResult::Success;
}
Kernel::KEvent* nvhost_nvdec_common::QueryEvent(u32 event_id) {
LOG_CRITICAL(Service_NVDRV, "Unknown HOSTX1 Event {}", event_id);
return nullptr;
@@ -111,12 +111,6 @@ protected:
};
static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size");
struct IoctlGetClkRate {
u32_le clk_rate{};
u32_le module_id{};
};
static_assert(sizeof(IoctlGetClkRate) == 8);
/// Ioctl command implementations
NvResult SetNVMAPfd(IoctlSetNvmapFD&);
NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd);
@@ -125,7 +119,6 @@ protected:
NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd);
NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries);
NvResult SetSubmitTimeout(u32 timeout);
NvResult GetClkRate(IoctlGetClkRate& params);
Kernel::KEvent* QueryEvent(u32 event_id) override;
+3 -65
View File
@@ -6,12 +6,10 @@
#include <memory>
#include "common/common_funcs.h"
#include "common/device_power_state.h"
#include "common/logging.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/result.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/ptm/psm.h"
@@ -136,12 +134,12 @@ PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} {
{9, nullptr, "DisableEnoughPowerChargeEmulation"},
{10, nullptr, "EnableFastBatteryCharging"},
{11, nullptr, "DisableFastBatteryCharging"},
{12, &PSM::GetBatteryVoltageState, "GetBatteryVoltageState"},
{12, nullptr, "GetBatteryVoltageState"},
{13, nullptr, "GetRawBatteryChargePercentage"},
{14, nullptr, "IsEnoughPowerSupplied"},
{15, &PSM::GetBatteryAgePercentage, "GetBatteryAgePercentage"},
{15, nullptr, "GetBatteryAgePercentage"},
{16, nullptr, "GetBatteryChargeInfoEvent"},
{17, &PSM::GetBatteryChargeInfoFields, "GetBatteryChargeInfoFields"},
{17, nullptr, "GetBatteryChargeInfoFields"},
{18, nullptr, "GetBatteryChargeCalibratedEvent"},
};
// clang-format on
@@ -189,64 +187,4 @@ void PSM::OpenSession(HLERequestContext& ctx) {
rb.PushIpcInterface<IPsmSession>(system);
}
void PSM::GetBatteryVoltageState(HLERequestContext& ctx) {
LOG_DEBUG(Service_PTM, "(stubbed)");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw<u32>(0); //
}
void PSM::GetBatteryAgePercentage(HLERequestContext& ctx) {
LOG_DEBUG(Service_PTM, "(stubbed)");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw<f64>(1.f);
}
struct BatteryChargeInfoFields {
u32 input_current_limit; //mA
u32 boost_mode_current_limit;
u32 fast_charge_current_limit;
u32 charge_voltage_limit;
u32 charger_type;
u8 hi2_mode;
u8 battery_charging;
INSERT_PADDING_BYTES_NOINIT(2);
u32 vdd50_state;
u32 temperature_celcius;
f32 battery_charge_percentage;
u32 battery_charge_milli_voltage;
f32 battery_age_percentage;
u32 usb_power_role;
u32 usb_charger_type;
u32 charger_input_voltage_limit;
u32 charger_input_current_limit;
u8 fast_battery_charging;
u8 controller_power_supply;
u8 otg_request;
INSERT_PADDING_BYTES_NOINIT(1);
INSERT_PADDING_BYTES_NOINIT(0x14); //[+17.0.0]
};
static_assert(sizeof(struct BatteryChargeInfoFields) == 0x54);
void PSM::GetBatteryChargeInfoFields(HLERequestContext& ctx) {
LOG_DEBUG(Service_PTM, "called");
Common::PowerStatus power_status = Common::GetPowerStatus();
BatteryChargeInfoFields r{};
r.battery_charge_percentage = f32(power_status.percentage); //100%
r.battery_age_percentage = f32(power_status.percentage); //100%
r.battery_charging = power_status.charging ? 1 : 0;
r.charger_type = u32(power_status.has_battery && power_status.charging
? ChargerType::RegularCharger : ChargerType::Unplugged);
r.charger_input_voltage_limit = 100;
r.charger_input_voltage_limit = 100;
r.input_current_limit = 100;
r.boost_mode_current_limit = 100;
r.fast_charge_current_limit = 100;
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw<BatteryChargeInfoFields>(r);
}
} // namespace Service::PTM
+2 -4
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -22,12 +22,10 @@ private:
LowPowerCharger = 2,
Unknown = 3,
};
void GetBatteryChargePercentage(HLERequestContext& ctx);
void GetChargerType(HLERequestContext& ctx);
void OpenSession(HLERequestContext& ctx);
void GetBatteryVoltageState(HLERequestContext& ctx);
void GetBatteryAgePercentage(HLERequestContext& ctx);
void GetBatteryChargeInfoFields(HLERequestContext& ctx);
};
} // namespace Service::PTM
+4 -7
View File
@@ -21,13 +21,10 @@ namespace Service::RO {
namespace {
// Atmosphere defines as follows:
// Sessions = 0x03, NrrInfos = 0x40, NroInfos = 0x40
// This may not be enough for some mods (plugin.nro dependant games) like SSBU
// Suppose someone loads like 64 plugins of these, now what?
constexpr size_t MaxSessions = 0x03; // No change
constexpr size_t MaxNrrInfos = 0x100; // Up to 256 NRRs
constexpr size_t MaxNroInfos = 0x100; // Up to 256 NROs
// Convenience definitions.
constexpr size_t MaxSessions = 0x3;
constexpr size_t MaxNrrInfos = 0x40;
constexpr size_t MaxNroInfos = 0x40;
constexpr u64 InvalidProcessId = 0xffffffffffffffffULL;
constexpr u64 InvalidContextId = 0xffffffffffffffffULL;
+2 -6
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -25,10 +25,8 @@
#include "core/hle/service/friend/friend.h"
#include "core/hle/service/glue/glue.h"
#include "core/hle/service/grc/grc.h"
#include "core/hle/service/gpio/gpio.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/i2c/i2c.h"
#include "core/hle/service/jit/jit.h"
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/ldn/ldn.h"
@@ -146,9 +144,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
{"ro", &RO::LoopProcess},
{"spl", &SPL::LoopProcess},
{"ssl", &SSL::LoopProcess},
{"usb", &USB::LoopProcess},
{"i2c", &I2C::LoopProcess},
{"gpio", &GPIO::LoopProcess},
{"usb", &USB::LoopProcess}
})
kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); });
}
@@ -142,10 +142,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{22, C<&ISystemSettingsServer::SetEulaVersions>, "SetEulaVersions"},
{23, C<&ISystemSettingsServer::GetColorSetId>, "GetColorSetId"},
{24, C<&ISystemSettingsServer::SetColorSetId>, "SetColorSetId"},
{25, C<&ISystemSettingsServer::GetConsoleInformationUploadFlag>, "GetConsoleInformationUploadFlag"},
{26, C<&ISystemSettingsServer::SetConsoleInformationUploadFlag>, "SetConsoleInformationUploadFlag"},
{27, C<&ISystemSettingsServer::GetAutomaticApplicationDownloadFlag>, "GetAutomaticApplicationDownloadFlag"},
{28, C<&ISystemSettingsServer::SetAutomaticApplicationDownloadFlag>, "SetAutomaticApplicationDownloadFlag"},
{25, nullptr, "GetConsoleInformationUploadFlag"},
{26, nullptr, "SetConsoleInformationUploadFlag"},
{27, nullptr, "GetAutomaticApplicationDownloadFlag"},
{28, nullptr, "SetAutomaticApplicationDownloadFlag"},
{29, C<&ISystemSettingsServer::GetNotificationSettings>, "GetNotificationSettings"},
{30, C<&ISystemSettingsServer::SetNotificationSettings>, "SetNotificationSettings"},
{31, C<&ISystemSettingsServer::GetAccountNotificationSettings>, "GetAccountNotificationSettings"},
@@ -160,8 +160,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{42, nullptr, "SetEdid"},
{43, C<&ISystemSettingsServer::GetAudioOutputMode>, "GetAudioOutputMode"},
{44, C<&ISystemSettingsServer::SetAudioOutputMode>, "SetAudioOutputMode"},
{45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag>, "GetSpeakerAutoMuteFlag"},
{46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag>, "SetSpeakerAutoMuteFlag"},
{45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag> , "GetSpeakerAutoMuteFlag"},
{46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag> , "SetSpeakerAutoMuteFlag"},
{47, C<&ISystemSettingsServer::GetQuestFlag>, "GetQuestFlag"},
{48, C<&ISystemSettingsServer::SetQuestFlag>, "SetQuestFlag"},
{49, nullptr, "GetDataDeletionSettings"},
@@ -180,8 +180,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{62, C<&ISystemSettingsServer::GetDebugModeFlag>, "GetDebugModeFlag"},
{63, C<&ISystemSettingsServer::GetPrimaryAlbumStorage>, "GetPrimaryAlbumStorage"},
{64, C<&ISystemSettingsServer::SetPrimaryAlbumStorage>, "SetPrimaryAlbumStorage"},
{65, C<&ISystemSettingsServer::GetUsb30EnableFlag>, "GetUsb30EnableFlag"},
{66, C<&ISystemSettingsServer::SetUsb30EnableFlag>, "SetUsb30EnableFlag"},
{65, nullptr, "GetUsb30EnableFlag"},
{66, nullptr, "SetUsb30EnableFlag"},
{67, C<&ISystemSettingsServer::GetBatteryLot>, "GetBatteryLot"},
{68, C<&ISystemSettingsServer::GetSerialNumber>, "GetSerialNumber"},
{69, C<&ISystemSettingsServer::GetNfcEnableFlag>, "GetNfcEnableFlag"},
@@ -1074,45 +1074,6 @@ Result ISystemSettingsServer::SetNfcEnableFlag(bool nfc_enable_flag) {
R_SUCCEED();
}
Result ISystemSettingsServer::GetConsoleInformationUploadFlag(Out<bool> out_flag) {
LOG_INFO(Service_SET, "called {}", m_system_settings.console_information_upload_flag);
*out_flag = m_system_settings.console_information_upload_flag;
R_SUCCEED();
}
Result ISystemSettingsServer::SetConsoleInformationUploadFlag(bool flag) {
LOG_INFO(Service_SET, "called {}", flag);
m_system_settings.usb_30_enable_flag = flag;
SetSaveNeeded();
R_SUCCEED();
}
Result ISystemSettingsServer::GetAutomaticApplicationDownloadFlag(Out<bool> out_flag) {
LOG_INFO(Service_SET, "called {}", m_system_settings.usb_30_enable_flag);
*out_flag = m_system_settings.automatic_application_download_flag;
R_SUCCEED();
}
Result ISystemSettingsServer::SetAutomaticApplicationDownloadFlag(bool flag) {
LOG_INFO(Service_SET, "called {}", flag);
m_system_settings.automatic_application_download_flag = flag;
SetSaveNeeded();
R_SUCCEED();
}
Result ISystemSettingsServer::GetUsb30EnableFlag(Out<bool> out_usb30_enable_flag) {
LOG_INFO(Service_SET, "called, usb30_enable_flag={}", m_system_settings.usb_30_enable_flag);
*out_usb30_enable_flag = m_system_settings.usb_30_enable_flag;
R_SUCCEED();
}
Result ISystemSettingsServer::SetUsb30EnableFlag(bool usb30_enable_flag) {
LOG_INFO(Service_SET, "called, usb30_enable_flag={}", usb30_enable_flag);
m_system_settings.usb_30_enable_flag = usb30_enable_flag;
SetSaveNeeded();
R_SUCCEED();
}
Result ISystemSettingsServer::GetSleepSettings(Out<SleepSettings> out_sleep_settings) {
LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}",
m_system_settings.sleep_settings.flags.raw,
@@ -109,12 +109,6 @@ public:
Result SetPrimaryAlbumStorage(PrimaryAlbumStorage primary_album_storage);
Result GetBatteryLot(Out<BatteryLot> out_battery_lot);
Result GetSerialNumber(Out<SerialNumber> out_console_serial);
Result GetConsoleInformationUploadFlag(Out<bool> out_flag);
Result SetConsoleInformationUploadFlag(bool flag);
Result GetAutomaticApplicationDownloadFlag(Out<bool> out_flag);
Result SetAutomaticApplicationDownloadFlag(bool flag);
Result GetUsb30EnableFlag(Out<bool> out_usb30_enable_flag);
Result SetUsb30EnableFlag(bool usb30_enable_flag);
Result GetNfcEnableFlag(Out<bool> out_nfc_enable_flag);
Result SetNfcEnableFlag(bool nfc_enable_flag);
Result GetSleepSettings(Out<SleepSettings> out_sleep_settings);
+2 -37
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -14,7 +11,6 @@
#include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_server_port.h"
#include "core/hle/result.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/sm/sm.h"
@@ -254,37 +250,15 @@ void SM::UnregisterService(HLERequestContext& ctx) {
rb.Push(service_manager.UnregisterService(name));
}
void SM::AtmosphereHasService(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
std::string name(PopServiceName(rp));
LOG_WARNING(Service_SM, "(stubbed) called with name={}", name);
IPC::ResponseBuilder rb{ctx, 3};
Kernel::KClientPort* out_client_port = nullptr;
rb.Push(ResultSuccess);
rb.Push<bool>(service_manager.GetServicePort(&out_client_port, name) == ResultSuccess);
}
SM::SM(ServiceManager& service_manager_, Core::System& system_)
: ServiceFramework{system_, "sm:", 4}
, service_manager{service_manager_}
, kernel{system_.Kernel()}
{
: ServiceFramework{system_, "sm:", 4},
service_manager{service_manager_}, kernel{system_.Kernel()} {
RegisterHandlers({
{0, &SM::Initialize, "Initialize"},
{1, &SM::GetServiceCmif, "GetService"},
{2, &SM::RegisterServiceCmif, "RegisterService"},
{3, &SM::UnregisterService, "UnregisterService"},
{4, nullptr, "DetachClient"},
// TODO: are these non-TIPC as well?
{65000, nullptr, "AtmosphereInstallMitm"},
{65001, nullptr, "AtmosphereUninstallMitm"},
{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
{65004, nullptr, "AtmosphereHasMitm"},
{65005, nullptr, "AtmosphereWaitMitm"},
{65006, nullptr, "AtmosphereDeclareFutureMitm"},
{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
{65101, nullptr, "AtmosphereWaitService"},
});
RegisterHandlersTipc({
{0, &SM::Initialize, "Initialize"},
@@ -292,15 +266,6 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
{2, &SM::RegisterServiceTipc, "RegisterService"},
{3, &SM::UnregisterService, "UnregisterService"},
{4, nullptr, "DetachClient"},
{65000, nullptr, "AtmosphereInstallMitm"},
{65001, nullptr, "AtmosphereUninstallMitm"},
{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
{65004, nullptr, "AtmosphereHasMitm"},
{65005, nullptr, "AtmosphereWaitMitm"},
{65006, nullptr, "AtmosphereDeclareFutureMitm"},
{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
{65101, nullptr, "AtmosphereWaitService"},
});
}
-1
View File
@@ -47,7 +47,6 @@ private:
void RegisterServiceCmif(HLERequestContext& ctx);
void RegisterServiceTipc(HLERequestContext& ctx);
void UnregisterService(HLERequestContext& ctx);
void AtmosphereHasService(HLERequestContext& ctx);
Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,
@@ -71,10 +71,9 @@ struct PatchCollection {
std::array<s32, 13> module_patcher_indices{};
};
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, bool override_update_)
: AppLoader(std::move(file_))
, override_update(override_update_)
{
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_,
bool override_update_)
: AppLoader(std::move(file_)), override_update(override_update_), is_hbl(false) {
const auto file_dir = file->GetContainingDirectory();
// Title ID
@@ -125,11 +124,9 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys
}
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
FileSys::VirtualDir directory, bool override_update_)
: AppLoader(directory->GetFile("main"))
, dir(std::move(directory))
, override_update(override_update_)
{}
FileSys::VirtualDir directory, bool override_update_, bool is_hbl_)
: AppLoader(directory->GetFile("main")), dir(std::move(directory)),
override_update(override_update_), is_hbl(is_hbl_) {}
FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& dir_file) {
if (FileSys::IsDirectoryExeFS(dir_file->GetContainingDirectory())) {
@@ -235,7 +232,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
? ::Settings::values.rng_seed.GetValue() : Common::Random::Random64(0)) << 12) & 0xfff000;
// Setup the process code layout
if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset).IsError()) {
if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset, is_hbl).IsError()) {
return {ResultStatus::ErrorUnableToParseKernelMetadata, {}};
}
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,9 +22,13 @@ namespace Loader {
*/
class AppLoader_DeconstructedRomDirectory final : public AppLoader {
public:
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file, bool override_update_ = false);
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file,
bool override_update_ = false);
// Overload to accept exefs directory. Must contain 'main' and 'main.npdm'
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory, bool override_update_ = false);
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory,
bool override_update_ = false,
bool is_hbl_ = false);
/**
* Identifies whether or not the given file is a deconstructed ROM directory.
@@ -62,6 +63,7 @@ private:
std::string name;
u64 title_id{};
bool override_update;
bool is_hbl;
Modules modules;
};
+1 -1
View File
@@ -93,7 +93,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
? ::Settings::values.rng_seed.GetValue() : Common::Random::Random64(0)) << 12) & 0xfff000;
// Setup the process code layout
if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset).IsError()) {
if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset, false).IsError()) {
return {ResultStatus::ErrorNotInitialized, {}};
}
const VAddr base_address = GetInteger(process.GetEntryPoint());
+15 -79
View File
@@ -4,15 +4,9 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <array>
#include <cstddef>
#include <cstring>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "common/alignment.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/logging.h"
@@ -29,6 +23,7 @@
#include "core/hle/kernel/k_thread.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/nro.h"
#include "core/loader/nso.h"
#include "core/memory.h"
#ifdef HAS_NCE
@@ -179,6 +174,19 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
codeset.segments[i].size = PageAlignSize(nro_header.segments[i].size);
}
if (!Settings::values.program_args.GetValue().empty()) {
const auto arg_data = Settings::values.program_args.GetValue();
codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE;
NSOArgumentHeader args_header{
NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}};
const auto end_offset = program_image.size();
program_image.resize(static_cast<u32>(program_image.size()) +
NSO_ARGUMENT_DATA_ALLOCATION_SIZE);
std::memcpy(program_image.data() + end_offset, &args_header, sizeof(NSOArgumentHeader));
std::memcpy(program_image.data() + end_offset + sizeof(NSOArgumentHeader), arg_data.data(),
arg_data.size());
}
// Default .bss to NRO header bss size if MOD0 section doesn't exist
u32 bss_size{PageAlignSize(nro_header.bss_size)};
@@ -195,47 +203,6 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
codeset.DataSegment().size += bss_size;
program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
struct ConfigEntry {
u32_le key;
u32_le flags;
u64_le value[2];
};
static_assert(sizeof(ConfigEntry) == 0x18);
// AArch64 encoding for svc #0x7 (ExitProcess).
constexpr u32 kSvcExitProcessInstruction = 0xD40000E1;
constexpr size_t kNumEntries = 4; // MainThreadHandle, AppletType, Argv, EndOfList
constexpr size_t kConfigTableSize = kNumEntries * sizeof(ConfigEntry);
std::string argv_string;
size_t args_offset_in_image = 0;
std::optional<size_t> exit_process_offset_in_image;
const auto& program_args = Settings::values.program_args.GetValue();
if (!program_args.empty()) {
argv_string = "homebrew ";
argv_string += program_args;
argv_string.push_back('\0');
const auto& code = codeset.CodeSegment();
const size_t code_end = (std::min)(program_image.size(), code.offset + code.size);
for (size_t offset = code.offset; offset + sizeof(u32) <= code_end; offset += sizeof(u32)) {
u32 instruction{};
std::memcpy(&instruction, program_image.data() + offset, sizeof(instruction));
if (instruction == kSvcExitProcessInstruction) {
exit_process_offset_in_image = offset;
break;
}
}
if (!exit_process_offset_in_image) {
LOG_WARNING(Loader,
"Unable to find svcExitProcess in NRO; returning from main may fault");
}
const size_t entries_and_argv =
Common::AlignUp(kConfigTableSize + argv_string.size(), Core::Memory::YUZU_PAGESIZE);
args_offset_in_image = program_image.size();
codeset.DataSegment().size += static_cast<u32>(entries_and_argv);
program_image.resize(args_offset_in_image + entries_and_argv);
}
size_t image_size = program_image.size();
#ifdef HAS_NCE
@@ -280,7 +247,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
// Setup the process code layout
if (process
.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, aslr_offset)
.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, aslr_offset, false)
.IsError()) {
return false;
}
@@ -297,37 +264,6 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
// Load codeset for current process
codeset.memory = std::move(program_image);
process.LoadModule(std::move(codeset), process.GetEntryPoint());
if (!argv_string.empty()) {
constexpr u32 kEntryEndOfList = 0;
constexpr u32 kEntryMainThreadHandle = 1;
constexpr u32 kEntryArgv = 5;
constexpr u32 kEntryAppletType = 7;
constexpr u32 kAppletTypeApplication = 0;
const u64 base = GetInteger(process.GetEntryPoint());
const u64 config_addr = base + args_offset_in_image;
const u64 argv_addr = config_addr + kConfigTableSize;
const ConfigEntry entries[kNumEntries] = {
{kEntryMainThreadHandle, 0, {0, 0}}, // Value[0] patched in Run()
{kEntryAppletType, 0, {kAppletTypeApplication, 0}},
{kEntryArgv, 0, {0, argv_addr}},
{kEntryEndOfList, 0, {0, 0}},
};
process.GetMemory().WriteBlock(Common::ProcessAddress{config_addr}, entries,
sizeof(entries));
process.GetMemory().WriteBlock(Common::ProcessAddress{argv_addr},
argv_string.data(), argv_string.size());
constexpr size_t kMainThreadHandleValueOffset = offsetof(ConfigEntry, value);
process.SetArgPointer(Kernel::KProcessAddress{config_addr});
if (exit_process_offset_in_image) {
process.SetArgReturnAddress(
Kernel::KProcessAddress{base + *exit_process_offset_in_image});
}
process.SetMainThreadHandleAddr(
Kernel::KProcessAddress{config_addr + kMainThreadHandleValueOffset});
}
return true;
}
+2 -1
View File
@@ -34,7 +34,8 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_,
}
if (nsp->IsExtractedType()) {
secondary_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(nsp->GetExeFS(), false);
secondary_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(
nsp->GetExeFS(), false, file->GetName() == "hbl.nsp");
} else {
const auto control_nca =
nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control);
@@ -90,8 +90,6 @@ std::once_flag flag;
std::optional<SpinLockImpl> impl;
void SpinLockImpl::Initialize() noexcept {
// Needed for W^X systems (i.e SElinux, OpenBSD)
code.setProtectMode(Xbyak::CodeArray::ProtectMode::PROTECT_RW);
Xbyak::Reg64 const ABI_PARAM1 = Backend::X64::HostLocToReg64(Backend::X64::ABI_PARAM1);
code.align();
lock = code.getCurr<void (*)(volatile int*)>();
@@ -101,7 +99,6 @@ void SpinLockImpl::Initialize() noexcept {
unlock = code.getCurr<void (*)(volatile int*)>();
EmitSpinLockUnlock(code, ABI_PARAM1, code.eax);
code.ret();
code.setProtectMode(Xbyak::CodeArray::ProtectMode::PROTECT_RE);
}
void SpinLockImpl::GlobalInitialize() noexcept {
+33 -17
View File
@@ -238,27 +238,33 @@ void Config::ReadControlValues() {
void Config::ReadMotionTouchValues() {
Settings::values.touch_from_button_maps.clear();
int num_touch_from_button_maps = BeginArray(std::string("touch_from_button_maps"));
if (num_touch_from_button_maps > 0) {
for (int i = 0; i < num_touch_from_button_maps; ++i) {
SetArrayIndex(i);
Settings::TouchFromButtonMap map;
map.name = ReadStringSetting(std::string("name"), std::string("default"));
int const num_touch_maps = BeginArray(std::string("entries"));
map.buttons.resize(num_touch_maps);
const int num_touch_maps = BeginArray(std::string("entries"));
map.buttons.reserve(num_touch_maps);
for (int j = 0; j < num_touch_maps; j++) {
SetArrayIndex(j);
map.buttons[j] = ReadStringSetting(std::string("bind"));
std::string touch_mapping = ReadStringSetting(std::string("bind"));
map.buttons.emplace_back(std::move(touch_mapping));
}
EndArray(); // entries
Settings::values.touch_from_button_maps.emplace_back(std::move(map));
}
} else {
Settings::values.touch_from_button_maps.emplace_back(Settings::TouchFromButtonMap{"default", {}});
Settings::values.touch_from_button_maps.emplace_back(
Settings::TouchFromButtonMap{"default", {}});
num_touch_from_button_maps = 1;
}
EndArray(); // touch_from_button_maps
Settings::values.touch_from_button_map_index = (std::min)(Settings::values.touch_from_button_map_index.GetValue(), u32(num_touch_from_button_maps - 1));
Settings::values.touch_from_button_map_index = std::clamp(
Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
}
void Config::ReadCoreValues() {
@@ -495,12 +501,15 @@ void Config::SaveMotionTouchValues() {
BeginArray(std::string("touch_from_button_maps"));
for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
SetArrayIndex(int(p));
WriteStringSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name, std::make_optional(std::string("default")));
WriteStringSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name,
std::make_optional(std::string("default")));
BeginArray(std::string("entries"));
for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
++q) {
SetArrayIndex(int(q));
WriteStringSetting(std::string("bind"), Settings::values.touch_from_button_maps[p].buttons[q]);
WriteStringSetting(std::string("bind"),
Settings::values.touch_from_button_maps[p].buttons[q]);
}
EndArray(); // entries
}
@@ -629,7 +638,8 @@ void Config::SaveDisabledAddOnValues() {
BeginArray(std::string("disabled"));
for (std::size_t j = 0; j < elem.second.size(); ++j) {
SetArrayIndex(int(j));
WriteStringSetting(std::string("d"), elem.second[j], std::make_optional(std::string("")));
WriteStringSetting(std::string("d"), elem.second[j],
std::make_optional(std::string("")));
}
EndArray(); // disabled
++i;
@@ -723,18 +733,21 @@ s64 Config::ReadIntegerSetting(const std::string& key, const std::optional<s64>
std::string full_key = GetFullKey(key, false);
if (!default_value.has_value()) {
try {
return std::stoll(std::string(config->GetValue(GetSection().c_str(), full_key.c_str(), "0")));
return std::stoll(
std::string(config->GetValue(GetSection().c_str(), full_key.c_str(), "0")));
} catch (...) {
return 0;
}
}
s64 result = 0;
if (config->GetBoolValue(GetSection().c_str(), std::string(full_key).append("\\default").c_str(), true)) {
if (config->GetBoolValue(GetSection().c_str(),
std::string(full_key).append("\\default").c_str(), true)) {
result = default_value.value();
} else {
try {
result = std::stoll(std::string(config->GetValue(GetSection().c_str(), full_key.c_str(), ToString(default_value.value()).c_str())));
result = std::stoll(std::string(config->GetValue(
GetSection().c_str(), full_key.c_str(), ToString(default_value.value()).c_str())));
} catch (...) {
result = default_value.value();
}
@@ -906,12 +919,14 @@ void Config::ReadSettingGeneric(Settings::BasicSetting* const setting) {
bool use_global = true;
if (setting->Switchable() && !global) {
use_global = ReadBooleanSetting(std::string(key).append("\\use_global"), std::make_optional(true));
use_global =
ReadBooleanSetting(std::string(key).append("\\use_global"), std::make_optional(true));
setting->SetGlobal(use_global);
}
if (global || !use_global) {
const bool is_default = ReadBooleanSetting(std::string(key).append("\\default"), std::make_optional(true));
const bool is_default =
ReadBooleanSetting(std::string(key).append("\\default"), std::make_optional(true));
if (!is_default) {
setting->LoadString(ReadStringSetting(key, default_value));
} else {
@@ -1035,9 +1050,10 @@ std::string Config::GetFullKey(const std::string& key, bool skipArrayIndex) {
int Config::BeginArray(const std::string& array) {
array_stack.push_back(ConfigArray{AdjustKey(array), 0, 0});
const int size = config->GetLongValue(GetSection().c_str(), GetFullKey(std::string("size"), true).c_str(), 0);
array_stack.back().size = (std::max)(0, size);
return array_stack.back().size;
const int size = config->GetLongValue(GetSection().c_str(),
GetFullKey(std::string("size"), true).c_str(), 0);
array_stack.back().size = size;
return size;
}
void Config::EndArray() {
@@ -1055,7 +1071,7 @@ void Config::EndArray() {
// Edge-case where the first array created doesn't have a name
config->SetValue(GetSection().c_str(), std::string("size").c_str(), ToString(size).c_str());
} else {
auto const key = GetFullKey(std::string("size"), true);
const auto key = GetFullKey(std::string("size"), true);
config->SetValue(GetSection().c_str(), key.c_str(), ToString(size).c_str());
}
+4 -11
View File
@@ -31,10 +31,8 @@ public:
using clock = std::chrono::system_clock;
explicit Socket(const std::string& host, u16 port, SocketCallback callback_)
: callback(std::move(callback_)), timer(io_context)
, socket(io_context, udp::endpoint(udp::v4(), 0))
, client_id(Common::Random::Random32(0))
{
: callback(std::move(callback_)), timer(io_context),
socket(io_context, udp::endpoint(udp::v4(), 0)), client_id(Common::Random::Random32(0)) {
boost::system::error_code ec{};
auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
if (ec.value() != boost::system::errc::success) {
@@ -355,13 +353,8 @@ PadIdentifier UDPClient::GetPadIdentifier(std::size_t pad_index) const {
}
Common::UUID UDPClient::GetHostUUID(const std::string& host) const {
boost::system::error_code ec{};
auto ip = boost::asio::ip::make_address_v4(host, ec);
if (ec.value() != boost::system::errc::success) {
LOG_ERROR(Input, "Invalid IPv4 address \"{}\" provided", host);
ip = boost::asio::ip::address_v4{};
}
auto const hex_host = fmt::format("00000000-0000-0000-0000-0000{:06x}", ip.to_uint());
const auto ip = boost::asio::ip::make_address_v4(host);
const auto hex_host = fmt::format("00000000-0000-0000-0000-0000{:06x}", ip.to_uint());
return Common::UUID{hex_host};
}
@@ -301,8 +301,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
tr("Controls the seed of the random number generator.\nMainly used for speedrunning."));
INSERT(Settings, rng_seed_enabled, QString(), QString());
INSERT(Settings, device_name, tr("Device Name"), tr("The name of the console."));
INSERT(Settings, program_args, tr("Homebrew Args"),
tr("Command-line arguments passed to homebrew at launch (e.g. -noglsl)."));
INSERT(Settings, custom_rtc, tr("Custom RTC Date:"),
tr("This option allows to change the clock of the console.\n"
"Can be used to manipulate time in games."));
+4 -3
View File
@@ -207,11 +207,12 @@ struct Values {
// Game List
Setting<bool> show_add_ons{linkage, true, "show_add_ons", Category::UiGameList};
Setting<u32, true> game_icon_size{linkage, 64, 8, 512, "game_icon_size", Category::UiGameList};
Setting<u32, true> folder_icon_size{linkage, 48, 8, 512, "folder_icon_size", Category::UiGameList};
Setting<u32> game_icon_size{linkage, 64, "game_icon_size", Category::UiGameList};
Setting<u32> folder_icon_size{linkage, 48, "folder_icon_size", Category::UiGameList};
Setting<u8> row_1_text_id{linkage, 3, "row_1_text_id", Category::UiGameList};
Setting<u8> row_2_text_id{linkage, 2, "row_2_text_id", Category::UiGameList};
Setting<Settings::GameListMode> game_list_mode{linkage, Settings::GameListMode::TreeView, "game_list_mode", Category::UiGameList};
Setting<Settings::GameListMode> game_list_mode{linkage, Settings::GameListMode::TreeView,
"game_list_mode", Category::UiGameList};
Setting<bool> show_game_name{linkage, true, "show_game_name", Category::UiGameList};
std::atomic_bool is_game_list_reload_pending{false};
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -240,14 +240,6 @@ constexpr size_t NUM_FIXEDFNCTEXTURE = 10;
return attribute >= Attribute::Generic0X && attribute <= Attribute::Generic31X;
}
[[nodiscard]] inline bool IsLegacyAttribute(Attribute attribute) noexcept {
return (attribute >= Attribute::ColorFrontDiffuseR &&
attribute <= Attribute::ColorBackSpecularA) ||
attribute == Attribute::FogCoordinate ||
(attribute >= Attribute::FixedFncTexture0S &&
attribute <= Attribute::FixedFncTexture9Q);
}
[[nodiscard]] inline u32 GenericAttributeIndex(Attribute attribute) {
if (!IsGeneric(attribute))
throw InvalidArgument("Attribute is not generic {}", attribute);
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -166,24 +163,12 @@ void TranslatorVisitor::IPA(u64 insn) {
const IR::Attribute attribute{ipa.attribute};
IR::F32 value{is_indexed ? ir.GetAttributeIndexed(X(ipa.index_reg))
: ir.GetAttribute(attribute)};
const bool is_legacy{IR::IsLegacyAttribute(attribute)};
if (IR::IsGeneric(attribute) || is_legacy) {
bool is_perspective{is_legacy &&
ipa.interpolation_mode != InterpolationMode::Sc};
if (!is_legacy) {
const ProgramHeader& sph{env.SPH()};
const u32 attr_index{IR::GenericAttributeIndex(attribute)};
const std::array input_map{sph.ps.GenericInputMap(attr_index)};
Shader::PixelImap effective_imap{Shader::PixelImap::Unused};
for (const Shader::PixelImap component : input_map) {
if (component != Shader::PixelImap::Unused) {
effective_imap = component;
break;
}
}
is_perspective = effective_imap == Shader::PixelImap::Perspective ||
effective_imap == Shader::PixelImap::Unused;
}
if (IR::IsGeneric(attribute)) {
const ProgramHeader& sph{env.SPH()};
const u32 attr_index{IR::GenericAttributeIndex(attribute)};
const u32 element{static_cast<u32>(attribute) % 4};
const std::array input_map{sph.ps.GenericInputMap(attr_index)};
const bool is_perspective{input_map[element] == Shader::PixelImap::Perspective};
if (is_perspective) {
const IR::F32 position_w{ir.GetAttribute(IR::Attribute::PositionW)};
value = ir.FPMul(value, position_w);
@@ -132,7 +132,13 @@ void AddNVNStorageBuffers(IR::Program& program) {
}
}
using IR::IsLegacyAttribute; //rescoped to attribute.h to make it visible in load_store_attribute.cpp IPA
bool IsLegacyAttribute(IR::Attribute attribute) {
return (attribute >= IR::Attribute::ColorFrontDiffuseR &&
attribute <= IR::Attribute::ColorBackSpecularA) ||
attribute == IR::Attribute::FogCoordinate ||
(attribute >= IR::Attribute::FixedFncTexture0S &&
attribute <= IR::Attribute::FixedFncTexture9Q);
}
std::map<IR::Attribute, IR::Attribute> GenerateLegacyToGenericMappings(
const VaryingState& state, std::queue<IR::Attribute> unused_generics,
@@ -1644,6 +1644,8 @@ bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si
start = (std::max)(start, gend);
});
push(start, end);
ClearDownload(addr, range_size);
gpu_modified_ranges.Subtract(addr, range_size);
});
if (upload_copies.empty()) {
return true;
-3
View File
@@ -1117,8 +1117,6 @@ void MacroJITx64Impl::Optimizer_ScanFlags() {
}
void MacroJITx64Impl::Compile() {
// Matching PROTECT_RE needed for W^X systems
setProtectMode(Xbyak::CodeArray::ProtectMode::PROTECT_RW);
labels.fill(Xbyak::Label());
Common::X64::ABI_PushRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
@@ -1166,7 +1164,6 @@ void MacroJITx64Impl::Compile() {
Common::X64::ABI_PopRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
ret();
ready();
setProtectMode(Xbyak::CodeArray::ProtectMode::PROTECT_RE);
program = getCode<ProgramType>();
}
+40 -30
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -12,22 +9,28 @@ namespace Tegra {
// https://github.com/NVIDIA/open-gpu-doc/blob/master/manuals/volta/gv100/dev_mmu.ref.txt
enum class PTEKind : u8 {
PITCH = 0x0,
Z16 = 0x1,
Z16_2C = 0x2,
Z16_MS2_2C = 0x3,
Z16_MS4_2C = 0x4,
Z16_MS8_2C = 0x5,
Z16_MS16_2C = 0x6,
Z16_2Z = 0x7,
Z16_MS2_2Z = 0x8,
Z16_MS4_2Z = 0x9,
Z16_MS8_2Z = 0xa,
Z16_MS16_2Z = 0xb,
Z16_4CZ = 0xc,
Z16_MS2_4CZ = 0xd,
Z16_MS4_4CZ = 0xe,
Z16_MS8_4CZ = 0xf,
INVALID = 0xff,
PITCH = 0x00,
Z16 = 0x01,
Z16_2C = 0x02,
Z16_MS2_2C = 0x03,
Z16_MS4_2C = 0x04,
Z16_MS8_2C = 0x05,
Z16_MS16_2C = 0x06,
Z16_2Z = 0x07,
Z16_MS2_2Z = 0x08,
Z16_MS4_2Z = 0x09,
Z16_MS8_2Z = 0x0a,
Z16_MS16_2Z = 0x0b,
Z16_2CZ = 0x36,
Z16_MS2_2CZ = 0x37,
Z16_MS4_2CZ = 0x38,
Z16_MS8_2CZ = 0x39,
Z16_MS16_2CZ = 0x5f,
Z16_4CZ = 0x0c,
Z16_MS2_4CZ = 0x0d,
Z16_MS4_4CZ = 0x0e,
Z16_MS8_4CZ = 0x0f,
Z16_MS16_4CZ = 0x10,
S8Z24 = 0x11,
S8Z24_1Z = 0x12,
@@ -40,7 +43,7 @@ enum class PTEKind : u8 {
S8Z24_MS4_2CZ = 0x19,
S8Z24_MS8_2CZ = 0x1a,
S8Z24_MS16_2CZ = 0x1b,
S8Z24_2CS = 0x1C,
S8Z24_2CS = 0x1c,
S8Z24_MS2_2CS = 0x1d,
S8Z24_MS4_2CS = 0x1e,
S8Z24_MS8_2CS = 0x1f,
@@ -54,8 +57,6 @@ enum class PTEKind : u8 {
V8Z24_MS4_VC4 = 0x27,
V8Z24_MS8_VC8 = 0x28,
V8Z24_MS8_VC24 = 0x29,
S8 = 0x2a,
S8_2S = 0x2b,
V8Z24_MS4_VC12_1ZV = 0x2e,
V8Z24_MS4_VC4_1ZV = 0x2f,
V8Z24_MS8_VC8_1ZV = 0x30,
@@ -98,9 +99,15 @@ enum class PTEKind : u8 {
Z24S8_MS8_4CSZV = 0x59,
Z24S8_MS16_4CSZV = 0x5a,
Z24V8_MS4_VC12 = 0x5b,
Z24V8_MS4_VC4 = 0x5C,
Z24V8_MS4_VC4 = 0x5c,
Z24V8_MS8_VC8 = 0x5d,
Z24V8_MS8_VC24 = 0x5e,
YUV_B8C1_2Y = 0x60,
YUV_B8C2_2Y = 0x61,
YUV_B10C1_2Y = 0x62,
YUV_B10C2_2Y = 0x6b,
YUV_B12C1_2Y = 0x6c,
YUV_B12C2_2Y = 0x6d,
Z24V8_MS4_VC12_1ZV = 0x63,
Z24V8_MS4_VC4_1ZV = 0x64,
Z24V8_MS8_VC8_1ZV = 0x65,
@@ -122,7 +129,7 @@ enum class PTEKind : u8 {
Z24V8_MS8_VC8_4CSZV = 0x79,
Z24V8_MS8_VC24_4CSZV = 0x7a,
ZF32 = 0x7b,
ZF32_1Z = 0x7C,
ZF32_1Z = 0x7c,
ZF32_MS2_1Z = 0x7d,
ZF32_MS4_1Z = 0x7e,
ZF32_MS8_1Z = 0x7f,
@@ -191,9 +198,6 @@ enum class PTEKind : u8 {
ZF32_X24S8_MS4_1CS = 0xc6,
ZF32_X24S8_MS8_1CS = 0xc7,
ZF32_X24S8_MS16_1CS = 0xc8,
SMASKED_MESSAGE = 0xca,
SMHOST_MESSAGE = 0xcb,
C64_MS2_2CRA = 0xcd,
ZF32_X24S8_2CSZV = 0xce,
ZF32_X24S8_MS2_2CSZV = 0xcf,
ZF32_X24S8_MS4_2CSZV = 0xd0,
@@ -204,6 +208,9 @@ enum class PTEKind : u8 {
ZF32_X24S8_MS4_2CS = 0xd5,
ZF32_X24S8_MS8_2CS = 0xd6,
ZF32_X24S8_MS16_2CS = 0xd7,
S8 = 0x2a,
S8_2S = 0x2b,
GENERIC_16BX2 = 0xfe,
C32_2C = 0xd8,
C32_2CBR = 0xd9,
C32_2CBA = 0xda,
@@ -211,12 +218,13 @@ enum class PTEKind : u8 {
C32_2BRA = 0xdc,
C32_MS2_2C = 0xdd,
C32_MS2_2CBR = 0xde,
C32_MS2_2CRA = 0xcc,
C32_MS2_4CBRA = 0xcc,
C32_MS4_2C = 0xdf,
C32_MS4_2CBR = 0xe0,
C32_MS4_2CBA = 0xe1,
C32_MS4_2CRA = 0xe2,
C32_MS4_2BRA = 0xe3,
C32_MS4_4CBRA = 0x2c,
C32_MS8_MS16_2C = 0xe4,
C32_MS8_MS16_2CRA = 0xe5,
C64_2C = 0xe6,
@@ -226,11 +234,13 @@ enum class PTEKind : u8 {
C64_2BRA = 0xea,
C64_MS2_2C = 0xeb,
C64_MS2_2CBR = 0xec,
C64_MS2_4CBRA = 0xcd,
C64_MS4_2C = 0xed,
C64_MS4_2CBR = 0xee,
C64_MS4_2CBA = 0xef,
C64_MS4_2CRA = 0xf0,
C64_MS4_2BRA = 0xf1,
C64_MS4_4CBRA = 0x2d,
C64_MS8_MS16_2C = 0xf2,
C64_MS8_MS16_2CRA = 0xf3,
C128_2C = 0xf4,
@@ -243,8 +253,8 @@ enum class PTEKind : u8 {
C128_MS8_MS16_2CR = 0xfb,
X8C24 = 0xfc,
PITCH_NO_SWIZZLE = 0xfd,
GENERIC_16BX2 = 0xfe,
INVALID = 0xff,
SMSKED_MESSAGE = 0xca,
SMHOST_MESSAGE = 0xcb,
};
constexpr bool IsPitchKind(PTEKind kind) {
@@ -203,7 +203,6 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS);
max_compute_shared_memory_size = GetInteger<u32>(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
max_glasm_storage_buffer_blocks = GetInteger<u32>(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
max_user_clip_distances = GetInteger<u32>(GL_MAX_CLIP_DISTANCES);
has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group &&
GLAD_GL_NV_shader_thread_shuffle;
has_shader_ballot = GLAD_GL_ARB_shader_ballot;
+1 -6
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
@@ -47,10 +47,6 @@ public:
return max_compute_shared_memory_size;
}
u32 GetMaxUserClipDistances() const {
return max_user_clip_distances;
}
u32 GetMaxGLASMStorageBufferBlocks() const {
return max_glasm_storage_buffer_blocks;
}
@@ -206,7 +202,6 @@ private:
u32 max_varyings{};
u32 max_compute_shared_memory_size{};
u32 max_glasm_storage_buffer_blocks{};
u32 max_user_clip_distances{};
bool has_warp_intrinsics{};
bool has_shader_ballot{};
@@ -238,11 +238,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.ignore_nan_fp_comparisons = true,
.gl_max_compute_smem_size = device.GetMaxComputeSharedMemorySize(),
.min_ssbo_alignment = device.GetShaderStorageBufferAlignment(),
// Use the host limit, but never more than the guest can produce. Maxwell exposes 8 clip
// distances and the SPIR-V output array is sized for at most 8, so clamping here keeps a
// host that reports a different count from under- or over-running that array.
.max_user_clip_distances =
std::min<u32>(device.GetMaxUserClipDistances(), Maxwell::Regs::NumClipDistances),
.max_user_clip_distances = 8,
},
host_info{
.support_float64 = true,
@@ -89,10 +89,11 @@ std::string BuildCommaSeparatedExtensions(
} // Anonymous namespace
Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld, VkSurfaceKHR surface) {
Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld,
VkSurfaceKHR surface) {
const std::vector<VkPhysicalDevice> devices = instance.EnumeratePhysicalDevices();
const u32 device_index = Settings::values.vulkan_device.GetValue();
if (device_index >= u32(devices.size())) {
const s32 device_index = Settings::values.vulkan_device.GetValue();
if (device_index < 0 || device_index >= static_cast<s32>(devices.size())) {
LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index);
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
}
-6
View File
@@ -254,9 +254,6 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
static constexpr u64 SELF_BRANCH_A = 0xE2400FFFFF87000FULL;
static constexpr u64 SELF_BRANCH_B = 0xE2400FFFFF07000FULL;
static constexpr u64 MESA_EXIT_MASK = 0xFFF00000000F001FULL;
static constexpr u64 MESA_EXIT_VALUE = (0xE30ULL << 52) | (0x7ULL << 16) | 0xFULL;
code.resize(MAXIMUM_SIZE / INST_SIZE);
GPUVAddr guest_addr{program_base + start_address};
@@ -270,9 +267,6 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
if (inst == SELF_BRANCH_A || inst == SELF_BRANCH_B) {
return offset + index;
}
if ((inst & MESA_EXIT_MASK) == MESA_EXIT_VALUE) {
return offset + index + INST_SIZE;
}
}
guest_addr += BLOCK_SIZE;
size += BLOCK_SIZE;
@@ -286,12 +286,6 @@ ankerl::unordered_dense::map<VkFormat, VkFormatProperties> GetFormatProperties(v
VK_FORMAT_R8_UNORM,
VK_FORMAT_R8_USCALED,
VK_FORMAT_S8_UINT,
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
};
ankerl::unordered_dense::map<VkFormat, VkFormatProperties> format_properties;
for (const auto format : formats) {
@@ -36,8 +36,8 @@ namespace {
}
[[nodiscard]] std::vector<const char*> RequiredExtensions(
const vk::InstanceDispatch& dld, std::vector<VkExtensionProperties> const& properties,
Core::Frontend::WindowSystemType window_type, bool enable_validation) {
const vk::InstanceDispatch& dld, Core::Frontend::WindowSystemType window_type,
bool enable_validation) {
std::vector<const char*> extensions;
extensions.reserve(6);
switch (window_type) {
@@ -74,14 +74,14 @@ namespace {
if (window_type != Core::Frontend::WindowSystemType::Headless) {
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
}
// Probe optional extensions against the same snapshot the caller verifies against, so the
// check here and the verification in CreateInstance can never disagree (see TOCTOU note below).
if (auto const properties = vk::EnumerateInstanceExtensionProperties(dld); properties) {
#ifdef __APPLE__
if (AreExtensionsSupported(dld, properties, std::array{VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME}))
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
if (AreExtensionsSupported(dld, *properties, std::array{VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME}))
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
#endif
if (enable_validation && AreExtensionsSupported(dld, properties, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME}))
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
if (enable_validation && AreExtensionsSupported(dld, *properties, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME}))
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
return extensions;
}
@@ -128,19 +128,9 @@ vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceD
LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers");
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
}
// Enumerate instance extensions exactly once. RequiredExtensions() used to enumerate a second
// time internally; if the driver returned a different set between the two calls (a real TOCTOU
// seen on some AMD iGPU drivers), an extension added to the list could be missing from the
// verification snapshot, throwing EXTENSION_NOT_PRESENT on an otherwise valid launch. Sharing
// one snapshot for both the optional-extension probe and the final check removes that window.
std::vector<const char*> const extensions = RequiredExtensions(dld, window_type, enable_validation);
auto const properties = vk::EnumerateInstanceExtensionProperties(dld);
if (!properties) {
LOG_ERROR(Render_Vulkan, "Failed to query instance extension properties");
throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT);
}
std::vector<const char*> const extensions =
RequiredExtensions(dld, *properties, window_type, enable_validation);
if (!AreExtensionsSupported(dld, *properties, extensions))
if (!properties || !AreExtensionsSupported(dld, *properties, extensions))
throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT);
std::vector<const char*> layers = Layers(enable_validation);
RemoveUnavailableLayers(dld, layers);
@@ -94,10 +94,11 @@ void ConfigureMotionTouch::SetConfiguration() {
const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
touch_from_button_maps = Settings::values.touch_from_button_maps;
for (const auto& touch_map : touch_from_button_maps)
for (const auto& touch_map : touch_from_button_maps) {
ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
if (auto const index = Settings::values.touch_from_button_map_index.GetValue(); int(index) < ui->touch_from_button_map->count())
ui->touch_from_button_map->setCurrentIndex(index);
}
ui->touch_from_button_map->setCurrentIndex(
Settings::values.touch_from_button_map_index.GetValue());
min_x = touch_param.Get("min_x", 100);
min_y = touch_param.Get("min_y", 50);
+5 -3
View File
@@ -183,7 +183,7 @@ void GameList::ResetViewMode() {
tree_view->setVisible(false);
break;
default:
UNREACHABLE();
break;
}
auto view = m_currentView->viewport();
@@ -196,8 +196,10 @@ void GameList::ResetViewMode() {
auto scroller = QScroller::scroller(view);
QScrollerProperties props;
props.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
props.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
props.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy,
QScrollerProperties::OvershootAlwaysOff);
props.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy,
QScrollerProperties::OvershootAlwaysOff);
scroller->setScrollerProperties(props);
if (m_isTreeMode != newTreeMode) {
+9 -7
View File
@@ -581,7 +581,7 @@ MainWindow::MainWindow(bool has_broken_vulkan)
} else if (should_launch_hlaunch) {
std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir);
auto const hbl_path = (sd_dir / "atmosphere" / "hbl.nsp").string();
BootGame(QString::fromStdString(hbl_path), LibraryAppletParameters(0x010000000000100Dull, Service::AM::AppletId::QLaunch));
BootGame(QString::fromStdString(hbl_path), ApplicationAppletParameters());
}
}
}
@@ -1088,9 +1088,10 @@ void MainWindow::InitializeWidgets() {
aa_status_button->setFocusPolicy(Qt::NoFocus);
connect(aa_status_button, &QPushButton::clicked, [&] {
auto aa_mode = Settings::values.anti_aliasing.GetValue();
aa_mode = Settings::AntiAliasing(u32(aa_mode) + 1);
if (u32(aa_mode) > u32(Settings::EnumMetadata<Settings::AntiAliasing>::GetLast()))
aa_mode = Settings::EnumMetadata<Settings::AntiAliasing>::GetFirst();
aa_mode = static_cast<Settings::AntiAliasing>(static_cast<u32>(aa_mode) + 1);
if (aa_mode == Settings::AntiAliasing::MaxEnum) {
aa_mode = Settings::AntiAliasing::None;
}
Settings::values.anti_aliasing.SetValue(aa_mode);
aa_status_button->setChecked(true);
UpdateAAText();
@@ -3622,9 +3623,10 @@ void MainWindow::OnIncreaseVolume() {
void MainWindow::OnToggleAdaptingFilter() {
auto filter = Settings::values.scaling_filter.GetValue();
filter = Settings::ScalingFilter(u32(filter) + 1);
if (u32(filter) > u32(Settings::EnumMetadata<Settings::ScalingFilter>::GetLast()))
filter = Settings::EnumMetadata<Settings::ScalingFilter>::GetFirst();
filter = static_cast<Settings::ScalingFilter>(static_cast<u32>(filter) + 1);
if (filter == Settings::ScalingFilter::MaxEnum) {
filter = Settings::ScalingFilter::NearestNeighbor;
}
Settings::values.scaling_filter.SetValue(filter);
filter_status_button->setChecked(true);
UpdateFilterText();
-2
View File
@@ -28,8 +28,6 @@ Tools for Eden and other subprojects. When adding new scripts please use `#!/bin
- `clang-format.sh`: Runs `clang-format` on the entire codebase.
* Requires: clang
- `find-unused-strings.sh`: Find any unused strings in the Android app (XML -> Kotlin).
- `cpp-lint.sh`: Homemade dumb C++ linter.
- `fuzzsettings.cpp`: Fuzz settings files.
## Android
It's recommended to run these scritps after almost any Android change, as they are relatively fast and important both for APK bloat and CI.
+13 -2
View File
@@ -83,8 +83,13 @@ for pkg in $packages; do
echo "-- Package $PACKAGE"
# TODO(crueter): Support for Forgejo updates w/ forgejo_token
# Use gh-cli to avoid ratelimits lmao
TAGS=$(gh api --method GET "/repos/$REPO/tags")
# Use gh-cli to avoid ratelimits, if available
endpoint="/repos/$REPO/tags"
if command -v gh >/dev/null 2>&1; then
TAGS=$(gh api --method GET "$endpoint")
else
TAGS=$(curl -sfL "https://api.github.com$endpoint")
fi
# filter out some commonly known annoyances
# TODO add more
@@ -105,6 +110,12 @@ for pkg in $packages; do
filter_out beta
filter_out rc
# openssl
if [ "$PACKAGE" = openssl ]; then
filter_out rsaref
filter_in "openssl-"
fi
# Add package-specific overrides here, e.g. here for fmt:
[ "$PACKAGE" != fmt ] || filter_out v0.11
-63
View File
@@ -1,63 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <ctime>
#include <string>
#include <string_view>
int main(int argc, char *argv[]) {
std::srand(unsigned(std::time(nullptr)));
FILE *fp = std::fopen(argv[1], "rt");
if (fp) {
char line[BUFSIZ];
while (std::fgets(line, sizeof(line), fp)) {
if (line[0] == '[') {
std::printf("%s", line);
} else if (std::isspace(line[0])) {
std::printf("%s", line);
} else {
char *p = std::strchr(line, '=');
if (std::strstr(line, "\\default") == nullptr) {
// not default
*p = '\0';
std::string new_line{line};
std::string value{p + 1};
if (value == "true" || value == "false") {
new_line += std::string{} + "=TreufLAlse857874FJJakshjryiu475" + '\n';
} else if (std::isdigit(value[0])) {
if (new_line == "size"
|| std::strstr(new_line.c_str(), "entries\\size") != nullptr
|| std::strstr(new_line.c_str(), "\\size")) {
new_line += "=-1\n";
} else {
new_line += '=' + std::to_string(int(std::rand())) + '\n';
}
} else {
std::string_view const cset{"03832///1/1/.1/1./1./1./1.1/.1194573290uwmgjouidyhiomHMNIODASJK,POF MSHDVLJPOIuksdtpsunmghns"};
std::string rst{"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"};
for (size_t i = 0; i < rst.size(); ++i)
rst[i] = cset[std::rand() % cset.size()];
//new_line += "=\"" + rst + "\"";
new_line += "=" + value;
}
std::printf("%s", new_line.c_str());
} else {
// yes default
*p = '\0';
std::string new_line{line};
std::string value{p + 1};
new_line += "=false\n";
std::printf("%s", new_line.c_str());
}
}
}
std::fclose(fp);
}
return 0;
}
-12
View File
@@ -1,12 +0,0 @@
#!/bin/sh -ex
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
ROOTDIR=$(CDPATH='' cd -- "$(dirname -- "$0")/" && pwd)
touch "$2"
c++ "$ROOTDIR/fuzzsettings.cpp" -o fuzzsettings
./fuzzsettings "$1" >"$2"
rm fuzzsettings