Merge remote-tracking branch 'origin/main' into kbm-only

This commit is contained in:
kalaposfos13 2025-01-13 07:14:58 +01:00
commit 9146ca01e9
155 changed files with 25393 additions and 20819 deletions

View File

@ -13,7 +13,11 @@ body:
**Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only.
If you have a support request or are unsure about the nature of your issue please contact us on [discord](https://discord.gg/bFJxfftGW6).**
You can also check the [Game Compatibility Repository](https://github.com/shadps4-emu/shadps4-game-compatibility) for the information about the status of the game.
This repository does not provide support for modded games. You should perform and test a clean game installation before submitting an issue.
This repository does not provide support for game patches. If you are having issues with patches please refer to [Cheats and Patches Repository](https://github.com/shadps4-emu/ps4_cheats).
Before submitting an issue please check [Game Compatibility Repository](https://github.com/shadps4-emu/shadps4-game-compatibility) for the information about the status of the game.
Please make an effort to make sure your issue isn't already reported.
@ -21,15 +25,15 @@ body:
- type: checkboxes
id: checklist
attributes:
label: Checklist
label: Checklist (we expect you to perform these steps before opening the issue)
options:
- label: I have searched for a similar issue in this repository and did not find one.
required: true
- label: I am using an official build obtained from [releases](https://github.com/shadps4-emu/shadPS4/releases) or updated one of those builds using its in-app updater.
required: true
- label: I have re-dumped the game and performed a clean install without mods.
- label: I have re-dumped the game and performed a clean install without mods and the issue is still present.
required: true
- label: I have disabled all patches and cheats.
- label: I have disabled all patches and cheats and the issue is still present.
required: true
- label: I have all the required [system modules](https://github.com/shadps4-emu/shadps4-game-compatibility?tab=readme-ov-file#informations) installed.
required: true
@ -85,7 +89,7 @@ body:
- type: textarea
id: logs
attributes:
label: "Logs"
description: Attach any logs here. Log can be found by right clicking on a game name -> Open Folder... -> Open Log Folder. Make sure that the log type is set to `sync`.
label: "Log File"
description: Drag and drop the log file here. It can be found by right clicking on a game name -> Open Folder... -> Open Log Folder. Make sure that the log type is set to `sync`.
validations:
required: false
required: true

View File

@ -14,14 +14,14 @@ env:
jobs:
reuse:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: fsfe/reuse-action@v5
clang-format:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
continue-on-error: true
steps:
- uses: actions/checkout@v4
@ -39,7 +39,7 @@ jobs:
run: ./.ci/clang-format.sh
get-info:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
outputs:
date: ${{ steps.vars.outputs.date }}
shorthash: ${{ steps.vars.outputs.shorthash }}
@ -57,7 +57,7 @@ jobs:
echo "fullhash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
windows-sdl:
runs-on: windows-latest
runs-on: windows-2025
needs: get-info
steps:
- uses: actions/checkout@v4
@ -101,7 +101,7 @@ jobs:
path: ${{github.workspace}}/build/shadPS4.exe
windows-qt:
runs-on: windows-latest
runs-on: windows-2025
needs: get-info
steps:
- uses: actions/checkout@v4
@ -376,6 +376,78 @@ jobs:
name: shadps4-linux-qt-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }}
path: Shadps4-qt.AppImage
linux-sdl-gcc:
runs-on: ubuntu-24.04
needs: get-info
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
- name: Cache CMake Configuration
uses: actions/cache@v4
env:
cache-name: ${{ runner.os }}-sdl-cache-cmake-configuration
with:
path: |
${{github.workspace}}/build
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
restore-keys: |
${{ env.cache-name }}-
- name: Cache CMake Build
uses: hendrikmuhs/ccache-action@v1.2.14
env:
cache-name: ${{ runner.os }}-sdl-cache-cmake-build
with:
append-timestamp: false
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
- name: Configure CMake
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
linux-qt-gcc:
runs-on: ubuntu-24.04
needs: get-info
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
- name: Cache CMake Configuration
uses: actions/cache@v4
env:
cache-name: ${{ runner.os }}-qt-cache-cmake-configuration
with:
path: |
${{github.workspace}}/build
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
restore-keys: |
${{ env.cache-name }}-
- name: Cache CMake Build
uses: hendrikmuhs/ccache-action@v1.2.14
env:
cache-name: ${{ runner.os }}-qt-cache-cmake-build
with:
append-timestamp: false
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
- name: Configure CMake
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
pre-release:
if: github.ref == 'refs/heads/main' && github.repository == 'shadps4-emu/shadPS4' && github.event_name == 'push'
needs: [get-info, windows-sdl, windows-qt, macos-sdl, macos-qt, linux-sdl, linux-qt]

View File

@ -209,6 +209,7 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp
set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
src/core/libraries/gnmdriver/gnmdriver.h
src/core/libraries/gnmdriver/gnmdriver_init.h
src/core/libraries/gnmdriver/gnm_error.h
)
@ -253,6 +254,8 @@ set(KERNEL_LIB src/core/libraries/kernel/sync/mutex.cpp
set(NETWORK_LIBS src/core/libraries/network/http.cpp
src/core/libraries/network/http.h
src/core/libraries/network/http2.cpp
src/core/libraries/network/http2.h
src/core/libraries/network/net.cpp
src/core/libraries/network/netctl.cpp
src/core/libraries/network/netctl.h
@ -262,6 +265,8 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp
src/core/libraries/network/net.h
src/core/libraries/network/ssl.cpp
src/core/libraries/network/ssl.h
src/core/libraries/network/ssl2.cpp
src/core/libraries/network/ssl2.h
)
set(AVPLAYER_LIB src/core/libraries/avplayer/avplayer_common.cpp
@ -335,6 +340,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/share_play/shareplay.h
src/core/libraries/razor_cpu/razor_cpu.cpp
src/core/libraries/razor_cpu/razor_cpu.h
src/core/libraries/mouse/mouse.cpp
src/core/libraries/mouse/mouse.h
)
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
@ -412,7 +419,9 @@ set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp
src/core/libraries/videodec/videodec_impl.h
)
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
set(NP_LIBS src/core/libraries/np_common/np_common.cpp
src/core/libraries/np_common/np_common.h
src/core/libraries/np_manager/np_manager.cpp
src/core/libraries/np_manager/np_manager.h
src/core/libraries/np_score/np_score.cpp
src/core/libraries/np_score/np_score.h
@ -1047,7 +1056,6 @@ install(TARGETS shadps4 BUNDLE DESTINATION .)
if (ENABLE_QT_GUI AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
install(FILES "dist/net.shadps4.shadPS4.desktop" DESTINATION "share/applications")
install(FILES "dist/net.shadps4.shadPS4.releases.xml" DESTINATION "share/metainfo/releases")
install(FILES "dist/net.shadps4.shadPS4.metainfo.xml" DESTINATION "share/metainfo")
install(FILES ".github/shadps4.png" DESTINATION "share/icons/hicolor/512x512/apps" RENAME "net.shadps4.shadPS4.png")
install(FILES "src/images/net.shadps4.shadPS4.svg" DESTINATION "share/icons/hicolor/scalable/apps")

View File

@ -11,7 +11,6 @@ path = [
"dist/net.shadps4.shadPS4.desktop",
"dist/net.shadps4.shadPS4_metadata.pot",
"dist/net.shadps4.shadPS4.metainfo.xml",
"dist/net.shadps4.shadPS4.releases.xml",
"documents/changelog.md",
"documents/Quickstart/2.png",
"documents/Screenshots/*",

View File

@ -36,9 +36,30 @@
<categories>
<category translate="no">Game</category>
</categories>
<releases type="external" url="https://cdn.jsdelivr.net/gh/fpiesche/flatpak-builds/apps/net.shadps4.shadPS4/net.shadps4.shadPS4.releases.xml">
<release version="v.0.4.0" date="2024-11-03">
<description></description>
<releases>
<release version="0.5.0" date="2024-12-25">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.5.0</url>
</release>
<release version="0.4.0" date="2024-10-31">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.4.0</url>
</release>
<release version="0.3.0" date="2024-09-23">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.3.0</url>
</release>
<release version="0.2.0" date="2024-08-15">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.2.0</url>
</release>
<release version="0.1.0" date="2024-07-01">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/0.1.0</url>
</release>
<release version="0.0.3" date="2024-03-23">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.3</url>
</release>
<release version="0.0.2" date="2023-10-21">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.2</url>
</release>
<release version="0.0.1" date="2024-09-29">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.1</url>
</release>
</releases>
<content_rating type="oars-1.1"/>

View File

@ -1,23 +0,0 @@
<releases>
<release version="0.4.0" date="2024-10-31">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.4.0</url>
</release>
<release version="0.3.0" date="2024-09-23">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.3.0</url>
</release>
<release version="0.2.0" date="2024-08-15">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.2.0</url>
</release>
<release version="0.1.0" date="2024-07-01">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/0.1.0</url>
</release>
<release version="0.0.3" date="2024-03-23">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.3</url>
</release>
<release version="0.0.2" date="2023-10-21">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.2</url>
</release>
<release version="0.0.1" date="2024-09-29">
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.1</url>
</release>
</releases>

View File

@ -213,9 +213,7 @@ endif()
# Discord RPC
if (ENABLE_DISCORD_RPC)
set(BUILD_EXAMPLES OFF)
add_subdirectory(discord-rpc)
target_include_directories(discord-rpc INTERFACE discord-rpc/include)
endif()
# GCN Headers

@ -1 +1 @@
Subproject commit 4ec218155d73bcb8022f8f7ca72305d801f84beb
Subproject commit 51b09d426a4a1bcfa6ee6d4894e57d669f4a2e65

2
externals/sdl3 vendored

@ -1 +1 @@
Subproject commit 3a1d76d298db023f6cf37fb08ee766f20a4e12ab
Subproject commit 22422f7748d5128135995ed34c8f8012861c7332

2
externals/sirit vendored

@ -1 +1 @@
Subproject commit 1e74f4ef8d2a0e3221a4de51977663f342b53c35
Subproject commit 26ad5a9d0fe13260b0d7d6c64419d01a196b2e32

View File

@ -33,6 +33,7 @@ namespace Config {
static bool isNeo = false;
static bool isFullscreen = false;
static std::string fullscreenMode = "borderless";
static bool playBGM = false;
static bool isTrophyPopupDisabled = false;
static int BGMvolume = 50;
@ -47,6 +48,7 @@ static std::string updateChannel;
static std::string backButtonBehavior = "left";
static bool useSpecialPad = false;
static int specialPadClass = 1;
static bool isMotionControlsEnabled = true;
static bool isDebugDump = false;
static bool isShaderDebug = false;
static bool isShowSplash = false;
@ -70,6 +72,7 @@ static bool checkCompatibilityOnStartup = false;
static std::string trophyKey;
// Gui
static bool load_game_size = true;
std::vector<std::filesystem::path> settings_install_dirs = {};
std::filesystem::path settings_addon_install_dir = {};
u32 main_window_geometry_x = 400;
@ -100,14 +103,26 @@ void setTrophyKey(std::string key) {
trophyKey = key;
}
bool isNeoMode() {
bool GetLoadGameSizeEnabled() {
return load_game_size;
}
void setLoadGameSizeEnabled(bool enable) {
load_game_size = enable;
}
bool isNeoModeConsole() {
return isNeo;
}
bool isFullscreenMode() {
bool getIsFullscreen() {
return isFullscreen;
}
std::string getFullscreenMode() {
return fullscreenMode;
}
bool getisTrophyPopupDisabled() {
return isTrophyPopupDisabled;
}
@ -172,6 +187,10 @@ int getSpecialPadClass() {
return specialPadClass;
}
bool getIsMotionControlsEnabled() {
return isMotionControlsEnabled;
}
bool debugDump() {
return isDebugDump;
}
@ -304,10 +323,14 @@ void setVblankDiv(u32 value) {
vblankDivider = value;
}
void setFullscreenMode(bool enable) {
void setIsFullscreen(bool enable) {
isFullscreen = enable;
}
void setFullscreenMode(std::string mode) {
fullscreenMode = mode;
}
void setisTrophyPopupDisabled(bool disable) {
isTrophyPopupDisabled = disable;
}
@ -368,6 +391,10 @@ void setSpecialPadClass(int type) {
specialPadClass = type;
}
void setIsMotionControlsEnabled(bool use) {
isMotionControlsEnabled = use;
}
void setSeparateUpdateEnabled(bool use) {
separateupdatefolder = use;
}
@ -566,6 +593,7 @@ void load(const std::filesystem::path& path) {
isNeo = toml::find_or<bool>(general, "isPS4Pro", false);
isFullscreen = toml::find_or<bool>(general, "Fullscreen", false);
fullscreenMode = toml::find_or<std::string>(general, "FullscreenMode", "borderless");
playBGM = toml::find_or<bool>(general, "playBGM", false);
isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false);
BGMvolume = toml::find_or<int>(general, "BGMvolume", 50);
@ -594,6 +622,7 @@ void load(const std::filesystem::path& path) {
backButtonBehavior = toml::find_or<std::string>(input, "backButtonBehavior", "left");
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
isMotionControlsEnabled = toml::find_or<bool>(input, "isMotionControlsEnabled", true);
}
if (data.contains("GPU")) {
@ -630,6 +659,7 @@ void load(const std::filesystem::path& path) {
if (data.contains("GUI")) {
const toml::value& gui = data.at("GUI");
load_game_size = toml::find_or<bool>(gui, "loadGameSizeEnabled", true);
m_icon_size = toml::find_or<int>(gui, "iconSize", 0);
m_icon_size_grid = toml::find_or<int>(gui, "iconSizeGrid", 0);
m_slider_pos = toml::find_or<int>(gui, "sliderPos", 0);
@ -691,6 +721,7 @@ void save(const std::filesystem::path& path) {
data["General"]["isPS4Pro"] = isNeo;
data["General"]["Fullscreen"] = isFullscreen;
data["General"]["FullscreenMode"] = fullscreenMode;
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled;
data["General"]["playBGM"] = playBGM;
data["General"]["BGMvolume"] = BGMvolume;
@ -709,6 +740,7 @@ void save(const std::filesystem::path& path) {
data["Input"]["backButtonBehavior"] = backButtonBehavior;
data["Input"]["useSpecialPad"] = useSpecialPad;
data["Input"]["specialPadClass"] = specialPadClass;
data["Input"]["isMotionControlsEnabled"] = isMotionControlsEnabled;
data["GPU"]["screenWidth"] = screenWidth;
data["GPU"]["screenHeight"] = screenHeight;
data["GPU"]["nullGpu"] = isNullGpu;
@ -733,6 +765,7 @@ void save(const std::filesystem::path& path) {
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
}
data["GUI"]["installDirs"] = install_dirs;
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
data["GUI"]["addonInstallDir"] =
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};

View File

@ -17,9 +17,11 @@ void saveMainWindow(const std::filesystem::path& path);
std::string getTrophyKey();
void setTrophyKey(std::string key);
bool isNeoMode();
bool isFullscreenMode();
bool GetLoadGameSizeEnabled();
void setLoadGameSizeEnabled(bool enable);
bool getIsFullscreen();
std::string getFullscreenMode();
bool isNeoModeConsole();
bool getPlayBGM();
int getBGMvolume();
bool getisTrophyPopupDisabled();
@ -38,6 +40,7 @@ int getCursorHideTimeout();
std::string getBackButtonBehavior();
bool getUseSpecialPad();
int getSpecialPadClass();
bool getIsMotionControlsEnabled();
u32 getScreenWidth();
u32 getScreenHeight();
@ -65,7 +68,8 @@ void setVblankDiv(u32 value);
void setGpuId(s32 selectedGpuId);
void setScreenWidth(u32 width);
void setScreenHeight(u32 height);
void setFullscreenMode(bool enable);
void setIsFullscreen(bool enable);
void setFullscreenMode(std::string mode);
void setisTrophyPopupDisabled(bool disable);
void setPlayBGM(bool enable);
void setBGMvolume(int volume);
@ -84,6 +88,7 @@ void setCursorHideTimeout(int newcursorHideTimeout);
void setBackButtonBehavior(const std::string& type);
void setUseSpecialPad(bool use);
void setSpecialPadClass(int type);
void setIsMotionControlsEnabled(bool use);
void setLogType(const std::string& type);
void setLogFilter(const std::string& type);

View File

@ -7,6 +7,7 @@
#include <string_view>
#include "assert.h"
#include "bit_field.h"
#include "singleton.h"
#include "types.h"
@ -16,6 +17,46 @@ class Emulator;
namespace Common {
union PSFAttributes {
/// Supports initial user's logout
BitField<0, 1, u32> support_initial_user_logout;
/// Enter button for the common dialog is cross.
BitField<1, 1, u32> enter_button_cross;
/// Warning dialog for PS Move is displayed in the options menu.
BitField<2, 1, u32> ps_move_warning;
/// Supports stereoscopic 3D.
BitField<3, 1, u32> support_stereoscopic_3d;
/// Suspends when PS button is pressed.
BitField<4, 1, u32> ps_button_suspend;
/// Enter button for the common dialog is assigned by the system software.
BitField<5, 1, u32> enter_button_system;
/// Overrides share menu behavior.
BitField<6, 1, u32> override_share_menu;
/// Suspends when PS button is pressed and special output resolution is set.
BitField<8, 1, u32> special_res_ps_button_suspend;
/// Enable HDCP.
BitField<9, 1, u32> enable_hdcp;
/// Disable HDCP for non-game.
BitField<10, 1, u32> disable_hdcp_non_game;
/// Supports PS VR.
BitField<14, 1, u32> support_ps_vr;
/// CPU mode (6 CPU)
BitField<15, 1, u32> six_cpu_mode;
/// CPU mode (7 CPU)
BitField<16, 1, u32> seven_cpu_mode;
/// Supports PS4 Pro (Neo) mode.
BitField<23, 1, u32> support_neo_mode;
/// Requires PS VR.
BitField<26, 1, u32> require_ps_vr;
/// Supports HDR.
BitField<29, 1, u32> support_hdr;
/// Display location.
BitField<31, 1, u32> display_location;
u32 raw{};
};
static_assert(sizeof(PSFAttributes) == 4);
class ElfInfo {
friend class Core::Emulator;
@ -26,6 +67,7 @@ class ElfInfo {
std::string app_ver{};
u32 firmware_ver = 0;
u32 raw_firmware_ver = 0;
PSFAttributes psf_attributes{};
public:
static constexpr u32 FW_15 = 0x1500000;
@ -68,6 +110,11 @@ public:
ASSERT(initialized);
return raw_firmware_ver;
}
[[nodiscard]] const PSFAttributes& GetPSFAttributes() const {
ASSERT(initialized);
return psf_attributes;
}
};
} // namespace Common

View File

@ -95,9 +95,12 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, SaveData) \
SUB(Lib, SaveDataDialog) \
SUB(Lib, Http) \
SUB(Lib, Http2) \
SUB(Lib, Ssl) \
SUB(Lib, Ssl2) \
SUB(Lib, SysModule) \
SUB(Lib, Move) \
SUB(Lib, NpCommon) \
SUB(Lib, NpManager) \
SUB(Lib, NpScore) \
SUB(Lib, NpTrophy) \
@ -126,6 +129,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, Vdec2) \
SUB(Lib, Videodec) \
SUB(Lib, RazorCpu) \
SUB(Lib, Mouse) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Vulkan) \

View File

@ -63,8 +63,11 @@ enum class Class : u8 {
Lib_SaveData, ///< The LibSceSaveData implementation.
Lib_SaveDataDialog, ///< The LibSceSaveDataDialog implementation.
Lib_Ssl, ///< The LibSceSsl implementation.
Lib_Ssl2, ///< The LibSceSsl2 implementation.
Lib_Http, ///< The LibSceHttp implementation.
Lib_Http2, ///< The LibSceHttp2 implementation.
Lib_SysModule, ///< The LibSceSysModule implementation
Lib_NpCommon, ///< The LibSceNpCommon implementation
Lib_NpManager, ///< The LibSceNpManager implementation
Lib_NpScore, ///< The LibSceNpScore implementation
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
@ -93,6 +96,7 @@ enum class Class : u8 {
Lib_Vdec2, ///< The LibSceVideodec2 implementation.
Lib_Videodec, ///< The LibSceVideodec implementation.
Lib_RazorCpu, ///< The LibRazorCpu implementation.
Lib_Mouse, ///< The LibSceMouse implementation
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend

View File

@ -66,7 +66,7 @@ void RegPopup::DrawColorBuffer(const AmdGpu::Liverpool::ColorBuffer& buffer) {
"GetColorSliceSize()", buffer.GetColorSliceSize(),
"GetTilingMode()", buffer.GetTilingMode(),
"IsTiled()", buffer.IsTiled(),
"NumFormat()", buffer.NumFormat()
"NumFormat()", buffer.GetNumberFmt()
);
// clang-format on

View File

@ -40,7 +40,8 @@ void MntPoints::UnmountAll() {
m_mnt_pairs.clear();
}
std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_read_only) {
std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_read_only,
bool force_base_path) {
// Evil games like Turok2 pass double slashes e.g /app0//game.kpf
std::string corrected_path(path);
size_t pos = corrected_path.find("//");
@ -72,7 +73,7 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea
patch_path /= rel_path;
if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) &&
std::filesystem::exists(patch_path)) {
!force_base_path && std::filesystem::exists(patch_path)) {
return patch_path;
}
@ -132,9 +133,11 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea
return std::optional<std::filesystem::path>(current_path);
};
if (!force_base_path) {
if (const auto path = search(patch_path)) {
return *path;
}
}
if (const auto path = search(host_path)) {
return *path;
}
@ -144,6 +147,39 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea
return host_path;
}
// TODO: Does not handle mount points inside mount points.
void MntPoints::IterateDirectory(std::string_view guest_directory,
const IterateDirectoryCallback& callback) {
const auto base_path = GetHostPath(guest_directory, nullptr, true);
const auto patch_path = GetHostPath(guest_directory, nullptr, false);
// Only need to consider patch path if it exists and does not resolve to the same as base.
const auto apply_patch = base_path != patch_path && std::filesystem::exists(patch_path);
// Pass 1: Any files that existed in the base directory, using patch directory if needed.
if (std::filesystem::exists(base_path)) {
for (const auto& entry : std::filesystem::directory_iterator(base_path)) {
if (apply_patch) {
const auto patch_entry_path = patch_path / entry.path().filename();
if (std::filesystem::exists(patch_entry_path)) {
callback(patch_entry_path, !std::filesystem::is_directory(patch_entry_path));
continue;
}
}
callback(entry.path(), !entry.is_directory());
}
}
// Pass 2: Any files that exist only in the patch directory.
if (apply_patch) {
for (const auto& entry : std::filesystem::directory_iterator(patch_path)) {
const auto base_entry_path = base_path / entry.path().filename();
if (!std::filesystem::exists(base_entry_path)) {
callback(entry.path(), !entry.is_directory());
}
}
}
}
int HandleTable::CreateHandle() {
std::scoped_lock lock{m_mutex};

View File

@ -36,7 +36,11 @@ public:
void UnmountAll();
std::filesystem::path GetHostPath(std::string_view guest_directory,
bool* is_read_only = nullptr);
bool* is_read_only = nullptr, bool force_base_path = false);
using IterateDirectoryCallback =
std::function<void(const std::filesystem::path& host_path, bool is_file)>;
void IterateDirectory(std::string_view guest_directory,
const IterateDirectoryCallback& callback);
const MntPair* GetMountFromHostPath(const std::string& host_path) {
std::scoped_lock lock{m_mutex};

View File

@ -3,13 +3,13 @@
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <stop_token>
#include <thread>
#include <magic_enum/magic_enum.hpp>
#include "common/assert.h"
#include "common/config.h"
#include "common/logging/log.h"
#include "common/polyfill_thread.h"
#include "common/thread.h"
#include "core/libraries/audio/audioout.h"
#include "core/libraries/audio/audioout_backend.h"
@ -18,7 +18,7 @@
namespace Libraries::AudioOut {
std::shared_mutex ports_mutex;
std::mutex port_open_mutex{};
std::array<PortOut, SCE_AUDIO_OUT_NUM_PORTS> ports_out{};
static std::unique_ptr<AudioOutBackend> audio;
@ -93,17 +93,20 @@ int PS4_SYSV_ABI sceAudioOutClose(s32 handle) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
std::scoped_lock lock(ports_mutex);
std::unique_lock open_lock{port_open_mutex};
auto& port = ports_out.at(handle - 1);
if (!port.impl) {
{
std::unique_lock lock{port.mutex};
if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
port.output_thread.Stop();
std::free(port.output_buffer);
port.output_buffer = nullptr;
port.output_ready = false;
port.impl = nullptr;
}
// Stop outside of port lock scope to prevent deadlocks.
port.output_thread.Stop();
return ORBIS_OK;
}
@ -172,15 +175,12 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
std::scoped_lock lock(ports_mutex);
const auto& port = ports_out.at(handle - 1);
if (!port.impl) {
auto& port = ports_out.at(handle - 1);
{
std::unique_lock lock{port.mutex};
if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
state->rerouteCounter = 0;
state->volume = 127;
switch (port.type) {
case OrbisAudioOutPort::Main:
case OrbisAudioOutPort::Bgm:
@ -200,7 +200,9 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
default:
UNREACHABLE();
}
state->rerouteCounter = 0;
state->volume = 127;
}
return ORBIS_OK;
}
@ -279,15 +281,16 @@ static void AudioOutputThread(PortOut* port, const std::stop_token& stop) {
while (true) {
timer.Start();
{
std::unique_lock lock{port->output_mutex};
Common::CondvarWait(port->output_cv, lock, stop, [&] { return port->output_ready; });
if (stop.stop_requested()) {
break;
}
std::unique_lock lock{port->mutex};
if (port->output_cv.wait(lock, stop, [&] { return port->output_ready; })) {
port->impl->Output(port->output_buffer);
port->output_ready = false;
}
}
port->output_cv.notify_one();
if (stop.stop_requested()) {
break;
}
timer.End();
}
}
@ -332,14 +335,17 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT;
}
std::scoped_lock lock{ports_mutex};
std::unique_lock open_lock{port_open_mutex};
const auto port =
std::ranges::find_if(ports_out, [&](const PortOut& p) { return p.impl == nullptr; });
std::ranges::find_if(ports_out, [&](const PortOut& p) { return !p.IsOpen(); });
if (port == ports_out.end()) {
LOG_ERROR(Lib_AudioOut, "Audio ports are full");
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL;
}
{
std::unique_lock port_lock(port->mutex);
port->type = port_type;
port->format_info = GetFormatInfo(format);
port->sample_rate = sample_rate;
@ -352,7 +358,7 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
port->output_ready = false;
port->output_thread.Run(
[port](const std::stop_token& stop) { AudioOutputThread(&*port, stop); });
}
return std::distance(ports_out.begin(), port) + 1;
}
@ -367,14 +373,13 @@ s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, void* ptr) {
}
auto& port = ports_out.at(handle - 1);
if (!port.impl) {
{
std::unique_lock lock{port.mutex};
if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
{
std::unique_lock lock{port.output_mutex};
port.output_cv.wait(lock, [&] { return !port.output_ready; });
if (ptr != nullptr) {
if (ptr != nullptr && port.IsOpen()) {
std::memcpy(port.output_buffer, ptr, port.BufferSize());
port.output_ready = true;
}
@ -488,19 +493,19 @@ s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
std::scoped_lock lock(ports_mutex);
auto& port = ports_out.at(handle - 1);
if (!port.impl) {
{
std::unique_lock lock{port.mutex};
if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
for (int i = 0; i < port.format_info.num_channels; i++, flag >>= 1u) {
if (flag & 0x1u) {
port.volume[i] = vol[i];
}
}
port.impl->SetVolume(port.volume);
}
return ORBIS_OK;
}

View File

@ -3,7 +3,9 @@
#pragma once
#include <condition_variable>
#include <memory>
#include <mutex>
#include "common/bit_field.h"
#include "core/libraries/kernel/threads.h"
@ -74,10 +76,10 @@ struct AudioFormatInfo {
};
struct PortOut {
std::mutex mutex;
std::unique_ptr<PortBackend> impl{};
void* output_buffer;
std::mutex output_mutex;
std::condition_variable_any output_cv;
bool output_ready;
Kernel::Thread output_thread{};
@ -88,6 +90,10 @@ struct PortOut {
u32 buffer_frames;
std::array<s32, 8> volume;
[[nodiscard]] bool IsOpen() const {
return impl != nullptr;
}
[[nodiscard]] u32 BufferSize() const {
return buffer_frames * format_info.FrameSize();
}

View File

@ -14,14 +14,7 @@ namespace Libraries::AudioOut {
class SDLPortBackend : public PortBackend {
public:
explicit SDLPortBackend(const PortOut& port)
: frame_size(port.format_info.FrameSize()), buffer_size(port.BufferSize()) {
// We want the latency for delivering frames out to be as small as possible,
// so set the sample frames hint to the number of frames per buffer.
const auto samples_num_str = std::to_string(port.buffer_frames);
if (!SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, samples_num_str.c_str())) {
LOG_WARNING(Lib_AudioOut, "Failed to set SDL audio sample frames hint to {}: {}",
samples_num_str, SDL_GetError());
}
: frame_size(port.format_info.FrameSize()), guest_buffer_size(port.BufferSize()) {
const SDL_AudioSpec fmt = {
.format = port.format_info.is_float ? SDL_AUDIO_F32LE : SDL_AUDIO_S16LE,
.channels = port.format_info.num_channels,
@ -33,7 +26,7 @@ public:
LOG_ERROR(Lib_AudioOut, "Failed to create SDL audio stream: {}", SDL_GetError());
return;
}
queue_threshold = CalculateQueueThreshold();
CalculateQueueThreshold();
if (!SDL_SetAudioStreamInputChannelMap(stream, port.format_info.channel_layout.data(),
port.format_info.num_channels)) {
LOG_ERROR(Lib_AudioOut, "Failed to configure SDL audio stream channel map: {}",
@ -71,9 +64,9 @@ public:
queue_threshold);
SDL_ClearAudioStream(stream);
// Recalculate the threshold in case this happened because of a device change.
queue_threshold = CalculateQueueThreshold();
CalculateQueueThreshold();
}
if (!SDL_PutAudioStreamData(stream, ptr, static_cast<int>(buffer_size))) {
if (!SDL_PutAudioStreamData(stream, ptr, static_cast<int>(guest_buffer_size))) {
LOG_ERROR(Lib_AudioOut, "Failed to output to SDL audio stream: {}", SDL_GetError());
}
}
@ -91,7 +84,7 @@ public:
}
private:
[[nodiscard]] u32 CalculateQueueThreshold() const {
void CalculateQueueThreshold() {
SDL_AudioSpec discard;
int sdl_buffer_frames;
if (!SDL_GetAudioDeviceFormat(SDL_GetAudioStreamDevice(stream), &discard,
@ -100,13 +93,22 @@ private:
SDL_GetError());
sdl_buffer_frames = 0;
}
return std::max<u32>(buffer_size, sdl_buffer_frames * frame_size) * 4;
const auto sdl_buffer_size = sdl_buffer_frames * frame_size;
const auto new_threshold = std::max(guest_buffer_size, sdl_buffer_size) * 4;
if (host_buffer_size != sdl_buffer_size || queue_threshold != new_threshold) {
host_buffer_size = sdl_buffer_size;
queue_threshold = new_threshold;
LOG_INFO(Lib_AudioOut,
"SDL audio buffers: guest = {} bytes, host = {} bytes, threshold = {} bytes",
guest_buffer_size, host_buffer_size, queue_threshold);
}
}
u32 frame_size;
u32 buffer_size;
u32 queue_threshold;
SDL_AudioStream* stream;
u32 guest_buffer_size;
u32 host_buffer_size{};
u32 queue_threshold{};
SDL_AudioStream* stream{};
};
std::unique_ptr<PortBackend> SDLAudioOut::Open(PortOut& port) {

View File

@ -12,6 +12,7 @@
#include "core/address_space.h"
#include "core/debug_state.h"
#include "core/libraries/gnmdriver/gnm_error.h"
#include "core/libraries/gnmdriver/gnmdriver_init.h"
#include "core/libraries/kernel/orbis_error.h"
#include "core/libraries/kernel/process.h"
#include "core/libraries/libs.h"
@ -54,244 +55,11 @@ enum ShaderStages : u32 {
static constexpr std::array indirect_sgpr_offsets{0u, 0u, 0x4cu, 0u, 0xccu, 0u, 0x14cu};
static constexpr auto HwInitPacketSize = 0x100u;
// clang-format off
static constexpr std::array InitSequence{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1ffu,
0xc0017600u, 0x46u, 0x1ffu,
0xc0017600u, 0x87u, 0x1ffu,
0xc0017600u, 0xc7u, 0x1ffu,
0xc0017600u, 0x107u, 0u,
0xc0017600u, 0x147u, 0x1ffu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6000000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
};
static_assert(InitSequence.size() == 0x73 + 2);
static constexpr std::array InitSequence175{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1ffu,
0xc0017600u, 0x46u, 0x1ffu,
0xc0017600u, 0x87u, 0x1ffu,
0xc0017600u, 0xc7u, 0x1ffu,
0xc0017600u, 0x107u, 0u,
0xc0017600u, 0x147u, 0x1ffu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
};
static_assert(InitSequence175.size() == 0x73 + 2);
static constexpr std::array InitSequence200{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
};
static_assert(InitSequence200.size() == 0x76 + 2);
static constexpr std::array InitSequence350{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
0xc0016900u, 0x2aau, 0xffu,
};
static_assert(InitSequence350.size() == 0x7c + 2);
static constexpr std::array CtxInitSequence{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0002f00u, 1u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0111000u, 0u
};
static_assert(CtxInitSequence.size() == 0x0f);
static constexpr std::array CtxInitSequence400{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0016900u, 0x2aau, 0xffu,
0xc09e1000u,
};
static_assert(CtxInitSequence400.size() == 0x61);
// clang-format on
// Gates use of what appear to be the neo-mode init sequences but with the older
// IA_MULTI_VGT_PARAM register address. No idea what this is for as the ioctl
// that controls it is still a mystery, but leaving the sequences in gated behind
// this flag in case we need it in the future.
static constexpr bool UseNeoCompatSequences = false;
// In case if `submitDone` is issued we need to block submissions until GPU idle
static u32 submission_lock{};
@ -317,6 +85,14 @@ static void WaitGpuIdle() {
cv_lock.wait(lock, [] { return submission_lock == 0; });
}
// Write a special ending NOP packet with N DWs data block
static inline u32* WriteTrailingNop(u32* cmdbuf, u32 data_block_size) {
auto* nop = reinterpret_cast<PM4CmdNop*>(cmdbuf);
nop->header = PM4Type3Header{PM4ItOpcode::Nop, data_block_size - 1};
nop->data_block[0] = 0u; // only one out of `data_block_size` is initialized
return cmdbuf + data_block_size + 1 /* header */;
}
// Write a special ending NOP packet with N DWs data block
template <u32 data_block_size>
static inline u32* WriteTrailingNop(u32* cmdbuf) {
@ -607,10 +383,17 @@ s32 PS4_SYSV_ABI sceGnmDispatchIndirect(u32* cmdbuf, u32 size, u32 data_offset,
return -1;
}
int PS4_SYSV_ABI sceGnmDispatchIndirectOnMec() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
s32 PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(u32* cmdbuf, u32 size, VAddr args, u32 modifier) {
if (cmdbuf != nullptr && size == 8 && args != 0 && ((args & 3u) == 0)) {
cmdbuf[0] = 0xc0021602 | (modifier & 1u);
*(VAddr*)(&cmdbuf[1]) = args;
cmdbuf[3] = (modifier & 0x18) | 1u;
cmdbuf[4] = 0xc0021000;
cmdbuf[5] = 0;
return ORBIS_OK;
}
return ORBIS_FAIL;
}
u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size) {
LOG_TRACE(Lib_GnmDriver, "called");
@ -619,17 +402,30 @@ u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size) {
return 0;
}
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x216u,
cmdbuf = PM4CmdSetData::SetShReg<PM4ShaderType::ShaderCompute>(
cmdbuf, 0x216u,
0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE0
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x217u,
cmdbuf = PM4CmdSetData::SetShReg<PM4ShaderType::ShaderCompute>(
cmdbuf, 0x217u,
0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE1
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x215u, 0x170u); // COMPUTE_RESOURCE_LIMITS
if (sceKernelIsNeoMode()) {
cmdbuf = PM4CmdSetData::SetShReg<PM4ShaderType::ShaderCompute>(
cmdbuf, 0x219u,
0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE2
cmdbuf = PM4CmdSetData::SetShReg<PM4ShaderType::ShaderCompute>(
cmdbuf, 0x21au,
0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE3
}
cmdbuf = PM4CmdSetData::SetShReg<PM4ShaderType::ShaderCompute>(
cmdbuf, 0x215u, 0x170u); // COMPUTE_RESOURCE_LIMITS
cmdbuf = WriteHeader<PM4ItOpcode::AcquireMem>(cmdbuf, 6);
cmdbuf = WriteBody(cmdbuf, 0x28000000u, 0u, 0u, 0u, 0u, 0u);
cmdbuf = WriteBody(cmdbuf, 0x28000000u, 0u, 0u, 0u, 0u, 0xau);
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 0xef);
cmdbuf = WriteBody(cmdbuf, 0xau, 0u);
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, sceKernelIsNeoMode() ? 0xe9 : 0xef);
cmdbuf = WriteBody(cmdbuf, 0u);
return HwInitPacketSize;
}
@ -646,7 +442,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr
draw_index->index_base_lo = u32(index_addr);
draw_index->index_base_hi = u32(index_addr >> 32);
draw_index->index_count = index_count;
draw_index->draw_initiator = 0;
draw_index->draw_initiator = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0;
WriteTrailingNop<3>(cmdbuf + 6);
return ORBIS_OK;
@ -659,8 +455,9 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32
if (cmdbuf && (size == 7) &&
(flags & 0x1ffffffe) == 0) { // no predication will be set in the packet
cmdbuf = WritePacket<PM4ItOpcode::DrawIndexAuto>(cmdbuf, PM4ShaderType::ShaderGraphics,
index_count, 2u);
cmdbuf = WritePacket<PM4ItOpcode::DrawIndexAuto>(
cmdbuf, PM4ShaderType::ShaderGraphics, index_count,
sceKernelIsNeoMode() ? flags & 0xe0000000u | 2u : 2u);
WriteTrailingNop<3>(cmdbuf);
return ORBIS_OK;
}
@ -684,7 +481,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset,
cmdbuf[0] = data_offset;
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
cmdbuf[3] = 0;
cmdbuf[3] = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0u;
cmdbuf += 4;
WriteTrailingNop<3>(cmdbuf);
@ -699,8 +496,9 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 da
u32 flags) {
LOG_TRACE(Lib_GnmDriver, "called");
if (cmdbuf && (size == 16) && (shader_stage < ShaderStages::Max) &&
(vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) {
if ((!sceKernelIsNeoMode() || !UseNeoCompatSequences) && !cmdbuf && (size == 16) &&
(shader_stage < ShaderStages::Max) && (vertex_sgpr_offset < 0x10u) &&
(instance_sgpr_offset < 0x10u)) {
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 2);
cmdbuf = WriteBody(cmdbuf, 0u);
@ -719,7 +517,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 da
cmdbuf[4] = max_count;
*(u64*)(&cmdbuf[5]) = count_addr;
cmdbuf[7] = sizeof(DrawIndexedIndirectArgs);
cmdbuf[8] = 0;
cmdbuf[8] = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0;
cmdbuf += 9;
WriteTrailingNop<2>(cmdbuf);
@ -748,7 +546,8 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset,
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndexOffset2>(
cmdbuf, 4, PM4ShaderType::ShaderGraphics, predicate);
cmdbuf = WriteBody(cmdbuf, index_count, index_offset, index_count, 0u);
cmdbuf = WriteBody(cmdbuf, index_count, index_offset, index_count,
sceKernelIsNeoMode() ? flags & 0xe0000000u : 0u);
WriteTrailingNop<3>(cmdbuf);
return ORBIS_OK;
@ -772,7 +571,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32
cmdbuf[0] = data_offset;
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
cmdbuf[3] = 2; // auto index
cmdbuf[3] = sceKernelIsNeoMode() ? flags & 0xe0000000u | 2u : 2u; // auto index
cmdbuf += 4;
WriteTrailingNop<3>(cmdbuf);
@ -801,6 +600,7 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) {
}
const auto& SetupContext = [](u32* cmdbuf, u32 size, bool clear_state) {
const auto* cmdbuf_end = cmdbuf + HwInitPacketSize;
if (clear_state) {
cmdbuf = ClearContextState(cmdbuf);
}
@ -808,10 +608,8 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) {
std::memcpy(cmdbuf, &InitSequence[2], (InitSequence.size() - 2) * 4);
cmdbuf += InitSequence.size() - 2;
const auto cmdbuf_left =
HwInitPacketSize - (InitSequence.size() - 2) - (clear_state ? 0xc : 0) - 1;
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
cmdbuf = WriteBody(cmdbuf, 0u);
const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1;
WriteTrailingNop(cmdbuf, cmdbuf_left);
return HwInitPacketSize;
};
@ -826,12 +624,13 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) {
return 0;
}
const auto* cmdbuf_end = cmdbuf + HwInitPacketSize;
cmdbuf = ClearContextState(cmdbuf);
std::memcpy(cmdbuf, &InitSequence175[2], (InitSequence175.size() - 2) * 4);
cmdbuf += InitSequence175.size() - 2;
constexpr auto cmdbuf_left = HwInitPacketSize - (InitSequence175.size() - 2) - 0xc - 1;
WriteTrailingNop<cmdbuf_left>(cmdbuf);
const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1;
WriteTrailingNop(cmdbuf, cmdbuf_left);
return HwInitPacketSize;
}
@ -844,17 +643,27 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) {
}
const auto& SetupContext200 = [](u32* cmdbuf, u32 size, bool clear_state) {
const auto* cmdbuf_end = cmdbuf + HwInitPacketSize;
if (clear_state) {
cmdbuf = ClearContextState(cmdbuf);
}
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
std::memcpy(cmdbuf, &InitSequence200Neo[2], (InitSequence200Neo.size() - 2) * 4);
cmdbuf += InitSequence200Neo.size() - 2;
} else {
std::memcpy(cmdbuf, &InitSequence200NeoCompat[2],
(InitSequence200NeoCompat.size() - 2) * 4);
cmdbuf += InitSequence200NeoCompat.size() - 2;
}
} else {
std::memcpy(cmdbuf, &InitSequence200[2], (InitSequence200.size() - 2) * 4);
cmdbuf += InitSequence200.size() - 2;
}
const auto cmdbuf_left =
HwInitPacketSize - (InitSequence200.size() - 2) - (clear_state ? 0xc : 0) - 1;
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
cmdbuf = WriteBody(cmdbuf, 0u);
const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1;
WriteTrailingNop(cmdbuf, cmdbuf_left);
return HwInitPacketSize;
};
@ -870,17 +679,27 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) {
}
const auto& SetupContext350 = [](u32* cmdbuf, u32 size, bool clear_state) {
const auto* cmdbuf_end = cmdbuf + HwInitPacketSize;
if (clear_state) {
cmdbuf = ClearContextState(cmdbuf);
}
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
std::memcpy(cmdbuf, &InitSequence350Neo[2], (InitSequence350Neo.size() - 2) * 4);
cmdbuf += InitSequence350Neo.size() - 2;
} else {
std::memcpy(cmdbuf, &InitSequence350NeoCompat[2],
(InitSequence350NeoCompat.size() - 2) * 4);
cmdbuf += InitSequence350NeoCompat.size() - 2;
}
} else {
std::memcpy(cmdbuf, &InitSequence350[2], (InitSequence350.size() - 2) * 4);
cmdbuf += InitSequence350.size() - 2;
}
const auto cmdbuf_left =
HwInitPacketSize - (InitSequence350.size() - 2) - (clear_state ? 0xc : 0) - 1;
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
cmdbuf = WriteBody(cmdbuf, 0u);
const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1;
WriteTrailingNop(cmdbuf, cmdbuf_left);
return HwInitPacketSize;
};
@ -896,7 +715,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState(u32* cmdbuf, u32 size) {
return 0;
}
if (sceKernelIsNeoMode()) {
std::memcpy(cmdbuf, CtxInitSequenceNeo.data(), CtxInitSequenceNeo.size() * 4);
} else {
std::memcpy(cmdbuf, CtxInitSequence.data(), CtxInitSequence.size() * 4);
}
return CtxInitPacketSize;
}
@ -908,7 +731,16 @@ u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400(u32* cmdbuf, u32 size) {
return 0;
}
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
std::memcpy(cmdbuf, CtxInitSequence400Neo.data(), CtxInitSequence400Neo.size() * 4);
} else {
std::memcpy(cmdbuf, CtxInitSequence400NeoCompat.data(),
CtxInitSequence400NeoCompat.size() * 4);
}
} else {
std::memcpy(cmdbuf, CtxInitSequence400.data(), CtxInitSequence400.size() * 4);
}
return CtxInitPacketSize;
}
@ -1030,7 +862,8 @@ int PS4_SYSV_ABI sceGnmGetGpuBlockStatus() {
u32 PS4_SYSV_ABI sceGnmGetGpuCoreClockFrequency() {
LOG_TRACE(Lib_GnmDriver, "called");
return Config::isNeoMode() ? 911'000'000 : 800'000'000;
// On console this uses an ioctl check, but we assume it is equal to just checking for neo mode.
return sceKernelIsNeoMode() ? 911'000'000 : 800'000'000;
}
int PS4_SYSV_ABI sceGnmGetGpuInfoStatus() {
@ -1369,7 +1202,15 @@ s32 PS4_SYSV_ABI sceGnmResetVgtControl(u32* cmdbuf, u32 size) {
if (cmdbuf == nullptr || size != 3) {
return -1;
}
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
PM4CmdSetData::SetUconfigReg(cmdbuf, 0x40000258u, 0x6d007fu); // IA_MULTI_VGT_PARAM
} else {
PM4CmdSetData::SetContextReg(cmdbuf, 0x100002aau, 0xd00ffu); // IA_MULTI_VGT_PARAM
}
} else {
PM4CmdSetData::SetContextReg(cmdbuf, 0x2aau, 0xffu); // IA_MULTI_VGT_PARAM
}
return ORBIS_OK;
}
@ -1830,9 +1671,25 @@ s32 PS4_SYSV_ABI sceGnmSetVgtControl(u32* cmdbuf, u32 size, u32 prim_group_sz_mi
return -1;
}
if (sceKernelIsNeoMode()) {
const u32 wd_switch_on_eop = u32(wd_switch_only_on_eop_mode != 0) << 0x14;
const u32 switch_on_eoi = u32(wd_switch_only_on_eop_mode == 0) << 0x13;
const u32 reg_value =
wd_switch_only_on_eop_mode != 0
? (partial_vs_wave_mode & 1) << 0x10 | prim_group_sz_minus_one | wd_switch_on_eop |
switch_on_eoi | 0x40000u
: prim_group_sz_minus_one & 0x1cffffu | wd_switch_on_eop | switch_on_eoi | 0x50000u;
if (!UseNeoCompatSequences) {
PM4CmdSetData::SetUconfigReg(cmdbuf, 0x40000258u,
reg_value | 0x600000u); // IA_MULTI_VGT_PARAM
} else {
PM4CmdSetData::SetContextReg(cmdbuf, 0x100002aau, reg_value); // IA_MULTI_VGT_PARAM
}
} else {
const u32 reg_value =
((partial_vs_wave_mode & 1) << 0x10) | (prim_group_sz_minus_one & 0xffffu);
PM4CmdSetData::SetContextReg(cmdbuf, 0x2aau, reg_value); // IA_MULTI_VGT_PARAM
}
return ORBIS_OK;
}
@ -2215,10 +2072,26 @@ int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload(u32 workload, u32 count,
if (sdk_version <= 0x1ffffffu) {
liverpool->SubmitGfx(InitSequence, {});
} else if (sdk_version <= 0x3ffffffu) {
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
liverpool->SubmitGfx(InitSequence200Neo, {});
} else {
liverpool->SubmitGfx(InitSequence200NeoCompat, {});
}
} else {
liverpool->SubmitGfx(InitSequence200, {});
}
} else {
if (sceKernelIsNeoMode()) {
if (!UseNeoCompatSequences) {
liverpool->SubmitGfx(InitSequence350Neo, {});
} else {
liverpool->SubmitGfx(InitSequence350NeoCompat, {});
}
} else {
liverpool->SubmitGfx(InitSequence350, {});
}
}
send_init_packet = false;
}

View File

@ -39,7 +39,7 @@ int PS4_SYSV_ABI sceGnmDisableMipStatsReport();
s32 PS4_SYSV_ABI sceGnmDispatchDirect(u32* cmdbuf, u32 size, u32 threads_x, u32 threads_y,
u32 threads_z, u32 flags);
s32 PS4_SYSV_ABI sceGnmDispatchIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 flags);
int PS4_SYSV_ABI sceGnmDispatchIndirectOnMec();
s32 PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(u32* cmdbuf, u32 size, VAddr args, u32 modifier);
u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size);
s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr_t index_addr,
u32 flags, u32 type);

View File

@ -0,0 +1,542 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
namespace Libraries::GnmDriver {
constexpr auto HwInitPacketSize = 0x100u;
// clang-format off
constexpr std::array InitSequence{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1ffu,
0xc0017600u, 0x46u, 0x1ffu,
0xc0017600u, 0x87u, 0x1ffu,
0xc0017600u, 0xc7u, 0x1ffu,
0xc0017600u, 0x107u, 0u,
0xc0017600u, 0x147u, 0x1ffu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6000000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
};
static_assert(InitSequence.size() == 0x73 + 2);
constexpr std::array InitSequence175{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1ffu,
0xc0017600u, 0x46u, 0x1ffu,
0xc0017600u, 0x87u, 0x1ffu,
0xc0017600u, 0xc7u, 0x1ffu,
0xc0017600u, 0x107u, 0u,
0xc0017600u, 0x147u, 0x1ffu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
};
static_assert(InitSequence175.size() == 0x73 + 2);
constexpr std::array InitSequence200{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
};
static_assert(InitSequence200.size() == 0x76 + 2);
constexpr std::array InitSequence200Neo{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x219u, 0xffffffffu,
0xc0017600u, 0x21au, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
0xc0017900u, 0x40000258u, 0x6d007fu,
};
static_assert(InitSequence200Neo.size() == 0x83 + 2);
constexpr std::array InitSequence200NeoCompat{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x219u, 0xffffffffu,
0xc0017600u, 0x21au, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
0xc0016900u, 0x100002aau, 0xd00ffu,
};
static_assert(InitSequence200NeoCompat.size() == 0x83 + 2);
constexpr std::array InitSequence350{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
0xc0016900u, 0x2aau, 0xffu,
};
static_assert(InitSequence350.size() == 0x7c + 2);
constexpr std::array InitSequence350Neo{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x219u, 0xffffffffu,
0xc0017600u, 0x21au, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
0xc0017900u, 0x40000258u, 0x6d007fu,
};
static_assert(InitSequence350Neo.size() == 0x86 + 2);
constexpr std::array InitSequence350NeoCompat{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x219u, 0xffffffffu,
0xc0017600u, 0x21au, 0xffffffffu,
0xc0017600u, 0x215u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0017600u, 7u, 0x1701ffu,
0xc0017600u, 0x46u, 0x1701fdu,
0xc0017600u, 0x87u, 0x1701ffu,
0xc0017600u, 0xc7u, 0x1701fdu,
0xc0017600u, 0x107u, 0x17u,
0xc0017600u, 0x147u, 0x1701fdu,
0xc0017600u, 0x47u, 0x1cu,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u,
0xc0016900u, 0x100002aau, 0xd00ffu,
};
static_assert(InitSequence350NeoCompat.size() == 0x86 + 2);
constexpr std::array CtxInitSequence{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0002f00u, 1u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0111000u, 0u
};
static_assert(CtxInitSequence.size() == 0x0f);
constexpr std::array CtxInitSequenceNeo{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0002f00u, 1u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc00d1000, 0u
};
static_assert(CtxInitSequenceNeo.size() == 0x13);
constexpr std::array CtxInitSequence400{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0016900u, 0x2aau, 0xffu,
0xc09e1000u,
};
static_assert(CtxInitSequence400.size() == 0x61);
constexpr std::array CtxInitSequence400Neo{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x40000258u, 0x6d007fu,
0xc09a1000u,
};
static_assert(CtxInitSequence400Neo.size() == 0x65);
constexpr std::array CtxInitSequence400NeoCompat{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0016900u, 0x100002aau, 0xd00ffu,
0xc09a1000u,
};
static_assert(CtxInitSequence400Neo.size() == 0x65);
// clang-format on
} // namespace Libraries::GnmDriver

View File

@ -46,17 +46,6 @@ static std::map<std::string, FactoryDevice> available_device = {
namespace Libraries::Kernel {
auto GetDirectoryEntries(const std::filesystem::path& path) {
std::vector<Core::FileSys::DirEntry> files;
for (const auto& entry : std::filesystem::directory_iterator(path)) {
auto& dir_entry = files.emplace_back();
dir_entry.name = entry.path().filename().string();
dir_entry.isFile = !std::filesystem::is_directory(entry.path().string());
}
return files;
}
int PS4_SYSV_ABI sceKernelOpen(const char* raw_path, int flags, u16 mode) {
LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {}", raw_path, flags, mode);
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
@ -115,7 +104,12 @@ int PS4_SYSV_ABI sceKernelOpen(const char* raw_path, int flags, u16 mode) {
if (create) {
return handle; // dir already exists
} else {
file->dirents = GetDirectoryEntries(file->m_host_name);
mnt->IterateDirectory(file->m_guest_name,
[&file](const auto& ent_path, const auto ent_is_file) {
auto& dir_entry = file->dirents.emplace_back();
dir_entry.name = ent_path.filename().string();
dir_entry.isFile = ent_is_file;
});
file->dirents_index = 0;
}
}
@ -695,66 +689,12 @@ static int GetDents(int fd, char* buf, int nbytes, s64* basep) {
return sizeof(OrbisKernelDirent);
}
static int HandleSeparateUpdateDents(int fd, char* buf, int nbytes, s64* basep) {
int dir_entries = 0;
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
auto* file = h->GetFile(fd);
auto update_dir_name = std::string{fmt::UTF(file->m_host_name.u8string()).data};
auto mount = mnt->GetMountFromHostPath(update_dir_name);
auto suffix = std::string{fmt::UTF(mount->host_path.u8string()).data};
size_t pos = update_dir_name.find("-UPDATE");
if (pos != std::string::npos) {
update_dir_name.erase(pos, 7);
auto guest_name = mount->mount + "/" + update_dir_name.substr(suffix.size() + 1);
int descriptor;
auto existent_folder = h->GetFile(update_dir_name);
if (!existent_folder) {
u32 handle = h->CreateHandle();
auto* new_file = h->GetFile(handle);
new_file->type = Core::FileSys::FileType::Directory;
new_file->m_guest_name = guest_name;
new_file->m_host_name = update_dir_name;
if (!std::filesystem::is_directory(new_file->m_host_name)) {
h->DeleteHandle(handle);
return dir_entries;
} else {
new_file->dirents = GetDirectoryEntries(new_file->m_host_name);
new_file->dirents_index = 0;
}
new_file->is_opened = true;
descriptor = h->GetFileDescriptor(new_file);
} else {
descriptor = h->GetFileDescriptor(existent_folder);
}
dir_entries = GetDents(descriptor, buf, nbytes, basep);
if (dir_entries == ORBIS_OK && existent_folder) {
existent_folder->dirents_index = 0;
file->dirents_index = 0;
}
}
return dir_entries;
}
int PS4_SYSV_ABI sceKernelGetdents(int fd, char* buf, int nbytes) {
int a = GetDents(fd, buf, nbytes, nullptr);
if (a == ORBIS_OK) {
return HandleSeparateUpdateDents(fd, buf, nbytes, nullptr);
}
return a;
return GetDents(fd, buf, nbytes, nullptr);
}
int PS4_SYSV_ABI sceKernelGetdirentries(int fd, char* buf, int nbytes, s64* basep) {
int a = GetDents(fd, buf, nbytes, basep);
if (a == ORBIS_OK) {
return HandleSeparateUpdateDents(fd, buf, nbytes, basep);
}
return a;
return GetDents(fd, buf, nbytes, basep);
}
s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) {

View File

@ -505,13 +505,13 @@ int PS4_SYSV_ABI posix_munmap(void* addr, size_t len) {
return result;
}
static constexpr int MAX_PTR_APERTURES = 3;
static constexpr int MAX_PRT_APERTURES = 3;
static constexpr VAddr PRT_AREA_START_ADDR = 0x1000000000;
static constexpr size_t PRT_AREA_SIZE = 0xec00000000;
static std::array<std::pair<VAddr, size_t>, MAX_PTR_APERTURES> PrtApertures{};
static std::array<std::pair<VAddr, size_t>, MAX_PRT_APERTURES> PrtApertures{};
int PS4_SYSV_ABI sceKernelSetPrtAperture(int id, VAddr address, size_t size) {
if (id < 0 || id >= MAX_PTR_APERTURES) {
if (id < 0 || id >= MAX_PRT_APERTURES) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
@ -531,12 +531,12 @@ int PS4_SYSV_ABI sceKernelSetPrtAperture(int id, VAddr address, size_t size) {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelGetPrtAperture(int id, VAddr* addres, size_t* size) {
if (id < 0 || id >= MAX_PTR_APERTURES) {
int PS4_SYSV_ABI sceKernelGetPrtAperture(int id, VAddr* address, size_t* size) {
if (id < 0 || id >= MAX_PRT_APERTURES) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
std::tie(*addres, *size) = PrtApertures[id];
std::tie(*address, *size) = PrtApertures[id];
return ORBIS_OK;
}

View File

@ -14,7 +14,8 @@ namespace Libraries::Kernel {
int PS4_SYSV_ABI sceKernelIsNeoMode() {
LOG_DEBUG(Kernel_Sce, "called");
return Config::isNeoMode();
return Config::isNeoModeConsole() &&
Common::ElfInfo::Instance().GetPSFAttributes().support_neo_mode;
}
int PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(int* ver) {

View File

@ -55,6 +55,9 @@ public:
stop.request_stop();
Join();
}
thread = nullptr;
func = nullptr;
stop = std::stop_source{};
}
static void* PS4_SYSV_ABI RunWrapper(void* arg) {

View File

@ -386,6 +386,9 @@ int PS4_SYSV_ABI posix_sched_get_priority_min() {
}
int PS4_SYSV_ABI posix_pthread_rename_np(PthreadT thread, const char* name) {
if (thread == nullptr) {
return POSIX_EINVAL;
}
LOG_INFO(Kernel_Pthread, "name = {}", name);
Common::SetThreadName(reinterpret_cast<void*>(thread->native_thr.GetHandle()), name);
thread->name = name;

View File

@ -18,11 +18,15 @@
#include "core/libraries/libc_internal/libc_internal.h"
#include "core/libraries/libpng/pngdec.h"
#include "core/libraries/libs.h"
#include "core/libraries/mouse/mouse.h"
#include "core/libraries/move/move.h"
#include "core/libraries/network/http.h"
#include "core/libraries/network/http2.h"
#include "core/libraries/network/net.h"
#include "core/libraries/network/netctl.h"
#include "core/libraries/network/ssl.h"
#include "core/libraries/network/ssl2.h"
#include "core/libraries/np_common/np_common.h"
#include "core/libraries/np_manager/np_manager.h"
#include "core/libraries/np_score/np_score.h"
#include "core/libraries/np_trophy/np_trophy.h"
@ -47,6 +51,8 @@
#include "core/libraries/videodec/videodec.h"
#include "core/libraries/videodec/videodec2.h"
#include "core/libraries/videoout/video_out.h"
#include "fiber/fiber.h"
#include "jpeg/jpegenc.h"
namespace Libraries {
@ -61,14 +67,17 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::MsgDialog::RegisterlibSceMsgDialog(sym);
Libraries::AudioOut::RegisterlibSceAudioOut(sym);
Libraries::Http::RegisterlibSceHttp(sym);
Libraries::Http2::RegisterlibSceHttp2(sym);
Libraries::Net::RegisterlibSceNet(sym);
Libraries::NetCtl::RegisterlibSceNetCtl(sym);
Libraries::SaveData::RegisterlibSceSaveData(sym);
Libraries::SaveData::Dialog::RegisterlibSceSaveDataDialog(sym);
Libraries::Ssl::RegisterlibSceSsl(sym);
Libraries::Ssl2::RegisterlibSceSsl2(sym);
Libraries::SysModule::RegisterlibSceSysmodule(sym);
Libraries::Posix::Registerlibsceposix(sym);
Libraries::AudioIn::RegisterlibSceAudioIn(sym);
Libraries::NpCommon::RegisterlibSceNpCommon(sym);
Libraries::NpManager::RegisterlibSceNpManager(sym);
Libraries::NpScore::RegisterlibSceNpScore(sym);
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
@ -93,6 +102,9 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::Videodec::RegisterlibSceVideodec(sym);
Libraries::RazorCpu::RegisterlibSceRazorCpu(sym);
Libraries::Move::RegisterlibSceMove(sym);
Libraries::Fiber::RegisterlibSceFiber(sym);
Libraries::JpegEnc::RegisterlibSceJpegEnc(sym);
Libraries::Mouse::RegisterlibSceMouse(sym);
}
} // namespace Libraries

View File

@ -0,0 +1,99 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// Generated By moduleGenerator
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "mouse.h"
namespace Libraries::Mouse {
int PS4_SYSV_ABI sceMouseClose() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseConnectPort() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseDebugGetDeviceId() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseDeviceOpen() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseDisconnectDevice() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseDisconnectPort() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseGetDeviceInfo() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseInit() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseMbusInit() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseOpen() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseRead() {
LOG_DEBUG(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseSetHandType() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseSetPointerSpeed() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMouseSetProcessPrivilege() {
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
return ORBIS_OK;
}
void RegisterlibSceMouse(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("cAnT0Rw-IwU", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseClose);
LIB_FUNCTION("Ymyy1HSSJLQ", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseConnectPort);
LIB_FUNCTION("BRXOoXQtb+k", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDebugGetDeviceId);
LIB_FUNCTION("WiGKINCZWkc", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDeviceOpen);
LIB_FUNCTION("eDQTFHbgeTU", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDisconnectDevice);
LIB_FUNCTION("jJP1vYMEPd4", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDisconnectPort);
LIB_FUNCTION("QA9Qupz3Zjw", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseGetDeviceInfo);
LIB_FUNCTION("Qs0wWulgl7U", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseInit);
LIB_FUNCTION("1FeceR5YhAo", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseMbusInit);
LIB_FUNCTION("RaqxZIf6DvE", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseOpen);
LIB_FUNCTION("x8qnXqh-tiM", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseRead);
LIB_FUNCTION("crkFfp-cmFo", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseSetHandType);
LIB_FUNCTION("ghLUU2Z5Lcg", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseSetPointerSpeed);
LIB_FUNCTION("6aANndpS0Wo", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseSetProcessPrivilege);
};
} // namespace Libraries::Mouse

View File

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Mouse {
int PS4_SYSV_ABI sceMouseClose();
int PS4_SYSV_ABI sceMouseConnectPort();
int PS4_SYSV_ABI sceMouseDebugGetDeviceId();
int PS4_SYSV_ABI sceMouseDeviceOpen();
int PS4_SYSV_ABI sceMouseDisconnectDevice();
int PS4_SYSV_ABI sceMouseDisconnectPort();
int PS4_SYSV_ABI sceMouseGetDeviceInfo();
int PS4_SYSV_ABI sceMouseInit();
int PS4_SYSV_ABI sceMouseMbusInit();
int PS4_SYSV_ABI sceMouseOpen();
int PS4_SYSV_ABI sceMouseRead();
int PS4_SYSV_ABI sceMouseSetHandType();
int PS4_SYSV_ABI sceMouseSetPointerSpeed();
int PS4_SYSV_ABI sceMouseSetProcessPrivilege();
void RegisterlibSceMouse(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Mouse

View File

@ -0,0 +1,360 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "core/libraries/network/http2.h"
namespace Libraries::Http2 {
int PS4_SYSV_ABI _Z5dummyv() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2AbortRequest() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2AddCookie() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2AddRequestHeader() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2AuthCacheFlush() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2CookieExport() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2CookieFlush() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2CookieImport() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2CreateCookieBox() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2CreateRequestWithURL() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2CreateTemplate() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2DeleteCookieBox() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2DeleteRequest() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2DeleteTemplate() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetAllResponseHeaders() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetAuthEnabled() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetAutoRedirect() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetCookie() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetCookieBox() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetCookieStats() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetMemoryPoolStats() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetResponseContentLength() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2GetStatusCode() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2Init(int net_id, int ssl_id, size_t pool_size, int max_requests) {
LOG_ERROR(Lib_Http2, "(DUMMY) called");
static int id = 0;
return ++id;
}
int PS4_SYSV_ABI sceHttp2ReadData() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2ReadDataAsync() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2RedirectCacheFlush() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2RemoveRequestHeader() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SendRequest() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SendRequestAsync() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetAuthEnabled() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetAuthInfoCallback() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetAutoRedirect() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetConnectionWaitTimeOut() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetConnectTimeOut() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetCookieBox() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetCookieMaxNum() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetCookieMaxNumPerDomain() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetCookieMaxSize() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetCookieRecvCallback() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetCookieSendCallback() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetInflateGZIPEnabled() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetMinSslVersion() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetPreSendCallback() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetRecvTimeOut() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetRedirectCallback() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetRequestContentLength() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetResolveRetry() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetResolveTimeOut() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetSendTimeOut() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetSslCallback() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SetTimeOut() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SslDisableOption() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2SslEnableOption() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2Term() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttp2WaitAsync() {
LOG_ERROR(Lib_Http2, "(STUBBED) called");
return ORBIS_OK;
}
void RegisterlibSceHttp2(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("AS45QoYHjc4", "libSceHttp2", 1, "libSceHttp2", 1, 1, _Z5dummyv);
LIB_FUNCTION("IZ-qjhRqvjk", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2AbortRequest);
LIB_FUNCTION("flPxnowtvWY", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2AddCookie);
LIB_FUNCTION("nrPfOE8TQu0", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2AddRequestHeader);
LIB_FUNCTION("WeuDjj5m4YU", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2AuthCacheFlush);
LIB_FUNCTION("JlFGR4v50Kw", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2CookieExport);
LIB_FUNCTION("5VlQSzXW-SQ", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2CookieFlush);
LIB_FUNCTION("B5ibZI5UlzU", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2CookieImport);
LIB_FUNCTION("N4UfjvWJsMw", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2CreateCookieBox);
LIB_FUNCTION("mmyOCxQMVYQ", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2CreateRequestWithURL);
LIB_FUNCTION("+wCt7fCijgk", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2CreateTemplate);
LIB_FUNCTION("O9ync3F-JVI", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2DeleteCookieBox);
LIB_FUNCTION("c8D9qIjo8EY", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2DeleteRequest);
LIB_FUNCTION("pDom5-078DA", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2DeleteTemplate);
LIB_FUNCTION("-rdXUi2XW90", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2GetAllResponseHeaders);
LIB_FUNCTION("m-OL13q8AI8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetAuthEnabled);
LIB_FUNCTION("od5QCZhZSfw", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetAutoRedirect);
LIB_FUNCTION("GQFGj0rYX+A", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetCookie);
LIB_FUNCTION("IX23slKvtQI", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetCookieBox);
LIB_FUNCTION("eij7UzkUqK8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetCookieStats);
LIB_FUNCTION("otUQuZa-mv0", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetMemoryPoolStats);
LIB_FUNCTION("o0DBQpFE13o", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2GetResponseContentLength);
LIB_FUNCTION("9XYJwCf3lEA", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2GetStatusCode);
LIB_FUNCTION("3JCe3lCbQ8A", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2Init);
LIB_FUNCTION("QygCNNmbGss", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2ReadData);
LIB_FUNCTION("bGN-6zbo7ms", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2ReadDataAsync);
LIB_FUNCTION("klwUy2Wg+q8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2RedirectCacheFlush);
LIB_FUNCTION("jHdP0CS4ZlA", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2RemoveRequestHeader);
LIB_FUNCTION("rbqZig38AT8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SendRequest);
LIB_FUNCTION("A+NVAFu4eCg", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SendRequestAsync);
LIB_FUNCTION("jjFahkBPCYs", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetAuthEnabled);
LIB_FUNCTION("Wwj6HbB2mOo", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetAuthInfoCallback);
LIB_FUNCTION("b9AvoIaOuHI", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetAutoRedirect);
LIB_FUNCTION("n8hMLe31OPA", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2SetConnectionWaitTimeOut);
LIB_FUNCTION("-HIO4VT87v8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetConnectTimeOut);
LIB_FUNCTION("jrVHsKCXA0g", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetCookieBox);
LIB_FUNCTION("mPKVhQqh2Es", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetCookieMaxNum);
LIB_FUNCTION("o7+WXe4WadE", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2SetCookieMaxNumPerDomain);
LIB_FUNCTION("6a0N6GPD7RM", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetCookieMaxSize);
LIB_FUNCTION("zdtXKn9X7no", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2SetCookieRecvCallback);
LIB_FUNCTION("McYmUpQ3-DY", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2SetCookieSendCallback);
LIB_FUNCTION("uRosf8GQbHQ", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2SetInflateGZIPEnabled);
LIB_FUNCTION("09tk+kIA1Ns", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetMinSslVersion);
LIB_FUNCTION("UL4Fviw+IAM", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetPreSendCallback);
LIB_FUNCTION("izvHhqgDt44", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetRecvTimeOut);
LIB_FUNCTION("BJgi0CH7al4", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetRedirectCallback);
LIB_FUNCTION("FSAFOzi0FpM", "libSceHttp2", 1, "libSceHttp2", 1, 1,
sceHttp2SetRequestContentLength);
LIB_FUNCTION("Gcjh+CisAZM", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetResolveRetry);
LIB_FUNCTION("ACjtE27aErY", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetResolveTimeOut);
LIB_FUNCTION("XPtW45xiLHk", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetSendTimeOut);
LIB_FUNCTION("YrWX+DhPHQY", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetSslCallback);
LIB_FUNCTION("VYMxTcBqSE0", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SetTimeOut);
LIB_FUNCTION("B37SruheQ5Y", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SslDisableOption);
LIB_FUNCTION("EWcwMpbr5F8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2SslEnableOption);
LIB_FUNCTION("YiBUtz-pGkc", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2Term);
LIB_FUNCTION("MOp-AUhdfi8", "libSceHttp2", 1, "libSceHttp2", 1, 1, sceHttp2WaitAsync);
};
} // namespace Libraries::Http2

View File

@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Http2 {
int PS4_SYSV_ABI _Z5dummyv();
int PS4_SYSV_ABI sceHttp2AbortRequest();
int PS4_SYSV_ABI sceHttp2AddCookie();
int PS4_SYSV_ABI sceHttp2AddRequestHeader();
int PS4_SYSV_ABI sceHttp2AuthCacheFlush();
int PS4_SYSV_ABI sceHttp2CookieExport();
int PS4_SYSV_ABI sceHttp2CookieFlush();
int PS4_SYSV_ABI sceHttp2CookieImport();
int PS4_SYSV_ABI sceHttp2CreateCookieBox();
int PS4_SYSV_ABI sceHttp2CreateRequestWithURL();
int PS4_SYSV_ABI sceHttp2CreateTemplate();
int PS4_SYSV_ABI sceHttp2DeleteCookieBox();
int PS4_SYSV_ABI sceHttp2DeleteRequest();
int PS4_SYSV_ABI sceHttp2DeleteTemplate();
int PS4_SYSV_ABI sceHttp2GetAllResponseHeaders();
int PS4_SYSV_ABI sceHttp2GetAuthEnabled();
int PS4_SYSV_ABI sceHttp2GetAutoRedirect();
int PS4_SYSV_ABI sceHttp2GetCookie();
int PS4_SYSV_ABI sceHttp2GetCookieBox();
int PS4_SYSV_ABI sceHttp2GetCookieStats();
int PS4_SYSV_ABI sceHttp2GetMemoryPoolStats();
int PS4_SYSV_ABI sceHttp2GetResponseContentLength();
int PS4_SYSV_ABI sceHttp2GetStatusCode();
int PS4_SYSV_ABI sceHttp2Init(int net_id, int ssl_id, size_t pool_size, int max_requests);
int PS4_SYSV_ABI sceHttp2ReadData();
int PS4_SYSV_ABI sceHttp2ReadDataAsync();
int PS4_SYSV_ABI sceHttp2RedirectCacheFlush();
int PS4_SYSV_ABI sceHttp2RemoveRequestHeader();
int PS4_SYSV_ABI sceHttp2SendRequest();
int PS4_SYSV_ABI sceHttp2SendRequestAsync();
int PS4_SYSV_ABI sceHttp2SetAuthEnabled();
int PS4_SYSV_ABI sceHttp2SetAuthInfoCallback();
int PS4_SYSV_ABI sceHttp2SetAutoRedirect();
int PS4_SYSV_ABI sceHttp2SetConnectionWaitTimeOut();
int PS4_SYSV_ABI sceHttp2SetConnectTimeOut();
int PS4_SYSV_ABI sceHttp2SetCookieBox();
int PS4_SYSV_ABI sceHttp2SetCookieMaxNum();
int PS4_SYSV_ABI sceHttp2SetCookieMaxNumPerDomain();
int PS4_SYSV_ABI sceHttp2SetCookieMaxSize();
int PS4_SYSV_ABI sceHttp2SetCookieRecvCallback();
int PS4_SYSV_ABI sceHttp2SetCookieSendCallback();
int PS4_SYSV_ABI sceHttp2SetInflateGZIPEnabled();
int PS4_SYSV_ABI sceHttp2SetMinSslVersion();
int PS4_SYSV_ABI sceHttp2SetPreSendCallback();
int PS4_SYSV_ABI sceHttp2SetRecvTimeOut();
int PS4_SYSV_ABI sceHttp2SetRedirectCallback();
int PS4_SYSV_ABI sceHttp2SetRequestContentLength();
int PS4_SYSV_ABI sceHttp2SetResolveRetry();
int PS4_SYSV_ABI sceHttp2SetResolveTimeOut();
int PS4_SYSV_ABI sceHttp2SetSendTimeOut();
int PS4_SYSV_ABI sceHttp2SetSslCallback();
int PS4_SYSV_ABI sceHttp2SetTimeOut();
int PS4_SYSV_ABI sceHttp2SslDisableOption();
int PS4_SYSV_ABI sceHttp2SslEnableOption();
int PS4_SYSV_ABI sceHttp2Term();
int PS4_SYSV_ABI sceHttp2WaitAsync();
void RegisterlibSceHttp2(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Http2

View File

@ -0,0 +1,353 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "core/libraries/network/ssl2.h"
namespace Libraries::Ssl2 {
int PS4_SYSV_ABI CA_MGMT_extractKeyBlobEx() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI CA_MGMT_extractPublicKeyInfo() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI CA_MGMT_freeKeyBlob() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI CRYPTO_initAsymmetricKey() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI CRYPTO_uninitAsymmetricKey() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI RSA_verifySignature() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslCheckRecvPending() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslClose() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslConnect() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslCreateConnection() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslCreateSslConnection() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslDeleteConnection() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslDeleteSslConnection() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslDisableOption() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslDisableOptionInternal() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslDisableOptionInternalInsecure() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslDisableVerifyOption() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslEnableOption() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslEnableOptionInternal() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslEnableVerifyOption() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslFreeCaCerts() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslFreeCaList() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslFreeSslCertName() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetAlpnSelected() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetCaCerts() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetCaList() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetFingerprint() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetIssuerName() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetMemoryPoolStats() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetNameEntryCount() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetNameEntryInfo() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetNanoSSLModuleId() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetNotAfter() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetNotBefore() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetPeerCert() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetPem() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetSerialNumber() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetSslError() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslGetSubjectName() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslInit(std::size_t poolSize) {
LOG_ERROR(Lib_Ssl2, "(DUMMY) called poolSize = {}", poolSize);
// return a value >1
static int id = 0;
return ++id;
}
int PS4_SYSV_ABI sceSslLoadCert() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslLoadRootCACert() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslRead() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslRecv() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslReuseConnection() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslSend() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslSetAlpn() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslSetMinSslVersion() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslSetSslVersion() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslSetVerifyCallback() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslTerm() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslUnloadCert() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSslWrite() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI VLONG_freeVlongQueue() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI Func_22E76E60BC0587D7() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI Func_28F8791A771D39C7() {
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
return ORBIS_OK;
}
void RegisterlibSceSsl2(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("Md+HYkCBZB4", "libSceSsl", 1, "libSceSsl", 2, 1, CA_MGMT_extractKeyBlobEx);
LIB_FUNCTION("9bKYzKP6kYU", "libSceSsl", 1, "libSceSsl", 2, 1, CA_MGMT_extractPublicKeyInfo);
LIB_FUNCTION("ipLIammTj2Q", "libSceSsl", 1, "libSceSsl", 2, 1, CA_MGMT_freeKeyBlob);
LIB_FUNCTION("PRWr3-ytpdg", "libSceSsl", 1, "libSceSsl", 2, 1, CRYPTO_initAsymmetricKey);
LIB_FUNCTION("cW7VCIMCh9A", "libSceSsl", 1, "libSceSsl", 2, 1, CRYPTO_uninitAsymmetricKey);
LIB_FUNCTION("pBwtarKd7eg", "libSceSsl", 1, "libSceSsl", 2, 1, RSA_verifySignature);
LIB_FUNCTION("1VM0h1JrUfA", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslCheckRecvPending);
LIB_FUNCTION("viRXSHZYd0c", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslClose);
LIB_FUNCTION("zXvd6iNyfgc", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslConnect);
LIB_FUNCTION("tuscfitnhEo", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslCreateConnection);
LIB_FUNCTION("P14ATpXc4J8", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslCreateSslConnection);
LIB_FUNCTION("HJ1n138CQ2g", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslDeleteConnection);
LIB_FUNCTION("hwrHV6Pprk4", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslDeleteSslConnection);
LIB_FUNCTION("iLKz4+ukLqk", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslDisableOption);
LIB_FUNCTION("-WqxBRAUVM4", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslDisableOptionInternal);
LIB_FUNCTION("w1+L-27nYas", "libSceSsl", 1, "libSceSsl", 2, 1,
sceSslDisableOptionInternalInsecure);
LIB_FUNCTION("PwsHbErG+e8", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslDisableVerifyOption);
LIB_FUNCTION("m-zPyAsIpco", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslEnableOption);
LIB_FUNCTION("g-zCwUKstEQ", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslEnableOptionInternal);
LIB_FUNCTION("po1X86mgHDU", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslEnableVerifyOption);
LIB_FUNCTION("qIvLs0gYxi0", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslFreeCaCerts);
LIB_FUNCTION("+DzXseDVkeI", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslFreeCaList);
LIB_FUNCTION("RwXD8grHZHM", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslFreeSslCertName);
LIB_FUNCTION("4O7+bRkRUe8", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetAlpnSelected);
LIB_FUNCTION("TDfQqO-gMbY", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetCaCerts);
LIB_FUNCTION("qOn+wm28wmA", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetCaList);
LIB_FUNCTION("brRtwGBu4A8", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetFingerprint);
LIB_FUNCTION("7whYpYfHP74", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetIssuerName);
LIB_FUNCTION("-PoIzr3PEk0", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetMemoryPoolStats);
LIB_FUNCTION("R1ePzopYPYM", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetNameEntryCount);
LIB_FUNCTION("7RBSTKGrmDA", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetNameEntryInfo);
LIB_FUNCTION("AzUipl-DpIw", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetNanoSSLModuleId);
LIB_FUNCTION("xHpt6+2pGYk", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetNotAfter);
LIB_FUNCTION("Eo0S65Jy28Q", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetNotBefore);
LIB_FUNCTION("-TbZc8pwPNc", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetPeerCert);
LIB_FUNCTION("kLB5aGoUJXg", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetPem);
LIB_FUNCTION("DOwXL+FQMEY", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetSerialNumber);
LIB_FUNCTION("0XcZknp7-Wc", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetSslError);
LIB_FUNCTION("dQReuBX9sD8", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslGetSubjectName);
LIB_FUNCTION("hdpVEUDFW3s", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslInit);
LIB_FUNCTION("Ab7+DH+gYyM", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslLoadCert);
LIB_FUNCTION("3-643mGVFJo", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslLoadRootCACert);
LIB_FUNCTION("jltWpVKtetg", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslRead);
LIB_FUNCTION("hi0veU3L2pU", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslRecv);
LIB_FUNCTION("50R2xYaYZwE", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslReuseConnection);
LIB_FUNCTION("p5bM5PPufFY", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslSend);
LIB_FUNCTION("TL86glUrmUw", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslSetAlpn);
LIB_FUNCTION("QWSxBzf6lAg", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslSetMinSslVersion);
LIB_FUNCTION("bKaEtQnoUuQ", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslSetSslVersion);
LIB_FUNCTION("E4a-ahM57QQ", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslSetVerifyCallback);
LIB_FUNCTION("0K1yQ6Lv-Yc", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslTerm);
LIB_FUNCTION("UQ+3Qu7v3cA", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslUnloadCert);
LIB_FUNCTION("iNjkt9Poblw", "libSceSsl", 1, "libSceSsl", 2, 1, sceSslWrite);
LIB_FUNCTION("wcVuyTUr5ys", "libSceSsl", 1, "libSceSsl", 2, 1, VLONG_freeVlongQueue);
LIB_FUNCTION("IuduYLwFh9c", "libSceSsl", 1, "libSceSsl", 2, 1, Func_22E76E60BC0587D7);
LIB_FUNCTION("KPh5GncdOcc", "libSceSsl", 1, "libSceSsl", 2, 1, Func_28F8791A771D39C7);
};
} // namespace Libraries::Ssl2

View File

@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Ssl2 {
void RegisterlibSceSsl2(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Ssl2

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/libraries/error_codes.h"
constexpr int ORBIS_NP_ERROR_INVALID_ARGUMENT = 0x80550003;
constexpr int ORBIS_NP_UTIL_ERROR_NOT_MATCH = 0x80550609;

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/config.h"
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
@ -972,11 +971,8 @@ int PS4_SYSV_ABI sceNpGetGamePresenceStatusA() {
}
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id) {
LOG_INFO(Lib_NpManager, "user_id {}", user_id);
const auto name = Config::getUserName();
std::memset(np_id, 0, sizeof(OrbisNpId));
name.copy(np_id->handle.data, sizeof(np_id->handle.data));
return ORBIS_OK;
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
return ORBIS_NP_ERROR_SIGNED_OUT;
}
int PS4_SYSV_ABI sceNpGetNpReachabilityState() {
@ -986,10 +982,7 @@ int PS4_SYSV_ABI sceNpGetNpReachabilityState() {
int PS4_SYSV_ABI sceNpGetOnlineId(s32 user_id, OrbisNpOnlineId* online_id) {
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
const auto name = Config::getUserName();
std::memset(online_id, 0, sizeof(OrbisNpOnlineId));
name.copy(online_id->data, sizeof(online_id->data));
return ORBIS_OK;
return ORBIS_NP_ERROR_SIGNED_OUT;
}
int PS4_SYSV_ABI sceNpGetParentalControlInfo() {

View File

@ -104,8 +104,8 @@ int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerIn
pInfo->touchPadInfo.pixelDensity = 1;
pInfo->touchPadInfo.resolution.x = 1920;
pInfo->touchPadInfo.resolution.y = 950;
pInfo->stickInfo.deadZoneLeft = 20;
pInfo->stickInfo.deadZoneRight = 20;
pInfo->stickInfo.deadZoneLeft = 2;
pInfo->stickInfo.deadZoneRight = 2;
pInfo->connectionType = ORBIS_PAD_PORT_TYPE_STANDARD;
pInfo->connectedCount = 1;
pInfo->connected = true;

View File

@ -157,7 +157,7 @@ s32 PS4_SYSV_ABI scePlayGoGetLocus(OrbisPlayGoHandle handle, const OrbisPlayGoCh
}
for (int i = 0; i < numberOfEntries; i++) {
if (chunkIds[i] <= playgo->chunks.size()) {
if (chunkIds[i] < playgo->chunks.size()) {
outLoci[i] = OrbisPlayGoLocus::LocalFast;
} else {
outLoci[i] = OrbisPlayGoLocus::NotDownloaded;

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <span>
#include <thread>
#include <vector>
#include <core/libraries/system/msgdialog_ui.h>
@ -1139,10 +1140,6 @@ Error PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getPar
LOG_INFO(Lib_SaveData, "called without save memory initialized");
return Error::MEMORY_NOT_READY;
}
if (SaveMemory::IsSaving()) {
LOG_TRACE(Lib_SaveData, "called while saving");
return Error::BUSY_FOR_SAVING;
}
LOG_DEBUG(Lib_SaveData, "called");
auto data = getParam->data;
if (data != nullptr) {
@ -1501,10 +1498,16 @@ Error PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(const OrbisSaveDataMemorySet2*
LOG_INFO(Lib_SaveData, "called without save memory initialized");
return Error::MEMORY_NOT_READY;
}
if (SaveMemory::IsSaving()) {
int count = 0;
while (++count < 100 && SaveMemory::IsSaving()) { // try for more 10 seconds
std::this_thread::sleep_for(chrono::milliseconds(100));
}
if (SaveMemory::IsSaving()) {
LOG_TRACE(Lib_SaveData, "called while saving");
return Error::BUSY_FOR_SAVING;
}
}
LOG_DEBUG(Lib_SaveData, "called");
auto data = setParam->data;
if (data != nullptr) {
@ -1584,8 +1587,8 @@ Error PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetu
} else {
SaveMemory::SetIcon(nullptr, 0);
}
}
SaveMemory::TriggerSaveWithoutEvent();
}
if (g_fw_ver >= ElfInfo::FW_45 && result != nullptr) {
result->existedMemorySize = existed_size;
}

View File

@ -215,7 +215,7 @@ int PS4_SYSV_ABI sceUsbdHandleEventsLocked() {
}
int PS4_SYSV_ABI sceUsbdHandleEventsTimeout() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called");
LOG_DEBUG(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK;
}

View File

@ -7,6 +7,7 @@
#include "common/debug.h"
#include "core/libraries/kernel/memory.h"
#include "core/libraries/kernel/orbis_error.h"
#include "core/libraries/kernel/process.h"
#include "core/memory.h"
#include "video_core/renderer_vulkan/vk_rasterizer.h"
@ -35,7 +36,7 @@ MemoryManager::~MemoryManager() = default;
void MemoryManager::SetupMemoryRegions(u64 flexible_size, bool use_extended_mem1,
bool use_extended_mem2) {
const bool is_neo = Config::isNeoMode();
const bool is_neo = ::Libraries::Kernel::sceKernelIsNeoMode();
auto total_size = is_neo ? SCE_KERNEL_TOTAL_MEM_PRO : SCE_KERNEL_TOTAL_MEM;
if (!use_extended_mem1 && is_neo) {
total_size -= 256_MB;
@ -170,10 +171,11 @@ int MemoryManager::PoolReserve(void** out_addr, VAddr virtual_addr, size_t size,
// Fixed mapping means the virtual address must exactly match the provided one.
if (True(flags & MemoryMapFlags::Fixed)) {
const auto& vma = FindVMA(mapped_addr)->second;
auto& vma = FindVMA(mapped_addr)->second;
// If the VMA is mapped, unmap the region first.
if (vma.IsMapped()) {
UnmapMemoryImpl(mapped_addr, size);
vma = FindVMA(mapped_addr)->second;
}
const size_t remaining_size = vma.base + vma.size - mapped_addr;
ASSERT_MSG(vma.type == VMAType::Free && remaining_size >= size);
@ -207,10 +209,11 @@ int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, Mem
// Fixed mapping means the virtual address must exactly match the provided one.
if (True(flags & MemoryMapFlags::Fixed)) {
const auto& vma = FindVMA(mapped_addr)->second;
auto& vma = FindVMA(mapped_addr)->second;
// If the VMA is mapped, unmap the region first.
if (vma.IsMapped()) {
UnmapMemoryImpl(mapped_addr, size);
vma = FindVMA(mapped_addr)->second;
}
const size_t remaining_size = vma.base + vma.size - mapped_addr;
ASSERT_MSG(vma.type == VMAType::Free && remaining_size >= size);
@ -392,14 +395,18 @@ s32 MemoryManager::UnmapMemoryImpl(VAddr virtual_addr, size_t size) {
ASSERT_MSG(vma_base.Contains(virtual_addr, size),
"Existing mapping does not contain requested unmap range");
const auto type = vma_base.type;
if (type == VMAType::Free) {
return ORBIS_OK;
}
const auto vma_base_addr = vma_base.base;
const auto vma_base_size = vma_base.size;
const auto phys_base = vma_base.phys_base;
const bool is_exec = vma_base.is_exec;
const auto start_in_vma = virtual_addr - vma_base_addr;
const auto type = vma_base.type;
const bool has_backing = type == VMAType::Direct || type == VMAType::File;
if (type == VMAType::Direct) {
if (type == VMAType::Direct || type == VMAType::Pooled) {
rasterizer->UnmapMemory(virtual_addr, size);
}
if (type == VMAType::Flexible) {
@ -417,10 +424,12 @@ s32 MemoryManager::UnmapMemoryImpl(VAddr virtual_addr, size_t size) {
MergeAdjacent(vma_map, new_it);
bool readonly_file = vma.prot == MemoryProt::CpuRead && type == VMAType::File;
if (type != VMAType::Reserved && type != VMAType::PoolReserved) {
// Unmap the memory region.
impl.Unmap(vma_base_addr, vma_base_size, start_in_vma, start_in_vma + size, phys_base, is_exec,
has_backing, readonly_file);
impl.Unmap(vma_base_addr, vma_base_size, start_in_vma, start_in_vma + size, phys_base,
is_exec, has_backing, readonly_file);
TRACK_FREE(virtual_addr, "VMEM");
}
return ORBIS_OK;
}

View File

@ -28,8 +28,6 @@
#include "core/file_format/trp.h"
#include "core/file_sys/fs.h"
#include "core/libraries/disc_map/disc_map.h"
#include "core/libraries/fiber/fiber.h"
#include "core/libraries/jpeg/jpegenc.h"
#include "core/libraries/libc_internal/libc_internal.h"
#include "core/libraries/libs.h"
#include "core/libraries/ngs2/ngs2.h"
@ -59,8 +57,8 @@ Emulator::Emulator() {
LOG_INFO(Loader, "Branch {}", Common::g_scm_branch);
LOG_INFO(Loader, "Description {}", Common::g_scm_desc);
LOG_INFO(Config, "General Logtype: {}", Config::getLogType());
LOG_INFO(Config, "General isNeo: {}", Config::isNeoMode());
LOG_INFO(Config, "General LogType: {}", Config::getLogType());
LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole());
LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu());
LOG_INFO(Config, "GPU shouldDumpShaders: {}", Config::dumpShaders());
LOG_INFO(Config, "GPU vblankDivider: {}", Config::vblankDiv());
@ -101,19 +99,12 @@ Emulator::~Emulator() {
}
void Emulator::Run(const std::filesystem::path& file) {
// Use the eboot from the separated updates folder if it's there
std::filesystem::path game_patch_folder = file.parent_path();
game_patch_folder += "-UPDATE";
std::filesystem::path eboot_path = std::filesystem::exists(game_patch_folder / file.filename())
? game_patch_folder / file.filename()
: file;
// Applications expect to be run from /app0 so mount the file's parent path as app0.
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(file.parent_path(), "/app0");
const auto game_folder = file.parent_path();
mnt->Mount(game_folder, "/app0");
// Certain games may use /hostapp as well such as CUSA001100
mnt->Mount(file.parent_path(), "/hostapp");
mnt->Mount(game_folder, "/hostapp");
auto& game_info = Common::ElfInfo::Instance();
@ -122,13 +113,12 @@ void Emulator::Run(const std::filesystem::path& file) {
std::string title;
std::string app_version;
u32 fw_version;
Common::PSFAttributes psf_attributes{};
std::filesystem::path sce_sys_folder = eboot_path.parent_path() / "sce_sys";
if (std::filesystem::is_directory(sce_sys_folder)) {
for (const auto& entry : std::filesystem::directory_iterator(sce_sys_folder)) {
if (entry.path().filename() == "param.sfo") {
const auto param_sfo_path = mnt->GetHostPath("/app0/sce_sys/param.sfo");
if (std::filesystem::exists(param_sfo_path)) {
auto* param_sfo = Common::Singleton<PSF>::Instance();
const bool success = param_sfo->Open(sce_sys_folder / "param.sfo");
const bool success = param_sfo->Open(param_sfo_path);
ASSERT_MSG(success, "Failed to open param.sfo");
const auto content_id = param_sfo->GetString("CONTENT_ID");
ASSERT_MSG(content_id.has_value(), "Failed to get CONTENT_ID");
@ -138,7 +128,7 @@ void Emulator::Run(const std::filesystem::path& file) {
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / id / "TrophyFiles";
if (!std::filesystem::exists(trophyDir)) {
TRP trp;
if (!trp.Extract(eboot_path.parent_path(), id)) {
if (!trp.Extract(game_folder, id)) {
LOG_ERROR(Loader, "Couldn't extract trophies");
}
}
@ -158,17 +148,20 @@ void Emulator::Run(const std::filesystem::path& file) {
fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000);
app_version = param_sfo->GetString("APP_VER").value_or("Unknown version");
LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version);
} else if (entry.path().filename() == "pic1.png") {
if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) {
psf_attributes.raw = *raw_attributes;
}
}
const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png");
if (std::filesystem::exists(pic1_path)) {
auto* splash = Common::Singleton<Splash>::Instance();
if (splash->IsLoaded()) {
continue;
}
if (!splash->Open(entry.path())) {
if (!splash->IsLoaded()) {
if (!splash->Open(pic1_path)) {
LOG_ERROR(Loader, "Game splash: unable to open file");
}
}
}
}
game_info.initialized = true;
game_info.game_serial = id;
@ -176,6 +169,7 @@ void Emulator::Run(const std::filesystem::path& file) {
game_info.app_ver = app_version;
game_info.firmware_ver = fw_version & 0xFFF00000;
game_info.raw_firmware_ver = fw_version;
game_info.psf_attributes = psf_attributes;
std::string game_title = fmt::format("{} - {} <{}>", id, title, app_version);
std::string window_title = "";
@ -219,42 +213,19 @@ void Emulator::Run(const std::filesystem::path& file) {
Libraries::InitHLELibs(&linker->GetHLESymbols());
// Load the module with the linker
const auto eboot_path = mnt->GetHostPath("/app0/" + file.filename().string());
linker->LoadModule(eboot_path);
// check if we have system modules to load
LoadSystemModules(eboot_path, game_info.game_serial);
LoadSystemModules(game_info.game_serial);
// Load all prx from game's sce_module folder
std::vector<std::filesystem::path> modules_to_load;
std::filesystem::path game_module_folder = file.parent_path() / "sce_module";
if (std::filesystem::is_directory(game_module_folder)) {
for (const auto& entry : std::filesystem::directory_iterator(game_module_folder)) {
if (entry.is_regular_file()) {
modules_to_load.push_back(entry.path());
mnt->IterateDirectory("/app0/sce_module", [this](const auto& path, const auto is_file) {
if (is_file) {
LOG_INFO(Loader, "Loading {}", fmt::UTF(path.u8string()));
linker->LoadModule(path);
}
}
}
// Load all prx from separate update's sce_module folder
std::filesystem::path update_module_folder = game_patch_folder / "sce_module";
if (std::filesystem::is_directory(update_module_folder)) {
for (const auto& entry : std::filesystem::directory_iterator(update_module_folder)) {
auto it = std::find_if(modules_to_load.begin(), modules_to_load.end(),
[&entry](const std::filesystem::path& p) {
return p.filename() == entry.path().filename();
});
if (it != modules_to_load.end()) {
*it = entry.path();
} else {
modules_to_load.push_back(entry.path());
}
}
}
for (const auto& module_path : modules_to_load) {
LOG_INFO(Loader, "Loading {}", fmt::UTF(module_path.u8string()));
linker->LoadModule(module_path);
}
#ifdef ENABLE_DISCORD_RPC
// Discord RPC
@ -281,17 +252,15 @@ void Emulator::Run(const std::filesystem::path& file) {
std::exit(0);
}
void Emulator::LoadSystemModules(const std::filesystem::path& file, std::string game_serial) {
constexpr std::array<SysModules, 13> ModulesToLoad{
void Emulator::LoadSystemModules(const std::string& game_serial) {
constexpr std::array<SysModules, 11> ModulesToLoad{
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
{"libSceFiber.sprx", &Libraries::Fiber::RegisterlibSceFiber},
{"libSceUlt.sprx", nullptr},
{"libSceJson.sprx", nullptr},
{"libSceJson2.sprx", nullptr},
{"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal},
{"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap},
{"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc},
{"libSceJpegEnc.sprx", &Libraries::JpegEnc::RegisterlibSceJpegEnc},
{"libSceCesCs.sprx", nullptr},
{"libSceFont.sprx", nullptr},
{"libSceFontFt.sprx", nullptr},

View File

@ -29,7 +29,7 @@ public:
void UpdatePlayTime(const std::string& serial);
private:
void LoadSystemModules(const std::filesystem::path& file, std::string game_serial);
void LoadSystemModules(const std::string& game_serial);
Core::MemoryManager* memory;
Input::GameController* controller;

View File

@ -11,7 +11,6 @@
#include <SDL3/SDL.h>
#if defined(__APPLE__)
#include <TargetConditionals.h>
#include <dispatch/dispatch.h>
#endif
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
@ -72,33 +71,25 @@ static void PlatformSetImeData(ImGuiContext*, ImGuiViewport* viewport, ImGuiPlat
auto window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
SDL_Window* window = SDL_GetWindowFromID(window_id);
if ((!data->WantVisible || bd->ime_window != window) && bd->ime_window != nullptr) {
auto stop_input = [&bd] { SDL_StopTextInput(bd->ime_window); };
#ifdef __APPLE__
dispatch_sync(dispatch_get_main_queue(), ^{
stop_input();
});
#else
stop_input();
#endif
SDL_RunOnMainThread(
[](void* userdata) { SDL_StopTextInput(static_cast<SDL_Window*>(userdata)); },
bd->ime_window, true);
bd->ime_window = nullptr;
}
if (data->WantVisible) {
SDL_Rect r;
r.x = (int)data->InputPos.x;
r.y = (int)data->InputPos.y;
r.w = 1;
r.h = (int)data->InputLineHeight;
const auto start_input = [&window, &r] {
SDL_SetTextInputArea(window, &r, 0);
SDL_StartTextInput(window);
};
#ifdef __APPLE__
dispatch_sync(dispatch_get_main_queue(), ^{
start_input();
});
#else
start_input();
#endif
std::pair<SDL_Window*, SDL_Rect> usr_data;
usr_data.first = window;
usr_data.second.x = (int)data->InputPos.x;
usr_data.second.y = (int)data->InputPos.y;
usr_data.second.w = 1;
usr_data.second.h = (int)data->InputLineHeight;
SDL_RunOnMainThread(
[](void* userdata) {
auto* params = static_cast<std::pair<SDL_Window*, SDL_Rect>*>(userdata);
SDL_SetTextInputArea(params->first, &params->second, 0);
SDL_StartTextInput(params->first);
},
&usr_data, true);
bd->ime_window = window;
}
}

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <SDL3/SDL.h>
#include "common/config.h"
#include "common/logging/log.h"
#include "core/libraries/kernel/time.h"
#include "core/libraries/pad/pad.h"
@ -189,11 +190,6 @@ void GameController::CalculateOrientation(Libraries::Pad::OrbisFVector3& acceler
gz += Kp * ez + Ki * eInt[2];
//// Integrate rate of change of quaternion
// float pa = q2, pb = q3, pc = q4;
// q1 += (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * deltaTime);
// q2 += (pa * gx + pb * gz - pc * gy) * (0.5f * deltaTime);
// q3 += (pb * gy - pa * gz + pc * gx) * (0.5f * deltaTime);
// q4 += (pc * gz + pa * gy - pb * gx) * (0.5f * deltaTime);
q1 += (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * deltaTime);
q2 += (q1 * gx + q3 * gz - q4 * gy) * (0.5f * deltaTime);
q3 += (q1 * gy - q2 * gz + q4 * gx) * (0.5f * deltaTime);
@ -247,6 +243,7 @@ void GameController::TryOpenSDLController() {
int gamepad_count;
SDL_JoystickID* gamepads = SDL_GetGamepads(&gamepad_count);
m_sdl_gamepad = gamepad_count > 0 ? SDL_OpenGamepad(gamepads[0]) : nullptr;
if (Config::getIsMotionControlsEnabled()) {
if (SDL_SetGamepadSensorEnabled(m_sdl_gamepad, SDL_SENSOR_GYRO, true)) {
gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_sdl_gamepad, SDL_SENSOR_GYRO);
LOG_INFO(Input, "Gyro initialized, poll rate: {}", gyro_poll_rate);
@ -259,6 +256,8 @@ void GameController::TryOpenSDLController() {
} else {
LOG_ERROR(Input, "Failed to initialize accel controls for gamepad");
}
}
SDL_free(gamepads);
SetLightBarRGB(0, 0, 255);
@ -266,6 +265,7 @@ void GameController::TryOpenSDLController() {
}
u32 GameController::Poll() {
std::scoped_lock lock{m_mutex};
if (m_connected) {
auto time = Libraries::Kernel::sceKernelGetProcessTime();
if (m_states_num == 0) {

View File

@ -86,7 +86,7 @@ int main(int argc, char* argv[]) {
exit(1);
}
// Set fullscreen mode without saving it to config file
Config::setFullscreenMode(is_fullscreen);
Config::setIsFullscreen(is_fullscreen);
}},
{"--fullscreen", [&](int& i) { arg_map["-f"](i); }},
{"--add-game-folder",

View File

@ -106,6 +106,8 @@ void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
void GameListFrame::PopulateGameList() {
// Do not show status column if it is not enabled
this->setColumnHidden(2, !Config::getCompatibilityEnabled());
this->setColumnHidden(6, !Config::GetLoadGameSizeEnabled());
this->setRowCount(m_game_info->m_games.size());
ResizeIcons(icon_size);

View File

@ -62,11 +62,46 @@ public:
QDir dir(dirPath);
QDirIterator it(dir.absolutePath(), QDirIterator::Subdirectories);
qint64 total = 0;
if (!Config::GetLoadGameSizeEnabled()) {
game.size = FormatSize(0).toStdString();
return;
}
// Cache path
QFile size_cache_file(Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
game.serial / "size_cache.txt");
QFileInfo cacheInfo(size_cache_file);
QFileInfo dirInfo(dirPath);
// Check if cache file exists and is valid
if (size_cache_file.exists() && cacheInfo.lastModified() >= dirInfo.lastModified()) {
if (size_cache_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&size_cache_file);
QString cachedSize = in.readLine();
size_cache_file.close();
if (!cachedSize.isEmpty()) {
game.size = cachedSize.toStdString();
return;
}
}
}
// Cache is invalid or does not exist; calculate size
while (it.hasNext()) {
it.next();
total += it.fileInfo().size();
}
game.size = FormatSize(total).toStdString();
// Save new cache
if (size_cache_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&size_cache_file);
out << QString::fromStdString(game.size) << "\n";
size_cache_file.close();
}
}
static QString GetRegion(char region) {

View File

@ -283,7 +283,7 @@ public:
#ifdef Q_OS_WIN
if (createShortcutWin(linkPath, ebootPath, icoPath, exePath)) {
#else
if (createShortcutLinux(linkPath, ebootPath, iconPath)) {
if (createShortcutLinux(linkPath, m_games[itemID].name, ebootPath, iconPath)) {
#endif
QMessageBox::information(
nullptr, tr("Shortcut creation"),
@ -301,7 +301,7 @@ public:
#ifdef Q_OS_WIN
if (createShortcutWin(linkPath, ebootPath, iconPath, exePath)) {
#else
if (createShortcutLinux(linkPath, ebootPath, iconPath)) {
if (createShortcutLinux(linkPath, m_games[itemID].name, ebootPath, iconPath)) {
#endif
QMessageBox::information(
nullptr, tr("Shortcut creation"),
@ -510,8 +510,8 @@ private:
return SUCCEEDED(hres);
}
#else
bool createShortcutLinux(const QString& linkPath, const QString& targetPath,
const QString& iconPath) {
bool createShortcutLinux(const QString& linkPath, const std::string& name,
const QString& targetPath, const QString& iconPath) {
QFile shortcutFile(linkPath);
if (!shortcutFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::critical(nullptr, "Error",
@ -522,7 +522,7 @@ private:
QTextStream out(&shortcutFile);
out << "[Desktop Entry]\n";
out << "Version=1.0\n";
out << "Name=" << QFileInfo(linkPath).baseName() << "\n";
out << "Name=" << QString::fromStdString(name) << "\n";
out << "Exec=" << QCoreApplication::applicationFilePath() << " \"" << targetPath << "\"\n";
out << "Icon=" << iconPath << "\n";
out << "Terminal=false\n";

View File

@ -97,7 +97,7 @@ int main(int argc, char* argv[]) {
exit(1);
}
// Set fullscreen mode without saving it to config file
Config::setFullscreenMode(is_fullscreen);
Config::setIsFullscreen(is_fullscreen);
}},
{"--fullscreen", [&](int& i) { arg_map["-f"](i); }},
{"--add-game-folder",

View File

@ -47,6 +47,9 @@ PKGViewer::PKGViewer(std::shared_ptr<GameInfoClass> game_info_get, QWidget* pare
connect(treeWidget, &QTreeWidget::customContextMenuRequested, this,
[=, this](const QPoint& pos) {
if (treeWidget->selectedItems().isEmpty()) {
return;
}
m_gui_context_menus.RequestGameMenuPKGViewer(pos, m_full_pkg_list, treeWidget,
InstallDragDropPkg);
});

View File

@ -17,6 +17,7 @@
#ifdef ENABLE_UPDATER
#include "check_update.h"
#endif
#include <QDesktopServices>
#include <toml.hpp>
#include "background_music_player.h"
#include "common/logging/backend.h"
@ -203,6 +204,16 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
});
}
// DEBUG TAB
{
connect(ui->OpenLogLocationButton, &QPushButton::clicked, this, []() {
QString userPath;
Common::FS::PathToQString(userPath,
Common::FS::GetUserPath(Common::FS::PathType::UserDir));
QDesktopServices::openUrl(QUrl::fromLocalFile(userPath + "/log"));
});
}
// Descriptions
{
// General
@ -213,6 +224,8 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
ui->showSplashCheckBox->installEventFilter(this);
ui->discordRPCCheckbox->installEventFilter(this);
ui->userName->installEventFilter(this);
ui->label_Trophy->installEventFilter(this);
ui->trophyKeyLineEdit->installEventFilter(this);
ui->logTypeGroupBox->installEventFilter(this);
ui->logFilter->installEventFilter(this);
#ifdef ENABLE_UPDATER
@ -298,8 +311,11 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->discordRPCCheckbox->setChecked(
toml::find_or<bool>(data, "General", "enableDiscordRPC", true));
ui->fullscreenCheckBox->setChecked(toml::find_or<bool>(data, "General", "Fullscreen", false));
ui->fullscreenModeComboBox->setCurrentText(QString::fromStdString(
toml::find_or<std::string>(data, "General", "FullscreenMode", "Borderless")));
ui->separateUpdatesCheckBox->setChecked(
toml::find_or<bool>(data, "General", "separateUpdateEnabled", false));
ui->gameSizeCheckBox->setChecked(toml::find_or<bool>(data, "GUI", "loadGameSizeEnabled", true));
ui->showSplashCheckBox->setChecked(toml::find_or<bool>(data, "General", "showSplash", false));
ui->logTypeComboBox->setCurrentText(
QString::fromStdString(toml::find_or<std::string>(data, "General", "logType", "async")));
@ -307,6 +323,9 @@ void SettingsDialog::LoadValuesFromConfig() {
QString::fromStdString(toml::find_or<std::string>(data, "General", "logFilter", "")));
ui->userNameLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "General", "userName", "shadPS4")));
ui->trophyKeyLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "Keys", "TrophyKey", "")));
ui->trophyKeyLineEdit->setEchoMode(QLineEdit::Password);
ui->debugDump->setChecked(toml::find_or<bool>(data, "Debug", "DebugDump", false));
ui->vkValidationCheckBox->setChecked(toml::find_or<bool>(data, "Vulkan", "validation", false));
ui->vkSyncValidationCheckBox->setChecked(
@ -334,6 +353,8 @@ void SettingsDialog::LoadValuesFromConfig() {
toml::find_or<std::string>(data, "Input", "backButtonBehavior", "left"));
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
ui->motionControlsCheckBox->setChecked(
toml::find_or<bool>(data, "Input", "isMotionControlsEnabled", true));
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
ResetInstallFolders();
@ -419,6 +440,10 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
text = tr("discordRPCCheckbox");
} else if (elementName == "userName") {
text = tr("userName");
} else if (elementName == "label_Trophy") {
text = tr("TrophyKey");
} else if (elementName == "trophyKeyLineEdit") {
text = tr("TrophyKey");
} else if (elementName == "logTypeGroupBox") {
text = tr("logTypeGroupBox");
} else if (elementName == "logFilter") {
@ -523,12 +548,15 @@ void SettingsDialog::UpdateSettings() {
const QVector<std::string> TouchPadIndex = {"left", "center", "right", "none"};
Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]);
Config::setFullscreenMode(ui->fullscreenCheckBox->isChecked());
Config::setIsFullscreen(ui->fullscreenCheckBox->isChecked());
Config::setFullscreenMode(ui->fullscreenModeComboBox->currentText().toStdString());
Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked());
Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked());
Config::setPlayBGM(ui->playBGMCheckBox->isChecked());
Config::setLogType(ui->logTypeComboBox->currentText().toStdString());
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString());
Config::setUserName(ui->userNameLineEdit->text().toStdString());
Config::setTrophyKey(ui->trophyKeyLineEdit->text().toStdString());
Config::setCursorState(ui->hideCursorComboBox->currentIndex());
Config::setCursorHideTimeout(ui->idleTimeoutSpinBox->value());
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1);
@ -541,6 +569,7 @@ void SettingsDialog::UpdateSettings() {
Config::setDumpShaders(ui->dumpShadersCheckBox->isChecked());
Config::setNullGpu(ui->nullGpuCheckBox->isChecked());
Config::setSeparateUpdateEnabled(ui->separateUpdatesCheckBox->isChecked());
Config::setLoadGameSizeEnabled(ui->gameSizeCheckBox->isChecked());
Config::setShowSplash(ui->showSplashCheckBox->isChecked());
Config::setDebugDump(ui->debugDump->isChecked());
Config::setVkValidation(ui->vkValidationCheckBox->isChecked());

View File

@ -11,8 +11,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>950</width>
<height>780</height>
<width>970</width>
<height>750</height>
</rect>
</property>
<property name="sizePolicy">
@ -67,8 +67,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>822</width>
<height>487</height>
<width>946</width>
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
@ -77,87 +77,7 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="2">
<layout class="QVBoxLayout" name="loggerTabLayoutRight">
<item>
<widget class="QGroupBox" name="loggerGroupBox">
<property name="title">
<string>Logger</string>
</property>
<layout class="QVBoxLayout" name="loggerLayout">
<item>
<widget class="QWidget" name="LogTypeWidget" native="true">
<layout class="QVBoxLayout" name="LogTypeLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="logTypeGroupBox">
<property name="title">
<string>Log Type</string>
</property>
<layout class="QVBoxLayout" name="logTypeBoxLayout">
<item>
<widget class="QComboBox" name="logTypeComboBox">
<item>
<property name="text">
<string>async</string>
</property>
</item>
<item>
<property name="text">
<string>sync</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutLogFilter">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="hLayoutLogFilter">
<item>
<widget class="QGroupBox" name="logFilter">
<property name="title">
<string>Log Filter</string>
</property>
<layout class="QVBoxLayout" name="logFilterLayout">
<item>
<widget class="QLineEdit" name="logFilterLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<item row="1" column="0">
<layout class="QVBoxLayout" name="systemTabLayoutLeft">
<item>
<widget class="QGroupBox" name="SystemSettings">
@ -194,7 +114,7 @@
</item>
</layout>
</item>
<item row="0" column="1">
<item row="0" column="0">
<layout class="QVBoxLayout" name="emulatorTabLayoutMiddle">
<item>
<widget class="QGroupBox" name="emulatorSettingsGroupBox">
@ -214,6 +134,35 @@
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="fullscreenModeGroupBox">
<property name="title">
<string>Fullscreen Mode</string>
</property>
<layout class="QVBoxLayout" name="fullscreenModeLayout">
<item>
<widget class="QComboBox" name="fullscreenModeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Borderless</string>
</property>
</item>
<item>
<property name="text">
<string>True</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="separateUpdatesCheckBox">
<property name="text">
@ -268,10 +217,10 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item row="1" column="2">
<layout class="QVBoxLayout" name="updaterTabLayoutLeft">
<property name="spacing">
<number>-1</number>
<number>6</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
@ -436,138 +385,8 @@
</layout>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
<item alignment="Qt::AlignmentFlag::AlignTop">
<widget class="QGroupBox" name="GUIgroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>GUI Settings</string>
</property>
<layout class="QVBoxLayout" name="GUILayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>11</number>
</property>
<item>
<widget class="QCheckBox" name="disableTrophycheckBox">
<property name="text">
<string>Disable Trophy Pop-ups</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="playBGMCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Play title music</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="GUIMusicLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="GUIverticalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="BGMVolumeSlider">
<property name="toolTip">
<string>Set the volume of the background music.</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::NoTicks</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="2">
<layout class="QVBoxLayout" name="CompatTabLayoutRight" stretch="0">
<item alignment="Qt::AlignmentFlag::AlignTop">
<item>
<widget class="QGroupBox" name="CompatgroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -638,6 +457,176 @@
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
<item>
<widget class="QGroupBox" name="GUIgroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>GUI Settings</string>
</property>
<layout class="QVBoxLayout" name="GUILayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>11</number>
</property>
<item>
<widget class="QCheckBox" name="gameSizeCheckBox">
<property name="text">
<string>Show Game Size In List</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="playBGMCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Play title music</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="GUIMusicLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_Volume">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="BGMVolumeSlider">
<property name="toolTip">
<string>Set the volume of the background music.</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::NoTicks</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutTrophy">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>50</number>
</property>
<item>
<layout class="QHBoxLayout" name="hLayoutTrophy">
<item>
<widget class="QGroupBox" name="trophyGroupBox">
<property name="title">
<string>Trophy</string>
</property>
<layout class="QVBoxLayout" name="userNameLayout">
<item>
<widget class="QCheckBox" name="disableTrophycheckBox">
<property name="text">
<string>Disable Trophy Pop-ups</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_Trophy">
<property name="text">
<string>Trophy Key</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="trophyKeyLineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<bold>false</bold>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
@ -655,8 +644,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>396</width>
<height>222</height>
<width>946</width>
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0">
@ -871,6 +860,13 @@
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="motionControlsCheckBox">
<property name="text">
<string>Enable Motion Controls</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="controllerWidgetSpacer" native="true">
<property name="enabled">
@ -946,8 +942,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>536</width>
<height>192</height>
<width>946</width>
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
@ -1197,8 +1193,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>146</width>
<height>215</height>
<width>946</width>
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout" name="pathsTabLayout" stretch="0">
@ -1211,12 +1207,10 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="removeFolderButton">
<property name="text">
<string>Remove</string>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addFolderButton">
<property name="text">
@ -1224,6 +1218,15 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeFolderButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="gameFoldersListWidget"/>
</item>
@ -1263,11 +1266,19 @@
<rect>
<x>0</x>
<y>0</y>
<width>288</width>
<height>163</height>
<width>946</width>
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="debugTabHLayout" stretch="1">
<item>
@ -1282,29 +1293,13 @@
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<layout class="QVBoxLayout" name="debugTabLayout">
<item alignment="Qt::AlignmentFlag::AlignTop">
<item>
<widget class="QCheckBox" name="debugDump">
<property name="text">
<string>Enable Debug Dumping</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="vkValidationCheckBox">
<property name="text">
@ -1331,6 +1326,95 @@
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="loggerTabLayoutRight">
<item>
<widget class="QGroupBox" name="loggerGroupBox">
<property name="title">
<string>Logger</string>
</property>
<layout class="QVBoxLayout" name="loggerLayout">
<item>
<widget class="QWidget" name="LogTypeWidget" native="true">
<layout class="QVBoxLayout" name="LogTypeLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="logTypeGroupBox">
<property name="title">
<string>Log Type</string>
</property>
<layout class="QVBoxLayout" name="logTypeBoxLayout">
<item>
<widget class="QComboBox" name="logTypeComboBox">
<item>
<property name="text">
<string>async</string>
</property>
</item>
<item>
<property name="text">
<string>sync</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutLogFilter">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="hLayoutLogFilter">
<item>
<widget class="QGroupBox" name="logFilter">
<property name="title">
<string>Log Filter</string>
</property>
<layout class="QVBoxLayout" name="logFilterLayout">
<item>
<widget class="QLineEdit" name="logFilterLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="OpenLogLocationButton">
<property name="text">
<string>Open Log Location</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="debugTabSpacer">
<property name="orientation">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -97,7 +97,23 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_
}
SDL_SetWindowMinimumSize(window, 640, 360);
SDL_SetWindowFullscreen(window, Config::isFullscreenMode());
bool error = false;
const SDL_DisplayID displayIndex = SDL_GetDisplayForWindow(window);
if (displayIndex < 0) {
LOG_ERROR(Frontend, "Error getting display index: {}", SDL_GetError());
error = true;
}
const SDL_DisplayMode* displayMode;
if ((displayMode = SDL_GetCurrentDisplayMode(displayIndex)) == 0) {
LOG_ERROR(Frontend, "Error getting display mode: {}", SDL_GetError());
error = true;
}
if (!error) {
SDL_SetWindowFullscreenMode(window,
Config::getFullscreenMode() == "True" ? displayMode : NULL);
}
SDL_SetWindowFullscreen(window, Config::getIsFullscreen());
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
controller->TryOpenSDLController();
@ -201,7 +217,9 @@ void WindowSDL::InitTimers() {
void WindowSDL::RequestKeyboard() {
if (keyboard_grab == 0) {
SDL_StartTextInput(window);
SDL_RunOnMainThread(
[](void* userdata) { SDL_StartTextInput(static_cast<SDL_Window*>(userdata)); }, window,
true);
}
keyboard_grab++;
}
@ -210,7 +228,9 @@ void WindowSDL::ReleaseKeyboard() {
ASSERT(keyboard_grab > 0);
keyboard_grab--;
if (keyboard_grab == 0) {
SDL_StopTextInput(window);
SDL_RunOnMainThread(
[](void* userdata) { SDL_StopTextInput(static_cast<SDL_Window*>(userdata)); }, window,
true);
}
}

View File

@ -172,20 +172,18 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod
const auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id);
const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info);
const auto type = sharp.GetBoundType();
const Id zero = ctx.u32_zero_value;
const auto mips{[&] { return has_mips ? ctx.OpImageQueryLevels(ctx.U32[1], image) : zero; }};
const bool uses_lod{type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage};
const bool uses_lod{texture.view_type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage};
const auto query{[&](Id type) {
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
: ctx.OpImageQuerySize(type, image);
}};
switch (type) {
switch (texture.view_type) {
case AmdGpu::ImageType::Color1D:
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
case AmdGpu::ImageType::Color1DArray:
case AmdGpu::ImageType::Color2D:
case AmdGpu::ImageType::Cube:
case AmdGpu::ImageType::Color2DMsaa:
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[2]), zero, mips());
case AmdGpu::ImageType::Color2DArray:
@ -257,4 +255,12 @@ void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id
ctx.OpImageWrite(image, coords, texel, operands.mask, operands.operands);
}
Id EmitCubeFaceIndex(EmitContext& ctx, IR::Inst* inst, Id cube_coords) {
if (ctx.profile.supports_native_cube_calc) {
return ctx.OpCubeFaceIndexAMD(ctx.F32[1], cube_coords);
} else {
UNREACHABLE_MSG("SPIR-V Instruction");
}
}
} // namespace Shader::Backend::SPIRV

View File

@ -439,6 +439,7 @@ Id EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
Id EmitImageAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
Id EmitImageAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
Id EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
Id EmitCubeFaceIndex(EmitContext& ctx, IR::Inst* inst, Id cube_coords);
Id EmitLaneId(EmitContext& ctx);
Id EmitWarpId(EmitContext& ctx);
Id EmitQuadShuffle(EmitContext& ctx, Id value, Id index);

View File

@ -773,8 +773,8 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) {
Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
const auto image = desc.GetSharp(ctx.info);
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown;
const auto type = image.GetBoundType();
const u32 sampled = desc.IsStorage(image) ? 2 : 1;
const auto type = image.GetViewType(desc.is_array);
const u32 sampled = desc.is_written ? 2 : 1;
switch (type) {
case AmdGpu::ImageType::Color1D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format);
@ -788,9 +788,6 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, false, true, sampled, format);
case AmdGpu::ImageType::Color3D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim3D, false, false, false, sampled, format);
case AmdGpu::ImageType::Cube:
return ctx.TypeImage(sampled_type, spv::Dim::Cube, false, desc.is_array, false, sampled,
format);
default:
break;
}
@ -802,7 +799,7 @@ void EmitContext::DefineImagesAndSamplers() {
const auto sharp = image_desc.GetSharp(info);
const auto nfmt = sharp.GetNumberFmt();
const bool is_integer = AmdGpu::IsInteger(nfmt);
const bool is_storage = image_desc.IsStorage(sharp);
const bool is_storage = image_desc.is_written;
const VectorIds& data_types = GetAttributeType(*this, nfmt);
const Id sampled_type = data_types[1];
const Id image_type{ImageType(*this, image_desc, sampled_type)};
@ -817,6 +814,7 @@ void EmitContext::DefineImagesAndSamplers() {
.sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type),
.pointer_type = pointer_type,
.image_type = image_type,
.view_type = sharp.GetViewType(image_desc.is_array),
.is_integer = is_integer,
.is_storage = is_storage,
});

View File

@ -222,6 +222,7 @@ public:
Id sampled_type;
Id pointer_type;
Id image_type;
AmdGpu::ImageType view_type;
bool is_integer = false;
bool is_storage = false;
};

View File

@ -47,13 +47,26 @@ static IR::Condition MakeCondition(const GcnInst& inst) {
}
}
static bool IgnoresExecMask(Opcode opcode) {
switch (opcode) {
case Opcode::V_WRITELANE_B32:
static bool IgnoresExecMask(const GcnInst& inst) {
// EXEC mask does not affect scalar instructions or branches.
switch (inst.category) {
case InstCategory::ScalarALU:
case InstCategory::ScalarMemory:
case InstCategory::FlowControl:
return true;
default:
return false;
break;
}
// Read/Write Lane instructions are not affected either.
switch (inst.opcode) {
case Opcode::V_READLANE_B32:
case Opcode::V_WRITELANE_B32:
case Opcode::V_READFIRSTLANE_B32:
return true;
default:
break;
}
return false;
}
static constexpr size_t LabelReserveSize = 32;
@ -147,8 +160,7 @@ void CFG::EmitDivergenceLabels() {
// If all instructions in the scope ignore exec masking, we shouldn't insert a
// scope.
const auto start = inst_list.begin() + curr_begin + 1;
if (!std::ranges::all_of(start, inst_list.begin() + index, IgnoresExecMask,
&GcnInst::opcode)) {
if (!std::ranges::all_of(start, inst_list.begin() + index, IgnoresExecMask)) {
// Add a label to the instruction right after the open scope call.
// It is the start of a new basic block.
const auto& save_inst = inst_list[curr_begin];

View File

@ -205,7 +205,6 @@ void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool strid
addr, ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0)));
ir.WriteShared(bit_size, ir.GetVectorReg(data0), addr0);
}
emit_ds_read_barrier = true;
}
void Translator::DS_SWIZZLE_B32(const GcnInst& inst) {
@ -222,11 +221,6 @@ void Translator::DS_SWIZZLE_B32(const GcnInst& inst) {
void Translator::DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64,
const GcnInst& inst) {
if (emit_ds_read_barrier && profile.needs_lds_barriers) {
ir.Barrier();
emit_ds_read_barrier = false;
}
const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))};
IR::VectorReg dst_reg{inst.dst[0].code};
if (is_pair) {

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "shader_recompiler/frontend/translate/translate.h"
#include "shader_recompiler/ir/reinterpret.h"
#include "shader_recompiler/runtime_info.h"
namespace Shader::Gcn {
@ -31,14 +32,16 @@ void Translator::EmitExport(const GcnInst& inst) {
return;
}
const u32 index = u32(attrib) - u32(IR::Attribute::RenderTarget0);
const auto [r, g, b, a] = runtime_info.fs_info.color_buffers[index].swizzle;
const auto col_buf = runtime_info.fs_info.color_buffers[index];
const auto converted = IR::ApplyWriteNumberConversion(ir, value, col_buf.num_conversion);
const auto [r, g, b, a] = col_buf.swizzle;
const std::array swizzle_array = {r, g, b, a};
const auto swizzled_comp = swizzle_array[comp];
if (u32(swizzled_comp) < u32(AmdGpu::CompSwizzle::Red)) {
ir.SetAttribute(attrib, value, comp);
ir.SetAttribute(attrib, converted, comp);
return;
}
ir.SetAttribute(attrib, value, u32(swizzled_comp) - u32(AmdGpu::CompSwizzle::Red));
ir.SetAttribute(attrib, converted, u32(swizzled_comp) - u32(AmdGpu::CompSwizzle::Red));
};
const auto unpack = [&](u32 idx) {

View File

@ -106,6 +106,10 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
return S_FF1_I32_B32(inst);
case Opcode::S_FF1_I32_B64:
return S_FF1_I32_B64(inst);
case Opcode::S_BITSET0_B32:
return S_BITSET_B32(inst, 0);
case Opcode::S_BITSET1_B32:
return S_BITSET_B32(inst, 1);
case Opcode::S_AND_SAVEEXEC_B64:
return S_SAVEEXEC_B64(NegateMode::None, false, inst);
case Opcode::S_ORN2_SAVEEXEC_B64:
@ -607,6 +611,13 @@ void Translator::S_FF1_I32_B64(const GcnInst& inst) {
SetDst(inst.dst[0], result);
}
void Translator::S_BITSET_B32(const GcnInst& inst, u32 bit_value) {
const IR::U32 old_value{GetSrc(inst.dst[0])};
const IR::U32 offset{ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0U), ir.Imm32(5U))};
const IR::U32 result{ir.BitFieldInsert(old_value, ir.Imm32(bit_value), offset, ir.Imm32(1U))};
SetDst(inst.dst[0], result);
}
void Translator::S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst) {
// This instruction normally operates on 64-bit data (EXEC, VCC, SGPRs)
// However here we flatten it to 1-bit EXEC and 1-bit VCC. For the destination

View File

@ -114,6 +114,7 @@ public:
void S_BCNT1_I32_B64(const GcnInst& inst);
void S_FF1_I32_B32(const GcnInst& inst);
void S_FF1_I32_B64(const GcnInst& inst);
void S_BITSET_B32(const GcnInst& inst, u32 bit_value);
void S_GETPC_B64(u32 pc, const GcnInst& inst);
void S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst);
void S_ABS_I32(const GcnInst& inst);
@ -300,6 +301,9 @@ private:
IR::U32 VMovRelSHelper(u32 src_vgprno, const IR::U32 m0);
void VMovRelDHelper(u32 dst_vgprno, const IR::U32 src_val, const IR::U32 m0);
IR::F32 SelectCubeResult(const IR::F32& x, const IR::F32& y, const IR::F32& z,
const IR::F32& x_res, const IR::F32& y_res, const IR::F32& z_res);
void LogMissingOpcode(const GcnInst& inst);
private:
@ -308,7 +312,6 @@ private:
const RuntimeInfo& runtime_info;
const Profile& profile;
bool opcode_missing = false;
bool emit_ds_read_barrier = false;
};
void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> inst_list, Info& info,

View File

@ -3,6 +3,7 @@
#include "shader_recompiler/frontend/opcodes.h"
#include "shader_recompiler/frontend/translate/translate.h"
#include "shader_recompiler/profile.h"
namespace Shader::Gcn {
@ -904,7 +905,7 @@ void Translator::V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst) {
case ConditionOp::GE:
return ir.FPGreaterThanEqual(src0, src1);
case ConditionOp::U:
return ir.LogicalNot(ir.LogicalAnd(ir.FPIsNan(src0), ir.FPIsNan(src1)));
return ir.LogicalOr(ir.FPIsNan(src0), ir.FPIsNan(src1));
default:
UNREACHABLE();
}
@ -1042,20 +1043,81 @@ void Translator::V_MAD_U32_U24(const GcnInst& inst) {
V_MAD_I32_I24(inst, false);
}
IR::F32 Translator::SelectCubeResult(const IR::F32& x, const IR::F32& y, const IR::F32& z,
const IR::F32& x_res, const IR::F32& y_res,
const IR::F32& z_res) {
const auto abs_x = ir.FPAbs(x);
const auto abs_y = ir.FPAbs(y);
const auto abs_z = ir.FPAbs(z);
const auto z_face_cond{
ir.LogicalAnd(ir.FPGreaterThanEqual(abs_z, abs_x), ir.FPGreaterThanEqual(abs_z, abs_y))};
const auto y_face_cond{ir.FPGreaterThanEqual(abs_y, abs_x)};
return IR::F32{ir.Select(z_face_cond, z_res, ir.Select(y_face_cond, y_res, x_res))};
}
void Translator::V_CUBEID_F32(const GcnInst& inst) {
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[2]));
const auto x = GetSrc<IR::F32>(inst.src[0]);
const auto y = GetSrc<IR::F32>(inst.src[1]);
const auto z = GetSrc<IR::F32>(inst.src[2]);
IR::F32 result;
if (profile.supports_native_cube_calc) {
result = ir.CubeFaceIndex(ir.CompositeConstruct(x, y, z));
} else {
const auto x_neg_cond{ir.FPLessThan(x, ir.Imm32(0.f))};
const auto y_neg_cond{ir.FPLessThan(y, ir.Imm32(0.f))};
const auto z_neg_cond{ir.FPLessThan(z, ir.Imm32(0.f))};
const IR::F32 x_face{ir.Select(x_neg_cond, ir.Imm32(1.f), ir.Imm32(0.f))};
const IR::F32 y_face{ir.Select(y_neg_cond, ir.Imm32(3.f), ir.Imm32(2.f))};
const IR::F32 z_face{ir.Select(z_neg_cond, ir.Imm32(5.f), ir.Imm32(4.f))};
result = SelectCubeResult(x, y, z, x_face, y_face, z_face);
}
SetDst(inst.dst[0], result);
}
void Translator::V_CUBESC_F32(const GcnInst& inst) {
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[0]));
const auto x = GetSrc<IR::F32>(inst.src[0]);
const auto y = GetSrc<IR::F32>(inst.src[1]);
const auto z = GetSrc<IR::F32>(inst.src[2]);
const auto x_neg_cond{ir.FPLessThan(x, ir.Imm32(0.f))};
const auto z_neg_cond{ir.FPLessThan(z, ir.Imm32(0.f))};
const IR::F32 x_sc{ir.Select(x_neg_cond, z, ir.FPNeg(z))};
const IR::F32 y_sc{x};
const IR::F32 z_sc{ir.Select(z_neg_cond, ir.FPNeg(x), x)};
const auto result{SelectCubeResult(x, y, z, x_sc, y_sc, z_sc)};
SetDst(inst.dst[0], result);
}
void Translator::V_CUBETC_F32(const GcnInst& inst) {
SetDst(inst.dst[0], GetSrc<IR::F32>(inst.src[1]));
const auto x = GetSrc<IR::F32>(inst.src[0]);
const auto y = GetSrc<IR::F32>(inst.src[1]);
const auto z = GetSrc<IR::F32>(inst.src[2]);
const auto y_neg_cond{ir.FPLessThan(y, ir.Imm32(0.f))};
const IR::F32 x_z_tc{ir.FPNeg(y)};
const IR::F32 y_tc{ir.Select(y_neg_cond, ir.FPNeg(z), z)};
const auto result{SelectCubeResult(x, y, z, x_z_tc, y_tc, x_z_tc)};
SetDst(inst.dst[0], result);
}
void Translator::V_CUBEMA_F32(const GcnInst& inst) {
SetDst(inst.dst[0], ir.Imm32(1.f));
const auto x = GetSrc<IR::F32>(inst.src[0]);
const auto y = GetSrc<IR::F32>(inst.src[1]);
const auto z = GetSrc<IR::F32>(inst.src[2]);
const auto two{ir.Imm32(2.f)};
const IR::F32 x_major_axis{ir.FPMul(x, two)};
const IR::F32 y_major_axis{ir.FPMul(y, two)};
const IR::F32 z_major_axis{ir.FPMul(z, two)};
const auto result{SelectCubeResult(x, y, z, x_major_axis, y_major_axis, z_major_axis)};
SetDst(inst.dst[0], result);
}
void Translator::V_BFE_U32(bool is_signed, const GcnInst& inst) {

View File

@ -418,6 +418,7 @@ void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) {
IR::TextureInstInfo info{};
info.has_lod.Assign(has_mip);
info.is_array.Assign(mimg.da);
const IR::Value texel = ir.ImageRead(handle, body, {}, {}, info);
for (u32 i = 0; i < 4; i++) {
@ -442,6 +443,7 @@ void Translator::IMAGE_STORE(bool has_mip, const GcnInst& inst) {
IR::TextureInstInfo info{};
info.has_lod.Assign(has_mip);
info.is_array.Assign(mimg.da);
boost::container::static_vector<IR::F32, 4> comps;
for (u32 i = 0; i < 4; i++) {
@ -456,13 +458,18 @@ void Translator::IMAGE_STORE(bool has_mip, const GcnInst& inst) {
}
void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) {
const auto& mimg = inst.control.mimg;
IR::VectorReg dst_reg{inst.dst[0].code};
const IR::ScalarReg tsharp_reg{inst.src[2].code * 4};
const auto flags = ImageResFlags(inst.control.mimg.dmask);
const bool has_mips = flags.test(ImageResComponent::MipCount);
const IR::U32 lod = ir.GetVectorReg(IR::VectorReg(inst.src[0].code));
const IR::Value tsharp = ir.GetScalarReg(tsharp_reg);
const IR::Value size = ir.ImageQueryDimension(tsharp, lod, ir.Imm1(has_mips));
IR::TextureInstInfo info{};
info.is_array.Assign(mimg.da);
const IR::Value size = ir.ImageQueryDimension(tsharp, lod, ir.Imm1(has_mips), info);
if (flags.test(ImageResComponent::Width)) {
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 0)});
@ -484,6 +491,9 @@ void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) {
IR::VectorReg addr_reg{inst.src[0].code};
const IR::ScalarReg tsharp_reg{inst.src[2].code * 4};
IR::TextureInstInfo info{};
info.is_array.Assign(mimg.da);
const IR::Value value = ir.GetVectorReg(val_reg);
const IR::Value handle = ir.GetScalarReg(tsharp_reg);
const IR::Value body =
@ -494,25 +504,25 @@ void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) {
case AtomicOp::Swap:
return ir.ImageAtomicExchange(handle, body, value, {});
case AtomicOp::Add:
return ir.ImageAtomicIAdd(handle, body, value, {});
return ir.ImageAtomicIAdd(handle, body, value, info);
case AtomicOp::Smin:
return ir.ImageAtomicIMin(handle, body, value, true, {});
return ir.ImageAtomicIMin(handle, body, value, true, info);
case AtomicOp::Umin:
return ir.ImageAtomicUMin(handle, body, value, {});
return ir.ImageAtomicUMin(handle, body, value, info);
case AtomicOp::Smax:
return ir.ImageAtomicIMax(handle, body, value, true, {});
return ir.ImageAtomicIMax(handle, body, value, true, info);
case AtomicOp::Umax:
return ir.ImageAtomicUMax(handle, body, value, {});
return ir.ImageAtomicUMax(handle, body, value, info);
case AtomicOp::And:
return ir.ImageAtomicAnd(handle, body, value, {});
return ir.ImageAtomicAnd(handle, body, value, info);
case AtomicOp::Or:
return ir.ImageAtomicOr(handle, body, value, {});
return ir.ImageAtomicOr(handle, body, value, info);
case AtomicOp::Xor:
return ir.ImageAtomicXor(handle, body, value, {});
return ir.ImageAtomicXor(handle, body, value, info);
case AtomicOp::Inc:
return ir.ImageAtomicInc(handle, body, value, {});
return ir.ImageAtomicInc(handle, body, value, info);
case AtomicOp::Dec:
return ir.ImageAtomicDec(handle, body, value, {});
return ir.ImageAtomicDec(handle, body, value, info);
default:
UNREACHABLE();
}
@ -643,11 +653,14 @@ void Translator::IMAGE_GET_LOD(const GcnInst& inst) {
IR::VectorReg addr_reg{inst.src[0].code};
const IR::ScalarReg tsharp_reg{inst.src[2].code * 4};
IR::TextureInstInfo info{};
info.is_array.Assign(mimg.da);
const IR::Value handle = ir.GetScalarReg(tsharp_reg);
const IR::Value body = ir.CompositeConstruct(
ir.GetVectorReg<IR::F32>(addr_reg), ir.GetVectorReg<IR::F32>(addr_reg + 1),
ir.GetVectorReg<IR::F32>(addr_reg + 2), ir.GetVectorReg<IR::F32>(addr_reg + 3));
const IR::Value lod = ir.ImageQueryLod(handle, body, {});
const IR::Value lod = ir.ImageQueryLod(handle, body, info);
ir.SetVectorReg(dst_reg++, IR::F32{ir.CompositeExtract(lod, 0)});
ir.SetVectorReg(dst_reg++, IR::F32{ir.CompositeExtract(lod, 1)});
}

View File

@ -70,14 +70,8 @@ struct ImageResource {
bool is_depth{};
bool is_atomic{};
bool is_array{};
bool is_read{};
bool is_written{};
[[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept {
// Need cube as storage when used with ImageRead.
return is_written || (is_read && image.GetBoundType() == AmdGpu::ImageType::Cube);
}
[[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
};
using ImageResourceList = boost::container::small_vector<ImageResource, 16>;

View File

@ -1732,11 +1732,6 @@ Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const
return Inst(Opcode::ImageGatherDref, Flags{info}, handle, coords, offset, dref);
}
Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod,
const IR::U1& skip_mips) {
return Inst(Opcode::ImageQueryDimensions, handle, lod, skip_mips);
}
Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod,
const IR::U1& skip_mips, TextureInstInfo info) {
return Inst(Opcode::ImageQueryDimensions, Flags{info}, handle, lod, skip_mips);
@ -1763,6 +1758,10 @@ void IREmitter::ImageWrite(const Value& handle, const Value& coords, const U32&
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, lod, multisampling, color);
}
[[nodiscard]] F32 IREmitter::CubeFaceIndex(const Value& cube_coords) {
return Inst<F32>(Opcode::CubeFaceIndex, cube_coords);
}
// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction
// Renderdoc will hook in its own implementation of the SPIRV instruction
// Renderdoc accepts format specifiers, e.g. %u, listed here:

View File

@ -324,8 +324,6 @@ public:
const F32& dref, const F32& lod,
const Value& offset, TextureInstInfo info);
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod,
const U1& skip_mips);
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod,
const U1& skip_mips, TextureInstInfo info);
@ -344,6 +342,8 @@ public:
void ImageWrite(const Value& handle, const Value& coords, const U32& lod,
const U32& multisampling, const Value& color, TextureInstInfo info);
[[nodiscard]] F32 CubeFaceIndex(const Value& cube_coords);
void EmitVertex();
void EmitPrimitive();

Some files were not shown because too many files have changed in this diff Show More