diff --git a/CMakeLists.txt b/CMakeLists.txt index dd8df7ba7..e32aabd0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,7 +203,7 @@ execute_process( # Set Version set(EMULATOR_VERSION_MAJOR "0") -set(EMULATOR_VERSION_MINOR "9") +set(EMULATOR_VERSION_MINOR "10") set(EMULATOR_VERSION_PATCH "1") set_source_files_properties(src/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}") diff --git a/dist/net.shadps4.shadPS4.metainfo.xml b/dist/net.shadps4.shadPS4.metainfo.xml index 493dc0df6..f9bd7c7c2 100644 --- a/dist/net.shadps4.shadPS4.metainfo.xml +++ b/dist/net.shadps4.shadPS4.metainfo.xml @@ -37,6 +37,9 @@ Game + + https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.10.0 + https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.9.0 diff --git a/src/common/config.cpp b/src/common/config.cpp index 4a764a4c6..d3a5fa6a1 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -31,31 +31,50 @@ std::filesystem::path find_fs_path_or(const basic_value& v, const K& ky, namespace Config { +// General static bool isNeo = false; static bool isDevKit = false; +static bool isPSNSignedIn = false; static bool isTrophyPopupDisabled = false; +static double trophyNotificationDuration = 6.0; static bool enableDiscordRPC = false; -static u32 screenWidth = 1280; -static u32 screenHeight = 720; -static s32 gpuId = -1; // Vulkan physical device index. Set to negative for auto select -static std::string logFilter; +static std::string logFilter = ""; static std::string logType = "sync"; static std::string userName = "shadPS4"; -static std::string chooseHomeTab; +static std::string chooseHomeTab = "General"; +static bool isShowSplash = false; +static std::string isSideTrophy = "right"; +static bool compatibilityData = false; +static bool checkCompatibilityOnStartup = false; + +// Input +static int cursorState = HideCursorState::Idle; +static int cursorHideTimeout = 5; // 5 seconds (default) static bool useSpecialPad = false; static int specialPadClass = 1; static bool isMotionControlsEnabled = true; -static bool isDebugDump = false; -static bool isShaderDebug = false; -static bool isShowSplash = false; -static std::string isSideTrophy = "right"; +static bool useUnifiedInputConfig = true; + +// These two entries aren't stored in the config +static bool overrideControllerColor = false; +static int controllerCustomColorRGB[3] = {0, 0, 255}; + +// GPU +static u32 screenWidth = 1280; +static u32 screenHeight = 720; static bool isNullGpu = false; static bool shouldCopyGPUBuffers = false; static bool readbacksEnabled = false; static bool directMemoryAccessEnabled = false; static bool shouldDumpShaders = false; -static bool shouldPatchShaders = true; +static bool shouldPatchShaders = false; static u32 vblankDivider = 1; +static bool isFullscreen = false; +static std::string fullscreenMode = "Windowed"; +static bool isHDRAllowed = false; + +// Vulkan +static s32 gpuId = -1; static bool vkValidation = false; static bool vkValidationSync = false; static bool vkValidationGpu = false; @@ -63,32 +82,29 @@ static bool vkCrashDiagnostic = false; static bool vkHostMarkers = false; static bool vkGuestMarkers = false; static bool rdocEnable = false; -static bool isFpsColor = true; -static bool isSeparateLogFilesEnabled = false; -static int cursorState = HideCursorState::Idle; -static int cursorHideTimeout = 5; // 5 seconds (default) -static double trophyNotificationDuration = 6.0; -static bool useUnifiedInputConfig = true; -static bool overrideControllerColor = false; -static int controllerCustomColorRGB[3] = {0, 0, 255}; -static bool compatibilityData = false; -static bool checkCompatibilityOnStartup = false; -static std::string trophyKey; -static bool isPSNSignedIn = false; -// Gui +// Debug +static bool isDebugDump = false; +static bool isShaderDebug = false; +static bool isSeparateLogFilesEnabled = false; +static bool isFpsColor = true; + +// GUI static bool load_game_size = true; static std::vector settings_install_dirs = {}; std::vector install_dirs_enabled = {}; std::filesystem::path settings_addon_install_dir = {}; std::filesystem::path save_data_path = {}; -static bool isFullscreen = false; -static std::string fullscreenMode = "Windowed"; -static bool isHDRAllowed = false; -// Language +// Settings u32 m_language = 1; // english +// Keys +static std::string trophyKey = ""; + +// Expected number of items in the config file +static constexpr u64 total_entries = 51; + bool allowHDR() { return isHDRAllowed; } @@ -565,36 +581,46 @@ void load(const std::filesystem::path& path) { fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); return; } + + u64 entry_count = 0; + if (data.contains("General")) { const toml::value& general = data.at("General"); - isNeo = toml::find_or(general, "isPS4Pro", false); - isDevKit = toml::find_or(general, "isDevKit", false); - isPSNSignedIn = toml::find_or(general, "isPSNSignedIn", false); - isTrophyPopupDisabled = toml::find_or(general, "isTrophyPopupDisabled", false); - trophyNotificationDuration = - toml::find_or(general, "trophyNotificationDuration", 5.0); - enableDiscordRPC = toml::find_or(general, "enableDiscordRPC", true); - logFilter = toml::find_or(general, "logFilter", ""); - logType = toml::find_or(general, "logType", "sync"); - userName = toml::find_or(general, "userName", "shadPS4"); - isShowSplash = toml::find_or(general, "showSplash", true); - isSideTrophy = toml::find_or(general, "sideTrophy", "right"); - compatibilityData = toml::find_or(general, "compatibilityEnabled", false); - checkCompatibilityOnStartup = - toml::find_or(general, "checkCompatibilityOnStartup", false); - chooseHomeTab = toml::find_or(general, "chooseHomeTab", "Release"); + isNeo = toml::find_or(general, "isPS4Pro", isNeo); + isDevKit = toml::find_or(general, "isDevKit", isDevKit); + isPSNSignedIn = toml::find_or(general, "isPSNSignedIn", isPSNSignedIn); + isTrophyPopupDisabled = + toml::find_or(general, "isTrophyPopupDisabled", isTrophyPopupDisabled); + trophyNotificationDuration = toml::find_or(general, "trophyNotificationDuration", + trophyNotificationDuration); + enableDiscordRPC = toml::find_or(general, "enableDiscordRPC", enableDiscordRPC); + logFilter = toml::find_or(general, "logFilter", logFilter); + logType = toml::find_or(general, "logType", logType); + userName = toml::find_or(general, "userName", userName); + isShowSplash = toml::find_or(general, "showSplash", isShowSplash); + isSideTrophy = toml::find_or(general, "sideTrophy", isSideTrophy); + compatibilityData = toml::find_or(general, "compatibilityEnabled", compatibilityData); + checkCompatibilityOnStartup = toml::find_or(general, "checkCompatibilityOnStartup", + checkCompatibilityOnStartup); + chooseHomeTab = toml::find_or(general, "chooseHomeTab", chooseHomeTab); + + entry_count += general.size(); } if (data.contains("Input")) { const toml::value& input = data.at("Input"); - cursorState = toml::find_or(input, "cursorState", HideCursorState::Idle); - cursorHideTimeout = toml::find_or(input, "cursorHideTimeout", 5); - useSpecialPad = toml::find_or(input, "useSpecialPad", false); - specialPadClass = toml::find_or(input, "specialPadClass", 1); - isMotionControlsEnabled = toml::find_or(input, "isMotionControlsEnabled", true); - useUnifiedInputConfig = toml::find_or(input, "useUnifiedInputConfig", true); + cursorState = toml::find_or(input, "cursorState", cursorState); + cursorHideTimeout = toml::find_or(input, "cursorHideTimeout", cursorHideTimeout); + useSpecialPad = toml::find_or(input, "useSpecialPad", useSpecialPad); + specialPadClass = toml::find_or(input, "specialPadClass", specialPadClass); + isMotionControlsEnabled = + toml::find_or(input, "isMotionControlsEnabled", isMotionControlsEnabled); + useUnifiedInputConfig = + toml::find_or(input, "useUnifiedInputConfig", useUnifiedInputConfig); + + entry_count += input.size(); } if (data.contains("GPU")) { @@ -602,44 +628,52 @@ void load(const std::filesystem::path& path) { screenWidth = toml::find_or(gpu, "screenWidth", screenWidth); screenHeight = toml::find_or(gpu, "screenHeight", screenHeight); - isNullGpu = toml::find_or(gpu, "nullGpu", false); - shouldCopyGPUBuffers = toml::find_or(gpu, "copyGPUBuffers", false); - readbacksEnabled = toml::find_or(gpu, "readbacks", false); - directMemoryAccessEnabled = toml::find_or(gpu, "directMemoryAccess", false); - shouldDumpShaders = toml::find_or(gpu, "dumpShaders", false); - shouldPatchShaders = toml::find_or(gpu, "patchShaders", true); - vblankDivider = toml::find_or(gpu, "vblankDivider", 1); - isFullscreen = toml::find_or(gpu, "Fullscreen", false); - fullscreenMode = toml::find_or(gpu, "FullscreenMode", "Windowed"); - isHDRAllowed = toml::find_or(gpu, "allowHDR", false); + isNullGpu = toml::find_or(gpu, "nullGpu", isNullGpu); + shouldCopyGPUBuffers = toml::find_or(gpu, "copyGPUBuffers", shouldCopyGPUBuffers); + readbacksEnabled = toml::find_or(gpu, "readbacks", readbacksEnabled); + directMemoryAccessEnabled = + toml::find_or(gpu, "directMemoryAccess", directMemoryAccessEnabled); + shouldDumpShaders = toml::find_or(gpu, "dumpShaders", shouldDumpShaders); + shouldPatchShaders = toml::find_or(gpu, "patchShaders", shouldPatchShaders); + vblankDivider = toml::find_or(gpu, "vblankDivider", vblankDivider); + isFullscreen = toml::find_or(gpu, "Fullscreen", isFullscreen); + fullscreenMode = toml::find_or(gpu, "FullscreenMode", fullscreenMode); + isHDRAllowed = toml::find_or(gpu, "allowHDR", isHDRAllowed); + + entry_count += gpu.size(); } if (data.contains("Vulkan")) { const toml::value& vk = data.at("Vulkan"); - gpuId = toml::find_or(vk, "gpuId", -1); - vkValidation = toml::find_or(vk, "validation", false); - vkValidationSync = toml::find_or(vk, "validation_sync", false); - vkValidationGpu = toml::find_or(vk, "validation_gpu", true); - vkCrashDiagnostic = toml::find_or(vk, "crashDiagnostic", false); - vkHostMarkers = toml::find_or(vk, "hostMarkers", false); - vkGuestMarkers = toml::find_or(vk, "guestMarkers", false); - rdocEnable = toml::find_or(vk, "rdocEnable", false); + gpuId = toml::find_or(vk, "gpuId", gpuId); + vkValidation = toml::find_or(vk, "validation", vkValidation); + vkValidationSync = toml::find_or(vk, "validation_sync", vkValidationSync); + vkValidationGpu = toml::find_or(vk, "validation_gpu", vkValidationGpu); + vkCrashDiagnostic = toml::find_or(vk, "crashDiagnostic", vkCrashDiagnostic); + vkHostMarkers = toml::find_or(vk, "hostMarkers", vkHostMarkers); + vkGuestMarkers = toml::find_or(vk, "guestMarkers", vkGuestMarkers); + rdocEnable = toml::find_or(vk, "rdocEnable", rdocEnable); + + entry_count += vk.size(); } if (data.contains("Debug")) { const toml::value& debug = data.at("Debug"); - isDebugDump = toml::find_or(debug, "DebugDump", false); - isSeparateLogFilesEnabled = toml::find_or(debug, "isSeparateLogFilesEnabled", false); - isShaderDebug = toml::find_or(debug, "CollectShader", false); - isFpsColor = toml::find_or(debug, "FPSColor", true); + isDebugDump = toml::find_or(debug, "DebugDump", isDebugDump); + isSeparateLogFilesEnabled = + toml::find_or(debug, "isSeparateLogFilesEnabled", isSeparateLogFilesEnabled); + isShaderDebug = toml::find_or(debug, "CollectShader", isShaderDebug); + isFpsColor = toml::find_or(debug, "FPSColor", isFpsColor); + + entry_count += debug.size(); } if (data.contains("GUI")) { const toml::value& gui = data.at("GUI"); - load_game_size = toml::find_or(gui, "loadGameSizeEnabled", true); + load_game_size = toml::find_or(gui, "loadGameSizeEnabled", load_game_size); const auto install_dir_array = toml::find_or>(gui, "installDirs", {}); @@ -661,20 +695,32 @@ void load(const std::filesystem::path& path) { {std::filesystem::path{install_dir_array[i]}, install_dirs_enabled[i]}); } - save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {}); + save_data_path = toml::find_fs_path_or(gui, "saveDataPath", save_data_path); - settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {}); + settings_addon_install_dir = + toml::find_fs_path_or(gui, "addonInstallDir", settings_addon_install_dir); + + entry_count += gui.size(); } if (data.contains("Settings")) { const toml::value& settings = data.at("Settings"); + m_language = toml::find_or(settings, "consoleLanguage", m_language); - m_language = toml::find_or(settings, "consoleLanguage", 1); + entry_count += settings.size(); } if (data.contains("Keys")) { const toml::value& keys = data.at("Keys"); - trophyKey = toml::find_or(keys, "TrophyKey", ""); + trophyKey = toml::find_or(keys, "TrophyKey", trophyKey); + + entry_count += keys.size(); + } + + // Run save after loading to generate any missing fields with default values. + if (entry_count != total_entries) { + fmt::print("Outdated config detected, updating config file.\n"); + save(path); } } @@ -822,32 +868,50 @@ void save(const std::filesystem::path& path) { } void setDefaultValues() { - isHDRAllowed = false; + // General isNeo = false; isDevKit = false; isPSNSignedIn = false; - isFullscreen = false; isTrophyPopupDisabled = false; - enableDiscordRPC = true; - screenWidth = 1280; - screenHeight = 720; + trophyNotificationDuration = 6.0; + enableDiscordRPC = false; logFilter = ""; logType = "sync"; userName = "shadPS4"; - chooseHomeTab = "General"; - cursorState = HideCursorState::Idle; - cursorHideTimeout = 5; - trophyNotificationDuration = 6.0; - useSpecialPad = false; - specialPadClass = 1; - isDebugDump = false; - isShaderDebug = false; isShowSplash = false; isSideTrophy = "right"; + compatibilityData = false; + checkCompatibilityOnStartup = false; + + // Input + cursorState = HideCursorState::Idle; + cursorHideTimeout = 5; + useSpecialPad = false; + specialPadClass = 1; + isMotionControlsEnabled = true; + useUnifiedInputConfig = true; + overrideControllerColor = false; + controllerCustomColorRGB[0] = 0; + controllerCustomColorRGB[1] = 0; + controllerCustomColorRGB[2] = 255; + + // GPU + screenWidth = 1280; + screenHeight = 720; isNullGpu = false; + shouldCopyGPUBuffers = false; + readbacksEnabled = false; + directMemoryAccessEnabled = false; shouldDumpShaders = false; + shouldPatchShaders = false; vblankDivider = 1; + isFullscreen = false; + fullscreenMode = "Windowed"; + isHDRAllowed = false; + + // Vulkan + gpuId = -1; vkValidation = false; vkValidationSync = false; vkValidationGpu = false; @@ -855,10 +919,18 @@ void setDefaultValues() { vkHostMarkers = false; vkGuestMarkers = false; rdocEnable = false; + + // Debug + isDebugDump = false; + isShaderDebug = false; + isSeparateLogFilesEnabled = false; + isFpsColor = true; + + // GUI + load_game_size = true; + + // Settings m_language = 1; - gpuId = -1; - compatibilityData = false; - checkCompatibilityOnStartup = false; } constexpr std::string_view GetDefaultKeyboardConfig() { diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 2e29f70ee..846bb5eb4 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -358,9 +358,17 @@ enum PosixPageProtection { [[nodiscard]] constexpr PosixPageProtection ToPosixProt(Core::MemoryProt prot) { if (True(prot & Core::MemoryProt::CpuReadWrite) || True(prot & Core::MemoryProt::GpuReadWrite)) { - return PAGE_READWRITE; + if (True(prot & Core::MemoryProt::CpuExec)) { + return PAGE_EXECUTE_READWRITE; + } else { + return PAGE_READWRITE; + } } else if (True(prot & Core::MemoryProt::CpuRead) || True(prot & Core::MemoryProt::GpuRead)) { - return PAGE_READONLY; + if (True(prot & Core::MemoryProt::CpuExec)) { + return PAGE_EXECUTE_READ; + } else { + return PAGE_READONLY; + } } else { return PAGE_NOACCESS; } diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index 114a096ca..e0c359f2c 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -573,11 +573,12 @@ void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, auto* memory = Core::Memory::Instance(); const auto mem_prot = static_cast(prot); const auto mem_flags = static_cast(flags); + const auto is_exec = True(mem_prot & Core::MemoryProt::CpuExec); s32 result = ORBIS_OK; if (fd == -1) { result = memory->MapMemory(&addr_out, std::bit_cast(addr), len, mem_prot, mem_flags, - Core::VMAType::Flexible); + Core::VMAType::Flexible, "anon", is_exec); } else { result = memory->MapFile(&addr_out, std::bit_cast(addr), len, mem_prot, mem_flags, fd, phys_addr); @@ -711,6 +712,7 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) { sceKernelConfiguredFlexibleMemorySize); LIB_FUNCTION("vSMAm3cxYTY", "libkernel", 1, "libkernel", 1, 1, sceKernelMprotect); + LIB_FUNCTION("YQOfxL4QfeU", "libkernel", 1, "libkernel", 1, 1, posix_mprotect); LIB_FUNCTION("YQOfxL4QfeU", "libScePosix", 1, "libkernel", 1, 1, posix_mprotect); LIB_FUNCTION("9bfdLIyuwCY", "libkernel", 1, "libkernel", 1, 1, sceKernelMtypeprotect); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 2372fafb5..3d9bf58a7 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -342,7 +342,7 @@ s32 MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, u64 size, Memo } } - // Limit the minumum address to SystemManagedVirtualBase to prevent hardware-specific issues. + // Limit the minimum address to SystemManagedVirtualBase to prevent hardware-specific issues. VAddr mapped_addr = (virtual_addr == 0) ? impl.SystemManagedVirtualBase() : virtual_addr; // Fixed mapping means the virtual address must exactly match the provided one. @@ -631,6 +631,9 @@ s64 MemoryManager::ProtectBytes(VAddr addr, VirtualMemoryArea vma_base, u64 size if (True(prot & MemoryProt::CpuReadWrite)) { perms |= Core::MemoryPermission::ReadWrite; } + if (True(prot & MemoryProt::CpuExec)) { + perms |= Core::MemoryPermission::Execute; + } if (True(prot & MemoryProt::GpuRead)) { perms |= Core::MemoryPermission::Read; } @@ -650,9 +653,9 @@ s32 MemoryManager::Protect(VAddr addr, u64 size, MemoryProt prot) { std::scoped_lock lk{mutex}; // Validate protection flags - constexpr static MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | - MemoryProt::CpuReadWrite | MemoryProt::GpuRead | - MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; + constexpr static MemoryProt valid_flags = + MemoryProt::NoAccess | MemoryProt::CpuRead | MemoryProt::CpuReadWrite | + MemoryProt::CpuExec | MemoryProt::GpuRead | MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; MemoryProt invalid_flags = prot & ~valid_flags; if (invalid_flags != MemoryProt::NoAccess) { diff --git a/src/core/memory.h b/src/core/memory.h index c800ef763..285d7dbed 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -31,6 +31,7 @@ enum class MemoryProt : u32 { NoAccess = 0, CpuRead = 1, CpuReadWrite = 2, + CpuExec = 4, GpuRead = 16, GpuWrite = 32, GpuReadWrite = 48, diff --git a/src/qt_gui/translations/ca_ES.ts b/src/qt_gui/translations/ca_ES.ts index c508a7146..9b7f47c75 100644 --- a/src/qt_gui/translations/ca_ES.ts +++ b/src/qt_gui/translations/ca_ES.ts @@ -527,71 +527,71 @@ unmapped - unmapped + sense assignar L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + Opcions R2 - R2 + R2 Touchpad Left - Touchpad Left + Touchpad esquerra Touchpad Center - Touchpad Center + Touchpad centre Touchpad Right - Touchpad Right + Touchpad dreta Triangle - Triangle + Triangle Square - Square + Quadrat Circle - Circle + Cercle Cross - Cross + Creu Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: + No es pot assignar una entrada més d'una vegada. S'han assignat de manera duplicada pels següents botons: %1 Press a button - Press a button + Clica un botó Move analog stick - Move analog stick + Mou la palanca diff --git a/src/qt_gui/translations/es_ES.ts b/src/qt_gui/translations/es_ES.ts index a31279d37..72b18437c 100644 --- a/src/qt_gui/translations/es_ES.ts +++ b/src/qt_gui/translations/es_ES.ts @@ -527,71 +527,69 @@ unmapped - unmapped + sin vincular L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + Opciones R2 - R2 + R2 Touchpad Left - Touchpad Left + Izquierda del Touchpad Touchpad Center - Touchpad Center + Centro del Touchpad Touchpad Right - Touchpad Right + Derecha del Touchpad Triangle - Triangle + Triángulo Square - Square + Cuadrado Circle - Circle + Círculo Cross - Cross + Equis Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: - -%1 + No se puede asignar un control único más de una vez. Controles duplicados asignados a los siguientes botones Press a button - Press a button + Presiona un botón Move analog stick - Move analog stick + Mueve el stick analógico @@ -778,7 +776,7 @@ Favorite - Favorite + Favorito @@ -984,11 +982,11 @@ Remove from Favorites - Remove from Favorites + Eliminar de Favoritos Add to Favorites - Add to Favorites + Añadir a favoritos @@ -1220,21 +1218,19 @@ Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: - -%1 + No se puede asignar un control único más de una vez. Controles duplicados asignados a los siguientes botones: Touchpad Left - Touchpad Left + Izquierda del Touchpad Touchpad Center - Touchpad Center + Centro del Touchpad Touchpad Right - Touchpad Right + Derecha del Touchpad diff --git a/src/qt_gui/translations/it_IT.ts b/src/qt_gui/translations/it_IT.ts index c636d48e4..5cd1a01f8 100644 --- a/src/qt_gui/translations/it_IT.ts +++ b/src/qt_gui/translations/it_IT.ts @@ -527,71 +527,71 @@ unmapped - unmapped + non mappato L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + Opzioni R2 - R2 + R2 Touchpad Left - Touchpad Left + Touchpad Sinistra Touchpad Center - Touchpad Center + Touchpad Centrale Touchpad Right - Touchpad Right + Touchpad Destra Triangle - Triangle + Triangolo Square - Square + Quadrato Circle - Circle + Cerchio Cross - Cross + Croce Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: + Non è possibile associare più di una volta qualsiasi input univoco. Sono presenti input duplicati mappati ai seguenti pulsanti: %1 Press a button - Press a button + Premi un pulsante Move analog stick - Move analog stick + Muovi levetta analogica @@ -778,7 +778,7 @@ Favorite - Favorite + Preferiti @@ -984,11 +984,11 @@ Remove from Favorites - Remove from Favorites + Rimuovi dai Preferiti Add to Favorites - Add to Favorites + Aggiungi ai preferiti @@ -1226,15 +1226,15 @@ Touchpad Left - Touchpad Left + Touchpad Sinistra Touchpad Center - Touchpad Center + Touchpad Centrale Touchpad Right - Touchpad Right + Touchpad Destra diff --git a/src/qt_gui/translations/nb_NO.ts b/src/qt_gui/translations/nb_NO.ts index 302229933..eea0f6eb7 100644 --- a/src/qt_gui/translations/nb_NO.ts +++ b/src/qt_gui/translations/nb_NO.ts @@ -495,7 +495,7 @@ Override Lightbar Color - Overstyr farge på lyslinja + Overstyr farge på lyslisten Override Color @@ -527,71 +527,71 @@ unmapped - unmapped + Ikke tildelt L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + Options R2 - R2 + R2 Touchpad Left - Touchpad Left + Venstre berøringsplate Touchpad Center - Touchpad Center + Midt berøringsplate Touchpad Right - Touchpad Right + Høyre berøringsplate Triangle - Triangle + Triangel Square - Square + Firkant Circle - Circle + Sirkel Cross - Cross + Kryss Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: + Kan ikke tildele samme inndata mer enn én gang. Dupliserte inndata tildeles følgende taster: %1 Press a button - Press a button + Trykk på en knapp Move analog stick - Move analog stick + Flytt på analog stikke @@ -1226,15 +1226,15 @@ Touchpad Left - Berøringsplate venstre + Venstre berøringsplate Touchpad Center - Berøringsplate midten + Midt berøringsplate Touchpad Right - Berøringsplate høyre + Høyre berøringsplate diff --git a/src/qt_gui/translations/pt_BR.ts b/src/qt_gui/translations/pt_BR.ts index c2058bf09..7fa0aea67 100644 --- a/src/qt_gui/translations/pt_BR.ts +++ b/src/qt_gui/translations/pt_BR.ts @@ -555,7 +555,7 @@ Touchpad Center - Touchpad Center + Centro do Touchpad Touchpad Right @@ -571,11 +571,11 @@ Circle - Circle + Círculo Cross - Cross + Cruz Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: @@ -591,7 +591,7 @@ Move analog stick - Move analog stick + Mover analógico diff --git a/src/qt_gui/translations/ru_RU.ts b/src/qt_gui/translations/ru_RU.ts index 7293a956e..1bbc2b3b8 100644 --- a/src/qt_gui/translations/ru_RU.ts +++ b/src/qt_gui/translations/ru_RU.ts @@ -591,7 +591,7 @@ Move analog stick - Move analog stick + Двиньте аналоговый стик diff --git a/src/qt_gui/translations/sq_AL.ts b/src/qt_gui/translations/sq_AL.ts index 71308a99f..9908dc564 100644 --- a/src/qt_gui/translations/sq_AL.ts +++ b/src/qt_gui/translations/sq_AL.ts @@ -527,71 +527,71 @@ unmapped - unmapped + pacaktuar L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + Options R2 - R2 + R2 Touchpad Left - Touchpad Left + Paneli me Prekje Majtas Touchpad Center - Touchpad Center + Paneli me Prekje në Qendër Touchpad Right - Touchpad Right + Paneli me Prekje Djathtas Triangle - Triangle + Trekëndësh Square - Square + Katror Circle - Circle + Rreth Cross - Cross + Kryq Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: + Nuk mund të caktohet e njëjta hyrje unike më shumë se një herë. Hyrjet e dyfishta janë caktuar në butonët e mëposhtëm: %1 Press a button - Press a button + Shtyp një buton Move analog stick - Move analog stick + Lëviz levën diff --git a/src/qt_gui/translations/sv_SE.ts b/src/qt_gui/translations/sv_SE.ts index 83081bf1a..65762f974 100644 --- a/src/qt_gui/translations/sv_SE.ts +++ b/src/qt_gui/translations/sv_SE.ts @@ -527,71 +527,71 @@ unmapped - unmapped + omappad L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + Options R2 - R2 + R2 Touchpad Left - Touchpad Left + Pekplatta vänster Touchpad Center - Touchpad Center + Pekplatta i mitten Touchpad Right - Touchpad Right + Pekplatta höger Triangle - Triangle + Triangel Square - Square + Fyrkant Circle - Circle + Cirkel Cross - Cross + Kors Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: + Det går inte att binda samma unika inmatning mer än en gång. Dubbletta inmatningar är mappade till följande knappar: %1 Press a button - Press a button + Tryck på en knapp Move analog stick - Move analog stick + Rör analog spak diff --git a/src/qt_gui/translations/zh_CN.ts b/src/qt_gui/translations/zh_CN.ts index 2956d9621..4504a2c11 100644 --- a/src/qt_gui/translations/zh_CN.ts +++ b/src/qt_gui/translations/zh_CN.ts @@ -527,71 +527,71 @@ unmapped - unmapped + 未映射 L1 - L1 + L1 R1 - R1 + R1 L2 - L2 + L2 Options - Options + 选项 R2 - R2 + R2 Touchpad Left - Touchpad Left + 触摸板左侧 Touchpad Center - Touchpad Center + 触控板中间 Touchpad Right - Touchpad Right + 触摸板右侧 Triangle - Triangle + 三角 Square - Square + 方框 Circle - Circle + Cross - Cross + Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: %1 - Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons: + 不能多次绑定任何同一输入。请重新映射以下按键的输入: %1 Press a button - Press a button + 请按一个按键 Move analog stick - Move analog stick + 移动模拟摇杆 diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 1ac2266bd..6e146c5f6 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -353,7 +353,7 @@ Id EmitFPIsInf32(EmitContext& ctx, Id value); Id EmitFPIsInf64(EmitContext& ctx, Id value); Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); Id EmitIAdd64(EmitContext& ctx, Id a, Id b); -Id EmitIAddCary32(EmitContext& ctx, Id a, Id b); +Id EmitIAddCarry32(EmitContext& ctx, Id a, Id b); Id EmitISub32(EmitContext& ctx, Id a, Id b); Id EmitISub64(EmitContext& ctx, Id a, Id b); Id EmitSMulHi(EmitContext& ctx, Id a, Id b); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index ddc1e7574..01652c1cf 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp @@ -60,7 +60,7 @@ Id EmitIAdd64(EmitContext& ctx, Id a, Id b) { return ctx.OpIAdd(ctx.U64, a, b); } -Id EmitIAddCary32(EmitContext& ctx, Id a, Id b) { +Id EmitIAddCarry32(EmitContext& ctx, Id a, Id b) { return ctx.OpIAddCarry(ctx.full_result_u32x2, a, b); } diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index 54f1088f2..74c7ec601 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -623,12 +623,15 @@ void Translator::V_ADDC_U32(const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 carry{GetCarryIn(inst)}; - const IR::U32 result{ir.IAdd(ir.IAdd(src0, src1), carry)}; - SetDst(inst.dst[0], result); + const IR::Value tmp1{ir.IAddCarry(src0, src1)}; + const IR::U32 result1{ir.CompositeExtract(tmp1, 0)}; + const IR::U32 carry_out1{ir.CompositeExtract(tmp1, 1)}; + const IR::Value tmp2{ir.IAddCarry(result1, carry)}; + const IR::U32 result2{ir.CompositeExtract(tmp2, 0)}; + const IR::U32 carry_out2{ir.CompositeExtract(tmp2, 1)}; + SetDst(inst.dst[0], result2); - const IR::U1 less_src0{ir.ILessThan(result, src0, false)}; - const IR::U1 less_src1{ir.ILessThan(result, src1, false)}; - const IR::U1 did_overflow{ir.LogicalOr(less_src0, less_src1)}; + const IR::U1 did_overflow{ir.INotEqual(ir.BitwiseOr(carry_out1, carry_out2), ir.Imm32(0))}; SetCarryOut(inst, did_overflow); } diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index 3d64cc5da..2334777ed 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1424,13 +1424,13 @@ U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { } } -Value IREmitter::IAddCary(const U32& a, const U32& b) { +Value IREmitter::IAddCarry(const U32& a, const U32& b) { if (a.Type() != b.Type()) { UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); } switch (a.Type()) { case Type::U32: - return Inst(Opcode::IAddCary32, a, b); + return Inst(Opcode::IAddCarry32, a, b); default: ThrowInvalidType(a.Type()); } diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 119e3752e..1c5a8f545 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -254,7 +254,7 @@ public: [[nodiscard]] F32F64 FPMedTri(const F32F64& a, const F32F64& b, const F32F64& c); [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); - [[nodiscard]] Value IAddCary(const U32& a, const U32& b); + [[nodiscard]] Value IAddCarry(const U32& a, const U32& b); [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); [[nodiscard]] U32 IMulHi(const U32& a, const U32& b, bool is_signed = false); [[nodiscard]] U32U64 IMul(const U32U64& a, const U32U64& b); diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index 008f44659..553e63f3e 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -328,7 +328,7 @@ OPCODE(FPCmpClass32, U1, F32, // Integer operations OPCODE(IAdd32, U32, U32, U32, ) OPCODE(IAdd64, U64, U64, U64, ) -OPCODE(IAddCary32, U32x2, U32, U32, ) +OPCODE(IAddCarry32, U32x2, U32, U32, ) OPCODE(ISub32, U32, U32, U32, ) OPCODE(ISub64, U64, U64, U64, ) OPCODE(IMul32, U32, U32, U32, ) diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index a50601af6..aa6563a84 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -169,7 +169,7 @@ ImageId TextureCache::ResolveDepthOverlap(const ImageInfo& requested_info, Bindi if (recreate) { auto new_info = requested_info; - new_info.resources = std::min(requested_info.resources, cache_image.info.resources); + new_info.resources = std::max(requested_info.resources, cache_image.info.resources); const auto new_image_id = slot_images.insert(instance, scheduler, new_info); RegisterImage(new_image_id);