Lib.SystemService: Add SDK checks for console language (#4444)

* Add proper SDK checks for language values

Fixes some crashes caused by otherwise valid languages in older titles.

* Rename firmware constants

Makes more sense this way, and works better in case we find an SDK check added in a more minor update.
Instead of 1.00 being 10, 1.50 being 15, and so on, this commit changes 1.00 to 100, 1.50 to 150, and so on.

* Claaaaang
This commit is contained in:
Stephen Miller
2026-05-17 20:35:36 -05:00
committed by GitHub
parent 94786d70ca
commit caec23154c
19 changed files with 115 additions and 90 deletions
+18 -17
View File
@@ -79,23 +79,24 @@ class ElfInfo {
std::map<int, std::string> trophyIndexMap{};
public:
static constexpr u32 FW_10 = 0x1000000;
static constexpr u32 FW_15 = 0x1500000;
static constexpr u32 FW_16 = 0x1600000;
static constexpr u32 FW_17 = 0x1700000;
static constexpr u32 FW_20 = 0x2000000;
static constexpr u32 FW_25 = 0x2500000;
static constexpr u32 FW_30 = 0x3000000;
static constexpr u32 FW_35 = 0x3500000;
static constexpr u32 FW_40 = 0x4000000;
static constexpr u32 FW_45 = 0x4500000;
static constexpr u32 FW_50 = 0x5000000;
static constexpr u32 FW_55 = 0x5500000;
static constexpr u32 FW_60 = 0x6000000;
static constexpr u32 FW_70 = 0x7000000;
static constexpr u32 FW_75 = 0x7500000;
static constexpr u32 FW_80 = 0x8000000;
static constexpr u32 FW_115 = 0x11500000;
static constexpr u32 FW_100 = 0x1000000;
static constexpr u32 FW_150 = 0x1500000;
static constexpr u32 FW_160 = 0x1600000;
static constexpr u32 FW_170 = 0x1700000;
static constexpr u32 FW_200 = 0x2000000;
static constexpr u32 FW_250 = 0x2500000;
static constexpr u32 FW_300 = 0x3000000;
static constexpr u32 FW_350 = 0x3500000;
static constexpr u32 FW_400 = 0x4000000;
static constexpr u32 FW_450 = 0x4500000;
static constexpr u32 FW_500 = 0x5000000;
static constexpr u32 FW_550 = 0x5500000;
static constexpr u32 FW_600 = 0x6000000;
static constexpr u32 FW_700 = 0x7000000;
static constexpr u32 FW_750 = 0x7500000;
static constexpr u32 FW_800 = 0x8000000;
static constexpr u32 FW_1000 = 0x10000000;
static constexpr u32 FW_1150 = 0x11500000;
static ElfInfo& Instance() {
return *Singleton<ElfInfo>::Instance();
+2 -2
View File
@@ -131,11 +131,11 @@ struct AddressSpace::Impl {
// 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) {
sdk_ver >= Common::ElfInfo::FW_300) {
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) {
if (sdk_ver < Common::ElfInfo::FW_300) {
LOG_WARNING(
Core,
"Older Windows version detected, reducing user max to {:#x} to avoid problems",
@@ -283,7 +283,7 @@ int PS4_SYSV_ABI sceAppContentGetRegion() {
int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam,
OrbisAppContentBootParam* bootParam) {
if (sdk_ver >= Common::ElfInfo::FW_15 && is_initialized) {
if (sdk_ver >= Common::ElfInfo::FW_150 && is_initialized) {
LOG_ERROR(Lib_AppContent, "Already initialized");
return ORBIS_APP_CONTENT_ERROR_BUSY;
}
+5 -5
View File
@@ -148,7 +148,7 @@ s32 PS4_SYSV_ABI sceCameraGetAutoExposureGain(s32 handle, OrbisCameraChannel cha
channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable == nullptr) {
return ORBIS_CAMERA_ERROR_PARAM;
}
if (option != nullptr && (g_firmware_version < Common::ElfInfo::FW_30 ||
if (option != nullptr && (g_firmware_version < Common::ElfInfo::FW_300 ||
option->sizeThis != sizeof(OrbisCameraAutoExposureGainTarget))) {
return ORBIS_CAMERA_ERROR_PARAM;
}
@@ -693,7 +693,7 @@ s32 PS4_SYSV_ABI sceCameraSetAutoExposureGain(s32 handle, OrbisCameraChannel cha
return ORBIS_CAMERA_ERROR_PARAM;
}
if (option != nullptr) {
if (g_firmware_version < Common::ElfInfo::FW_30 ||
if (g_firmware_version < Common::ElfInfo::FW_300 ||
option->sizeThis != sizeof(OrbisCameraAutoExposureGainTarget)) {
return ORBIS_CAMERA_ERROR_PARAM;
}
@@ -751,7 +751,7 @@ s32 PS4_SYSV_ABI sceCameraSetConfig(s32 handle, OrbisCameraConfig* config) {
case ORBIS_CAMERA_CONFIG_TYPE5:
int sdk_ver;
Libraries::Kernel::sceKernelGetCompiledSdkVersion(&sdk_ver);
if (sdk_ver < Common::ElfInfo::FW_45) {
if (sdk_ver < Common::ElfInfo::FW_450) {
return ORBIS_CAMERA_ERROR_UNKNOWN_CONFIG;
}
output_config0 = camera_config_types[config->configType - 1][0];
@@ -944,7 +944,7 @@ s32 PS4_SYSV_ABI sceCameraSetSharpness(s32 handle, OrbisCameraChannel channel, u
channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || option != nullptr) {
return ORBIS_CAMERA_ERROR_PARAM;
}
if (g_firmware_version >= Common::ElfInfo::FW_35 && sharpness > 10) {
if (g_firmware_version >= Common::ElfInfo::FW_350 && sharpness > 10) {
return ORBIS_CAMERA_ERROR_PARAM;
}
if (!g_library_opened) {
@@ -1007,7 +1007,7 @@ s32 PS4_SYSV_ABI sceCameraStart(s32 handle, OrbisCameraStartParameter* param) {
if (!g_library_opened) {
return ORBIS_CAMERA_ERROR_NOT_OPEN;
}
if (g_firmware_version >= Common::ElfInfo::FW_25 &&
if (g_firmware_version >= Common::ElfInfo::FW_250 &&
(param->formatLevel[0] >= 0xf || param->formatLevel[1] >= 0xf ||
(param->formatLevel[0] | param->formatLevel[1]) == 0)) {
return ORBIS_CAMERA_ERROR_FORMAT_UNKNOWN;
+1 -1
View File
@@ -177,7 +177,7 @@ s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, Orb
}
u32 user_flags = flags;
if (build_ver >= Common::ElfInfo::FW_35) {
if (build_ver >= Common::ElfInfo::FW_350) {
user_flags |= FiberFlags::SetFpuRegs;
}
if (context_size_check) {
+4 -4
View File
@@ -2234,9 +2234,9 @@ int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload(u32 workload, u32 count,
}
if (send_init_packet) {
if (sdk_version < Common::ElfInfo::FW_20) {
if (sdk_version < Common::ElfInfo::FW_200) {
liverpool->SubmitGfx(InitSequence, {});
} else if (sdk_version < Common::ElfInfo::FW_40) {
} else if (sdk_version < Common::ElfInfo::FW_400) {
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
liverpool->SubmitGfx(InitSequence200Neo, {});
@@ -2817,7 +2817,7 @@ int PS4_SYSV_ABI Func_C4C328B7CF3B4171() {
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalCommand(u32* cmdbuf, u32 size) {
LOG_TRACE(Lib_GnmDriver, "called");
if (sdk_version >= Common::ElfInfo::FW_40) {
if (sdk_version >= Common::ElfInfo::FW_400) {
return sceGnmDrawInitToDefaultContextState400(cmdbuf, size);
}
return sceGnmDrawInitToDefaultContextState(cmdbuf, size);
@@ -2825,7 +2825,7 @@ int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalCommand(u32* cmdbuf,
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalSize() {
LOG_TRACE(Lib_GnmDriver, "called");
if (sdk_version >= Common::ElfInfo::FW_40) {
if (sdk_version >= Common::ElfInfo::FW_400) {
return 0x100;
}
return 0x20;
+5 -5
View File
@@ -76,7 +76,7 @@ s32 PS4_SYSV_ABI sceHmdGet2DEyeOffset(s32 handle, OrbisHmdEyeOffset* left_offset
if (handle != g_internal_handle) {
return ORBIS_HMD_ERROR_HANDLE_INVALID;
}
if (g_firmware_version >= Common::ElfInfo::FW_45) {
if (g_firmware_version >= Common::ElfInfo::FW_450) {
// Due to some faulty in-library checks, a missing headset results in this error
// instead of the expected ORBIS_HMD_ERROR_DEVICE_DISCONNECTED error.
return ORBIS_HMD_ERROR_HANDLE_INVALID;
@@ -128,7 +128,7 @@ s32 PS4_SYSV_ABI sceHmdGetDeviceInformationByHandle(s32 handle, OrbisHmdDeviceIn
if (handle != g_internal_handle) {
return ORBIS_HMD_ERROR_HANDLE_INVALID;
}
if (g_firmware_version >= Common::ElfInfo::FW_45) {
if (g_firmware_version >= Common::ElfInfo::FW_450) {
// Due to some faulty in-library checks, a missing headset results in this error
// instead of the expected ORBIS_HMD_ERROR_DEVICE_DISCONNECTED error.
return ORBIS_HMD_ERROR_HANDLE_INVALID;
@@ -154,7 +154,7 @@ s32 PS4_SYSV_ABI sceHmdGetFieldOfView(s32 handle, OrbisHmdFieldOfView* field_of_
if (handle != g_internal_handle) {
return ORBIS_HMD_ERROR_HANDLE_INVALID;
}
if (g_firmware_version >= Common::ElfInfo::FW_45) {
if (g_firmware_version >= Common::ElfInfo::FW_450) {
// Due to some faulty in-library checks, a missing headset results in this error
// instead of the expected ORBIS_HMD_ERROR_DEVICE_DISCONNECTED error.
return ORBIS_HMD_ERROR_HANDLE_INVALID;
@@ -182,7 +182,7 @@ s32 PS4_SYSV_ABI sceHmdGetInertialSensorData(s32 handle, void* data, s32 unk) {
if (handle != g_internal_handle) {
return ORBIS_HMD_ERROR_HANDLE_INVALID;
}
if (g_firmware_version >= Common::ElfInfo::FW_45) {
if (g_firmware_version >= Common::ElfInfo::FW_450) {
// Due to some faulty in-library checks, a missing headset results in this error
// instead of the expected ORBIS_HMD_ERROR_DEVICE_DISCONNECTED error.
return ORBIS_HMD_ERROR_HANDLE_INVALID;
@@ -799,7 +799,7 @@ s32 PS4_SYSV_ABI Func_69383B2B4E3AEABF(s32 handle, void* data, s32 unk) {
if (handle != g_internal_handle) {
return ORBIS_HMD_ERROR_HANDLE_INVALID;
}
if (g_firmware_version >= Common::ElfInfo::FW_45) {
if (g_firmware_version >= Common::ElfInfo::FW_450) {
// Due to some faulty in-library checks, a missing headset results in this error
// instead of the expected ORBIS_HMD_ERROR_DEVICE_DISCONNECTED error.
return ORBIS_HMD_ERROR_HANDLE_INVALID;
+2 -1
View File
@@ -219,7 +219,8 @@ s32 PS4_SYSV_ABI sceKernelMapNamedDirectMemory(void** addr, u64 len, s32 prot, s
auto* memory = Core::Memory::Instance();
bool should_check = false;
if (g_sdk_version >= Common::ElfInfo::FW_25 && False(map_flags & Core::MemoryMapFlags::Stack)) {
if (g_sdk_version >= Common::ElfInfo::FW_250 &&
False(map_flags & Core::MemoryMapFlags::Stack)) {
// Under these conditions, this would normally redirect to sceKernelMapDirectMemory2.
should_check = !g_alias_dmem;
}
+1 -1
View File
@@ -34,7 +34,7 @@ static int RwlockInit(PthreadRwlockT* rwlock, const PthreadRwlockAttrT* attr) {
if (prwlock == nullptr) {
return POSIX_ENOMEM;
}
if (attr != nullptr && sdk_version >= Common::ElfInfo::FW_45) {
if (attr != nullptr && sdk_version >= Common::ElfInfo::FW_450) {
if ((*attr)->type > 2) {
delete prwlock;
return POSIX_EINVAL;
+6 -6
View File
@@ -41,7 +41,7 @@ s32 PS4_SYSV_ABI sceNpWebApiCreateServicePushEventFilter(
if (pNpServiceName == nullptr || pFilterParam == nullptr || filterParamNum == 0) {
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_20 &&
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_200 &&
npServiceLabel == ORBIS_NP_INVALID_SERVICE_LABEL) {
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
@@ -88,7 +88,7 @@ s32 PS4_SYSV_ABI sceNpWebApiRegisterNotificationCallback(s32 titleUserCtxId,
s32 PS4_SYSV_ABI sceNpWebApiRegisterPushEventCallback(s32 titleUserCtxId, s32 filterId,
OrbisNpWebApiPushEventCallback cbFunc,
void* pUserArg) {
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_10 && cbFunc == nullptr) {
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_100 && cbFunc == nullptr) {
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
LOG_INFO(Lib_NpWebApi, "called, titleUserCtxId = {:#x}, filterId = {:#x}, cbFunc = {}",
@@ -99,7 +99,7 @@ s32 PS4_SYSV_ABI sceNpWebApiRegisterPushEventCallback(s32 titleUserCtxId, s32 fi
s32 PS4_SYSV_ABI sceNpWebApiRegisterServicePushEventCallback(
s32 titleUserCtxId, s32 filterId, OrbisNpWebApiServicePushEventCallback cbFunc,
void* pUserArg) {
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_10 && cbFunc == nullptr) {
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_100 && cbFunc == nullptr) {
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
LOG_INFO(Lib_NpWebApi, "called, titleUserCtxId = {:#x}, filterId = {:#x}, cbFunc = {}",
@@ -223,7 +223,7 @@ s32 PS4_SYSV_ABI sceNpWebApiCreateMultipartRequest(s32 titleUserCtxId, const cha
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_25 &&
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_250 &&
method > OrbisNpWebApiHttpMethod::ORBIS_NP_WEBAPI_HTTP_METHOD_DELETE) {
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
@@ -249,7 +249,7 @@ s32 PS4_SYSV_ABI sceNpWebApiCreateRequest(s32 titleUserCtxId, const char* pApiGr
return ORBIS_NP_WEBAPI_ERROR_INVALID_CONTENT_PARAMETER;
}
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_25 &&
if (getCompiledSdkVersion() >= Common::ElfInfo::FW_250 &&
method > OrbisNpWebApiHttpMethod::ORBIS_NP_WEBAPI_HTTP_METHOD_DELETE) {
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
}
@@ -317,7 +317,7 @@ s32 PS4_SYSV_ABI sceNpWebApiGetHttpResponseHeaderValueLength(s64 requestId, cons
s32 PS4_SYSV_ABI sceNpWebApiGetHttpStatusCode(s64 requestId, s32* out_status_code) {
LOG_ERROR(Lib_NpWebApi, "called : requestId = {:#x}", requestId);
// On newer SDKs, NULL output pointer is invalid
if (getCompiledSdkVersion() > Common::ElfInfo::FW_10 && out_status_code == nullptr)
if (getCompiledSdkVersion() > Common::ElfInfo::FW_100 && out_status_code == nullptr)
return ORBIS_NP_WEBAPI_ERROR_INVALID_ARGUMENT;
s32 returncode = getHttpStatusCodeInternal(requestId, out_status_code);
return returncode;
+12 -12
View File
@@ -170,7 +170,7 @@ s32 terminateContext(s32 libCtxId) {
return ORBIS_NP_WEBAPI_ERROR_LIB_CONTEXT_NOT_FOUND;
}
if (g_sdk_ver < Common::ElfInfo::FW_40 && isContextBusy(ctx)) {
if (g_sdk_ver < Common::ElfInfo::FW_400 && isContextBusy(ctx)) {
releaseContext(ctx);
return ORBIS_NP_WEBAPI_ERROR_LIB_CONTEXT_BUSY;
}
@@ -182,13 +182,13 @@ s32 terminateContext(s32 libCtxId) {
for (s32 user_context_id : user_context_ids) {
s32 result = deleteUserContext(user_context_id);
if (result != ORBIS_NP_WEBAPI_ERROR_USER_CONTEXT_NOT_FOUND ||
g_sdk_ver < Common::ElfInfo::FW_40) {
g_sdk_ver < Common::ElfInfo::FW_400) {
return result;
}
}
lockContext(ctx);
if (g_sdk_ver >= Common::ElfInfo::FW_40) {
if (g_sdk_ver >= Common::ElfInfo::FW_400) {
for (auto& handle : ctx->handles) {
abortHandle(libCtxId, handle.first);
}
@@ -377,7 +377,7 @@ s32 deleteUserContext(s32 titleUserCtxId) {
return ORBIS_NP_WEBAPI_ERROR_USER_CONTEXT_NOT_FOUND;
}
if (g_sdk_ver < Common::ElfInfo::FW_40) {
if (g_sdk_ver < Common::ElfInfo::FW_400) {
if (isUserContextBusy(user_context)) {
releaseUserContext(user_context);
unlockContext(context);
@@ -439,7 +439,7 @@ s32 createRequest(s32 titleUserCtxId, const char* pApiGroup, const char* pPath,
}
lockContext(user_context->parentContext);
if (g_sdk_ver >= Common::ElfInfo::FW_40 && user_context->deleted) {
if (g_sdk_ver >= Common::ElfInfo::FW_400 && user_context->deleted) {
unlockContext(user_context->parentContext);
releaseUserContext(user_context);
releaseContext(context);
@@ -590,7 +590,7 @@ s32 sendRequest(s64 requestId, s32 partIndex, const void* pData, u64 dataSize, s
// TODO: multipart logic
if (g_sdk_ver >= Common::ElfInfo::FW_25 && !request->sent) {
if (g_sdk_ver >= Common::ElfInfo::FW_250 && !request->sent) {
request->sent = true;
}
@@ -694,7 +694,7 @@ s32 deleteRequest(s64 requestId) {
return ORBIS_NP_WEBAPI_ERROR_REQUEST_NOT_FOUND;
}
if (g_sdk_ver < Common::ElfInfo::FW_40 && isRequestBusy(request)) {
if (g_sdk_ver < Common::ElfInfo::FW_400 && isRequestBusy(request)) {
releaseRequest(request);
releaseUserContext(user_context);
releaseContext(context);
@@ -733,7 +733,7 @@ s32 createHandleInternal(OrbisNpWebApiContext* context) {
handle->aborted = false;
handle->deleted = false;
if (g_sdk_ver >= Common::ElfInfo::FW_30) {
if (g_sdk_ver >= Common::ElfInfo::FW_300) {
context->timerHandles[handle_id] = new OrbisNpWebApiTimerHandle{};
auto& timer_handle = context->timerHandles[handle_id];
timer_handle->handleId = handle_id;
@@ -840,7 +840,7 @@ s32 deleteHandleInternal(OrbisNpWebApiContext* context, s32 handleId) {
}
auto& handle = context->handles[handleId];
if (g_sdk_ver >= Common::ElfInfo::FW_40) {
if (g_sdk_ver >= Common::ElfInfo::FW_400) {
if (handle->deleted) {
unlockContext(context);
return ORBIS_NP_WEBAPI_ERROR_HANDLE_NOT_FOUND;
@@ -865,7 +865,7 @@ s32 deleteHandleInternal(OrbisNpWebApiContext* context, s32 handleId) {
context->handles.erase(handleId);
if (g_sdk_ver >= Common::ElfInfo::FW_30 && context->timerHandles.contains(handleId)) {
if (g_sdk_ver >= Common::ElfInfo::FW_300 && context->timerHandles.contains(handleId)) {
auto& timer_handle = context->timerHandles[handleId];
context->timerHandles.erase(handleId);
}
@@ -976,7 +976,7 @@ s32 registerPushEventCallback(s32 titleUserCtxId, s32 filterId,
return ORBIS_NP_WEBAPI_ERROR_USER_CONTEXT_NOT_FOUND;
}
if (g_sdk_ver >= Common::ElfInfo::FW_25 && !context->pushEventFilters.contains(filterId)) {
if (g_sdk_ver >= Common::ElfInfo::FW_250 && !context->pushEventFilters.contains(filterId)) {
releaseUserContext(user_context);
releaseContext(context);
return ORBIS_NP_WEBAPI_ERROR_PUSH_EVENT_FILTER_NOT_FOUND;
@@ -1150,7 +1150,7 @@ s32 registerServicePushEventCallback(s32 titleUserCtxId, s32 filterId,
return ORBIS_NP_WEBAPI_ERROR_USER_CONTEXT_NOT_FOUND;
}
if (g_sdk_ver >= Common::ElfInfo::FW_25 &&
if (g_sdk_ver >= Common::ElfInfo::FW_250 &&
!context->servicePushEventFilters.contains(filterId)) {
releaseUserContext(user_context);
releaseContext(context);
+1 -1
View File
@@ -491,7 +491,7 @@ int ProcessStates(s32 handle, OrbisPadData* pData, Input::GameController& contro
pData[i].touchData.touch[1].y = states[i].touchpad[1].y;
pData[i].touchData.touch[1].id = states[i].touchpad[1].ID;
}
if (Common::ElfInfo::Instance().FirmwareVer() > Common::ElfInfo::FW_35) {
if (Common::ElfInfo::Instance().FirmwareVer() > Common::ElfInfo::FW_350) {
pData[i].touchData.time_since_touch_held_down =
controller.last_touch_down_timestamp == 0
? 0
@@ -698,7 +698,7 @@ void SaveDialogUi::DrawUser() {
}
SameLine();
if (Button("No", BUTTON_SIZE)) {
if (ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_45) {
if (ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_450) {
Finish(ButtonId::INVALID, Result::USER_CANCELED);
} else {
Finish(ButtonId::NO);
@@ -710,7 +710,7 @@ void SaveDialogUi::DrawUser() {
} else {
if (Button("OK", BUTTON_SIZE)) {
if (btn_type == ButtonType::OK &&
ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_45) {
ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_450) {
Finish(ButtonId::INVALID, Result::USER_CANCELED);
} else {
Finish(ButtonId::OK);
@@ -763,7 +763,7 @@ void SaveDialogUi::DrawSystemMessage() {
});
BeginGroup();
if (Button(sys_state.show_no ? "Yes" : "OK", BUTTON_SIZE)) {
if (sys_state.return_cancel && ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_45) {
if (sys_state.return_cancel && ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_450) {
Finish(ButtonId::INVALID, Result::USER_CANCELED);
} else {
Finish(ButtonId::YES);
@@ -772,7 +772,7 @@ void SaveDialogUi::DrawSystemMessage() {
SameLine();
if (sys_state.show_no) {
if (Button("No", BUTTON_SIZE)) {
if (ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_45) {
if (ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_450) {
Finish(ButtonId::INVALID, Result::USER_CANCELED);
} else {
Finish(ButtonId::NO);
@@ -811,7 +811,7 @@ void SaveDialogUi::DrawErrorCode() {
ws.y - FOOTER_HEIGHT + 5.0f,
});
if (Button("OK", BUTTON_SIZE)) {
if (ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_45) {
if (ElfInfo::Instance().FirmwareVer() < ElfInfo::FW_450) {
Finish(ButtonId::INVALID, Result::USER_CANCELED);
} else {
Finish(ButtonId::OK);
+17 -17
View File
@@ -356,10 +356,10 @@ static bool match(std::string_view str, std::string_view pattern) {
}
static Error setNotInitializedError() {
if (g_fw_ver < ElfInfo::FW_20) {
if (g_fw_ver < ElfInfo::FW_200) {
return Error::INTERNAL;
}
if (g_fw_ver < ElfInfo::FW_25) {
if (g_fw_ver < ElfInfo::FW_250) {
return Error::USER_SERVICE_NOT_INITIALIZED;
}
return Error::NOT_INITIALIZED;
@@ -391,13 +391,13 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info,
const bool create = True(mount_mode & OrbisSaveDataMountMode::CREATE);
const bool create_if_not_exist =
True(mount_mode & OrbisSaveDataMountMode::CREATE2) && g_fw_ver >= ElfInfo::FW_45;
True(mount_mode & OrbisSaveDataMountMode::CREATE2) && g_fw_ver >= ElfInfo::FW_450;
ASSERT(!create || !create_if_not_exist); // Can't have both
const bool copy_icon = True(mount_mode & OrbisSaveDataMountMode::COPY_ICON);
const bool ignore_corrupt =
True(mount_mode & OrbisSaveDataMountMode::DESTRUCT_OFF) || g_fw_ver < ElfInfo::FW_16;
True(mount_mode & OrbisSaveDataMountMode::DESTRUCT_OFF) || g_fw_ver < ElfInfo::FW_160;
const std::string_view dir_name{mount_info->dirName->data};
@@ -470,7 +470,7 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info,
mount_result->mount_point.data.FromString(save_instance.GetMountPoint());
if (g_fw_ver >= ElfInfo::FW_45) {
if (g_fw_ver >= ElfInfo::FW_450) {
mount_result->mount_status = create_if_not_exist && to_be_created
? OrbisSaveDataMountStatus::CREATED
: OrbisSaveDataMountStatus::NOTHING;
@@ -795,7 +795,7 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond
if (!fs::exists(save_path)) {
result->hitNum = 0;
if (g_fw_ver >= ElfInfo::FW_17) {
if (g_fw_ver >= ElfInfo::FW_170) {
result->setNum = 0;
}
return Error::OK;
@@ -869,7 +869,7 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond
}
size_t max_count = std::min(static_cast<size_t>(result->dirNamesNum), dir_list.size());
if (g_fw_ver >= ElfInfo::FW_17) {
if (g_fw_ver >= ElfInfo::FW_170) {
result->hitNum = dir_list.size();
result->setNum = max_count;
} else {
@@ -880,13 +880,13 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond
auto& name_data = result->dirNames[i].data;
name_data.FromString(dir_list[i]);
if (g_fw_ver >= ElfInfo::FW_17 && result->params != nullptr) {
if (g_fw_ver >= ElfInfo::FW_170 && result->params != nullptr) {
auto& sfo = map_dir_sfo.at(dir_list[i]);
auto& param_data = result->params[i];
param_data.FromSFO(sfo);
}
if (g_fw_ver >= ElfInfo::FW_25 && result->infos != nullptr) {
if (g_fw_ver >= ElfInfo::FW_250 && result->infos != nullptr) {
auto& info = result->infos[i];
info.blocks = map_max_blocks.at(dir_list[i]);
info.freeBlocks = map_free_size.at(dir_list[i]);
@@ -1139,7 +1139,7 @@ Error PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getPar
}
u32 slot_id = 0;
if (g_fw_ver > ElfInfo::FW_50) {
if (g_fw_ver > ElfInfo::FW_500) {
slot_id = getParam->slotId;
}
if (!SaveMemory::IsSaveMemoryInitialized(slot_id)) {
@@ -1503,7 +1503,7 @@ Error PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(const OrbisSaveDataMemorySet2*
}
u32 slot_id = 0;
u32 data_num = 1;
if (g_fw_ver > ElfInfo::FW_50) {
if (g_fw_ver > ElfInfo::FW_500) {
slot_id = setParam->slotId;
if (setParam->dataNum > 1) {
data_num = setParam->dataNum;
@@ -1573,7 +1573,7 @@ Error PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetu
LOG_DEBUG(Lib_SaveData, "called");
u32 slot_id = 0;
if (g_fw_ver > ElfInfo::FW_50) {
if (g_fw_ver > ElfInfo::FW_500) {
slot_id = setupParam->slotId;
}
@@ -1588,20 +1588,20 @@ Error PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetu
size_t existed_size = SaveMemory::SetupSaveMemory(setupParam->userId, slot_id,
g_game_serial, setupParam->memorySize);
if (existed_size == 0) { // Just created
if (g_fw_ver >= ElfInfo::FW_45 && setupParam->initParam != nullptr) {
if (g_fw_ver >= ElfInfo::FW_450 && setupParam->initParam != nullptr) {
auto& sfo = SaveMemory::GetParamSFO(slot_id);
setupParam->initParam->ToSFO(sfo);
}
SaveMemory::SaveSFO(slot_id);
auto init_icon = setupParam->initIcon;
if (g_fw_ver >= ElfInfo::FW_45 && init_icon != nullptr) {
if (g_fw_ver >= ElfInfo::FW_450 && init_icon != nullptr) {
SaveMemory::SetIcon(slot_id, init_icon->buf, init_icon->bufSize);
} else {
SaveMemory::SetIcon(slot_id);
}
}
if (g_fw_ver >= ElfInfo::FW_45 && result != nullptr) {
if (g_fw_ver >= ElfInfo::FW_450 && result != nullptr) {
result->existedMemorySize = existed_size;
}
} catch (const fs::filesystem_error& e) {
@@ -1645,7 +1645,7 @@ Error PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(OrbisSaveDataMemorySync* syncPa
}
u32 slot_id = 0;
if (g_fw_ver > ElfInfo::FW_50) {
if (g_fw_ver > ElfInfo::FW_500) {
slot_id = syncParam->slotId;
}
@@ -1670,7 +1670,7 @@ Error PS4_SYSV_ABI sceSaveDataTerminate() {
}
for (auto& instance : g_mount_slots) {
if (instance.has_value()) {
if (g_fw_ver >= ElfInfo::FW_40) {
if (g_fw_ver >= ElfInfo::FW_400) {
return Error::BUSY;
}
instance->Umount();
+1 -1
View File
@@ -86,7 +86,7 @@ s32 PS4_SYSV_ABI sceSysmoduleLoadModule(OrbisSysModule id) {
if (result == ORBIS_KERNEL_ERROR_ESTART) {
s32 sdk_ver = 0;
result = Kernel::sceKernelGetCompiledSdkVersion(&sdk_ver);
if (sdk_ver < Common::ElfInfo::FW_115 || result != ORBIS_OK) {
if (sdk_ver < Common::ElfInfo::FW_1150 || result != ORBIS_OK) {
return ORBIS_KERNEL_ERROR_EINVAL;
} else {
return ORBIS_KERNEL_ERROR_ESTART;
@@ -94,17 +94,17 @@ bool validateModuleId(s32 id) {
"Failed to retrieve compiled SDK version");
// libSceGameCustomDialog isn't loadable on SDK >= 7.50
if (id == 0xb8 && sdk_ver >= Common::ElfInfo::FW_75) {
if (id == 0xb8 && sdk_ver >= Common::ElfInfo::FW_750) {
return ORBIS_SYSMODULE_INVALID_ID;
}
// libSceNpSnsFacebookDialog isn't loadable on SDK >= 7.00
if (id == 0xb0 && sdk_ver >= Common::ElfInfo::FW_70) {
if (id == 0xb0 && sdk_ver >= Common::ElfInfo::FW_700) {
return ORBIS_SYSMODULE_INVALID_ID;
}
// libSceJson isn't loadable on SDK >= 3.00
if (id == 0x80 && sdk_ver >= Common::ElfInfo::FW_30) {
if (id == 0x80 && sdk_ver >= Common::ElfInfo::FW_300) {
return ORBIS_SYSMODULE_INVALID_ID;
}
@@ -405,7 +405,7 @@ s32 preloadModulesForLibkernel() {
}
// libSceDiscMap case, skipped on newer SDK versions.
if (module_index == 0x22 && sdk_ver >= Common::ElfInfo::FW_20) {
if (module_index == 0x22 && sdk_ver >= Common::ElfInfo::FW_200) {
continue;
}
@@ -416,18 +416,18 @@ s32 preloadModulesForLibkernel() {
}
// libSceRazorCpu, skipped for old non-devkit consoles.
if (module_index == 0x25 && sdk_ver < Common::ElfInfo::FW_45 &&
if (module_index == 0x25 && sdk_ver < Common::ElfInfo::FW_450 &&
!EmulatorSettings.IsDevKit()) {
continue;
}
// libSceHttp2, skipped for SDK versions below 7.00.
if (module_index == 0x28 && sdk_ver < Common::ElfInfo::FW_70) {
if (module_index == 0x28 && sdk_ver < Common::ElfInfo::FW_700) {
continue;
}
// libSceNpWebApi2 and libSceNpGameIntent, skipped for SDK versions below 7.50
if ((module_index == 0x29 || module_index == 0x2a) && sdk_ver < Common::ElfInfo::FW_75) {
if ((module_index == 0x29 || module_index == 0x2a) && sdk_ver < Common::ElfInfo::FW_750) {
continue;
}
+25 -2
View File
@@ -2,9 +2,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include "common/elf_info.h"
#include "common/singleton.h"
#include "core/emulator_settings.h"
#include "core/file_sys/fs.h"
#include "core/libraries/kernel/process.h"
#include "core/libraries/libs.h"
#include "core/libraries/system/systemservice.h"
#include "core/libraries/system/systemservice_error.h"
@@ -15,6 +17,7 @@ namespace Libraries::SystemService {
bool g_splash_status{true};
std::queue<OrbisSystemServiceEvent> g_event_queue;
std::mutex g_event_queue_mutex;
s32 g_sdk_version{};
bool IsSplashVisible() {
return EmulatorSettings.IsShowSplash() && g_splash_status;
@@ -1916,9 +1919,26 @@ s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(OrbisSystemServiceParamId param_id,
return ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER;
}
switch (param_id) {
case OrbisSystemServiceParamId::Lang:
*value = EmulatorSettings.GetConsoleLanguage();
case OrbisSystemServiceParamId::Lang: {
s32 lang = EmulatorSettings.GetConsoleLanguage();
if (lang == 0x15 && g_sdk_version < Common::ElfInfo::FW_200) {
lang = 0x12;
}
if (lang == 0x16 && g_sdk_version < Common::ElfInfo::FW_250) {
lang = 2;
}
if ((lang >= 0x17 && lang <= 0x1a) && g_sdk_version < Common::ElfInfo::FW_500) {
lang = 0x12;
}
if ((lang >= 0x1b && lang <= 0x1d) && g_sdk_version < Common::ElfInfo::FW_500) {
lang = 1;
}
if (lang == 0x1e && g_sdk_version < Common::ElfInfo::FW_1000) {
lang = 0x12;
}
*value = lang;
break;
}
case OrbisSystemServiceParamId::DateFormat:
*value = u32(OrbisSystemParamDateFormat::FmtDDMMYYYY);
break;
@@ -2448,6 +2468,9 @@ void PushSystemServiceEvent(const OrbisSystemServiceEvent& event) {
}
void RegisterLib(Core::Loader::SymbolsResolver* sym) {
ASSERT_MSG(Libraries::Kernel::sceKernelGetCompiledSdkVersion(&g_sdk_version) == 0,
"Failed to retrieve SDK version");
LIB_FUNCTION("alZfRdr2RP8", "libSceAppMessaging", 1, "libSceSystemService",
sceAppMessagingClearEventFlag);
LIB_FUNCTION("jKgAUl6cLy0", "libSceAppMessaging", 1, "libSceSystemService",
+1 -1
View File
@@ -103,7 +103,7 @@ void Linker::Execute(const std::vector<std::string>& args) {
}
const u64 sdk_ver = proc_param->sdk_version;
if (sdk_ver < Common::ElfInfo::FW_50) {
if (sdk_ver < Common::ElfInfo::FW_500) {
use_extended_mem1 = mem_param.extended_memory_1 ? *mem_param.extended_memory_1 : false;
use_extended_mem2 = mem_param.extended_memory_2 ? *mem_param.extended_memory_2 : false;
}
+1 -1
View File
@@ -652,7 +652,7 @@ s32 MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, u64 size, Memo
ASSERT_MSG(remaining_size == 0, "Failed to map physical memory");
}
if (new_vma.type != VMAType::Direct || sdk_version >= Common::ElfInfo::FW_20) {
if (new_vma.type != VMAType::Direct || sdk_version >= Common::ElfInfo::FW_200) {
// Merge this VMA with similar nearby areas
// Direct memory mappings only coalesce on SDK version 2.00 or later.
MergeAdjacent(vma_map, new_vma_handle);