From bc51044eaae6ad8019388118f72078cf6d40dcf4 Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 01:56:43 +0300 Subject: [PATCH 01/31] Progress further in json config implementation --- CMakeLists.txt | 3 +- core/videoout/CMakeLists.txt | 3 +- modules/libSceAudioOut/CMakeLists.txt | 3 + modules/libSceAudioOut/entry.cpp | 2 + modules/libScePad/CMakeLists.txt | 3 + tools/config/CmakeLists.txt | 6 +- tools/config/config.cpp | 111 ++++++++++++++++++++++++-- tools/config/config.h | 15 +++- 8 files changed, 134 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2253eda..bae78bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,9 +37,9 @@ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/lib) # Move all libs here post-build, ex # include_directories(BEFORE ${CMAKE_INSTALL_PREFIX}/development/include - ${PRJ_SRC_DIR}/third_party/SDL2/include ${PRJ_SRC_DIR}/modules_include ${PRJ_SRC_DIR}/tools/logging + ${PRJ_SRC_DIR}/tools/config ${PRJ_SRC_DIR} ${CMAKE_BINARY_DIR}/third_party/install/include ) @@ -52,6 +52,7 @@ link_directories(BEFORE ) add_subdirectory(tools/logging) # include before link_libraries +add_subdirectory(tools/config) # include before link_libraries add_subdirectory(tools/dll2Nids) add_dependencies(dll2Nids third_party) diff --git a/core/videoout/CMakeLists.txt b/core/videoout/CMakeLists.txt index fa5d20c..fa8958a 100644 --- a/core/videoout/CMakeLists.txt +++ b/core/videoout/CMakeLists.txt @@ -9,4 +9,5 @@ target_include_directories(videoout PRIVATE ${Vulkan_INCLUDE_DIRS} ${PRJ_SRC_DIR}/third_party/optick/src ${PRJ_SRC_DIR}/third_party/magic_enum/include -) \ No newline at end of file + ${PRJ_SRC_DIR}/third_party/SDL2/include +) diff --git a/modules/libSceAudioOut/CMakeLists.txt b/modules/libSceAudioOut/CMakeLists.txt index 887c656..cb375f7 100644 --- a/modules/libSceAudioOut/CMakeLists.txt +++ b/modules/libSceAudioOut/CMakeLists.txt @@ -9,5 +9,8 @@ add_library(${libName} SHARED entry.cpp) add_dependencies(${libName} third_party) target_link_libraries(${libName} PRIVATE SDL2) +target_include_directories(${libName} PRIVATE + ${PRJ_SRC_DIR}/third_party/SDL2/include +) setupModule(${libName}) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index ea9f8a2..bad9273 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "logging.h" #include "types.h" +// #include "config.h" #include #include @@ -136,6 +137,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type char* dname; SDL_AudioSpec fmt_curr; + // accessConfig()->accessModule(ConfigSaveFlags::AUDIO); SDL_GetDefaultAudioInfo(&dname, &fmt_curr, 0); LOG_INFO(L"Opening audio device: %S\n", dname); auto devId = SDL_OpenAudioDevice(dname, 0, &fmt, NULL, 0); diff --git a/modules/libScePad/CMakeLists.txt b/modules/libScePad/CMakeLists.txt index 9616672..272e13a 100644 --- a/modules/libScePad/CMakeLists.txt +++ b/modules/libScePad/CMakeLists.txt @@ -8,5 +8,8 @@ add_library(${libName} SHARED entry.cpp) add_dependencies(${libName} core) target_link_libraries(${libName} PRIVATE SDL2 ${Vulkan_LIBRARIES} core.lib) +target_include_directories(${libName} PRIVATE + ${PRJ_SRC_DIR}/third_party/SDL2/include +) setupModule(${libName}) diff --git a/tools/config/CmakeLists.txt b/tools/config/CmakeLists.txt index 881f9d6..819d8db 100644 --- a/tools/config/CmakeLists.txt +++ b/tools/config/CmakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.24) add_library(config SHARED config.cpp) +target_link_directories(config PRIVATE + ${CMAKE_BINARY_DIR}/third_party/install/lib +) + add_dependencies(config boost) target_link_libraries(config libboost_thread) @@ -18,4 +22,4 @@ set_target_properties(config ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/third_party/intall/lib" ) -install(TARGETS config LIBRARY DESTINATION .) \ No newline at end of file +install(TARGETS config LIBRARY DESTINATION .) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 500eb7e..50c800d 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -2,15 +2,31 @@ #include "config.h" #undef __APICALL_EXTERN +#include "logging.h" +#include + +LOG_DEFINE_MODULE(Config); + +using json = nlohmann::json; + class Config: public IConfig { - nlohmann::json m_logging; - boost::mutex m_mutex_logging; + json m_logging; + json m_graphics; + json m_audio; + json m_controls; + boost::mutex m_mutex_logging; + boost::mutex m_mutex_graphics; + boost::mutex m_mutex_audio; + boost::mutex m_mutex_controls; public: Config() = default; virtual ~Config() = default; - std::pair, nlohmann::json*> accessLogging() final; + std::pair, json*> accessModule(ConfigSaveFlags flag); + + virtual bool load(); + virtual bool save(uint32_t flags); }; IConfig* accessConfig() { @@ -18,7 +34,88 @@ IConfig* accessConfig() { return &obj; } -std::pair, nlohmann::json*> Config::accessLogging() { - boost::unique_lock lock(m_mutex_logging); - return std::make_pair(std::move(lock), &m_logging); -} \ No newline at end of file +std::pair, json*> Config::accessModule(ConfigSaveFlags flag) { + switch (flag) { + case ConfigSaveFlags::LOGGING: + return std::make_pair(std::move(boost::unique_lock(m_mutex_logging)), &m_logging); + case ConfigSaveFlags::GRAPHICS: + return std::make_pair(std::move(boost::unique_lock(m_mutex_graphics)), &m_graphics); + case ConfigSaveFlags::AUDIO: + return std::make_pair(std::move(boost::unique_lock(m_mutex_audio)), &m_audio); + case ConfigSaveFlags::CONTROLS: + return std::make_pair(std::move(boost::unique_lock(m_mutex_controls)), &m_controls); + + default: + throw std::exception("Invalid bit flag"); + } +} + +bool Config::load() { + auto load = [this](std::string_view fname, json& j, json defaults = {}, ConfigSaveFlags dflag = ConfigSaveFlags::NONE) { + LOG_USE_MODULE(Config); + + auto path = std::string("./config/") + fname.data(); + + try { + std::ifstream log_file(path); + j = json::parse(log_file, nullptr, true, true); + } catch (const json::exception& e) { + LOG_ERR(L"Failed to open %S: %S", fname, e.what()); + + std::filesystem::path newp(path); + newp.replace_extension(".back"); + std::filesystem::rename(path, newp); + + j = defaults; + if (dflag != ConfigSaveFlags::NONE) + this->save((uint32_t)dflag); + } + }; + + load("logging.json", m_logging, { + {"sink", "baical"} + }, ConfigSaveFlags::LOGGING); + load("graphics.json", m_graphics, { + }, ConfigSaveFlags::GRAPHICS); + load("audio.json", m_audio, { + {"volume", 0.5f}, + {"device", "[default]"} + }, ConfigSaveFlags::AUDIO); + load("controls.json", m_controls, { + {"type", "gamepad"}, + {"keybinds", { + {"triangle", ""}, + {"square", ""}, + {"circle", ""}, + {"cross", ""}, + {"dpad_up", ""}, + {"dpad_down", ""}, + {"dpad_left", ""}, + {"dpad_right", ""}, + {"options", ""}, + {"touchpad", ""}, + {"l1", ""}, + {"l2", ""}, + {"l3", ""}, + {"r1", ""}, + {"r2", ""}, + {"r3", ""}, + {"lx-", ""}, + {"lx+", ""}, + {"ly-", ""}, + {"ly+", ""}, + {"rx-", ""}, + {"rx+", ""}, + {"ry-", ""}, + {"ry+", ""}, + }} + }, ConfigSaveFlags::CONTROLS); + + return true; +} + +bool Config::save(uint32_t flags) { + if (flags & (uint32_t)ConfigSaveFlags::LOGGING) {} + + return true; +} diff --git a/tools/config/config.h b/tools/config/config.h index c0fc534..c05e9e7 100644 --- a/tools/config/config.h +++ b/tools/config/config.h @@ -4,6 +4,14 @@ #include +enum class ConfigSaveFlags : uint32_t { + NONE = 0, + LOGGING = 2 << 0, + GRAPHICS = 2 << 1, + AUDIO = 2 << 2, + CONTROLS = 2 << 3 +}; + class IConfig { CLASS_NO_COPY(IConfig); CLASS_NO_MOVE(IConfig); @@ -14,7 +22,10 @@ class IConfig { public: virtual ~IConfig() = default; - virtual std::pair, nlohmann::json*> accessLogging() = 0; + virtual std::pair, nlohmann::json*> accessModule(ConfigSaveFlags) = 0; + + virtual bool load() = 0; + virtual bool save(uint32_t flags) = 0; }; #ifdef __APICALL_EXTERN @@ -24,4 +35,4 @@ class IConfig { #endif __APICALL IConfig* accessConfig(); -#undef __APICALL \ No newline at end of file +#undef __APICALL From a34357eb29930d32b6b1afb978d044968d72585d Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 02:05:42 +0300 Subject: [PATCH 02/31] Make it clang formatted --- tools/config/config.cpp | 72 ++++++++++++----------------------------- tools/config/config.h | 10 ++---- 2 files changed, 23 insertions(+), 59 deletions(-) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 50c800d..0a0cfb3 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -3,6 +3,7 @@ #undef __APICALL_EXTERN #include "logging.h" + #include LOG_DEFINE_MODULE(Config); @@ -36,17 +37,12 @@ IConfig* accessConfig() { std::pair, json*> Config::accessModule(ConfigSaveFlags flag) { switch (flag) { - case ConfigSaveFlags::LOGGING: - return std::make_pair(std::move(boost::unique_lock(m_mutex_logging)), &m_logging); - case ConfigSaveFlags::GRAPHICS: - return std::make_pair(std::move(boost::unique_lock(m_mutex_graphics)), &m_graphics); - case ConfigSaveFlags::AUDIO: - return std::make_pair(std::move(boost::unique_lock(m_mutex_audio)), &m_audio); - case ConfigSaveFlags::CONTROLS: - return std::make_pair(std::move(boost::unique_lock(m_mutex_controls)), &m_controls); + case ConfigSaveFlags::LOGGING: return std::make_pair(std::move(boost::unique_lock(m_mutex_logging)), &m_logging); + case ConfigSaveFlags::GRAPHICS: return std::make_pair(std::move(boost::unique_lock(m_mutex_graphics)), &m_graphics); + case ConfigSaveFlags::AUDIO: return std::make_pair(std::move(boost::unique_lock(m_mutex_audio)), &m_audio); + case ConfigSaveFlags::CONTROLS: return std::make_pair(std::move(boost::unique_lock(m_mutex_controls)), &m_controls); - default: - throw std::exception("Invalid bit flag"); + default: throw std::exception("Invalid bit flag"); } } @@ -67,55 +63,29 @@ bool Config::load() { std::filesystem::rename(path, newp); j = defaults; - if (dflag != ConfigSaveFlags::NONE) - this->save((uint32_t)dflag); + if (dflag != ConfigSaveFlags::NONE) this->save((uint32_t)dflag); } }; - load("logging.json", m_logging, { - {"sink", "baical"} - }, ConfigSaveFlags::LOGGING); - load("graphics.json", m_graphics, { - }, ConfigSaveFlags::GRAPHICS); - load("audio.json", m_audio, { - {"volume", 0.5f}, - {"device", "[default]"} - }, ConfigSaveFlags::AUDIO); - load("controls.json", m_controls, { - {"type", "gamepad"}, - {"keybinds", { - {"triangle", ""}, - {"square", ""}, - {"circle", ""}, - {"cross", ""}, - {"dpad_up", ""}, - {"dpad_down", ""}, - {"dpad_left", ""}, - {"dpad_right", ""}, - {"options", ""}, - {"touchpad", ""}, - {"l1", ""}, - {"l2", ""}, - {"l3", ""}, - {"r1", ""}, - {"r2", ""}, - {"r3", ""}, - {"lx-", ""}, - {"lx+", ""}, - {"ly-", ""}, - {"ly+", ""}, - {"rx-", ""}, - {"rx+", ""}, - {"ry-", ""}, - {"ry+", ""}, - }} - }, ConfigSaveFlags::CONTROLS); + load("logging.json", m_logging, {{"sink", "baical"}}, ConfigSaveFlags::LOGGING); + load("graphics.json", m_graphics, {}, ConfigSaveFlags::GRAPHICS); + load("audio.json", m_audio, {{"volume", 0.5f}, {"device", "[default]"}}, ConfigSaveFlags::AUDIO); + load("controls.json", m_controls, + {{"type", "gamepad"}, + {"keybinds", + { + {"triangle", ""}, {"square", ""}, {"circle", ""}, {"cross", ""}, {"dpad_up", ""}, {"dpad_down", ""}, {"dpad_left", ""}, {"dpad_right", ""}, + {"options", ""}, {"touchpad", ""}, {"l1", ""}, {"l2", ""}, {"l3", ""}, {"r1", ""}, {"r2", ""}, {"r3", ""}, + {"lx-", ""}, {"lx+", ""}, {"ly-", ""}, {"ly+", ""}, {"rx-", ""}, {"rx+", ""}, {"ry-", ""}, {"ry+", ""}, + }}}, + ConfigSaveFlags::CONTROLS); return true; } bool Config::save(uint32_t flags) { - if (flags & (uint32_t)ConfigSaveFlags::LOGGING) {} + if (flags & (uint32_t)ConfigSaveFlags::LOGGING) { + } return true; } diff --git a/tools/config/config.h b/tools/config/config.h index c05e9e7..9f09f00 100644 --- a/tools/config/config.h +++ b/tools/config/config.h @@ -4,13 +4,7 @@ #include -enum class ConfigSaveFlags : uint32_t { - NONE = 0, - LOGGING = 2 << 0, - GRAPHICS = 2 << 1, - AUDIO = 2 << 2, - CONTROLS = 2 << 3 -}; +enum class ConfigSaveFlags : uint32_t { NONE = 0, LOGGING = 2 << 0, GRAPHICS = 2 << 1, AUDIO = 2 << 2, CONTROLS = 2 << 3 }; class IConfig { CLASS_NO_COPY(IConfig); @@ -24,7 +18,7 @@ class IConfig { virtual std::pair, nlohmann::json*> accessModule(ConfigSaveFlags) = 0; - virtual bool load() = 0; + virtual bool load() = 0; virtual bool save(uint32_t flags) = 0; }; From 74eb42022e71a68d7e793d34e63ffc86253da23d Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 02:43:18 +0300 Subject: [PATCH 03/31] Fix --- tools/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 0a0cfb3..75ad195 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -56,7 +56,7 @@ bool Config::load() { std::ifstream log_file(path); j = json::parse(log_file, nullptr, true, true); } catch (const json::exception& e) { - LOG_ERR(L"Failed to open %S: %S", fname, e.what()); + LOG_ERR(L"Failed to open %S: %S", fname.data(), e.what()); std::filesystem::path newp(path); newp.replace_extension(".back"); From c962100b5577cc65881725ff4314197e636a60a3 Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 12:36:03 +0300 Subject: [PATCH 04/31] More things implemented --- tools/config/config.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 75ad195..431a2cf 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -53,10 +53,10 @@ bool Config::load() { auto path = std::string("./config/") + fname.data(); try { - std::ifstream log_file(path); - j = json::parse(log_file, nullptr, true, true); + std::ifstream json_file(path); + j = json::parse(json_file, nullptr, true, true); } catch (const json::exception& e) { - LOG_ERR(L"Failed to open %S: %S", fname.data(), e.what()); + LOG_ERR(L"Failed to parse %S: %S", fname.data(), e.what()); std::filesystem::path newp(path); newp.replace_extension(".back"); @@ -84,8 +84,26 @@ bool Config::load() { } bool Config::save(uint32_t flags) { - if (flags & (uint32_t)ConfigSaveFlags::LOGGING) { - } + auto save = [this](std::string_view fname, json& j) { + LOG_USE_MODULE(Config); + + auto path = std::string("./config/") + fname.data(); + try { + std::ofstream json_file(path); + json_file << j; + return true; + } catch (const json::exception& e) { + LOG_ERR(L"Failed to save %S: %S", fname.data(), e.what()); + return false; + } + }; + + bool result = true; + + if (std::filesystem::is_directory("./config/")) std::filesystem::create_directory("./config/"); + if (flags & (uint32_t)ConfigSaveFlags::LOGGING) result &= save("logging.json", m_logging); + if (flags & (uint32_t)ConfigSaveFlags::GRAPHICS) result &= save("graphics.json", m_graphics); + if (flags & (uint32_t)ConfigSaveFlags::AUDIO) result &= save("audio.json", m_audio); return true; } From ea1eb481137a534d28a4b04ee614db580042b29f Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 15:21:24 +0300 Subject: [PATCH 05/31] Update config.cpp --- tools/config/config.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 431a2cf..50f2f32 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -2,12 +2,8 @@ #include "config.h" #undef __APICALL_EXTERN -#include "logging.h" - #include -LOG_DEFINE_MODULE(Config); - using json = nlohmann::json; class Config: public IConfig { @@ -48,15 +44,13 @@ std::pair, json*> Config::accessModule(ConfigSa bool Config::load() { auto load = [this](std::string_view fname, json& j, json defaults = {}, ConfigSaveFlags dflag = ConfigSaveFlags::NONE) { - LOG_USE_MODULE(Config); - auto path = std::string("./config/") + fname.data(); try { std::ifstream json_file(path); j = json::parse(json_file, nullptr, true, true); } catch (const json::exception& e) { - LOG_ERR(L"Failed to parse %S: %S", fname.data(), e.what()); + printf("Failed to parse %s: %s\n", fname.data(), e.what()); std::filesystem::path newp(path); newp.replace_extension(".back"); @@ -85,15 +79,13 @@ bool Config::load() { bool Config::save(uint32_t flags) { auto save = [this](std::string_view fname, json& j) { - LOG_USE_MODULE(Config); - auto path = std::string("./config/") + fname.data(); try { std::ofstream json_file(path); json_file << j; return true; } catch (const json::exception& e) { - LOG_ERR(L"Failed to save %S: %S", fname.data(), e.what()); + printf(L"Failed to save %s: %s\n", fname.data(), e.what()); return false; } }; From 83e01145be468ee5e383edb80cc40ddf16d3e234 Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 15:28:59 +0300 Subject: [PATCH 06/31] Update config.cpp --- tools/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 50f2f32..b5aade6 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -85,7 +85,7 @@ bool Config::save(uint32_t flags) { json_file << j; return true; } catch (const json::exception& e) { - printf(L"Failed to save %s: %s\n", fname.data(), e.what()); + printf("Failed to save %s: %s\n", fname.data(), e.what()); return false; } }; From a9df0df001aa6c2b8620c4aa48089730b47729ec Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 19:04:33 +0300 Subject: [PATCH 07/31] Fixes --- .github/workflows/build.yml | 2 +- modules/libSceAudioOut/CMakeLists.txt | 3 +- modules/libSceAudioOut/entry.cpp | 25 ++++++++--- tools/config/config.cpp | 65 +++++++++++++-------------- tools/config/config.h | 5 ++- 5 files changed, 58 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1cb7d26..cabe1b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,7 +77,7 @@ jobs: cache: true - name: Configure - run: cmake.exe -S. -B_build/_Release -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=_build/_Install -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe + run: cmake.exe -S. -B_build/_Release -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=_build/_Install -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe -j4 - name: Build run: cmake --build _build/_Release -j4 diff --git a/modules/libSceAudioOut/CMakeLists.txt b/modules/libSceAudioOut/CMakeLists.txt index cb375f7..5714e67 100644 --- a/modules/libSceAudioOut/CMakeLists.txt +++ b/modules/libSceAudioOut/CMakeLists.txt @@ -8,7 +8,8 @@ add_library(${libName} SHARED entry.cpp) add_dependencies(${libName} third_party) -target_link_libraries(${libName} PRIVATE SDL2) +target_link_libraries(${libName} PRIVATE config.lib SDL2 libboost_thread) +target_compile_definitions(${libName} PRIVATE BOOST_ALL_NO_LIB WIN32_LEAN_AND_MEAN) target_include_directories(${libName} PRIVATE ${PRJ_SRC_DIR}/third_party/SDL2/include ) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index bad9273..ef5f4a2 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -1,7 +1,7 @@ #include "common.h" #include "logging.h" #include "types.h" -// #include "config.h" +#include "tools/config/config.h" #include #include @@ -135,10 +135,25 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type .callback = nullptr, .userdata = nullptr}; - char* dname; - SDL_AudioSpec fmt_curr; - // accessConfig()->accessModule(ConfigSaveFlags::AUDIO); - SDL_GetDefaultAudioInfo(&dname, &fmt_curr, 0); + const char* dname; + auto [lock, jData] = accessConfig()->accessModule(ConfigSaveFlags::AUDIO); + + // lock.lock(); + if ((*jData)["device"] == "[default]") { + SDL_AudioSpec fmt_curr; + SDL_GetDefaultAudioInfo((char **)&dname, &fmt_curr, 0); + } else { + try { + std::string jdname; + (*jData)["device"].get_to(jdname); + dname = jdname.c_str(); + } catch (const json::exception& e) { + LOG_ERR(L"Invalid audio device name: %S", e.what()); + dname = NULL; + } + } + // lock.unlock(); + LOG_INFO(L"Opening audio device: %S\n", dname); auto devId = SDL_OpenAudioDevice(dname, 0, &fmt, NULL, 0); if (devId <= 0) return devId; diff --git a/tools/config/config.cpp b/tools/config/config.cpp index b5aade6..159bc03 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -4,8 +4,6 @@ #include -using json = nlohmann::json; - class Config: public IConfig { json m_logging; json m_graphics; @@ -17,12 +15,11 @@ class Config: public IConfig { boost::mutex m_mutex_controls; public: - Config() = default; + Config(); virtual ~Config() = default; std::pair, json*> accessModule(ConfigSaveFlags flag); - virtual bool load(); virtual bool save(uint32_t flags); }; @@ -42,19 +39,46 @@ std::pair, json*> Config::accessModule(ConfigSa } } -bool Config::load() { +bool Config::save(uint32_t flags) { + auto save = [this](std::string_view fname, json& j) { + auto path = std::string("./config/") + fname.data(); + try { + std::ofstream json_file(path); + json_file << std::setw(4) << j; + return true; + } catch (const json::exception& e) { + printf("Failed to save %s: %s\n", fname.data(), e.what()); + return false; + } + }; + + bool result = true; + + if (!std::filesystem::is_directory("./config/")) std::filesystem::create_directory("./config/"); + if (flags & (uint32_t)ConfigSaveFlags::LOGGING) result &= save("logging.json", m_logging); + if (flags & (uint32_t)ConfigSaveFlags::GRAPHICS) result &= save("graphics.json", m_graphics); + if (flags & (uint32_t)ConfigSaveFlags::AUDIO) result &= save("audio.json", m_audio); + if (flags & (uint32_t)ConfigSaveFlags::CONTROLS) result &= save("controls.json", m_controls); + + return true; +} + +Config::Config() { auto load = [this](std::string_view fname, json& j, json defaults = {}, ConfigSaveFlags dflag = ConfigSaveFlags::NONE) { auto path = std::string("./config/") + fname.data(); try { std::ifstream json_file(path); j = json::parse(json_file, nullptr, true, true); + printf("Config %s loaded successfully\n", fname.data()); } catch (const json::exception& e) { printf("Failed to parse %s: %s\n", fname.data(), e.what()); - std::filesystem::path newp(path); - newp.replace_extension(".back"); - std::filesystem::rename(path, newp); + try { + std::filesystem::path newp(path); + newp.replace_extension(".back"); + std::filesystem::rename(path, newp); + } catch (const std::filesystem::filesystem_error& e) {} j = defaults; if (dflag != ConfigSaveFlags::NONE) this->save((uint32_t)dflag); @@ -73,29 +97,4 @@ bool Config::load() { {"lx-", ""}, {"lx+", ""}, {"ly-", ""}, {"ly+", ""}, {"rx-", ""}, {"rx+", ""}, {"ry-", ""}, {"ry+", ""}, }}}, ConfigSaveFlags::CONTROLS); - - return true; -} - -bool Config::save(uint32_t flags) { - auto save = [this](std::string_view fname, json& j) { - auto path = std::string("./config/") + fname.data(); - try { - std::ofstream json_file(path); - json_file << j; - return true; - } catch (const json::exception& e) { - printf("Failed to save %s: %s\n", fname.data(), e.what()); - return false; - } - }; - - bool result = true; - - if (std::filesystem::is_directory("./config/")) std::filesystem::create_directory("./config/"); - if (flags & (uint32_t)ConfigSaveFlags::LOGGING) result &= save("logging.json", m_logging); - if (flags & (uint32_t)ConfigSaveFlags::GRAPHICS) result &= save("graphics.json", m_graphics); - if (flags & (uint32_t)ConfigSaveFlags::AUDIO) result &= save("audio.json", m_audio); - - return true; } diff --git a/tools/config/config.h b/tools/config/config.h index 9f09f00..adfe487 100644 --- a/tools/config/config.h +++ b/tools/config/config.h @@ -4,6 +4,8 @@ #include +using json = nlohmann::json; + enum class ConfigSaveFlags : uint32_t { NONE = 0, LOGGING = 2 << 0, GRAPHICS = 2 << 1, AUDIO = 2 << 2, CONTROLS = 2 << 3 }; class IConfig { @@ -16,9 +18,8 @@ class IConfig { public: virtual ~IConfig() = default; - virtual std::pair, nlohmann::json*> accessModule(ConfigSaveFlags) = 0; + virtual std::pair, json*> accessModule(ConfigSaveFlags) = 0; - virtual bool load() = 0; virtual bool save(uint32_t flags) = 0; }; From 16853dbb4a7b7abf776c52c77938b74920e30127 Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 19:13:12 +0300 Subject: [PATCH 08/31] No std::move needed, format fixes --- modules/libSceAudioOut/entry.cpp | 6 +++--- tools/config/config.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index ef5f4a2..d0bdf4b 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -138,10 +138,10 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type const char* dname; auto [lock, jData] = accessConfig()->accessModule(ConfigSaveFlags::AUDIO); - // lock.lock(); + lock.lock(); if ((*jData)["device"] == "[default]") { SDL_AudioSpec fmt_curr; - SDL_GetDefaultAudioInfo((char **)&dname, &fmt_curr, 0); + SDL_GetDefaultAudioInfo((char**)&dname, &fmt_curr, 0); } else { try { std::string jdname; @@ -152,7 +152,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type dname = NULL; } } - // lock.unlock(); + lock.unlock(); LOG_INFO(L"Opening audio device: %S\n", dname); auto devId = SDL_OpenAudioDevice(dname, 0, &fmt, NULL, 0); diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 159bc03..0168278 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -30,10 +30,10 @@ IConfig* accessConfig() { std::pair, json*> Config::accessModule(ConfigSaveFlags flag) { switch (flag) { - case ConfigSaveFlags::LOGGING: return std::make_pair(std::move(boost::unique_lock(m_mutex_logging)), &m_logging); - case ConfigSaveFlags::GRAPHICS: return std::make_pair(std::move(boost::unique_lock(m_mutex_graphics)), &m_graphics); - case ConfigSaveFlags::AUDIO: return std::make_pair(std::move(boost::unique_lock(m_mutex_audio)), &m_audio); - case ConfigSaveFlags::CONTROLS: return std::make_pair(std::move(boost::unique_lock(m_mutex_controls)), &m_controls); + case ConfigSaveFlags::LOGGING: return std::make_pair(boost::unique_lock(m_mutex_logging), &m_logging); + case ConfigSaveFlags::GRAPHICS: return std::make_pair(boost::unique_lock(m_mutex_graphics), &m_graphics); + case ConfigSaveFlags::AUDIO: return std::make_pair(boost::unique_lock(m_mutex_audio), &m_audio); + case ConfigSaveFlags::CONTROLS: return std::make_pair(boost::unique_lock(m_mutex_controls), &m_controls); default: throw std::exception("Invalid bit flag"); } @@ -78,7 +78,8 @@ Config::Config() { std::filesystem::path newp(path); newp.replace_extension(".back"); std::filesystem::rename(path, newp); - } catch (const std::filesystem::filesystem_error& e) {} + } catch (const std::filesystem::filesystem_error& e) { + } j = defaults; if (dflag != ConfigSaveFlags::NONE) this->save((uint32_t)dflag); From 3f89578c432c88b927d5b19c14646dddf8651e26 Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 19:21:40 +0300 Subject: [PATCH 09/31] Update entry.cpp --- modules/libSceAudioOut/entry.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index d0bdf4b..ea022b4 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -138,7 +138,6 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type const char* dname; auto [lock, jData] = accessConfig()->accessModule(ConfigSaveFlags::AUDIO); - lock.lock(); if ((*jData)["device"] == "[default]") { SDL_AudioSpec fmt_curr; SDL_GetDefaultAudioInfo((char**)&dname, &fmt_curr, 0); @@ -152,7 +151,6 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type dname = NULL; } } - lock.unlock(); LOG_INFO(L"Opening audio device: %S\n", dname); auto devId = SDL_OpenAudioDevice(dname, 0, &fmt, NULL, 0); From f155285cb88928fafe946a664d0427c406ea104d Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 19:23:33 +0300 Subject: [PATCH 10/31] Fix clang formatting --- modules/libSceAudioOut/entry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index ea022b4..6283b7a 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -1,7 +1,7 @@ #include "common.h" #include "logging.h" -#include "types.h" #include "tools/config/config.h" +#include "types.h" #include #include From 6ff98336d3b7eea670bb162eb945196731d0cc6c Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 19:53:26 +0300 Subject: [PATCH 11/31] Whoops --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cabe1b6..1cb7d26 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,7 +77,7 @@ jobs: cache: true - name: Configure - run: cmake.exe -S. -B_build/_Release -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=_build/_Install -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe -j4 + run: cmake.exe -S. -B_build/_Release -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=_build/_Install -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe - name: Build run: cmake --build _build/_Release -j4 From c3fceace58d7c31669c50401a485945fc5666dad Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 22:08:02 +0300 Subject: [PATCH 12/31] Volume changing implemented --- modules/libSceAudioOut/entry.cpp | 52 +++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index 6283b7a..d491b90 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -23,6 +23,8 @@ struct PortOut { int channelsNum = 0; int volume[8] = {}; SDL_AudioDeviceID device = 0; + SDL_AudioFormat sdlFormat = AUDIO_F32; + std::vector mixedAudio; }; struct Pimpl { @@ -40,15 +42,23 @@ int writeOut(Pimpl* pimpl, int32_t handle, const void* ptr) { auto& port = pimpl->portsOut[handle - 1]; if (!port.open || ptr == nullptr) return 0; - port.lastOutputTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); - const size_t bytesize = port.samplesNum * port.sampleSize * port.channelsNum; + port.lastOutputTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + const size_t bytesize_1ch = port.samplesNum * port.sampleSize; + const size_t bytesize = bytesize_1ch * port.channelsNum; + auto& mixed = port.mixedAudio; + std::fill(mixed.begin(), mixed.end(), 0); + + for (size_t i = 0; i < port.channelsNum; i++) { + SDL_MixAudioFormat(mixed.data() + i * bytesize_1ch, ((const uint8_t*)ptr) + i * bytesize_1ch, port.sdlFormat, bytesize_1ch, + SDL_MIX_MAXVOLUME * ((float)port.volume[i] / SCE_AUDIO_VOLUME_0DB)); + } if (SDL_GetAudioDeviceStatus(port.device) != SDL_AUDIO_PLAYING) SDL_PauseAudioDevice(port.device, 0); while (SDL_GetQueuedAudioSize(port.device) > bytesize * 2) SDL_Delay(0); - return SDL_QueueAudio(port.device, ptr, bytesize); + return SDL_QueueAudio(port.device, mixed.data(), bytesize); } } // namespace @@ -80,56 +90,51 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type port.format = format; port.lastOutputTime = 0; - SDL_AudioFormat sampleFormat; switch (format) { case SceAudioOutParamFormat::S16_MONO: - sampleFormat = AUDIO_S16SYS; + port.sdlFormat = AUDIO_S16; port.channelsNum = 1; port.sampleSize = 2; break; case SceAudioOutParamFormat::FLOAT_MONO: - sampleFormat = AUDIO_F32SYS; + port.sdlFormat = AUDIO_F32; port.channelsNum = 1; port.sampleSize = 4; break; case SceAudioOutParamFormat::S16_STEREO: - sampleFormat = AUDIO_S16SYS; + port.sdlFormat = AUDIO_S16; port.channelsNum = 2; port.sampleSize = 2; break; case SceAudioOutParamFormat::FLOAT_STEREO: - sampleFormat = AUDIO_F32SYS; + port.sdlFormat = AUDIO_F32; port.channelsNum = 2; port.sampleSize = 4; break; case SceAudioOutParamFormat::S16_8CH: - sampleFormat = AUDIO_S16SYS; + port.sdlFormat = AUDIO_S16; port.channelsNum = 8; port.sampleSize = 2; break; case SceAudioOutParamFormat::FLOAT_8CH: - sampleFormat = AUDIO_F32SYS; + port.sdlFormat = AUDIO_F32; port.channelsNum = 8; port.sampleSize = 4; break; case SceAudioOutParamFormat::S16_8CH_STD: - sampleFormat = AUDIO_S16SYS; + port.sdlFormat = AUDIO_S16; port.channelsNum = 8; port.sampleSize = 2; break; case SceAudioOutParamFormat::FLOAT_8CH_STD: - sampleFormat = AUDIO_F32SYS; + port.sdlFormat = AUDIO_F32; port.channelsNum = 8; port.sampleSize = 4; break; } - for (int i = 0; i < port.channelsNum; i++) { - port.volume[i] = 32768; - } - SDL_AudioSpec fmt {.freq = static_cast(freq), - .format = sampleFormat, + .format = port.sdlFormat, .channels = static_cast(port.channelsNum), .samples = static_cast(port.samplesNum), .callback = nullptr, @@ -137,6 +142,17 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type const char* dname; auto [lock, jData] = accessConfig()->accessModule(ConfigSaveFlags::AUDIO); + float volume = 0.0f; + + try { + (*jData)["volume"].get_to(volume); + } catch (const json::exception& e) { + LOG_ERR(L"Invalid audio volume setting: %S", e.what()); + } + + for (int i = 0; i < port.channelsNum; i++) { + port.volume[i] = SCE_AUDIO_VOLUME_0DB * volume; + } if ((*jData)["device"] == "[default]") { SDL_AudioSpec fmt_curr; @@ -155,6 +171,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type LOG_INFO(L"Opening audio device: %S\n", dname); auto devId = SDL_OpenAudioDevice(dname, 0, &fmt, NULL, 0); if (devId <= 0) return devId; + port.mixedAudio.resize(port.sampleSize * port.samplesNum * port.channelsNum); SDL_PauseAudioDevice(devId, 0); port.device = devId; @@ -175,6 +192,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutClose(int32_t handle) { port.open = false; if (port.device > 0) { + port.mixedAudio.clear(); SDL_CloseAudioDevice(port.device); } } From 51058f8c8cb138838758a922ab5dc2ffddeecb33 Mon Sep 17 00:00:00 2001 From: igor725 Date: Fri, 15 Mar 2024 23:57:04 +0300 Subject: [PATCH 13/31] Fix SDL touchpad --- modules/libScePad/entry.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/libScePad/entry.cpp b/modules/libScePad/entry.cpp index 1d28fa9..2e163bd 100644 --- a/modules/libScePad/entry.cpp +++ b/modules/libScePad/entry.cpp @@ -151,12 +151,11 @@ ScePadData getPadData(int handle) { data.touchData.touchNum = 0; for (int f = 0; f < SDL_GameControllerGetNumTouchpadFingers(pController, 0); f++) { - uint8_t s = 0; - float x = 0.0f, y = 0.0f; + float x = 0.0f, y = 0.0f, p = 0.0f; auto& touch = data.touchData.touch[f]; - SDL_GameControllerGetTouchpadFinger(pController, 0, f, &s, &x, &y, NULL); - if (s > 0) { + SDL_GameControllerGetTouchpadFinger(pController, 0, f, NULL, &x, &y, &p); + if (p > 0) { touch.x = x * 0xFFFF, touch.y = y * 0xFFFF; ++data.touchData.touchNum; } @@ -173,11 +172,11 @@ EXPORT const char* MODULE_NAME = "libScePad"; EXPORT SYSV_ABI int scePadInit(void) { LOG_USE_MODULE(libScePad); - int32_t ret = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0 ? Ok : Err::FATAL; + int32_t ret = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0; if (SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt") < 0) { LOG_WARN(L"Failed to load game controller mappings"); } - return ret; + return ret ? Ok : Err::FATAL; } EXPORT SYSV_ABI int scePadOpen(int32_t userId, PadPortType type, int32_t index, const void* pParam) { From 1f1518fe68645c7be394af21cb356b19202dc543 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 00:01:36 +0300 Subject: [PATCH 14/31] Format it again --- modules/libScePad/entry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/libScePad/entry.cpp b/modules/libScePad/entry.cpp index 2e163bd..a94ae91 100644 --- a/modules/libScePad/entry.cpp +++ b/modules/libScePad/entry.cpp @@ -151,8 +151,8 @@ ScePadData getPadData(int handle) { data.touchData.touchNum = 0; for (int f = 0; f < SDL_GameControllerGetNumTouchpadFingers(pController, 0); f++) { - float x = 0.0f, y = 0.0f, p = 0.0f; - auto& touch = data.touchData.touch[f]; + float x = 0.0f, y = 0.0f, p = 0.0f; + auto& touch = data.touchData.touch[f]; SDL_GameControllerGetTouchpadFinger(pController, 0, f, NULL, &x, &y, &p); if (p > 0) { From 9b18904e379efb838dfec8dcd733ef71229939af Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 11:19:18 +0300 Subject: [PATCH 15/31] Deal with missing/unused parameters --- modules/libScePad/entry.cpp | 67 +++++++++++++++++++++++++++++-------- tools/config/config.cpp | 41 +++++++++++++++++++++-- 2 files changed, 92 insertions(+), 16 deletions(-) diff --git a/modules/libScePad/entry.cpp b/modules/libScePad/entry.cpp index a94ae91..45e1a2b 100644 --- a/modules/libScePad/entry.cpp +++ b/modules/libScePad/entry.cpp @@ -33,16 +33,17 @@ static auto* getData() { } static SDL_GameController* setupPad(int n, int userId) { - auto pData = getData(); - auto padPtr = SDL_GameControllerOpen(n); - if (padPtr == nullptr) return nullptr; + auto pData = getData(); + auto pController = SDL_GameControllerOpen(n); + if (pController == nullptr) return nullptr; - SDL_GameControllerSetPlayerIndex(padPtr, userId - 1); + SDL_GameControllerSetPlayerIndex(pController, userId - 1); if (userId > 0) pData->controller[n].userId = userId; pData->controller[n].prePadData = ScePadData(); - pData->controller[n].padPtr = padPtr; + pData->controller[n].padPtr = pController; ++pData->controller[n].countConnect; - return padPtr; + + return pController; } uint32_t getButtons(SDL_GameController* pad) { @@ -89,7 +90,6 @@ ScePadData getPadData(int handle) { if (pController == nullptr) return ScePadData(); auto lockSDL2 = accessVideoOut().getSDLLock(); - // SDL_GameControllerTouch data = ScePadData { .buttons = getButtons(pController), @@ -161,6 +161,28 @@ ScePadData getPadData(int handle) { } } + if (SDL_GameControllerIsSensorEnabled(pController, SDL_SENSOR_GYRO)) { + float gdata[3]; + if (SDL_GameControllerGetSensorData(pController, SDL_SENSOR_GYRO, gdata, 3) == 0) { + auto cr = std::cosf(gdata[2] * 0.5f); + auto sr = std::sinf(gdata[2] * 0.5f); + auto cp = std::cosf(gdata[0] * 0.5f); + auto sp = std::sinf(gdata[0] * 0.5f); + auto cy = std::cosf(gdata[1] * 0.5f); + auto sy = std::sinf(gdata[1] * 0.5f); + + data.orientation = { + .x = sr * cp * cy - cr * sp * sy, .y = cr * sp * cy + sr * cp * sy, .z = cr * cp * sy - sr * sp * cy, .w = cr * cp * cy + sr * sp * sy}; + } + } + + if (SDL_GameControllerIsSensorEnabled(pController, SDL_SENSOR_ACCEL)) { + float adata[3]; + if (SDL_GameControllerGetSensorData(pController, SDL_SENSOR_ACCEL, adata, 3) == 0) { + data.acceleration = {.x = adata[0], .y = adata[1], .z = adata[2]}; + } + } + return data; } } // namespace @@ -172,10 +194,14 @@ EXPORT const char* MODULE_NAME = "libScePad"; EXPORT SYSV_ABI int scePadInit(void) { LOG_USE_MODULE(libScePad); - int32_t ret = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0; + int32_t ret = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC | SDL_INIT_SENSOR) == 0; if (SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt") < 0) { LOG_WARN(L"Failed to load game controller mappings"); } + + SDL_JoystickEventState(SDL_ENABLE); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); return ret ? Ok : Err::FATAL; } @@ -237,12 +263,11 @@ EXPORT SYSV_ABI int scePadRead(int32_t handle, ScePadData* pPadData, int32_t num LOG_USE_MODULE(libScePad); if (handle < 0) return Err::INVALID_HANDLE; - auto pData = getData(); - auto pController = &pData->controller[handle]; - auto pSDLController = pController->padPtr; - if (SDL_GameControllerGetAttached(pSDLController) == false) { - SDL_GameControllerClose(pSDLController); - if ((pSDLController = setupPad(handle, 0)) == nullptr) return Err::DEVICE_NOT_CONNECTED; + auto pData = getData(); + auto pController = pData->controller[handle].padPtr; + if (SDL_GameControllerGetAttached(pController) == false) { + SDL_GameControllerClose(pController); + if ((pController = setupPad(handle, 0)) == nullptr) return Err::DEVICE_NOT_CONNECTED; } std::unique_lock const lock(pData->m_mutexInt); @@ -263,7 +288,21 @@ EXPORT SYSV_ABI int scePadReadState(int32_t handle, ScePadData* pData) { } EXPORT SYSV_ABI int scePadSetMotionSensorState(int32_t handle, bool bEnable) { + LOG_USE_MODULE(libScePad); if (handle < 0) return Err::INVALID_HANDLE; + + auto pData = getData(); + auto pController = pData->controller[handle].padPtr; + + if (SDL_GameControllerHasSensor(pController, SDL_SENSOR_GYRO)) { + if (SDL_GameControllerSetSensorEnabled(pController, SDL_SENSOR_GYRO, (SDL_bool)bEnable) == 0 && + SDL_GameControllerSetSensorEnabled(pController, SDL_SENSOR_ACCEL, (SDL_bool)bEnable) == 0) { + LOG_INFO(L"Gyroscope sensor %S successfully!", bEnable ? "enabled" : "disabled"); + } else { + LOG_WARN(L"Failed to enable the gyroscope sensor: %S", SDL_GetError()); + } + } + return Ok; } diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 0168278..09ff307 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -44,7 +44,7 @@ bool Config::save(uint32_t flags) { auto path = std::string("./config/") + fname.data(); try { std::ofstream json_file(path); - json_file << std::setw(4) << j; + json_file << std::setw(2) << j; return true; } catch (const json::exception& e) { printf("Failed to save %s: %s\n", fname.data(), e.what()); @@ -66,6 +66,7 @@ bool Config::save(uint32_t flags) { Config::Config() { auto load = [this](std::string_view fname, json& j, json defaults = {}, ConfigSaveFlags dflag = ConfigSaveFlags::NONE) { auto path = std::string("./config/") + fname.data(); + bool should_resave = false; try { std::ifstream json_file(path); @@ -82,8 +83,26 @@ Config::Config() { } j = defaults; - if (dflag != ConfigSaveFlags::NONE) this->save((uint32_t)dflag); + should_resave = true; } + + for (auto& [dkey, dval] : defaults.items()) { + if (j[dkey].is_null() && !dval.is_null()) { + j[dkey] = dval; + should_resave = true; + printf("%s: missing parameter \"%s\" has been added!\n", fname.data(), dkey.c_str()); + } + } + + for (auto& [ckey, cval] : j.items()) { + if (defaults[ckey].is_null()) { + j.erase(cval); + should_resave = true; + printf("%s: unused parameter \"%s\" has been removed!\n", fname.data(), ckey.c_str()); + } + } + + if (should_resave && dflag != ConfigSaveFlags::NONE) this->save((uint32_t)dflag); }; load("logging.json", m_logging, {{"sink", "baical"}}, ConfigSaveFlags::LOGGING); @@ -91,6 +110,24 @@ Config::Config() { load("audio.json", m_audio, {{"volume", 0.5f}, {"device", "[default]"}}, ConfigSaveFlags::AUDIO); load("controls.json", m_controls, {{"type", "gamepad"}, + {"deadzones", json::array({ + { + {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, + {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} + }, + { + {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, + {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} + }, + { + {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, + {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} + }, + { + {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, + {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} + } + })}, {"keybinds", { {"triangle", ""}, {"square", ""}, {"circle", ""}, {"cross", ""}, {"dpad_up", ""}, {"dpad_down", ""}, {"dpad_left", ""}, {"dpad_right", ""}, From fc0cf4ae0b39896b883f26a4d9e3750fa5322c16 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 11:23:29 +0300 Subject: [PATCH 16/31] Fix formatting --- tools/config/config.cpp | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/tools/config/config.cpp b/tools/config/config.cpp index 09ff307..ab18f95 100644 --- a/tools/config/config.cpp +++ b/tools/config/config.cpp @@ -65,7 +65,7 @@ bool Config::save(uint32_t flags) { Config::Config() { auto load = [this](std::string_view fname, json& j, json defaults = {}, ConfigSaveFlags dflag = ConfigSaveFlags::NONE) { - auto path = std::string("./config/") + fname.data(); + auto path = std::string("./config/") + fname.data(); bool should_resave = false; try { @@ -82,19 +82,19 @@ Config::Config() { } catch (const std::filesystem::filesystem_error& e) { } - j = defaults; + j = defaults; should_resave = true; } - for (auto& [dkey, dval] : defaults.items()) { + for (auto& [dkey, dval]: defaults.items()) { if (j[dkey].is_null() && !dval.is_null()) { - j[dkey] = dval; + j[dkey] = dval; should_resave = true; printf("%s: missing parameter \"%s\" has been added!\n", fname.data(), dkey.c_str()); } } - for (auto& [ckey, cval] : j.items()) { + for (auto& [ckey, cval]: j.items()) { if (defaults[ckey].is_null()) { j.erase(cval); should_resave = true; @@ -110,24 +110,10 @@ Config::Config() { load("audio.json", m_audio, {{"volume", 0.5f}, {"device", "[default]"}}, ConfigSaveFlags::AUDIO); load("controls.json", m_controls, {{"type", "gamepad"}, - {"deadzones", json::array({ - { - {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, - {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} - }, - { - {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, - {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} - }, - { - {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, - {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} - }, - { - {"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, - {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}} - } - })}, + {"deadzones", json::array({{{"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}}}, + {{"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}}}, + {{"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}}}, + {{"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}}}})}, {"keybinds", { {"triangle", ""}, {"square", ""}, {"circle", ""}, {"cross", ""}, {"dpad_up", ""}, {"dpad_down", ""}, {"dpad_left", ""}, {"dpad_right", ""}, From b4aa1234683f0c09013422ab44a7d05844b938c8 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 11:55:11 +0300 Subject: [PATCH 17/31] Cleanup --- .vscode/settings.json | 16 +++++++++++----- modules/libSceAudioOut/entry.cpp | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 19bfe93..4522ed3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,13 +15,19 @@ ], "ccls.index.threads": 0, - "cmake.buildDirectory": "${workspaceFolder}/_build", - "cmake.installPrefix": "_Install", - "cmake.sourceDirectory": "${workspaceFolder}", + "cmake.generator": "Ninja", + "cmake.sourceDirectory": "${workspaceFolder}", + "cmake.buildDirectory": "${workspaceFolder}/_build/_Release", + "cmake.configureSettings": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${workspaceFolder}/_build/_Install", + "CMAKE_C_COMPILER": "clang-cl.exe", + "CMAKE_CXX_COMPILER": "clang-cl.exe" + }, + "C_Cpp.default.compilerPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\bin\\clang-cl.exe", "C_Cpp.default.intelliSenseMode": "windows-clang-x64", "C_Cpp.default.cppStandard": "c++20", "C_Cpp.autoAddFileAssociations": false, - "cmake.generator": "Ninja", "editor.tabSize": 2, "editor.insertSpaces": true, "git.ignoredRepositories": [ @@ -29,5 +35,5 @@ "third_party/optick", "third_party/magic_enum", "third_part/SDL2" - ] + ] } diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index d491b90..40bdb96 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -49,7 +49,8 @@ int writeOut(Pimpl* pimpl, int32_t handle, const void* ptr) { std::fill(mixed.begin(), mixed.end(), 0); for (size_t i = 0; i < port.channelsNum; i++) { - SDL_MixAudioFormat(mixed.data() + i * bytesize_1ch, ((const uint8_t*)ptr) + i * bytesize_1ch, port.sdlFormat, bytesize_1ch, + auto ch_offset = i * bytesize_1ch; + SDL_MixAudioFormat(mixed.data() + ch_offset, ((const uint8_t*)ptr) + ch_offset, port.sdlFormat, bytesize_1ch, SDL_MIX_MAXVOLUME * ((float)port.volume[i] / SCE_AUDIO_VOLUME_0DB)); } From 77fd28ef8929ee65af06cf1f185e885eb71f36cc Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 11:57:23 +0300 Subject: [PATCH 18/31] Fix json indent --- .vscode/settings.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4522ed3..53ecc42 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,15 +25,15 @@ "CMAKE_CXX_COMPILER": "clang-cl.exe" }, "C_Cpp.default.compilerPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\bin\\clang-cl.exe", - "C_Cpp.default.intelliSenseMode": "windows-clang-x64", - "C_Cpp.default.cppStandard": "c++20", - "C_Cpp.autoAddFileAssociations": false, + "C_Cpp.default.intelliSenseMode": "windows-clang-x64", + "C_Cpp.default.cppStandard": "c++20", + "C_Cpp.autoAddFileAssociations": false, "editor.tabSize": 2, "editor.insertSpaces": true, "git.ignoredRepositories": [ "third_party/boost", "third_party/optick", "third_party/magic_enum", - "third_part/SDL2" + "third_part/SDL2" ] } From 4865b78b13914656293c639428d792223a5fd001 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 12:56:57 +0300 Subject: [PATCH 19/31] Fix volume config --- modules/libSceAudioOut/entry.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index 40bdb96..ddc3cb4 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -25,6 +25,7 @@ struct PortOut { SDL_AudioDeviceID device = 0; SDL_AudioFormat sdlFormat = AUDIO_F32; std::vector mixedAudio; + float volumeModifier; }; struct Pimpl { @@ -45,13 +46,14 @@ int writeOut(Pimpl* pimpl, int32_t handle, const void* ptr) { port.lastOutputTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); const size_t bytesize_1ch = port.samplesNum * port.sampleSize; const size_t bytesize = bytesize_1ch * port.channelsNum; + const int maxVolume = SDL_MIX_MAXVOLUME * port.volumeModifier; auto& mixed = port.mixedAudio; std::fill(mixed.begin(), mixed.end(), 0); for (size_t i = 0; i < port.channelsNum; i++) { auto ch_offset = i * bytesize_1ch; SDL_MixAudioFormat(mixed.data() + ch_offset, ((const uint8_t*)ptr) + ch_offset, port.sdlFormat, bytesize_1ch, - SDL_MIX_MAXVOLUME * ((float)port.volume[i] / SCE_AUDIO_VOLUME_0DB)); + maxVolume * ((float)port.volume[i] / SCE_AUDIO_VOLUME_0DB)); } if (SDL_GetAudioDeviceStatus(port.device) != SDL_AUDIO_PLAYING) SDL_PauseAudioDevice(port.device, 0); @@ -143,16 +145,15 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type const char* dname; auto [lock, jData] = accessConfig()->accessModule(ConfigSaveFlags::AUDIO); - float volume = 0.0f; try { - (*jData)["volume"].get_to(volume); + (*jData)["volume"].get_to(port.volumeModifier); } catch (const json::exception& e) { LOG_ERR(L"Invalid audio volume setting: %S", e.what()); } for (int i = 0; i < port.channelsNum; i++) { - port.volume[i] = SCE_AUDIO_VOLUME_0DB * volume; + port.volume[i] = SCE_AUDIO_VOLUME_0DB; } if ((*jData)["device"] == "[default]") { From bd50662e946b2ff34b2b89f58036b812688a1b79 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 19:39:37 +0300 Subject: [PATCH 20/31] Uncomment mutexes --- modules/libSceAudioOut/entry.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index ddc3cb4..1eb7b92 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -29,7 +29,7 @@ struct PortOut { }; struct Pimpl { - std::mutex mutexInt; + boost::mutex mutexInt; std::array portsOut; Pimpl() = default; }; @@ -79,7 +79,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type LOG_TRACE(L"%S", __FUNCTION__); auto pimpl = getData(); - std::unique_lock const lock(pimpl->mutexInt); + boost::unique_lock const lock(pimpl->mutexInt); for (int id = 0; id < pimpl->portsOut.size(); id++) { auto& port = pimpl->portsOut[id]; @@ -187,7 +187,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutClose(int32_t handle) { LOG_TRACE(L"%S", __FUNCTION__); auto pimpl = getData(); - std::unique_lock const lock(pimpl->mutexInt); + boost::unique_lock const lock(pimpl->mutexInt); auto& port = pimpl->portsOut[handle - 1]; if (port.open) { @@ -204,7 +204,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutClose(int32_t handle) { EXPORT SYSV_ABI int32_t sceAudioOutOutput(int32_t handle, const void* ptr) { auto pimpl = getData(); - // std::unique_lock const lock(pimpl->mutexInt); + boost::unique_lock const lock(pimpl->mutexInt); return writeOut(pimpl, handle, ptr); } @@ -212,7 +212,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutSetVolume(int32_t handle, int32_t flag, int32 LOG_USE_MODULE(libSceAudioOut); auto pimpl = getData(); - std::unique_lock const lock(pimpl->mutexInt); + boost::unique_lock const lock(pimpl->mutexInt); auto& port = pimpl->portsOut[handle - 1]; if (!port.open) return Err::INVALID_PORT; @@ -240,7 +240,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutSetVolume(int32_t handle, int32_t flag, int32 EXPORT SYSV_ABI int32_t sceAudioOutOutputs(SceAudioOutOutputParam* param, uint32_t num) { auto pimpl = getData(); - // std::unique_lock const lock(pimpl->mutexInt); // dont block, causes audio artifacts + boost::unique_lock const lock(pimpl->mutexInt); for (uint32_t i = 0; i < num; i++) { if (auto err = writeOut(pimpl, param[i].handle, param[i].ptr); err != 0) return err; } @@ -250,7 +250,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutOutputs(SceAudioOutOutputParam* param, uint32 EXPORT SYSV_ABI int32_t sceAudioOutGetLastOutputTime(int32_t handle, uint64_t* outputTime) { auto pimpl = getData(); - std::unique_lock const lock(pimpl->mutexInt); + boost::unique_lock const lock(pimpl->mutexInt); auto& port = pimpl->portsOut[handle - 1]; if (!port.open) return Err::INVALID_PORT; @@ -265,7 +265,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutSetMixLevelPadSpk(int32_t handle, int32_t mix EXPORT SYSV_ABI int32_t sceAudioOutGetPortState(int32_t handle, SceAudioOutPortState* state) { auto pimpl = getData(); - std::unique_lock const lock(pimpl->mutexInt); + boost::unique_lock const lock(pimpl->mutexInt); auto& port = pimpl->portsOut[handle - 1]; From fd4b9679be5f93885a9d4540d4a88e1447112b0f Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 21:31:24 +0300 Subject: [PATCH 21/31] _writev implemented, touchpad fixed --- modules/libScePad/entry.cpp | 5 ++--- modules/libkernel/entry.cpp | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/libScePad/entry.cpp b/modules/libScePad/entry.cpp index 45e1a2b..a54941b 100644 --- a/modules/libScePad/entry.cpp +++ b/modules/libScePad/entry.cpp @@ -152,12 +152,11 @@ ScePadData getPadData(int handle) { data.touchData.touchNum = 0; for (int f = 0; f < SDL_GameControllerGetNumTouchpadFingers(pController, 0); f++) { float x = 0.0f, y = 0.0f, p = 0.0f; - auto& touch = data.touchData.touch[f]; SDL_GameControllerGetTouchpadFinger(pController, 0, f, NULL, &x, &y, &p); if (p > 0) { - touch.x = x * 0xFFFF, touch.y = y * 0xFFFF; - ++data.touchData.touchNum; + auto& touch = data.touchData.touch[data.touchData.touchNum++]; + touch.x = x * 0xFFFF, touch.y = y * 0xFFFF, touch.id = f; } } diff --git a/modules/libkernel/entry.cpp b/modules/libkernel/entry.cpp index e5db621..73bbb3c 100644 --- a/modules/libkernel/entry.cpp +++ b/modules/libkernel/entry.cpp @@ -68,6 +68,21 @@ EXPORT SYSV_ABI void __NID(_exit)(int code) { ::exit(code); } +struct iovec { + void* iov_base; + size_t iov_len; +}; + +EXPORT SYSV_ABI size_t __NID(_writev)(int fd, const struct iovec* iov, int iovcn) { + size_t total = 0; + + for (int i = 0; i < iovcn; i++) { + total += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout); + } + + return total; +} + EXPORT SYSV_ABI int __NID(_is_signal_return)(uint64_t* param) { if ((uintptr_t)param < 4 * 1024) return 1; if (param[0] != 0x48006a40247c8d48 || param[1] != 0x050f000001a1c0c7 || (param[2] & 0xffffff) != 0xfdebf4) @@ -379,4 +394,4 @@ EXPORT SYSV_ABI int __NID(getrusage)(rusageWho who, rusage_t* usage) { *usage = rusage_t(); return Ok; } -} \ No newline at end of file +} From 0eeb1b677b09e395fa164ed2c7a36b7fbbbafbc2 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 21:33:29 +0300 Subject: [PATCH 22/31] Fix format --- modules/libkernel/entry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libkernel/entry.cpp b/modules/libkernel/entry.cpp index 73bbb3c..5fd5f73 100644 --- a/modules/libkernel/entry.cpp +++ b/modules/libkernel/entry.cpp @@ -69,7 +69,7 @@ EXPORT SYSV_ABI void __NID(_exit)(int code) { } struct iovec { - void* iov_base; + void* iov_base; size_t iov_len; }; From 9ec3e37a22e41a8f520cee0afc5c608033e3b92c Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 22:05:06 +0300 Subject: [PATCH 23/31] Stub libSceErrorDialog --- modules/libSceErrorDialog/CMakeLists.txt | 9 +++++++ modules/libSceErrorDialog/codes.h | 5 ++++ modules/libSceErrorDialog/entry.cpp | 33 ++++++++++++++++++++++++ modules/libSceErrorDialog/types.h | 4 +++ modules/libkernel/entry.cpp | 5 ---- modules/libkernel/types.h | 5 ++++ 6 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 modules/libSceErrorDialog/CMakeLists.txt create mode 100644 modules/libSceErrorDialog/codes.h create mode 100644 modules/libSceErrorDialog/entry.cpp create mode 100644 modules/libSceErrorDialog/types.h diff --git a/modules/libSceErrorDialog/CMakeLists.txt b/modules/libSceErrorDialog/CMakeLists.txt new file mode 100644 index 0000000..3758182 --- /dev/null +++ b/modules/libSceErrorDialog/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.24) +include(../setupModule.cmake) + +set(libName libSceErrorDialog) +project(${libName}) + +add_library(${libName} SHARED entry.cpp) + +setupModule(${libName}) diff --git a/modules/libSceErrorDialog/codes.h b/modules/libSceErrorDialog/codes.h new file mode 100644 index 0000000..80c0ed3 --- /dev/null +++ b/modules/libSceErrorDialog/codes.h @@ -0,0 +1,5 @@ +#pragma once +#include + +namespace Err {} // namespace Err + diff --git a/modules/libSceErrorDialog/entry.cpp b/modules/libSceErrorDialog/entry.cpp new file mode 100644 index 0000000..6d31591 --- /dev/null +++ b/modules/libSceErrorDialog/entry.cpp @@ -0,0 +1,33 @@ +#include "codes.h" +#include "common.h" +#include "logging.h" +#include "types.h" + +LOG_DEFINE_MODULE(libSceErrorDialog); + +namespace { +static SceCommonDialogStatus g_curStatus = SceCommonDialogStatus::NONE; +} // namespace + +extern "C" { + +EXPORT const char* MODULE_NAME = "libSceErrorDialog"; + +EXPORT SYSV_ABI int32_t sceErrorDialogInitialize() { + g_curStatus = SceCommonDialogStatus::INITIALIZED; + return Ok; +} + +EXPORT SYSV_ABI int32_t sceErrorDialogTerminate(void) { + g_curStatus = SceCommonDialogStatus::NONE; + return Ok; +} + +EXPORT SYSV_ABI SceCommonDialogStatus sceErrorDialogUpdateStatus(void) { + return g_curStatus; +} + +EXPORT SYSV_ABI SceCommonDialogStatus sceErrorDialogGetStatus(void) { + return g_curStatus; +} +} diff --git a/modules/libSceErrorDialog/types.h b/modules/libSceErrorDialog/types.h new file mode 100644 index 0000000..8c259a1 --- /dev/null +++ b/modules/libSceErrorDialog/types.h @@ -0,0 +1,4 @@ +#pragma once +#include "..\libSceCommonDialog\types.h" +#include "codes.h" + diff --git a/modules/libkernel/entry.cpp b/modules/libkernel/entry.cpp index 5fd5f73..fe81bfd 100644 --- a/modules/libkernel/entry.cpp +++ b/modules/libkernel/entry.cpp @@ -68,11 +68,6 @@ EXPORT SYSV_ABI void __NID(_exit)(int code) { ::exit(code); } -struct iovec { - void* iov_base; - size_t iov_len; -}; - EXPORT SYSV_ABI size_t __NID(_writev)(int fd, const struct iovec* iov, int iovcn) { size_t total = 0; diff --git a/modules/libkernel/types.h b/modules/libkernel/types.h index a32d29a..c66184f 100644 --- a/modules/libkernel/types.h +++ b/modules/libkernel/types.h @@ -91,3 +91,8 @@ struct rusage_t { uint32_t ru_nvcsw = 0; uint32_t ru_nivcsw = 0; }; + +struct iovec { + void* iov_base; + size_t iov_len; +}; From 7b57f8188f4ead2172793e0548b9f8bcf3263661 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sat, 16 Mar 2024 22:36:37 +0300 Subject: [PATCH 24/31] Remove trailing NL --- modules/libSceErrorDialog/codes.h | 1 - modules/libSceErrorDialog/types.h | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/libSceErrorDialog/codes.h b/modules/libSceErrorDialog/codes.h index 80c0ed3..e9f8a9f 100644 --- a/modules/libSceErrorDialog/codes.h +++ b/modules/libSceErrorDialog/codes.h @@ -2,4 +2,3 @@ #include namespace Err {} // namespace Err - diff --git a/modules/libSceErrorDialog/types.h b/modules/libSceErrorDialog/types.h index 8c259a1..8a7ec65 100644 --- a/modules/libSceErrorDialog/types.h +++ b/modules/libSceErrorDialog/types.h @@ -1,4 +1,3 @@ #pragma once #include "..\libSceCommonDialog\types.h" #include "codes.h" - From 323559712ed84375f14845356983a0c0ee712f46 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 00:09:54 +0300 Subject: [PATCH 25/31] Missed it --- modules/libSceErrorDialog/entry.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/libSceErrorDialog/entry.cpp b/modules/libSceErrorDialog/entry.cpp index 6d31591..a9ae5d4 100644 --- a/modules/libSceErrorDialog/entry.cpp +++ b/modules/libSceErrorDialog/entry.cpp @@ -30,4 +30,9 @@ EXPORT SYSV_ABI SceCommonDialogStatus sceErrorDialogUpdateStatus(void) { EXPORT SYSV_ABI SceCommonDialogStatus sceErrorDialogGetStatus(void) { return g_curStatus; } + +EXPORT SYSV_ABI int32_t sceSaveDataDialogOpen(const void* param) { + g_curStatus = SceCommonDialogStatus::FINISHED; + return Ok; +} } From db3e6f04a2858c2f42acb6b002acebfa5bc5d309 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 02:47:48 +0300 Subject: [PATCH 26/31] More stubs --- core/kernel/filesystem.cpp | 38 ++++++++- modules/libSceAudioOut/entry.cpp | 4 +- modules/libSceHttp2/CMakeLists.txt | 9 +++ modules/libSceHttp2/codes.h | 4 + modules/libSceHttp2/entry.cpp | 15 ++++ modules/libSceHttp2/types.h | 2 + modules/libSceJson2/CMakeLists.txt | 9 +++ modules/libSceJson2/codes.h | 4 + modules/libSceJson2/entry.cpp | 108 +++++++++++++++++++++++++ modules/libSceJson2/types.h | 2 + modules/libSceNpWebApi2/CMakeLists.txt | 9 +++ modules/libSceNpWebApi2/codes.h | 4 + modules/libSceNpWebApi2/entry.cpp | 15 ++++ modules/libSceNpWebApi2/types.h | 2 + modules/libkernel/entry.cpp | 29 ++++--- modules/libkernel/fs.cpp | 6 +- modules/libkernel/types.h | 9 ++- 17 files changed, 249 insertions(+), 20 deletions(-) create mode 100644 modules/libSceHttp2/CMakeLists.txt create mode 100644 modules/libSceHttp2/codes.h create mode 100644 modules/libSceHttp2/entry.cpp create mode 100644 modules/libSceHttp2/types.h create mode 100644 modules/libSceJson2/CMakeLists.txt create mode 100644 modules/libSceJson2/codes.h create mode 100644 modules/libSceJson2/entry.cpp create mode 100644 modules/libSceJson2/types.h create mode 100644 modules/libSceNpWebApi2/CMakeLists.txt create mode 100644 modules/libSceNpWebApi2/codes.h create mode 100644 modules/libSceNpWebApi2/entry.cpp create mode 100644 modules/libSceNpWebApi2/types.h diff --git a/core/kernel/filesystem.cpp b/core/kernel/filesystem.cpp index 6a6ac99..6972361 100644 --- a/core/kernel/filesystem.cpp +++ b/core/kernel/filesystem.cpp @@ -353,8 +353,40 @@ size_t readv(int handle, const SceKernelIovec* iov, int iovcnt) { size_t writev(int handle, const SceKernelIovec* iov, int iovcnt) { LOG_USE_MODULE(filesystem); - LOG_ERR(L"todo %S", __FUNCTION__); - return Ok; + if (handle < FILE_DESCRIPTOR_MIN) { + return getErr(ErrCode::_EPERM); + } + + auto file = accessFileManager().getFile(handle); + if (file == nullptr) { + return getErr(ErrCode::_EBADF); + } + if (!(*file)) { + LOG_TRACE(L"file end"); + return 0; + } + + size_t count = 0; + + for (int n = 0; n < iovcnt; n++) { + auto* item = &iov[n]; + + if (item->iov_base == nullptr || item->iov_len == 0) continue; + + auto const start = file->tellp(); + + file->write((const char*)item->iov_base, item->iov_len); + + LOG_TRACE(L"KernelWrite[%d]: 0x%08llx:%llu write(%lld)", handle, (uint64_t)item->iov_base, item->iov_len, start); + + count = file->tellp() - start; + if (!(*file)) { + LOG_TRACE(L"file end"); + break; + } + } + + return count; } int fchmod(int fd, SceKernelMode mode) { @@ -624,4 +656,4 @@ int64_t lwfsLseek(int fd, int64_t offset, int whence) { size_t lwfsWrite(int fd, const void* buf, size_t nbytes) { return Ok; } -} // namespace filesystem \ No newline at end of file +} // namespace filesystem diff --git a/modules/libSceAudioOut/entry.cpp b/modules/libSceAudioOut/entry.cpp index 1eb7b92..17ff7f3 100644 --- a/modules/libSceAudioOut/entry.cpp +++ b/modules/libSceAudioOut/entry.cpp @@ -204,7 +204,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutClose(int32_t handle) { EXPORT SYSV_ABI int32_t sceAudioOutOutput(int32_t handle, const void* ptr) { auto pimpl = getData(); - boost::unique_lock const lock(pimpl->mutexInt); + // boost::unique_lock const lock(pimpl->mutexInt); return writeOut(pimpl, handle, ptr); } @@ -240,7 +240,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutSetVolume(int32_t handle, int32_t flag, int32 EXPORT SYSV_ABI int32_t sceAudioOutOutputs(SceAudioOutOutputParam* param, uint32_t num) { auto pimpl = getData(); - boost::unique_lock const lock(pimpl->mutexInt); + // boost::unique_lock const lock(pimpl->mutexInt); // dont block, causes audio artifacts for (uint32_t i = 0; i < num; i++) { if (auto err = writeOut(pimpl, param[i].handle, param[i].ptr); err != 0) return err; } diff --git a/modules/libSceHttp2/CMakeLists.txt b/modules/libSceHttp2/CMakeLists.txt new file mode 100644 index 0000000..18f1a99 --- /dev/null +++ b/modules/libSceHttp2/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.24) +include(../setupModule.cmake) + +set(libName libSceHttp2) +project(${libName}) + +add_library(${libName} SHARED entry.cpp) + +setupModule(${libName}) diff --git a/modules/libSceHttp2/codes.h b/modules/libSceHttp2/codes.h new file mode 100644 index 0000000..e9f8a9f --- /dev/null +++ b/modules/libSceHttp2/codes.h @@ -0,0 +1,4 @@ +#pragma once +#include + +namespace Err {} // namespace Err diff --git a/modules/libSceHttp2/entry.cpp b/modules/libSceHttp2/entry.cpp new file mode 100644 index 0000000..ada921f --- /dev/null +++ b/modules/libSceHttp2/entry.cpp @@ -0,0 +1,15 @@ +#include "codes.h" +#include "common.h" +#include "logging.h" +#include "types.h" + +LOG_DEFINE_MODULE(libSceHttp2); + +extern "C" { + +EXPORT const char* MODULE_NAME = "libSceHttp2"; + +EXPORT SYSV_ABI int32_t sceHttp2Init() { + return Ok; +} +} diff --git a/modules/libSceHttp2/types.h b/modules/libSceHttp2/types.h new file mode 100644 index 0000000..7832fd4 --- /dev/null +++ b/modules/libSceHttp2/types.h @@ -0,0 +1,2 @@ +#pragma once +#include "codes.h" diff --git a/modules/libSceJson2/CMakeLists.txt b/modules/libSceJson2/CMakeLists.txt new file mode 100644 index 0000000..951752c --- /dev/null +++ b/modules/libSceJson2/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.24) +include(../setupModule.cmake) + +set(libName libSceJson2) +project(${libName}) + +add_library(${libName} SHARED entry.cpp) + +setupModule(${libName}) diff --git a/modules/libSceJson2/codes.h b/modules/libSceJson2/codes.h new file mode 100644 index 0000000..e9f8a9f --- /dev/null +++ b/modules/libSceJson2/codes.h @@ -0,0 +1,4 @@ +#pragma once +#include + +namespace Err {} // namespace Err diff --git a/modules/libSceJson2/entry.cpp b/modules/libSceJson2/entry.cpp new file mode 100644 index 0000000..66e3327 --- /dev/null +++ b/modules/libSceJson2/entry.cpp @@ -0,0 +1,108 @@ +#include "codes.h" +#include "common.h" +#include "logging.h" +#include "types.h" + +LOG_DEFINE_MODULE(libSceJson2); + +extern "C" { + +EXPORT const char* MODULE_NAME = "libSceJson"; + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json12MemAllocatorC2Ev)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5ValueC1Ev)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5Value3setEb)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5Value3setEl)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5Value3setEm)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5Value3setEd)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json6StringC1EPKc)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5Value3setERKNS0_6StringE)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json6StringD1Ev)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json5Value3setENS0_9ValueTypeE)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID_HEX(5923AE81EE48B028)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID_HEX(12EF798E6AA7E51C)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID_HEX(236402F0F6212566)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json11InitializerC1Ev)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID(_ZN3sce4Json11Initializer10initializeEPKNS0_14InitParameter2E)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +EXPORT SYSV_ABI int32_t __NID_HEX(F9DAC3172012EAEE)() { + LOG_USE_MODULE(libSceJson2); + LOG_ERR(L"todo %S", __FUNCTION__); + return Ok; +} + +} diff --git a/modules/libSceJson2/types.h b/modules/libSceJson2/types.h new file mode 100644 index 0000000..7832fd4 --- /dev/null +++ b/modules/libSceJson2/types.h @@ -0,0 +1,2 @@ +#pragma once +#include "codes.h" diff --git a/modules/libSceNpWebApi2/CMakeLists.txt b/modules/libSceNpWebApi2/CMakeLists.txt new file mode 100644 index 0000000..ba0bd60 --- /dev/null +++ b/modules/libSceNpWebApi2/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.24) +include(../setupModule.cmake) + +set(libName libSceNpWebApi2) +project(${libName}) + +add_library(${libName} SHARED entry.cpp) + +setupModule(${libName}) diff --git a/modules/libSceNpWebApi2/codes.h b/modules/libSceNpWebApi2/codes.h new file mode 100644 index 0000000..e9f8a9f --- /dev/null +++ b/modules/libSceNpWebApi2/codes.h @@ -0,0 +1,4 @@ +#pragma once +#include + +namespace Err {} // namespace Err diff --git a/modules/libSceNpWebApi2/entry.cpp b/modules/libSceNpWebApi2/entry.cpp new file mode 100644 index 0000000..5372e8d --- /dev/null +++ b/modules/libSceNpWebApi2/entry.cpp @@ -0,0 +1,15 @@ +#include "codes.h" +#include "common.h" +#include "logging.h" +#include "types.h" + +LOG_DEFINE_MODULE(libSceNpWebApi2); + +extern "C" { + +EXPORT const char* MODULE_NAME = "libSceNpWebApi2"; + +EXPORT SYSV_ABI int32_t sceNpWebApi2Initialize() { + return Ok; +} +} diff --git a/modules/libSceNpWebApi2/types.h b/modules/libSceNpWebApi2/types.h new file mode 100644 index 0000000..7832fd4 --- /dev/null +++ b/modules/libSceNpWebApi2/types.h @@ -0,0 +1,2 @@ +#pragma once +#include "codes.h" diff --git a/modules/libkernel/entry.cpp b/modules/libkernel/entry.cpp index fe81bfd..179b010 100644 --- a/modules/libkernel/entry.cpp +++ b/modules/libkernel/entry.cpp @@ -68,16 +68,6 @@ EXPORT SYSV_ABI void __NID(_exit)(int code) { ::exit(code); } -EXPORT SYSV_ABI size_t __NID(_writev)(int fd, const struct iovec* iov, int iovcn) { - size_t total = 0; - - for (int i = 0; i < iovcn; i++) { - total += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout); - } - - return total; -} - EXPORT SYSV_ABI int __NID(_is_signal_return)(uint64_t* param) { if ((uintptr_t)param < 4 * 1024) return 1; if (param[0] != 0x48006a40247c8d48 || param[1] != 0x050f000001a1c0c7 || (param[2] & 0xffffff) != 0xfdebf4) @@ -115,6 +105,25 @@ EXPORT SYSV_ABI int sceKernelInternalMemoryGetModuleSegmentInfo(ModulInfo* info) return Ok; } +EXPORT SYSV_ABI int sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, struct timesec* st, unsigned long* dstsec) { + const auto* tz = std::chrono::current_zone(); + auto sys_inf = tz->get_info(std::chrono::system_clock::now()); + + *local_time = sys_inf.offset.count() + sys_inf.save.count() * 60 + time; + + if (st != nullptr) { + st->t = time; + st->westsec = sys_inf.offset.count() * 60; + st->dstsec = sys_inf.save.count() * 60; + } + + if (dstsec != nullptr) { + *dstsec = sys_inf.save.count() * 60; + } + + return 0; +} + EXPORT SYSV_ABI unsigned int sceKernelSleep(unsigned int seconds) { boost::this_thread::sleep_for(boost::chrono::seconds(seconds)); return Ok; diff --git a/modules/libkernel/fs.cpp b/modules/libkernel/fs.cpp index 67137fa..7f422bd 100644 --- a/modules/libkernel/fs.cpp +++ b/modules/libkernel/fs.cpp @@ -74,6 +74,10 @@ EXPORT SYSV_ABI size_t __NID(_readv)(int handle, const filesystem::SceKernelIove return POSIX_CALL(filesystem::readv(handle, iov, iovcnt)); } +EXPORT SYSV_ABI size_t __NID(_writev)(int handle, const filesystem::SceKernelIovec* iov, int iovcnt) { + return POSIX_CALL(filesystem::writev(handle, iov, iovcnt)); +} + EXPORT SYSV_ABI size_t sceKernelWritev(int handle, const filesystem::SceKernelIovec* iov, int iovcnt) { return filesystem::writev(handle, iov, iovcnt); } @@ -177,4 +181,4 @@ EXPORT SYSV_ABI int64_t sceKernelLwfsLseek(int fd, int64_t offset, int whence) { EXPORT SYSV_ABI size_t sceKernelLwfsWrite(int fd, const void* buf, size_t nbytes) { return filesystem::lwfsWrite(fd, buf, nbytes); } -} \ No newline at end of file +} diff --git a/modules/libkernel/types.h b/modules/libkernel/types.h index c66184f..5b819ea 100644 --- a/modules/libkernel/types.h +++ b/modules/libkernel/types.h @@ -6,7 +6,7 @@ using SceKernelModule = int32_t; using get_thread_atexit_count_func_t = SYSV_ABI int (*)(SceKernelModule); -using thread_atexit_report_func_t = SYSV_ABI void (*)(SceKernelModule); +using thread_atexit_report_func_t = SYSV_ABI void (*)(SceKernelModule); typedef int SceKernelAioSubmitId; typedef void* sigset_t; @@ -92,7 +92,8 @@ struct rusage_t { uint32_t ru_nivcsw = 0; }; -struct iovec { - void* iov_base; - size_t iov_len; +struct timesec { + time_t t; + unsigned long westsec; + unsigned long dstsec; }; From 8f39a3b4c36b2988f567ea6f7af86a28c417f090 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 02:52:22 +0300 Subject: [PATCH 27/31] Fix formatting --- modules/libkernel/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libkernel/types.h b/modules/libkernel/types.h index 5b819ea..76f09d7 100644 --- a/modules/libkernel/types.h +++ b/modules/libkernel/types.h @@ -6,7 +6,7 @@ using SceKernelModule = int32_t; using get_thread_atexit_count_func_t = SYSV_ABI int (*)(SceKernelModule); -using thread_atexit_report_func_t = SYSV_ABI void (*)(SceKernelModule); +using thread_atexit_report_func_t = SYSV_ABI void (*)(SceKernelModule); typedef int SceKernelAioSubmitId; typedef void* sigset_t; From e44f1176fa33b7aba7e424538ab640a3ff4b843e Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 02:55:42 +0300 Subject: [PATCH 28/31] Format it once more --- modules/libSceJson2/entry.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/libSceJson2/entry.cpp b/modules/libSceJson2/entry.cpp index 66e3327..b287117 100644 --- a/modules/libSceJson2/entry.cpp +++ b/modules/libSceJson2/entry.cpp @@ -104,5 +104,4 @@ EXPORT SYSV_ABI int32_t __NID_HEX(F9DAC3172012EAEE)() { LOG_ERR(L"todo %S", __FUNCTION__); return Ok; } - } From 087911f1832de6a1ac5f5b9092a54c4bb1964d50 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 03:41:04 +0300 Subject: [PATCH 29/31] Stdout workaround --- core/kernel/filesystem.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/kernel/filesystem.cpp b/core/kernel/filesystem.cpp index 6972361..cb1ccce 100644 --- a/core/kernel/filesystem.cpp +++ b/core/kernel/filesystem.cpp @@ -354,6 +354,16 @@ size_t readv(int handle, const SceKernelIovec* iov, int iovcnt) { size_t writev(int handle, const SceKernelIovec* iov, int iovcnt) { LOG_USE_MODULE(filesystem); if (handle < FILE_DESCRIPTOR_MIN) { + if (handle == 0) { + size_t count = 0; + + for (int n = 0; n < iovcnt; n++) { + count += ::fwrite(iov[n].iov_base, 1, iov[n].iov_len, stdout); + } + + return count; + } + return getErr(ErrCode::_EPERM); } From aebfcccf5f96af5cd85e5ca9e70c613e62718aaa Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 13:51:57 +0300 Subject: [PATCH 30/31] Fix touchpad bit --- modules/libScePad/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/libScePad/types.h b/modules/libScePad/types.h index 4b4edec..e3c4786 100644 --- a/modules/libScePad/types.h +++ b/modules/libScePad/types.h @@ -24,7 +24,7 @@ enum class ScePadButtonDataOffset : uint32_t { CIRCLE, CROSS, SQUARE, - TOUCH_PAD, + TOUCH_PAD = 20, INTERCEPTED, }; @@ -291,4 +291,4 @@ struct ScePadDeviceClassExtendedInformation { uint8_t data[12]; } classData; -}; \ No newline at end of file +}; From daa4f6bd58053a49e0a7cf2031d7dc8c48d06cb7 Mon Sep 17 00:00:00 2001 From: igor725 Date: Sun, 17 Mar 2024 15:02:17 +0300 Subject: [PATCH 31/31] Rename struct --- modules/libkernel/entry.cpp | 2 +- modules/libkernel/types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/libkernel/entry.cpp b/modules/libkernel/entry.cpp index 179b010..e505d0e 100644 --- a/modules/libkernel/entry.cpp +++ b/modules/libkernel/entry.cpp @@ -105,7 +105,7 @@ EXPORT SYSV_ABI int sceKernelInternalMemoryGetModuleSegmentInfo(ModulInfo* info) return Ok; } -EXPORT SYSV_ABI int sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, struct timesec* st, unsigned long* dstsec) { +EXPORT SYSV_ABI int sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, struct SceTimesec* st, unsigned long* dstsec) { const auto* tz = std::chrono::current_zone(); auto sys_inf = tz->get_info(std::chrono::system_clock::now()); diff --git a/modules/libkernel/types.h b/modules/libkernel/types.h index 76f09d7..5501a5e 100644 --- a/modules/libkernel/types.h +++ b/modules/libkernel/types.h @@ -92,7 +92,7 @@ struct rusage_t { uint32_t ru_nivcsw = 0; }; -struct timesec { +struct SceTimesec { time_t t; unsigned long westsec; unsigned long dstsec;