diff --git a/.ci/build-mac-arm64.sh b/.ci/build-mac-arm64.sh index d1b48c03f9..0c9f86cfc2 100755 --- a/.ci/build-mac-arm64.sh +++ b/.ci/build-mac-arm64.sh @@ -6,14 +6,14 @@ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 export HOMEBREW_NO_ENV_HINTS=1 export HOMEBREW_NO_INSTALL_CLEANUP=1 -/opt/homebrew/bin/brew install -f --overwrite --quiet nasm ninja p7zip ccache pipenv gnutls freetype #create-dmg +/opt/homebrew/bin/brew install -f --overwrite --quiet nasm ninja p7zip ccache pipenv gnutls freetype googletest #create-dmg /opt/homebrew/bin/brew install -f --quiet ffmpeg@5 /opt/homebrew/bin/brew install --quiet "llvm@$LLVM_COMPILER_VER" glew cmake sdl3 vulkan-headers coreutils /opt/homebrew/bin/brew link -f --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5 # moltenvk based on commit for 1.3.0 release wget https://raw.githubusercontent.com/Homebrew/homebrew-core/7255441cbcafabaa8950f67c7ec55ff499dbb2d3/Formula/m/molten-vk.rb -/opt/homebrew/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb +/opt/homebrew/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb export CXX=clang++ export CC=clang @@ -32,7 +32,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then git clone https://github.com/engnr/qt-downloader.git cd qt-downloader git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597 - # nested Qt 6.9.0 URL workaround + # nested Qt 6.9.1 URL workaround # sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader # sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader # archived Qt 6.7.3 URL workaround @@ -41,7 +41,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then arch -arm64 "$BREW_PATH/bin/pipenv" run pip3 uninstall py7zr requests semantic_version lxml arch -arm64 "$BREW_PATH/bin/pipenv" run pip3 install py7zr requests semantic_version lxml --no-cache mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64" - # sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.0 workaround + # sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.1 workaround arch -arm64 "$BREW_PATH/bin/pipenv" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats # -o "$QT_VER/clang_64" fi @@ -77,8 +77,8 @@ mkdir build && cd build || exit 1 export MACOSX_DEPLOYMENT_TARGET=14.0 "$BREW_PATH/bin/cmake" .. \ - -DBUILD_RPCS3_TESTS=OFF \ - -DRUN_RPCS3_TESTS=OFF \ + -DBUILD_RPCS3_TESTS="${RUN_UNIT_TESTS}" \ + -DRUN_RPCS3_TESTS="${RUN_UNIT_TESTS}" \ -DUSE_SDL=ON \ -DUSE_DISCORD_RPC=ON \ -DUSE_VULKAN=ON \ diff --git a/.ci/build-mac.sh b/.ci/build-mac.sh index 675811539e..4c2f18f924 100755 --- a/.ci/build-mac.sh +++ b/.ci/build-mac.sh @@ -36,7 +36,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then git clone https://github.com/engnr/qt-downloader.git cd qt-downloader git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597 - # nested Qt 6.9.0 URL workaround + # nested Qt 6.9.1 URL workaround # sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader # sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader # archived Qt 6.7.3 URL workaround @@ -44,7 +44,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then cd "/tmp/Qt" arch -x86_64 "$BREW_X64_PATH/bin/pipenv" --python "$BREW_X64_PATH/bin/python3" run pip3 install py7zr requests semantic_version lxml mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64" - # sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.0 workaround + # sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.1 workaround arch -x86_64 "$BREW_X64_PATH/bin/pipenv" --python "$BREW_X64_PATH/bin/python3" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats # -o "$QT_VER/clang_64" fi diff --git a/.cirrus.yml b/.cirrus.yml index 41132c0bce..86d50a8ef6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -7,99 +7,8 @@ env: BUILD_SOURCEBRANCHNAME: $CIRRUS_BRANCH RPCS3_TOKEN: ENCRYPTED[100ebb8e3552bf2021d0ef55dccda3e58d27be5b6cab0b0b92843ef490195d3c4edaefa087e4a3b425caa6392300b9b1] QT_VER_MAIN: '6' - QT_VER: '6.9.0' + QT_VER: '6.9.1' LLVM_COMPILER_VER: '19' - LLVM_VER: '19.1.7' - -# windows_task: -# matrix: -# - name: Cirrus Windows -# windows_container: -# image: cirrusci/windowsservercore:visualstudio2019 -# cpu: 8 -# memory: 16G -# env: -# CIRRUS_SHELL: "bash" -# COMPILER: msvc -# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}\artifacts\ -# QT_VER_MSVC: 'msvc2022' -# QT_DATE: '202503301022' -# QTDIR: C:\Qt\${QT_VER}\${QT_VER_MSVC}_64 -# VULKAN_VER: '1.3.268.0' -# VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5' -# VULKAN_SDK: C:\VulkanSDK\${VULKAN_VER} -# CACHE_DIR: "./cache" -# UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e -# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-win" -# deps_cache: -# folder: "./cache" -# #obj_cache: -# # folder: "./tmp" -# #obj2_cache: -# # folder: "./rpcs3/x64" -# setup_script: -# - './.ci/get_keys-windows.sh' -# - './.ci/setup-windows.sh' -# rpcs3_script: -# - export PATH=${PATH}:"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin" -# - msbuild.exe rpcs3.sln //p:Configuration=Release //m -# deploy_script: -# - mkdir artifacts -# - source './.ci/export-cirrus-vars.sh' -# - './.ci/deploy-windows.sh' -# artifacts: -# name: Artifact -# path: "*.7z*" -# push_script: | -# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then -# source './.ci/export-cirrus-vars.sh' -# './.ci/github-upload.sh' -# fi; - -# linux_task: -# container: -# image: rpcs3/rpcs3-ci-jammy:1.6 -# cpu: 4 -# memory: 16G -# env: -# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts -# ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/ -# CCACHE_DIR: "/tmp/ccache_dir" -# CCACHE_MAXSIZE: 300M -# CI_HAS_ARTIFACTS: true -# UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f -# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux" -# DEPLOY_APPIMAGE: true -# APPDIR: "./appdir" -# RELEASE_MESSAGE: "../GitHubReleaseMessage.txt" -# ccache_cache: -# folder: "/tmp/ccache_dir" -# matrix: -# - name: Cirrus Linux GCC -# env: -# COMPILER: gcc -# gcc_script: -# - mkdir artifacts -# - ".ci/build-linux.sh" -# - name: Cirrus Linux Clang -# env: -# COMPILER: clang -# clang_script: -# - mkdir artifacts -# - ".ci/build-linux.sh" -# artifacts: -# name: Artifact -# path: "artifacts/*" -# push_script: | -# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ] && [ "$COMPILER" = "gcc" ]; then -# COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp) -# COMM_COUNT=$(git rev-list --count HEAD) -# COMM_HASH=$(git rev-parse --short=8 HEAD) - -# export AVVER="${COMM_TAG}-${COMM_COUNT}" - -# .ci/github-upload.sh -# fi; freebsd_task: matrix: @@ -115,39 +24,3 @@ freebsd_task: folder: /tmp/ccache_dir install_script: "sh -ex ./.ci/install-freebsd.sh" script: "./.ci/build-freebsd.sh" - -# linux_aarch64_task: -# env: -# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts -# ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/ -# CCACHE_DIR: "/tmp/ccache_dir" -# CCACHE_MAXSIZE: 300M -# CI_HAS_ARTIFACTS: true -# UPLOAD_COMMIT_HASH: a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1 -# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux-arm64" -# DEPLOY_APPIMAGE: true -# APPDIR: "./appdir" -# RELEASE_MESSAGE: "../GitHubReleaseMessage.txt" -# COMPILER: clang -# ccache_cache: -# folder: "/tmp/ccache_dir" -# matrix: -# - name: Cirrus Linux AArch64 Clang -# arm_container: -# image: 'docker.io/rpcs3/rpcs3-ci-jammy-aarch64:1.6' -# cpu: 8 -# memory: 8G -# clang_script: -# - mkdir artifacts -# - "sh -ex ./.ci/build-linux-aarch64.sh" -# artifacts: -# name: Artifact -# path: "artifacts/*" -# push_script: | -# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then -# COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp) -# COMM_COUNT=$(git rev-list --count HEAD) -# COMM_HASH=$(git rev-parse --short=8 HEAD) -# export AVVER="${COMM_TAG}-${COMM_COUNT}" -# .ci/github-upload.sh -# fi; diff --git a/.github/workflows/rpcs3.yml b/.github/workflows/rpcs3.yml index 2d7f0a8282..b6d02dbbec 100644 --- a/.github/workflows/rpcs3.yml +++ b/.github/workflows/rpcs3.yml @@ -137,6 +137,7 @@ jobs: RELEASE_MESSAGE: ../GitHubReleaseMessage.txt UPLOAD_COMMIT_HASH: ${{ matrix.UPLOAD_COMMIT_HASH }} UPLOAD_REPO_FULL_NAME: ${{ matrix.UPLOAD_REPO_FULL_NAME }} + RUN_UNIT_TESTS: github.event_name == 'pull_request' && 'ON' || 'OFF' steps: - name: Checkout repository uses: actions/checkout@main @@ -160,7 +161,7 @@ jobs: restore-keys: ${{ runner.os }}-qt-${{ matrix.name }}-${{ env.QT_VER }} - name: Build - run: ${{ matrix.build_sh }} + run: ${{ matrix.build_sh }} - name: Upload artifacts uses: actions/upload-artifact@main @@ -185,7 +186,7 @@ jobs: env: RPCS3_TOKEN: ${{ secrets.RPCS3_TOKEN }} run: .ci/github-upload.sh - + - name: Save Build Ccache if: github.ref == 'refs/heads/master' uses: actions/cache/save@main @@ -208,9 +209,9 @@ jobs: env: COMPILER: msvc QT_VER_MAIN: '6' - QT_VER: '6.9.0' + QT_VER: '6.9.1' QT_VER_MSVC: 'msvc2022' - QT_DATE: '202503301022' + QT_DATE: '202505291653' LLVM_VER: '19.1.7' VULKAN_VER: '1.3.268.0' VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5' diff --git a/BUILDING.md b/BUILDING.md index 09f523d567..311bbddeee 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -19,26 +19,26 @@ The following tools are required to build RPCS3 on Windows 10 or later: with standalone **CMake** tool. - [Python 3.6+](https://www.python.org/downloads/) (add to PATH) -- [Qt 6.9.0](https://www.qt.io/download-qt-installer) In case you can't download from the official installer, you can use [Another Qt installer](https://github.com/miurahr/aqtinstall) (In that case you will need to manually add the "qtmultimedia" module when installing Qt) +- [Qt 6.9.1](https://www.qt.io/download-qt-installer) In case you can't download from the official installer, you can use [Another Qt installer](https://github.com/miurahr/aqtinstall) (In that case you will need to manually add the "qtmultimedia" module when installing Qt) - [Vulkan SDK 1.3.268.0](https://vulkan.lunarg.com/sdk/home) (see "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html)) for now future SDKs don't work. You need precisely 1.3.268.0. The `sln` solution available only on **Visual Studio** is the preferred building solution. It easily allows to build the **RPCS3** application in `Release` and `Debug` mode. In order to build **RPCS3** with the `sln` solution (with **Visual Studio**), **Qt** libs need to be detected. To detect the libs: -- add and set the `QTDIR` environment variable, e.g. `\6.9.0\msvc2022_64\` +- add and set the `QTDIR` environment variable, e.g. `\6.9.1\msvc2022_64\` - or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2022) **NOTE:** If you have issues with the **Visual Studio Qt Plugin**, you may want to uninstall it and install the [Legacy Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.LEGACYQtVisualStudioTools2022) instead. In order to build **RPCS3** with the `CMake` solution (with both **Visual Studio** and standalone **CMake** tool): -- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `\6.9.0\msvc2022_64\` +- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `\6.9.1\msvc2022_64\` ### Linux These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager: - Clang 17+ or GCC 13+ - [CMake 3.28.0+](https://www.cmake.org/download/) -- [Qt 6.9.0](https://www.qt.io/download-qt-installer) +- [Qt 6.9.1](https://www.qt.io/download-qt-installer) - [Vulkan SDK 1.3.268.0](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html)) for now future SDKs don't work. You need precisely 1.3.268.0. - [SDL3](https://github.com/libsdl-org/SDL/releases) (for the FAudio backend) @@ -121,7 +121,7 @@ Start **Visual Studio**, click on `Open a project or solution` and select the `r ##### Configuring the Qt Plugin (if used) 1) go to `Extensions->Qt VS Tools->Qt Versions` -2) add the path to your Qt installation with compiler e.g. `\6.9.0\msvc2022_64`, version will fill in automatically +2) add the path to your Qt installation with compiler e.g. `\6.9.1\msvc2022_64`, version will fill in automatically 3) go to `Extensions->Qt VS Tools->Options->Legacy Project Format`. (Only available in the **Legacy Qt Plugin**) 4) set `Build: Run pre-build setup` to `true`. (Only available in the **Legacy Qt Plugin**) diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 52096a2702..6dc2dc8cf6 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -96,7 +96,7 @@ class thread_future thread_future* prev{}; protected: - atomic_t exec{}; + atomic_t exec{}; atomic_t done{0}; @@ -389,7 +389,7 @@ public: : m_args(std::forward(args)...) , m_func(std::forward(func)) { - thread_future::exec.raw() = +[](thread_base* tb, thread_future* tf) + thread_future::exec.raw() = +[](const thread_base* tb, thread_future* tf) { const auto _this = static_cast(tf); diff --git a/Utilities/transactional_storage.h b/Utilities/transactional_storage.h index 55e8aa9f95..1be923233e 100644 --- a/Utilities/transactional_storage.h +++ b/Utilities/transactional_storage.h @@ -84,9 +84,8 @@ public: transactional_storage& operator=(const transactional_storage&) = delete; transactional_storage(transactional_storage&& other) + : pool(std::move(other.pool)) { - pool = std::move(other.pool); - std::unique_lock lock_other{other.current_mutex}; const std::shared_ptr other_current = other.current; other.current = nullptr; diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index bfbeb416df..ba796be28e 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -351,7 +351,7 @@ public: for (u32 i = 0; i < CELL_GEM_MAX_NUM; i++) { const auto& pad = ::at32(handler->GetPads(), pad_num(i)); - const bool connected = pad && pad->is_connected() && i < attribute.max_connect; + const bool connected = pad && pad->is_connected() && !pad->is_copilot() && i < attribute.max_connect; const bool is_real_move = g_cfg.io.move != move_handler::real || pad->m_pad_handler == pad_handler::move; update_connection(i, connected && is_real_move); @@ -407,7 +407,7 @@ public: std::lock_guard pad_lock(pad::g_pad_mutex); const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad && pad->m_pad_handler == pad_handler::move) + if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot()) { if (!pad->move_data.calibration_requested || !pad->move_data.calibration_succeeded) { @@ -437,7 +437,7 @@ public: std::lock_guard pad_lock(pad::g_pad_mutex); const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad && pad->m_pad_handler == pad_handler::move) + if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot()) { pad->move_data.calibration_requested = false; pad->move_data.calibration_succeeded = false; @@ -469,7 +469,7 @@ public: for (u32 i = 0; i < std::min(attribute.max_connect, CELL_GEM_MAX_NUM); i++) { const auto& pad = ::at32(handler->GetPads(), pad_num(i)); - if (pad && pad->m_pad_handler == pad_handler::move && pad->is_connected()) + if (pad && pad->m_pad_handler == pad_handler::move && pad->is_connected() && !pad->is_copilot()) { connected_controllers++; @@ -490,7 +490,7 @@ public: for (u32 i = 0; i < std::min(attribute.max_connect, CELL_GEM_MAX_NUM); i++) { const auto& pad = ::at32(handler->GetPads(), pad_num(i)); - if (pad && pad->is_connected()) + if (pad && pad->is_connected() && !pad->is_copilot()) { connected_controllers++; @@ -1776,7 +1776,7 @@ static void ds3_input_to_pad(const u32 gem_num, be_t& digital_buttons, be_t const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (!pad->is_connected()) + if (!pad->is_connected() || pad->is_copilot()) { return; } @@ -1864,7 +1864,7 @@ static void ds3_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& contro const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (!pad->is_connected()) + if (!pad->is_connected() || pad->is_copilot()) { return; } @@ -1895,7 +1895,7 @@ static void ps_move_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& co const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad->m_pad_handler != pad_handler::move || !pad->is_connected()) + if (pad->m_pad_handler != pad_handler::move || !pad->is_connected() || pad->is_copilot()) { return; } @@ -1940,7 +1940,7 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (!pad->is_connected()) + if (!pad->is_connected() || pad->is_copilot()) { return; } @@ -1952,7 +1952,7 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller ext.status = controller.ext_status; - for (const AnalogStick& stick : pad->m_sticks) + for (const AnalogStick& stick : pad->m_sticks_external) { switch (stick.m_offset) { @@ -1964,7 +1964,7 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller } } - for (const Button& button : pad->m_buttons) + for (const Button& button : pad->m_buttons_external) { if (!button.m_pressed) continue; @@ -2400,7 +2400,7 @@ error_code cellGemEnableMagnetometer(u32 gem_num, u32 enable) const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad && pad->m_pad_handler == pad_handler::move) + if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot()) { pad->move_data.magnetometer_enabled = controller.enabled_magnetometer; } @@ -2448,7 +2448,7 @@ error_code cellGemEnableMagnetometer2(u32 gem_num, u32 enable) const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad && pad->m_pad_handler == pad_handler::move) + if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot()) { pad->move_data.magnetometer_enabled = controller.enabled_magnetometer; } @@ -2777,7 +2777,7 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad && pad->is_connected()) + if (pad && pad->is_connected() && !pad->is_copilot()) { inertial_state->temperature = pad->move_data.temperature; inertial_state->accelerometer[0] = pad->move_data.accelerometer_x; @@ -3392,7 +3392,7 @@ error_code cellGemReadExternalPortDeviceInfo(u32 gem_num, vm::ptr ext_id, v const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num)); - if (pad->m_pad_handler != pad_handler::move || !pad->is_connected()) + if (pad->m_pad_handler != pad_handler::move || !pad->is_connected() || pad->is_copilot()) { return CELL_GEM_NOT_CONNECTED; } @@ -3706,7 +3706,7 @@ error_code cellGemWriteExternalPort(u32 gem_num, vm::ptrGetPads(), pad_num(gem_num)); - if (pad->m_pad_handler != pad_handler::move || !pad->is_connected()) + if (pad->m_pad_handler != pad_handler::move || !pad->is_connected() || pad->is_copilot()) { return CELL_GEM_NOT_CONNECTED; } diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index 61e29805aa..086a341854 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -411,60 +411,27 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false) } }; - for (const Button& button : pad->m_buttons) + for (const Button& button : pad->m_buttons_external) { // here we check btns, and set pad accordingly, // if something changed, set btnChanged - bool pressed = button.m_pressed; - u16 value = button.m_value; - - // Merge copilots - if (!pad->copilots.empty()) - { - for (const auto& copilot : pad->copilots) - { - if (!copilot || !copilot->is_connected()) - { - continue; - } - - for (const Button& other : copilot->m_buttons) - { - if (button.m_offset == other.m_offset && button.m_outKeyCode == other.m_outKeyCode) - { - if (other.m_pressed) - { - pressed = true; - - if (value < other.m_value) - { - value = other.m_value; - } - } - - break; - } - } - } - } - switch (button.m_offset) { case CELL_PAD_BTN_OFFSET_DIGITAL1: { - if (pressed) + if (button.m_pressed) pad->m_digital_1 |= button.m_outKeyCode; else pad->m_digital_1 &= ~button.m_outKeyCode; switch (button.m_outKeyCode) { - case CELL_PAD_CTRL_LEFT: set_value(pad->m_press_left, value); break; - case CELL_PAD_CTRL_DOWN: set_value(pad->m_press_down, value); break; - case CELL_PAD_CTRL_RIGHT: set_value(pad->m_press_right, value); break; - case CELL_PAD_CTRL_UP: set_value(pad->m_press_up, value); break; - // These arent pressure btns + case CELL_PAD_CTRL_LEFT: set_value(pad->m_press_left, button.m_value); break; + case CELL_PAD_CTRL_DOWN: set_value(pad->m_press_down, button.m_value); break; + case CELL_PAD_CTRL_RIGHT: set_value(pad->m_press_right, button.m_value); break; + case CELL_PAD_CTRL_UP: set_value(pad->m_press_up, button.m_value); break; + // These aren't pressure btns case CELL_PAD_CTRL_R3: case CELL_PAD_CTRL_L3: case CELL_PAD_CTRL_START: @@ -475,21 +442,21 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false) } case CELL_PAD_BTN_OFFSET_DIGITAL2: { - if (pressed) + if (button.m_pressed) pad->m_digital_2 |= button.m_outKeyCode; else pad->m_digital_2 &= ~button.m_outKeyCode; switch (button.m_outKeyCode) { - case CELL_PAD_CTRL_SQUARE: set_value(pad->m_press_square, value); break; - case CELL_PAD_CTRL_CROSS: set_value(pad->m_press_cross, value); break; - case CELL_PAD_CTRL_CIRCLE: set_value(pad->m_press_circle, value); break; - case CELL_PAD_CTRL_TRIANGLE: set_value(pad->m_press_triangle, value); break; - case CELL_PAD_CTRL_R1: set_value(pad->m_press_R1, value); break; - case CELL_PAD_CTRL_L1: set_value(pad->m_press_L1, value); break; - case CELL_PAD_CTRL_R2: set_value(pad->m_press_R2, value); break; - case CELL_PAD_CTRL_L2: set_value(pad->m_press_L2, value); break; + case CELL_PAD_CTRL_SQUARE: set_value(pad->m_press_square, button.m_value); break; + case CELL_PAD_CTRL_CROSS: set_value(pad->m_press_cross, button.m_value); break; + case CELL_PAD_CTRL_CIRCLE: set_value(pad->m_press_circle, button.m_value); break; + case CELL_PAD_CTRL_TRIANGLE: set_value(pad->m_press_triangle, button.m_value); break; + case CELL_PAD_CTRL_R1: set_value(pad->m_press_R1, button.m_value); break; + case CELL_PAD_CTRL_L1: set_value(pad->m_press_L1, button.m_value); break; + case CELL_PAD_CTRL_R2: set_value(pad->m_press_R2, button.m_value); break; + case CELL_PAD_CTRL_L2: set_value(pad->m_press_L2, button.m_value); break; default: break; } break; @@ -498,18 +465,18 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false) { switch (button.m_outKeyCode) { - case CELL_PAD_CTRL_PRESS_RIGHT: set_value(pad->m_press_right, value, true); break; - case CELL_PAD_CTRL_PRESS_LEFT: set_value(pad->m_press_left, value, true); break; - case CELL_PAD_CTRL_PRESS_UP: set_value(pad->m_press_up, value, true); break; - case CELL_PAD_CTRL_PRESS_DOWN: set_value(pad->m_press_down, value, true); break; - case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value(pad->m_press_triangle, value, true, 255, 63); break; // Infrared on RIDE Skateboard - case CELL_PAD_CTRL_PRESS_CIRCLE: set_value(pad->m_press_circle, value, true, 255, 63); break; // Infrared on RIDE Skateboard - case CELL_PAD_CTRL_PRESS_CROSS: set_value(pad->m_press_cross, value, true, 255, 63); break; // Infrared on RIDE Skateboard - case CELL_PAD_CTRL_PRESS_SQUARE: set_value(pad->m_press_square, value, true, 255, 63); break; // Infrared on RIDE Skateboard - case CELL_PAD_CTRL_PRESS_L1: set_value(pad->m_press_L1, value, true); break; - case CELL_PAD_CTRL_PRESS_R1: set_value(pad->m_press_R1, value, true); break; - case CELL_PAD_CTRL_PRESS_L2: set_value(pad->m_press_L2, value, true); break; - case CELL_PAD_CTRL_PRESS_R2: set_value(pad->m_press_R2, value, true); break; + case CELL_PAD_CTRL_PRESS_RIGHT: set_value(pad->m_press_right, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_LEFT: set_value(pad->m_press_left, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_UP: set_value(pad->m_press_up, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_DOWN: set_value(pad->m_press_down, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value(pad->m_press_triangle, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard + case CELL_PAD_CTRL_PRESS_CIRCLE: set_value(pad->m_press_circle, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard + case CELL_PAD_CTRL_PRESS_CROSS: set_value(pad->m_press_cross, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard + case CELL_PAD_CTRL_PRESS_SQUARE: set_value(pad->m_press_square, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard + case CELL_PAD_CTRL_PRESS_L1: set_value(pad->m_press_L1, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_R1: set_value(pad->m_press_R1, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_L2: set_value(pad->m_press_L2, button.m_value, true); break; + case CELL_PAD_CTRL_PRESS_R2: set_value(pad->m_press_R2, button.m_value, true); break; default: break; } break; @@ -519,46 +486,14 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false) } } - for (const AnalogStick& stick : pad->m_sticks) + for (const AnalogStick& stick : pad->m_sticks_external) { - u16 value = stick.m_value; - - // Merge copilots - if (!pad->copilots.empty()) - { - const auto normalize = [](s32 value) - { - return (value - 128) / 127.0f; - }; - - f32 accumulated_value = normalize(value); - - for (const auto& copilot : pad->copilots) - { - if (!copilot || !copilot->is_connected()) - { - continue; - } - - for (const AnalogStick& other : copilot->m_sticks) - { - if (stick.m_offset == other.m_offset) - { - accumulated_value += normalize(other.m_value); - break; - } - } - } - - value = static_cast(std::round(std::clamp(accumulated_value * 127.0f + 128.0f, 0.0f, 255.0f))); - } - switch (stick.m_offset) { - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value(pad->m_analog_left_x, value); break; - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value(pad->m_analog_left_y, value); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value(pad->m_analog_right_x, value); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value(pad->m_analog_right_y, value); break; + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value(pad->m_analog_left_x, stick.m_value); break; + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value(pad->m_analog_left_y, stick.m_value); break; + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value(pad->m_analog_right_x, stick.m_value); break; + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value(pad->m_analog_right_y, stick.m_value); break; default: break; } } @@ -1305,7 +1240,7 @@ error_code cellPadLddGetPortNo(s32 handle) return CELL_PAD_ERROR_UNINITIALIZED; const auto handler = pad::get_pad_thread(); - auto& pads = handler->GetPads(); + const auto& pads = handler->GetPads(); if (handle < 0 || static_cast(handle) >= pads.size()) return CELL_PAD_ERROR_INVALID_PARAMETER; diff --git a/rpcs3/Emu/Cell/Modules/cellPad.h b/rpcs3/Emu/Cell/Modules/cellPad.h index 3394fe6b2b..0d199e488c 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.h +++ b/rpcs3/Emu/Cell/Modules/cellPad.h @@ -3,7 +3,6 @@ #include "Emu/Io/pad_types.h" #include -#include "util/types.hpp" enum CellPadError : u32 { diff --git a/rpcs3/Emu/Io/Buzz.cpp b/rpcs3/Emu/Io/Buzz.cpp index d5b7fe4f23..840220b967 100644 --- a/rpcs3/Emu/Io/Buzz.cpp +++ b/rpcs3/Emu/Io/Buzz.cpp @@ -173,7 +173,7 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/ { const auto& pad = pads[i]; - if (!pad->is_connected()) + if (!pad->is_connected() || pad->is_copilot()) { continue; } diff --git a/rpcs3/Emu/Io/GHLtar.cpp b/rpcs3/Emu/Io/GHLtar.cpp index 9a2b9d0ce6..0c99c6aabf 100644 --- a/rpcs3/Emu/Io/GHLtar.cpp +++ b/rpcs3/Emu/Io/GHLtar.cpp @@ -152,7 +152,7 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint const auto handler = pad::get_pad_thread(); const auto& pad = ::at32(handler->GetPads(), m_controller_index); - if (!pad->is_connected()) + if (!pad->is_connected() || pad->is_copilot()) { return; } diff --git a/rpcs3/Emu/Io/GameTablet.cpp b/rpcs3/Emu/Io/GameTablet.cpp index 0b87a709bf..4c2330d908 100644 --- a/rpcs3/Emu/Io/GameTablet.cpp +++ b/rpcs3/Emu/Io/GameTablet.cpp @@ -198,9 +198,9 @@ void usb_device_gametablet::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endp const auto gamepad_handler = pad::get_pad_thread(); const auto& pads = gamepad_handler->GetPads(); const auto& pad = ::at32(pads, m_controller_index); - if (pad->is_connected()) + if (pad->is_connected() && !pad->is_copilot()) { - for (Button& button : pad->m_buttons) + for (Button& button : pad->m_buttons_external) { if (!button.m_pressed) { diff --git a/rpcs3/Emu/Io/GunCon3.cpp b/rpcs3/Emu/Io/GunCon3.cpp index 8dc5688f73..522369d8a4 100644 --- a/rpcs3/Emu/Io/GunCon3.cpp +++ b/rpcs3/Emu/Io/GunCon3.cpp @@ -258,7 +258,7 @@ void usb_device_guncon3::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, const auto gamepad_handler = pad::get_pad_thread(); const auto& pads = gamepad_handler->GetPads(); const auto& pad = ::at32(pads, m_controller_index); - if (pad->is_connected()) + if (pad->is_connected() && !pad->is_copilot()) { cfg->handle_input(pad, true, input_callback); } diff --git a/rpcs3/Emu/Io/TopShotElite.cpp b/rpcs3/Emu/Io/TopShotElite.cpp index b7e2b64b98..c241fe1ed4 100644 --- a/rpcs3/Emu/Io/TopShotElite.cpp +++ b/rpcs3/Emu/Io/TopShotElite.cpp @@ -318,7 +318,7 @@ void usb_device_topshotelite::interrupt_transfer(u32 buf_size, u8* buf, u32 /*en const auto gamepad_handler = pad::get_pad_thread(); const auto& pads = gamepad_handler->GetPads(); const auto& pad = ::at32(pads, m_controller_index); - if (pad->is_connected()) + if (pad->is_connected() && !pad->is_copilot()) { cfg->handle_input(pad, true, input_callback); } diff --git a/rpcs3/Emu/Io/TopShotFearmaster.cpp b/rpcs3/Emu/Io/TopShotFearmaster.cpp index 03c634d839..eed7ade977 100644 --- a/rpcs3/Emu/Io/TopShotFearmaster.cpp +++ b/rpcs3/Emu/Io/TopShotFearmaster.cpp @@ -342,7 +342,7 @@ void usb_device_topshotfearmaster::interrupt_transfer(u32 buf_size, u8* buf, u32 const auto gamepad_handler = pad::get_pad_thread(); const auto& pads = gamepad_handler->GetPads(); const auto& pad = ::at32(pads, m_controller_index); - if (pad->is_connected()) + if (pad->is_connected() && !pad->is_copilot()) { cfg->handle_input(pad, true, input_callback); } diff --git a/rpcs3/Emu/Io/Turntable.cpp b/rpcs3/Emu/Io/Turntable.cpp index ec67fabc22..261af88d16 100644 --- a/rpcs3/Emu/Io/Turntable.cpp +++ b/rpcs3/Emu/Io/Turntable.cpp @@ -166,7 +166,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo const auto& pads = handler->GetPads(); const auto& pad = ::at32(pads, m_controller_index); - if (!pad->is_connected()) + if (!pad->is_connected() || pad->is_copilot()) return; const auto& cfg = ::at32(g_cfg_turntable.players, m_controller_index); diff --git a/rpcs3/Emu/Io/emulated_pad_config.h b/rpcs3/Emu/Io/emulated_pad_config.h index e2b46d3daa..b9bf68a223 100644 --- a/rpcs3/Emu/Io/emulated_pad_config.h +++ b/rpcs3/Emu/Io/emulated_pad_config.h @@ -90,10 +90,10 @@ public: void handle_input(std::shared_ptr pad, bool press_only, const std::function& func) const { - if (!pad) + if (!pad || pad->is_copilot()) return; - for (const Button& button : pad->m_buttons) + for (const Button& button : pad->m_buttons_external) { if (button.m_pressed || !press_only) { @@ -104,7 +104,7 @@ public: } } - for (const AnalogStick& stick : pad->m_sticks) + for (const AnalogStick& stick : pad->m_sticks_external) { if (handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true)) { diff --git a/rpcs3/Emu/Io/pad_types.h b/rpcs3/Emu/Io/pad_types.h index 57634a66b4..356c86d6ae 100644 --- a/rpcs3/Emu/Io/pad_types.h +++ b/rpcs3/Emu/Io/pad_types.h @@ -543,6 +543,9 @@ struct Pad std::array m_sensors{}; std::array m_vibrateMotors{}; + std::vector