diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ac1a6025..ed366a0b5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ # SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later -cmake_minimum_required(VERSION 3.16.3) +# Version 3.24 needed for FetchContent OVERRIDE_FIND_PACKAGE +cmake_minimum_required(VERSION 3.24) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED True) @@ -110,7 +111,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_ find_package(Boost 1.84.0 CONFIG) find_package(FFmpeg 5.1.2 MODULE) find_package(fmt 10.2.0 CONFIG) -find_package(glslang 14.2.0 CONFIG) +find_package(glslang 15 CONFIG) find_package(half 1.12.0 MODULE) find_package(magic_enum 0.9.6 CONFIG) find_package(PNG 1.6 MODULE) @@ -373,6 +374,8 @@ set(JPEG_LIB src/core/libraries/jpeg/jpeg_error.h set(PLAYGO_LIB src/core/libraries/playgo/playgo.cpp src/core/libraries/playgo/playgo.h + src/core/libraries/playgo/playgo_dialog.cpp + src/core/libraries/playgo/playgo_dialog.h src/core/libraries/playgo/playgo_types.h ) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 53802276e..50eda0288 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -38,7 +38,8 @@ else() set(CRYPTOPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp/) add_subdirectory(cryptopp-cmake) file(COPY cryptopp DESTINATION cryptopp FILES_MATCHING PATTERN "*.h") - target_include_directories(cryptopp INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/cryptopp") + # remove externals/cryptopp from include directories because it contains a conflicting zlib.h file + set_target_properties(cryptopp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/cryptopp") endif() endif() @@ -67,6 +68,8 @@ if (NOT TARGET ZLIB::ZLIB) ) FetchContent_MakeAvailable(ZLIB) add_library(ZLIB::ZLIB ALIAS zlib) + # libpng expects this variable to exist after its find_package(ZLIB) + get_target_property(ZLIB_INCLUDE_DIRS zlib INTERFACE_INCLUDE_DIRECTORIES) endif() # SDL3 diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 5f44658f0..632b2b329 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -107,6 +107,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, Png) \ SUB(Lib, Jpeg) \ SUB(Lib, PlayGo) \ + SUB(Lib, PlayGoDialog) \ SUB(Lib, Random) \ SUB(Lib, Usbd) \ SUB(Lib, Ajm) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index a373e8f1b..e7e91882a 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -74,6 +74,7 @@ enum class Class : u8 { Lib_Png, ///< The LibScePng implementation. Lib_Jpeg, ///< The LibSceJpeg implementation. Lib_PlayGo, ///< The LibScePlayGo implementation. + Lib_PlayGoDialog, ///< The LibScePlayGoDialog implementation. Lib_Random, ///< The libSceRandom implementation. Lib_Usbd, ///< The LibSceUsbd implementation. Lib_Ajm, ///< The LibSceAjm implementation. diff --git a/src/core/file_format/playgo_chunk.h b/src/core/file_format/playgo_chunk.h index 2a234f5fe..12d8f022e 100644 --- a/src/core/file_format/playgo_chunk.h +++ b/src/core/file_format/playgo_chunk.h @@ -97,7 +97,6 @@ struct PlaygoChunk { class PlaygoFile { public: - bool initialized = false; OrbisPlayGoHandle handle = 0; OrbisPlayGoChunkId id = 0; OrbisPlayGoLocus locus = OrbisPlayGoLocus::NotDownloaded; diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 53b67b395..66cdd5b87 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -27,6 +27,7 @@ #include "core/libraries/np_trophy/np_trophy.h" #include "core/libraries/pad/pad.h" #include "core/libraries/playgo/playgo.h" +#include "core/libraries/playgo/playgo_dialog.h" #include "core/libraries/random/random.h" #include "core/libraries/razor_cpu/razor_cpu.h" #include "core/libraries/remote_play/remoteplay.h" @@ -74,6 +75,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { Libraries::AppContent::RegisterlibSceAppContent(sym); Libraries::PngDec::RegisterlibScePngDec(sym); Libraries::PlayGo::RegisterlibScePlayGo(sym); + Libraries::PlayGo::Dialog::RegisterlibScePlayGoDialog(sym); Libraries::Random::RegisterlibSceRandom(sym); Libraries::Usbd::RegisterlibSceUsbd(sym); Libraries::Pad::RegisterlibScePad(sym); diff --git a/src/core/libraries/playgo/playgo.cpp b/src/core/libraries/playgo/playgo.cpp index 6fcf875da..13d6f991f 100644 --- a/src/core/libraries/playgo/playgo.cpp +++ b/src/core/libraries/playgo/playgo.cpp @@ -2,7 +2,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" +#include "common/singleton.h" #include "core/file_format/playgo_chunk.h" +#include "core/file_sys/fs.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/system/systemservice.h" @@ -29,10 +31,9 @@ s32 PS4_SYSV_ABI scePlayGoClose(OrbisPlayGoHandle handle) { if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } - playgo.reset(); return ORBIS_OK; } @@ -98,7 +99,7 @@ s32 PS4_SYSV_ABI scePlayGoGetInstallSpeed(OrbisPlayGoHandle handle, if (outSpeed == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -126,7 +127,7 @@ s32 PS4_SYSV_ABI scePlayGoGetLanguageMask(OrbisPlayGoHandle handle, if (outLanguageMask == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -148,7 +149,7 @@ s32 PS4_SYSV_ABI scePlayGoGetLocus(OrbisPlayGoHandle handle, const OrbisPlayGoCh if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } if (playgo->GetPlaygoHeader().file_size == 0) { @@ -180,7 +181,7 @@ s32 PS4_SYSV_ABI scePlayGoGetProgress(OrbisPlayGoHandle handle, const OrbisPlayG if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } if (playgo->GetPlaygoHeader().file_size == 0) { @@ -219,7 +220,7 @@ s32 PS4_SYSV_ABI scePlayGoGetToDoList(OrbisPlayGoHandle handle, OrbisPlayGoToDo* if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } *outEntries = 0; // nothing to do @@ -242,17 +243,24 @@ s32 PS4_SYSV_ABI scePlayGoInitialize(OrbisPlayGoInitParams* param) { if (param->bufSize < 0x200000) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - - playgo = std::make_unique(); - if (!playgo->initialized) { - using namespace SystemService; - s32 system_lang = 0; - sceSystemServiceParamGetInt(OrbisSystemServiceParamId::Lang, &system_lang); - playgo->langMask = scePlayGoConvertLanguage(system_lang); - playgo->initialized = true; - } else { + if (playgo) { return ORBIS_PLAYGO_ERROR_ALREADY_INITIALIZED; } + + using namespace SystemService; + + playgo = std::make_unique(); + + auto* mnt = Common::Singleton::Instance(); + const auto file_path = mnt->GetHostPath("/app0/sce_sys/playgo-chunk.dat"); + if (!playgo->Open(file_path)) { + LOG_WARNING(Lib_PlayGo, "Could not open PlayGo file"); + } + + s32 system_lang = 0; + sceSystemServiceParamGetInt(OrbisSystemServiceParamId::Lang, &system_lang); + playgo->langMask = scePlayGoConvertLanguage(system_lang); + return ORBIS_OK; } @@ -265,7 +273,7 @@ s32 PS4_SYSV_ABI scePlayGoOpen(OrbisPlayGoHandle* outHandle, const void* param) if (param) { return ORBIS_PLAYGO_ERROR_INVALID_ARGUMENT; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } if (playgo->GetPlaygoHeader().file_size == 0) { @@ -289,7 +297,7 @@ s32 PS4_SYSV_ABI scePlayGoPrefetch(OrbisPlayGoHandle handle, const OrbisPlayGoCh if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -310,7 +318,7 @@ s32 PS4_SYSV_ABI scePlayGoSetInstallSpeed(OrbisPlayGoHandle handle, OrbisPlayGoI if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -339,7 +347,7 @@ s32 PS4_SYSV_ABI scePlayGoSetLanguageMask(OrbisPlayGoHandle handle, if (handle != 1) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -360,7 +368,7 @@ s32 PS4_SYSV_ABI scePlayGoSetToDoList(OrbisPlayGoHandle handle, const OrbisPlayG if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } return ORBIS_OK; @@ -369,11 +377,10 @@ s32 PS4_SYSV_ABI scePlayGoSetToDoList(OrbisPlayGoHandle handle, const OrbisPlayG s32 PS4_SYSV_ABI scePlayGoTerminate() { LOG_INFO(Lib_PlayGo, "called"); - if (playgo->initialized) { - playgo->initialized = false; - } else { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } + playgo.reset(); return ORBIS_OK; } diff --git a/src/core/libraries/playgo/playgo_dialog.cpp b/src/core/libraries/playgo/playgo_dialog.cpp new file mode 100644 index 000000000..16f7aa05d --- /dev/null +++ b/src/core/libraries/playgo/playgo_dialog.cpp @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/libraries/libs.h" +#include "core/libraries/playgo/playgo_dialog.h" +#include "core/libraries/system/commondialog.h" + +namespace Libraries::PlayGo::Dialog { + +using CommonDialog::Error; +using CommonDialog::Result; +using CommonDialog::Status; + +Error PS4_SYSV_ABI scePlayGoDialogClose() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Error::OK; +} + +Error PS4_SYSV_ABI scePlayGoDialogGetResult(OrbisPlayGoDialogResult* result) { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + if (result == nullptr) { + return Error::ARG_NULL; + } + // Result value 3 allows games to proceed. + result->result = static_cast(3); + return Error::OK; +} + +Status PS4_SYSV_ABI scePlayGoDialogGetStatus() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Status::FINISHED; +} + +Error PS4_SYSV_ABI scePlayGoDialogInitialize() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Error::OK; +} + +Error PS4_SYSV_ABI scePlayGoDialogOpen(const OrbisPlayGoDialogParam* param) { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + if (param == nullptr) { + return Error::ARG_NULL; + } + ASSERT(param->size == sizeof(OrbisPlayGoDialogParam)); + ASSERT(param->baseParam.size == sizeof(CommonDialog::BaseParam)); + return Error::OK; +} + +Error PS4_SYSV_ABI scePlayGoDialogTerminate() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Error::OK; +} + +Status PS4_SYSV_ABI scePlayGoDialogUpdateStatus() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Status::FINISHED; +} + +void RegisterlibScePlayGoDialog(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("fbigNQiZpm0", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogClose); + LIB_FUNCTION("wx9TDplJKB4", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogGetResult); + LIB_FUNCTION("NOAMxY2EGS0", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogGetStatus); + LIB_FUNCTION("fECamTJKpsM", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogInitialize); + LIB_FUNCTION("kHd72ukqbxw", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogOpen); + LIB_FUNCTION("okgIGdr5Iz0", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogTerminate); + LIB_FUNCTION("Yb60K7BST48", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogUpdateStatus); +}; + +} // namespace Libraries::PlayGo::Dialog diff --git a/src/core/libraries/playgo/playgo_dialog.h b/src/core/libraries/playgo/playgo_dialog.h new file mode 100644 index 000000000..fa9c64680 --- /dev/null +++ b/src/core/libraries/playgo/playgo_dialog.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "core/libraries/system/commondialog.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::PlayGo::Dialog { + +struct OrbisPlayGoDialogParam { + CommonDialog::BaseParam baseParam; + s32 size; + u8 unk[0x30]; +}; +static_assert(sizeof(OrbisPlayGoDialogParam) == 0x68); + +struct OrbisPlayGoDialogResult { + u8 unk1[0x4]; + CommonDialog::Result result; + u8 unk2[0x20]; +}; +static_assert(sizeof(OrbisPlayGoDialogResult) == 0x28); + +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogClose(); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogGetResult(OrbisPlayGoDialogResult* result); +CommonDialog::Status PS4_SYSV_ABI scePlayGoDialogGetStatus(); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogInitialize(); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogOpen(const OrbisPlayGoDialogParam* param); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogTerminate(); +CommonDialog::Status PS4_SYSV_ABI scePlayGoDialogUpdateStatus(); + +void RegisterlibScePlayGoDialog(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::PlayGo::Dialog diff --git a/src/emulator.cpp b/src/emulator.cpp index 4ab535a2c..1d2542d2b 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -22,7 +22,6 @@ #include "common/scm_rev.h" #include "common/singleton.h" #include "common/version.h" -#include "core/file_format/playgo_chunk.h" #include "core/file_format/psf.h" #include "core/file_format/splash.h" #include "core/file_format/trp.h" @@ -157,12 +156,6 @@ void Emulator::Run(const std::filesystem::path& file) { fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); - } else if (entry.path().filename() == "playgo-chunk.dat") { - auto* playgo = Common::Singleton::Instance(); - auto filepath = sce_sys_folder / "playgo-chunk.dat"; - if (!playgo->Open(filepath)) { - LOG_ERROR(Loader, "PlayGo: unable to open file"); - } } else if (entry.path().filename() == "pic1.png") { auto* splash = Common::Singleton::Instance(); if (splash->IsLoaded()) {