Merge branch 'main' into fontlib

This commit is contained in:
georgemoralis 2025-11-14 22:04:24 +02:00 committed by GitHub
commit d0855348f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 72 additions and 32 deletions

2
.gitmodules vendored
View File

@ -108,7 +108,7 @@
branch = dist
[submodule "externals/MoltenVK"]
path = externals/MoltenVK
url = https://github.com/KhronosGroup/MoltenVK.git
url = https://github.com/shadPS4-emu/ext-MoltenVK.git
shallow = true
[submodule "externals/json"]
path = externals/json

View File

@ -36,9 +36,8 @@ Go through the Git for Windows installation as normal
1. Open up Visual Studio, select `Open a local folder` and select the folder with the shadPS4 source code. The folder should contain `CMakeLists.txt`
2. Change Clang x64 Debug to Clang x64 Release if you want a regular, non-debug build.
3. If you want to build shadPS4 with the Qt Gui, simply select Clang x64 Release with Qt instead.
4. Change the project to build to shadps4.exe
5. Build -> Build All
3. Change the project to build to shadps4.exe
4. Build -> Build All
Your shadps4.exe will be in `C:\path\to\source\Build\x64-Clang-Release\`

2
externals/MoltenVK vendored

@ -1 +1 @@
Subproject commit b23d42534622cd9926fe526fec1b7f8795a2853c
Subproject commit f168dec05998ab0ca09a400bab6831a95c0bdb2e

View File

@ -68,6 +68,7 @@ class ElfInfo {
std::string app_ver{};
u32 firmware_ver = 0;
u32 raw_firmware_ver = 0;
u32 sdk_ver = 0;
PSFAttributes psf_attributes{};
std::filesystem::path splash_path{};
@ -117,6 +118,11 @@ public:
return raw_firmware_ver;
}
[[nodiscard]] u32 CompiledSdkVer() const {
ASSERT(initialized);
return sdk_ver;
}
[[nodiscard]] const PSFAttributes& GetPSFAttributes() const {
ASSERT(initialized);
return psf_attributes;

View File

@ -6,6 +6,7 @@
#include "common/arch.h"
#include "common/assert.h"
#include "common/config.h"
#include "common/elf_info.h"
#include "common/error.h"
#include "core/address_space.h"
#include "core/libraries/kernel/memory.h"
@ -103,8 +104,8 @@ struct AddressSpace::Impl {
GetSystemInfo(&sys_info);
u64 alignment = sys_info.dwAllocationGranularity;
// Determine the host OS build number
// Retrieve module handle for ntdll
// Older Windows builds have a severe performance issue with VirtualAlloc2.
// We need to get the host's Windows version, then determine if it needs a workaround.
auto ntdll_handle = GetModuleHandleW(L"ntdll.dll");
ASSERT_MSG(ntdll_handle, "Failed to retrieve ntdll handle");
@ -120,12 +121,20 @@ struct AddressSpace::Impl {
u64 supported_user_max = USER_MAX;
// This is the build number for Windows 11 22H2
static constexpr s32 AffectedBuildNumber = 22621;
if (os_version_info.dwBuildNumber <= AffectedBuildNumber) {
// Older Windows builds have an issue with VirtualAlloc2 on higher addresses.
// To prevent regressions, limit the maximum address we reserve for this platform.
supported_user_max = 0x11000000000ULL;
LOG_WARNING(Core, "Windows 10 detected, reducing user max to {:#x} to avoid problems",
supported_user_max);
// Higher PS4 firmware versions prevent higher address mappings too.
s32 sdk_ver = Common::ElfInfo::Instance().CompiledSdkVer();
if (os_version_info.dwBuildNumber <= AffectedBuildNumber ||
sdk_ver >= Common::ElfInfo::FW_30) {
supported_user_max = 0x10000000000ULL;
// Only log the message if we're restricting the user max due to operating system.
// Since higher compiled SDK versions also get reduced max, we don't need to log there.
if (sdk_ver < Common::ElfInfo::FW_30) {
LOG_WARNING(
Core,
"Older Windows version detected, reducing user max to {:#x} to avoid problems",
supported_user_max);
}
}
// Determine the free address ranges we can access.

View File

@ -36,7 +36,7 @@ s32 PS4_SYSV_ABI sceKernelGetMainSocId() {
}
s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver) {
s32 version = Common::ElfInfo::Instance().RawFirmwareVer();
s32 version = Common::ElfInfo::Instance().CompiledSdkVer();
*ver = version;
return (version >= 0) ? ORBIS_OK : ORBIS_KERNEL_ERROR_EINVAL;
}

View File

@ -312,7 +312,7 @@ public:
const auto endpoint_descs = FillEndpointDescriptorPair();
const auto interface_desc = FillInterfaceDescriptor(endpoint_descs);
const auto interface = static_cast<libusb_interface*>(calloc(1, sizeof(libusb_interface*)));
const auto interface = static_cast<libusb_interface*>(calloc(1, sizeof(libusb_interface)));
interface->altsetting = interface_desc;
interface->num_altsetting = 1;
@ -366,7 +366,7 @@ public:
const auto desc = FillDeviceDescriptor();
ASSERT(desc);
const auto fake = static_cast<UsbDevice*>(calloc(1, sizeof(UsbDevice*)));
const auto fake = static_cast<UsbDevice*>(calloc(1, sizeof(UsbDevice)));
fake->bus_number = 0;
fake->port_number = 0;
fake->device_address = 0;

View File

@ -113,6 +113,7 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
std::string id;
std::string title;
std::string app_version;
u32 sdk_version;
u32 fw_version;
Common::PSFAttributes psf_attributes{};
if (param_sfo_exists) {
@ -132,8 +133,48 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) {
psf_attributes.raw = *raw_attributes;
}
// Extract sdk version from pubtool info.
std::string_view pubtool_info =
param_sfo->GetString("PUBTOOLINFO").value_or("Unknown value");
u64 sdk_ver_offset = pubtool_info.find("sdk_ver");
if (sdk_ver_offset == pubtool_info.npos) {
// Default to using firmware version if SDK version is not found.
sdk_version = fw_version;
} else {
// Increment offset to account for sdk_ver= part of string.
sdk_ver_offset += 8;
u64 sdk_ver_len = pubtool_info.find(",", sdk_ver_offset);
if (sdk_ver_len == pubtool_info.npos) {
// If there's no more commas, this is likely the last entry of pubtool info.
// Use string length instead.
sdk_ver_len = pubtool_info.size();
}
sdk_ver_len -= sdk_ver_offset;
std::string sdk_ver_string = pubtool_info.substr(sdk_ver_offset, sdk_ver_len).data();
// Number is stored in base 16.
sdk_version = std::stoi(sdk_ver_string, nullptr, 16);
}
}
auto& game_info = Common::ElfInfo::Instance();
game_info.initialized = true;
game_info.game_serial = id;
game_info.title = title;
game_info.app_ver = app_version;
game_info.firmware_ver = fw_version & 0xFFF00000;
game_info.raw_firmware_ver = fw_version;
game_info.sdk_ver = sdk_version;
game_info.psf_attributes = psf_attributes;
const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png");
if (std::filesystem::exists(pic1_path)) {
game_info.splash_path = pic1_path;
}
game_info.game_folder = game_folder;
Config::load(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (id + ".toml"),
true);
@ -196,6 +237,7 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
if (param_sfo_exists) {
LOG_INFO(Loader, "Game id: {} Title: {}", id, title);
LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version);
LOG_INFO(Loader, "Compiled SDK version: {:#x}", sdk_version);
LOG_INFO(Loader, "PSVR Supported: {}", (bool)psf_attributes.support_ps_vr.Value());
LOG_INFO(Loader, "PSVR Required: {}", (bool)psf_attributes.require_ps_vr.Value());
}
@ -235,22 +277,6 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
}
}
auto& game_info = Common::ElfInfo::Instance();
game_info.initialized = true;
game_info.game_serial = id;
game_info.title = title;
game_info.app_ver = app_version;
game_info.firmware_ver = fw_version & 0xFFF00000;
game_info.raw_firmware_ver = fw_version;
game_info.psf_attributes = psf_attributes;
const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png");
if (std::filesystem::exists(pic1_path)) {
game_info.splash_path = pic1_path;
}
game_info.game_folder = game_folder;
std::string game_title = fmt::format("{} - {} <{}>", id, title, app_version);
std::string window_title = "";
std::string remote_url(Common::g_scm_remote_url);