mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
Merge remote-tracking branch 'origin/main' into feature/fullscreen-flag
This commit is contained in:
commit
c1ce5d7780
2
.github/linux-appimage-qt.sh
vendored
2
.github/linux-appimage-qt.sh
vendored
@ -9,6 +9,8 @@ fi
|
|||||||
|
|
||||||
export Qt6_DIR="/usr/lib/qt6"
|
export Qt6_DIR="/usr/lib/qt6"
|
||||||
export PATH="$Qt6_DIR/bin:$PATH"
|
export PATH="$Qt6_DIR/bin:$PATH"
|
||||||
|
export EXTRA_QT_PLUGINS="waylandcompositor"
|
||||||
|
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so"
|
||||||
|
|
||||||
# Prepare Tools for building the AppImage
|
# Prepare Tools for building the AppImage
|
||||||
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -287,7 +287,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential libasound2-dev libpulse-dev libopenal-dev
|
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 clang build-essential libasound2-dev libpulse-dev libopenal-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@ -343,7 +343,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev
|
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 clang build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
25
CMakeLists.txt
Normal file → Executable file
25
CMakeLists.txt
Normal file → Executable file
@ -282,6 +282,14 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
|||||||
src/core/libraries/audio3d/audio3d_error.h
|
src/core/libraries/audio3d/audio3d_error.h
|
||||||
src/core/libraries/audio3d/audio3d_impl.cpp
|
src/core/libraries/audio3d/audio3d_impl.cpp
|
||||||
src/core/libraries/audio3d/audio3d_impl.h
|
src/core/libraries/audio3d/audio3d_impl.h
|
||||||
|
src/core/libraries/ime/ime.cpp
|
||||||
|
src/core/libraries/ime/ime.h
|
||||||
|
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
|
||||||
|
src/core/libraries/game_live_streaming/gamelivestreaming.h
|
||||||
|
src/core/libraries/remote_play/remoteplay.cpp
|
||||||
|
src/core/libraries/remote_play/remoteplay.h
|
||||||
|
src/core/libraries/share_play/shareplay.cpp
|
||||||
|
src/core/libraries/share_play/shareplay.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||||
@ -297,6 +305,8 @@ set(LIBC_SOURCES src/core/libraries/libc_internal/libc_internal.cpp
|
|||||||
|
|
||||||
set(DIALOGS_LIB src/core/libraries/dialogs/error_dialog.cpp
|
set(DIALOGS_LIB src/core/libraries/dialogs/error_dialog.cpp
|
||||||
src/core/libraries/dialogs/error_dialog.h
|
src/core/libraries/dialogs/error_dialog.h
|
||||||
|
src/core/libraries/dialogs/ime_dialog_ui.cpp
|
||||||
|
src/core/libraries/dialogs/ime_dialog_ui.h
|
||||||
src/core/libraries/dialogs/ime_dialog.cpp
|
src/core/libraries/dialogs/ime_dialog.cpp
|
||||||
src/core/libraries/dialogs/ime_dialog.h
|
src/core/libraries/dialogs/ime_dialog.h
|
||||||
src/core/libraries/dialogs/error_codes.h
|
src/core/libraries/dialogs/error_codes.h
|
||||||
@ -324,6 +334,10 @@ set(USBD_LIB src/core/libraries/usbd/usbd.cpp
|
|||||||
src/core/libraries/usbd/usbd.h
|
src/core/libraries/usbd/usbd.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(FIBER_LIB src/core/libraries/fiber/fiber.cpp
|
||||||
|
src/core/libraries/fiber/fiber.h
|
||||||
|
)
|
||||||
|
|
||||||
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
||||||
src/core/libraries/np_manager/np_manager.h
|
src/core/libraries/np_manager/np_manager.h
|
||||||
src/core/libraries/np_score/np_score.cpp
|
src/core/libraries/np_score/np_score.cpp
|
||||||
@ -464,6 +478,7 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||||||
${USBD_LIB}
|
${USBD_LIB}
|
||||||
${MISC_LIBS}
|
${MISC_LIBS}
|
||||||
${DIALOGS_LIB}
|
${DIALOGS_LIB}
|
||||||
|
${FIBER_LIB}
|
||||||
${DEV_TOOLS}
|
${DEV_TOOLS}
|
||||||
src/core/debug_state.cpp
|
src/core/debug_state.cpp
|
||||||
src/core/debug_state.h
|
src/core/debug_state.h
|
||||||
@ -693,6 +708,8 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
|||||||
src/qt_gui/game_grid_frame.h
|
src/qt_gui/game_grid_frame.h
|
||||||
src/qt_gui/game_install_dialog.cpp
|
src/qt_gui/game_install_dialog.cpp
|
||||||
src/qt_gui/game_install_dialog.h
|
src/qt_gui/game_install_dialog.h
|
||||||
|
src/qt_gui/install_dir_select.cpp
|
||||||
|
src/qt_gui/install_dir_select.h
|
||||||
src/qt_gui/pkg_viewer.cpp
|
src/qt_gui/pkg_viewer.cpp
|
||||||
src/qt_gui/pkg_viewer.h
|
src/qt_gui/pkg_viewer.h
|
||||||
src/qt_gui/trophy_viewer.cpp
|
src/qt_gui/trophy_viewer.cpp
|
||||||
@ -863,3 +880,11 @@ endif()
|
|||||||
|
|
||||||
# Discord RPC
|
# Discord RPC
|
||||||
target_link_libraries(shadps4 PRIVATE discord-rpc)
|
target_link_libraries(shadps4 PRIVATE discord-rpc)
|
||||||
|
|
||||||
|
# Install rules
|
||||||
|
install(TARGETS shadps4 BUNDLE DESTINATION .)
|
||||||
|
|
||||||
|
if (ENABLE_QT_GUI AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
install(FILES ".github/shadps4.desktop" DESTINATION "share/applications")
|
||||||
|
install(FILES ".github/shadps4.png" DESTINATION "share/icons/hicolor/512x512/apps")
|
||||||
|
endif()
|
||||||
|
12
externals/CMakeLists.txt
vendored
12
externals/CMakeLists.txt
vendored
@ -3,7 +3,10 @@
|
|||||||
|
|
||||||
set(BUILD_SHARED_LIBS OFF)
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
set(BUILD_TESTING OFF)
|
set(BUILD_TESTING OFF)
|
||||||
set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON)
|
set_directory_properties(PROPERTIES
|
||||||
|
EXCLUDE_FROM_ALL ON
|
||||||
|
SYSTEM ON
|
||||||
|
)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# Silence "deprecation" warnings
|
# Silence "deprecation" warnings
|
||||||
@ -13,11 +16,8 @@ endif()
|
|||||||
# Boost
|
# Boost
|
||||||
if (NOT TARGET Boost::headers)
|
if (NOT TARGET Boost::headers)
|
||||||
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/ext-boost" CACHE STRING "")
|
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/ext-boost" CACHE STRING "")
|
||||||
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/ext-boost" CACHE STRING "")
|
|
||||||
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
||||||
add_library(boost INTERFACE)
|
add_subdirectory(ext-boost)
|
||||||
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
|
||||||
add_library(Boost::headers ALIAS boost)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# fmtlib
|
# fmtlib
|
||||||
@ -77,7 +77,7 @@ endif()
|
|||||||
# RenderDoc
|
# RenderDoc
|
||||||
if (NOT TARGET RenderDoc::API)
|
if (NOT TARGET RenderDoc::API)
|
||||||
add_library(renderdoc INTERFACE)
|
add_library(renderdoc INTERFACE)
|
||||||
target_include_directories(renderdoc SYSTEM INTERFACE ./renderdoc)
|
target_include_directories(renderdoc INTERFACE ./renderdoc)
|
||||||
add_library(RenderDoc::API ALIAS renderdoc)
|
add_library(RenderDoc::API ALIAS renderdoc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
2
externals/ext-boost
vendored
2
externals/ext-boost
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a04136add1e469f46d8ae8d3e8307779240a5c53
|
Subproject commit f2474e1b584fb7a3ed6f85ba875e6eacd742ec8a
|
@ -63,7 +63,7 @@ static s16 cursorState = HideCursorState::Idle;
|
|||||||
static int cursorHideTimeout = 5; // 5 seconds (default)
|
static int cursorHideTimeout = 5; // 5 seconds (default)
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
std::filesystem::path settings_install_dir = {};
|
std::vector<std::filesystem::path> settings_install_dirs = {};
|
||||||
std::filesystem::path settings_addon_install_dir = {};
|
std::filesystem::path settings_addon_install_dir = {};
|
||||||
u32 main_window_geometry_x = 400;
|
u32 main_window_geometry_x = 400;
|
||||||
u32 main_window_geometry_y = 400;
|
u32 main_window_geometry_y = 400;
|
||||||
@ -334,8 +334,19 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
|||||||
main_window_geometry_w = w;
|
main_window_geometry_w = w;
|
||||||
main_window_geometry_h = h;
|
main_window_geometry_h = h;
|
||||||
}
|
}
|
||||||
void setGameInstallDir(const std::filesystem::path& dir) {
|
bool addGameInstallDir(const std::filesystem::path& dir) {
|
||||||
settings_install_dir = dir;
|
if (std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir) ==
|
||||||
|
settings_install_dirs.end()) {
|
||||||
|
settings_install_dirs.push_back(dir);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void removeGameInstallDir(const std::filesystem::path& dir) {
|
||||||
|
auto iterator = std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir);
|
||||||
|
if (iterator != settings_install_dirs.end()) {
|
||||||
|
settings_install_dirs.erase(iterator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void setAddonInstallDir(const std::filesystem::path& dir) {
|
void setAddonInstallDir(const std::filesystem::path& dir) {
|
||||||
settings_addon_install_dir = dir;
|
settings_addon_install_dir = dir;
|
||||||
@ -393,8 +404,8 @@ u32 getMainWindowGeometryW() {
|
|||||||
u32 getMainWindowGeometryH() {
|
u32 getMainWindowGeometryH() {
|
||||||
return main_window_geometry_h;
|
return main_window_geometry_h;
|
||||||
}
|
}
|
||||||
std::filesystem::path getGameInstallDir() {
|
const std::vector<std::filesystem::path>& getGameInstallDirs() {
|
||||||
return settings_install_dir;
|
return settings_install_dirs;
|
||||||
}
|
}
|
||||||
std::filesystem::path getAddonInstallDir() {
|
std::filesystem::path getAddonInstallDir() {
|
||||||
if (settings_addon_install_dir.empty()) {
|
if (settings_addon_install_dir.empty()) {
|
||||||
@ -490,6 +501,7 @@ void load(const std::filesystem::path& path) {
|
|||||||
|
|
||||||
cursorState = toml::find_or<int>(input, "cursorState", HideCursorState::Idle);
|
cursorState = toml::find_or<int>(input, "cursorState", HideCursorState::Idle);
|
||||||
cursorHideTimeout = toml::find_or<int>(input, "cursorHideTimeout", 5);
|
cursorHideTimeout = toml::find_or<int>(input, "cursorHideTimeout", 5);
|
||||||
|
backButtonBehavior = toml::find_or<std::string>(input, "backButtonBehavior", "left");
|
||||||
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
|
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
|
||||||
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
|
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
|
||||||
}
|
}
|
||||||
@ -533,7 +545,19 @@ void load(const std::filesystem::path& path) {
|
|||||||
mw_themes = toml::find_or<int>(gui, "theme", 0);
|
mw_themes = toml::find_or<int>(gui, "theme", 0);
|
||||||
m_window_size_W = toml::find_or<int>(gui, "mw_width", 0);
|
m_window_size_W = toml::find_or<int>(gui, "mw_width", 0);
|
||||||
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
||||||
settings_install_dir = toml::find_fs_path_or(gui, "installDir", {});
|
|
||||||
|
// TODO Migration code, after a major release this should be removed.
|
||||||
|
auto old_game_install_dir = toml::find_fs_path_or(gui, "installDir", {});
|
||||||
|
if (!old_game_install_dir.empty()) {
|
||||||
|
settings_install_dirs.emplace_back(std::filesystem::path{old_game_install_dir});
|
||||||
|
} else {
|
||||||
|
const auto install_dir_array =
|
||||||
|
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||||
|
for (const auto& dir : install_dir_array) {
|
||||||
|
settings_install_dirs.emplace_back(std::filesystem::path{dir});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
||||||
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
||||||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||||
@ -599,7 +623,7 @@ void save(const std::filesystem::path& path) {
|
|||||||
data["General"]["patchFile"] = patchFile;
|
data["General"]["patchFile"] = patchFile;
|
||||||
data["Input"]["cursorState"] = cursorState;
|
data["Input"]["cursorState"] = cursorState;
|
||||||
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
||||||
data["General"]["backButtonBehavior"] = backButtonBehavior;
|
data["Input"]["backButtonBehavior"] = backButtonBehavior;
|
||||||
data["Input"]["useSpecialPad"] = useSpecialPad;
|
data["Input"]["useSpecialPad"] = useSpecialPad;
|
||||||
data["Input"]["specialPadClass"] = specialPadClass;
|
data["Input"]["specialPadClass"] = specialPadClass;
|
||||||
data["GPU"]["screenWidth"] = screenWidth;
|
data["GPU"]["screenWidth"] = screenWidth;
|
||||||
@ -624,7 +648,13 @@ void save(const std::filesystem::path& path) {
|
|||||||
data["GUI"]["gameTableMode"] = m_table_mode;
|
data["GUI"]["gameTableMode"] = m_table_mode;
|
||||||
data["GUI"]["mw_width"] = m_window_size_W;
|
data["GUI"]["mw_width"] = m_window_size_W;
|
||||||
data["GUI"]["mw_height"] = m_window_size_H;
|
data["GUI"]["mw_height"] = m_window_size_H;
|
||||||
data["GUI"]["installDir"] = std::string{fmt::UTF(settings_install_dir.u8string()).data};
|
|
||||||
|
std::vector<std::string> install_dirs;
|
||||||
|
for (const auto& dirString : settings_install_dirs) {
|
||||||
|
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
|
||||||
|
}
|
||||||
|
data["GUI"]["installDirs"] = install_dirs;
|
||||||
|
|
||||||
data["GUI"]["addonInstallDir"] =
|
data["GUI"]["addonInstallDir"] =
|
||||||
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
||||||
data["GUI"]["geometry_x"] = main_window_geometry_x;
|
data["GUI"]["geometry_x"] = main_window_geometry_x;
|
||||||
@ -638,6 +668,9 @@ void save(const std::filesystem::path& path) {
|
|||||||
|
|
||||||
data["Settings"]["consoleLanguage"] = m_language;
|
data["Settings"]["consoleLanguage"] = m_language;
|
||||||
|
|
||||||
|
// TODO Migration code, after a major release this should be removed.
|
||||||
|
data.at("GUI").as_table().erase("installDir");
|
||||||
|
|
||||||
std::ofstream file(path, std::ios::out);
|
std::ofstream file(path, std::ios::out);
|
||||||
file << data;
|
file << data;
|
||||||
file.close();
|
file.close();
|
||||||
@ -649,8 +682,6 @@ void setDefaultValues() {
|
|||||||
playBGM = false;
|
playBGM = false;
|
||||||
BGMvolume = 50;
|
BGMvolume = 50;
|
||||||
enableDiscordRPC = true;
|
enableDiscordRPC = true;
|
||||||
cursorState = HideCursorState::Idle;
|
|
||||||
cursorHideTimeout = 5;
|
|
||||||
screenWidth = 1280;
|
screenWidth = 1280;
|
||||||
screenHeight = 720;
|
screenHeight = 720;
|
||||||
logFilter = "";
|
logFilter = "";
|
||||||
@ -662,6 +693,8 @@ void setDefaultValues() {
|
|||||||
updateChannel = "Nightly";
|
updateChannel = "Nightly";
|
||||||
}
|
}
|
||||||
patchFile = "";
|
patchFile = "";
|
||||||
|
cursorState = HideCursorState::Idle;
|
||||||
|
cursorHideTimeout = 5;
|
||||||
backButtonBehavior = "left";
|
backButtonBehavior = "left";
|
||||||
useSpecialPad = false;
|
useSpecialPad = false;
|
||||||
specialPadClass = 1;
|
specialPadClass = 1;
|
||||||
|
@ -21,9 +21,6 @@ bool getPlayBGM();
|
|||||||
int getBGMvolume();
|
int getBGMvolume();
|
||||||
bool getEnableDiscordRPC();
|
bool getEnableDiscordRPC();
|
||||||
|
|
||||||
s16 getCursorState();
|
|
||||||
int getCursorHideTimeout();
|
|
||||||
|
|
||||||
std::string getLogFilter();
|
std::string getLogFilter();
|
||||||
std::string getLogType();
|
std::string getLogType();
|
||||||
std::string getUserName();
|
std::string getUserName();
|
||||||
@ -31,6 +28,9 @@ std::string getUpdateChannel();
|
|||||||
std::string getPatchFile();
|
std::string getPatchFile();
|
||||||
std::string getBackButtonBehavior();
|
std::string getBackButtonBehavior();
|
||||||
|
|
||||||
|
s16 getCursorState();
|
||||||
|
int getCursorHideTimeout();
|
||||||
|
std::string getBackButtonBehavior();
|
||||||
bool getUseSpecialPad();
|
bool getUseSpecialPad();
|
||||||
int getSpecialPadClass();
|
int getSpecialPadClass();
|
||||||
|
|
||||||
@ -61,8 +61,6 @@ void setFullscreenMode(bool enable);
|
|||||||
void setPlayBGM(bool enable);
|
void setPlayBGM(bool enable);
|
||||||
void setBGMvolume(int volume);
|
void setBGMvolume(int volume);
|
||||||
void setEnableDiscordRPC(bool enable);
|
void setEnableDiscordRPC(bool enable);
|
||||||
void setCursorState(s16 cursorState);
|
|
||||||
void setCursorHideTimeout(int newcursorHideTimeout);
|
|
||||||
void setLanguage(u32 language);
|
void setLanguage(u32 language);
|
||||||
void setNeoMode(bool enable);
|
void setNeoMode(bool enable);
|
||||||
void setUserName(const std::string& type);
|
void setUserName(const std::string& type);
|
||||||
@ -70,6 +68,9 @@ void setUpdateChannel(const std::string& type);
|
|||||||
void setPatchFile(const std::string& fileName);
|
void setPatchFile(const std::string& fileName);
|
||||||
void setBackButtonBehavior(const std::string& type);
|
void setBackButtonBehavior(const std::string& type);
|
||||||
|
|
||||||
|
void setCursorState(s16 cursorState);
|
||||||
|
void setCursorHideTimeout(int newcursorHideTimeout);
|
||||||
|
void setBackButtonBehavior(const std::string& type);
|
||||||
void setUseSpecialPad(bool use);
|
void setUseSpecialPad(bool use);
|
||||||
void setSpecialPadClass(int type);
|
void setSpecialPadClass(int type);
|
||||||
|
|
||||||
@ -88,7 +89,8 @@ bool vkCrashDiagnosticEnabled();
|
|||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
||||||
void setGameInstallDir(const std::filesystem::path& dir);
|
bool addGameInstallDir(const std::filesystem::path& dir);
|
||||||
|
void removeGameInstallDir(const std::filesystem::path& dir);
|
||||||
void setAddonInstallDir(const std::filesystem::path& dir);
|
void setAddonInstallDir(const std::filesystem::path& dir);
|
||||||
void setMainWindowTheme(u32 theme);
|
void setMainWindowTheme(u32 theme);
|
||||||
void setIconSize(u32 size);
|
void setIconSize(u32 size);
|
||||||
@ -107,7 +109,7 @@ u32 getMainWindowGeometryX();
|
|||||||
u32 getMainWindowGeometryY();
|
u32 getMainWindowGeometryY();
|
||||||
u32 getMainWindowGeometryW();
|
u32 getMainWindowGeometryW();
|
||||||
u32 getMainWindowGeometryH();
|
u32 getMainWindowGeometryH();
|
||||||
std::filesystem::path getGameInstallDir();
|
const std::vector<std::filesystem::path>& getGameInstallDirs();
|
||||||
std::filesystem::path getAddonInstallDir();
|
std::filesystem::path getAddonInstallDir();
|
||||||
u32 getMainWindowTheme();
|
u32 getMainWindowTheme();
|
||||||
u32 getIconSize();
|
u32 getIconSize();
|
||||||
|
@ -81,34 +81,42 @@ public:
|
|||||||
return std::basic_string_view<T>{data};
|
return std::basic_string_view<T>{data};
|
||||||
}
|
}
|
||||||
|
|
||||||
char* begin() {
|
T* begin() {
|
||||||
if (this == nullptr) {
|
if (this == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* begin() const {
|
const T* begin() const {
|
||||||
if (this == nullptr) {
|
if (this == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* end() {
|
T* end() {
|
||||||
if (this == nullptr) {
|
if (this == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return data + N;
|
return data + N;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* end() const {
|
const T* end() const {
|
||||||
if (this == nullptr) {
|
if (this == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return data + N;
|
return data + N;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t capacity() const {
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const {
|
||||||
|
return std::char_traits<T>::length(data);
|
||||||
|
}
|
||||||
|
|
||||||
T& operator[](size_t idx) {
|
T& operator[](size_t idx) {
|
||||||
return data[idx];
|
return data[idx];
|
||||||
}
|
}
|
||||||
@ -152,6 +160,12 @@ public:
|
|||||||
static_assert(sizeof(CString<13>) == sizeof(char[13])); // Ensure size still matches a simple array
|
static_assert(sizeof(CString<13>) == sizeof(char[13])); // Ensure size still matches a simple array
|
||||||
static_assert(std::weakly_incrementable<CString<13>::Iterator>);
|
static_assert(std::weakly_incrementable<CString<13>::Iterator>);
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
using CWString = CString<N, wchar_t>;
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
using CU16String = CString<N, char16_t>;
|
||||||
|
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
@ -231,7 +231,7 @@ void IOFile::Unlink() {
|
|||||||
|
|
||||||
// Mark the file for deletion
|
// Mark the file for deletion
|
||||||
// TODO: Also remove the file path?
|
// TODO: Also remove the file path?
|
||||||
#if _WIN64
|
#ifdef _WIN64
|
||||||
FILE_DISPOSITION_INFORMATION disposition;
|
FILE_DISPOSITION_INFORMATION disposition;
|
||||||
IO_STATUS_BLOCK iosb;
|
IO_STATUS_BLOCK iosb;
|
||||||
|
|
||||||
@ -242,7 +242,11 @@ void IOFile::Unlink() {
|
|||||||
NtSetInformationFile(hfile, &iosb, &disposition, sizeof(disposition),
|
NtSetInformationFile(hfile, &iosb, &disposition, sizeof(disposition),
|
||||||
FileDispositionInformation);
|
FileDispositionInformation);
|
||||||
#else
|
#else
|
||||||
UNREACHABLE_MSG("Missing Linux implementation");
|
if (unlink(file_path.c_str()) != 0) {
|
||||||
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
|
LOG_ERROR(Common_Filesystem, "Failed to unlink the file at path={}, ec_message={}",
|
||||||
|
PathToUTF8String(file_path), ec.message());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,11 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
|||||||
SUB(Lib, AvPlayer) \
|
SUB(Lib, AvPlayer) \
|
||||||
SUB(Lib, Ngs2) \
|
SUB(Lib, Ngs2) \
|
||||||
SUB(Lib, Audio3d) \
|
SUB(Lib, Audio3d) \
|
||||||
|
SUB(Lib, Ime) \
|
||||||
|
SUB(Lib, GameLiveStreaming) \
|
||||||
|
SUB(Lib, Remoteplay) \
|
||||||
|
SUB(Lib, SharePlay) \
|
||||||
|
SUB(Lib, Fiber) \
|
||||||
CLS(Frontend) \
|
CLS(Frontend) \
|
||||||
CLS(Render) \
|
CLS(Render) \
|
||||||
SUB(Render, Vulkan) \
|
SUB(Render, Vulkan) \
|
||||||
|
@ -81,6 +81,11 @@ enum class Class : u8 {
|
|||||||
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
||||||
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
||||||
Lib_Audio3d, ///< The LibSceAudio3d implementation.
|
Lib_Audio3d, ///< The LibSceAudio3d implementation.
|
||||||
|
Lib_Ime, ///< The LibSceIme implementation
|
||||||
|
Lib_GameLiveStreaming, ///< The LibSceGameLiveStreaming implementation
|
||||||
|
Lib_Remoteplay, ///< The LibSceRemotePlay implementation
|
||||||
|
Lib_SharePlay, ///< The LibSceSharePlay implemenation
|
||||||
|
Lib_Fiber, ///< The LibSceFiber implementation.
|
||||||
Frontend, ///< Emulator UI
|
Frontend, ///< Emulator UI
|
||||||
Render, ///< Video Core
|
Render, ///< Video Core
|
||||||
Render_Vulkan, ///< Vulkan backend
|
Render_Vulkan, ///< Vulkan backend
|
||||||
|
@ -95,6 +95,18 @@ static auto UserPaths = [] {
|
|||||||
user_dir =
|
user_dir =
|
||||||
std::filesystem::path(getenv("HOME")) / "Library" / "Application Support" / "shadPS4";
|
std::filesystem::path(getenv("HOME")) / "Library" / "Application Support" / "shadPS4";
|
||||||
}
|
}
|
||||||
|
#elif defined(__linux__)
|
||||||
|
auto user_dir = std::filesystem::current_path() / PORTABLE_DIR;
|
||||||
|
// Check if the "user" directory exists in the current path:
|
||||||
|
if (!std::filesystem::exists(user_dir)) {
|
||||||
|
// If it doesn't exist, use XDG_DATA_HOME if it is set, and provide a standard default
|
||||||
|
const char* xdg_data_home = getenv("XDG_DATA_HOME");
|
||||||
|
if (xdg_data_home != nullptr && strlen(xdg_data_home) > 0) {
|
||||||
|
user_dir = std::filesystem::path(xdg_data_home) / "shadPS4";
|
||||||
|
} else {
|
||||||
|
user_dir = std::filesystem::path(getenv("HOME")) / ".local" / "share" / "shadPS4";
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR;
|
const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR;
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,8 +6,10 @@
|
|||||||
#include "avplayer_impl.h"
|
#include "avplayer_impl.h"
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/libkernel.h"
|
#include "core/libraries/kernel/libkernel.h"
|
||||||
|
#include "core/linker.h"
|
||||||
|
|
||||||
using namespace Libraries::Kernel;
|
using namespace Libraries::Kernel;
|
||||||
|
|
||||||
@ -17,28 +19,32 @@ void* PS4_SYSV_ABI AvPlayer::Allocate(void* handle, u32 alignment, u32 size) {
|
|||||||
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
||||||
const auto allocate = self->m_init_data_original.memory_replacement.allocate;
|
const auto allocate = self->m_init_data_original.memory_replacement.allocate;
|
||||||
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
||||||
return allocate(ptr, alignment, size);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(allocate, ptr, alignment, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS4_SYSV_ABI AvPlayer::Deallocate(void* handle, void* memory) {
|
void PS4_SYSV_ABI AvPlayer::Deallocate(void* handle, void* memory) {
|
||||||
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
||||||
const auto deallocate = self->m_init_data_original.memory_replacement.deallocate;
|
const auto deallocate = self->m_init_data_original.memory_replacement.deallocate;
|
||||||
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
||||||
return deallocate(ptr, memory);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(deallocate, ptr, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* PS4_SYSV_ABI AvPlayer::AllocateTexture(void* handle, u32 alignment, u32 size) {
|
void* PS4_SYSV_ABI AvPlayer::AllocateTexture(void* handle, u32 alignment, u32 size) {
|
||||||
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
||||||
const auto allocate = self->m_init_data_original.memory_replacement.allocate_texture;
|
const auto allocate = self->m_init_data_original.memory_replacement.allocate_texture;
|
||||||
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
||||||
return allocate(ptr, alignment, size);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(allocate, ptr, alignment, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS4_SYSV_ABI AvPlayer::DeallocateTexture(void* handle, void* memory) {
|
void PS4_SYSV_ABI AvPlayer::DeallocateTexture(void* handle, void* memory) {
|
||||||
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
const auto* const self = reinterpret_cast<AvPlayer*>(handle);
|
||||||
const auto deallocate = self->m_init_data_original.memory_replacement.deallocate_texture;
|
const auto deallocate = self->m_init_data_original.memory_replacement.deallocate_texture;
|
||||||
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.memory_replacement.object_ptr;
|
||||||
return deallocate(ptr, memory);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(deallocate, ptr, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI AvPlayer::OpenFile(void* handle, const char* filename) {
|
int PS4_SYSV_ABI AvPlayer::OpenFile(void* handle, const char* filename) {
|
||||||
@ -47,7 +53,8 @@ int PS4_SYSV_ABI AvPlayer::OpenFile(void* handle, const char* filename) {
|
|||||||
|
|
||||||
const auto open = self->m_init_data_original.file_replacement.open;
|
const auto open = self->m_init_data_original.file_replacement.open;
|
||||||
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
||||||
return open(ptr, filename);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(open, ptr, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI AvPlayer::CloseFile(void* handle) {
|
int PS4_SYSV_ABI AvPlayer::CloseFile(void* handle) {
|
||||||
@ -56,7 +63,8 @@ int PS4_SYSV_ABI AvPlayer::CloseFile(void* handle) {
|
|||||||
|
|
||||||
const auto close = self->m_init_data_original.file_replacement.close;
|
const auto close = self->m_init_data_original.file_replacement.close;
|
||||||
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
||||||
return close(ptr);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(close, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI AvPlayer::ReadOffsetFile(void* handle, u8* buffer, u64 position, u32 length) {
|
int PS4_SYSV_ABI AvPlayer::ReadOffsetFile(void* handle, u8* buffer, u64 position, u32 length) {
|
||||||
@ -65,7 +73,8 @@ int PS4_SYSV_ABI AvPlayer::ReadOffsetFile(void* handle, u8* buffer, u64 position
|
|||||||
|
|
||||||
const auto read_offset = self->m_init_data_original.file_replacement.readOffset;
|
const auto read_offset = self->m_init_data_original.file_replacement.readOffset;
|
||||||
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
||||||
return read_offset(ptr, buffer, position, length);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(read_offset, ptr, buffer, position, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI AvPlayer::SizeFile(void* handle) {
|
u64 PS4_SYSV_ABI AvPlayer::SizeFile(void* handle) {
|
||||||
@ -74,7 +83,8 @@ u64 PS4_SYSV_ABI AvPlayer::SizeFile(void* handle) {
|
|||||||
|
|
||||||
const auto size = self->m_init_data_original.file_replacement.size;
|
const auto size = self->m_init_data_original.file_replacement.size;
|
||||||
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
const auto ptr = self->m_init_data_original.file_replacement.object_ptr;
|
||||||
return size(ptr);
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
return linker->ExecuteGuest(size, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SceAvPlayerInitData AvPlayer::StubInitData(const SceAvPlayerInitData& data) {
|
SceAvPlayerInitData AvPlayer::StubInitData(const SceAvPlayerInitData& data) {
|
||||||
|
@ -87,7 +87,12 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, SceAvPlayer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass other events to the game
|
DefaultEventCallback(opaque, event_id, 0, event_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvPlayerState::DefaultEventCallback(void* opaque, SceAvPlayerEvents event_id, s32 source_id,
|
||||||
|
void* event_data) {
|
||||||
|
auto const self = reinterpret_cast<AvPlayerState*>(opaque);
|
||||||
const auto callback = self->m_event_replacement.event_callback;
|
const auto callback = self->m_event_replacement.event_callback;
|
||||||
const auto ptr = self->m_event_replacement.object_ptr;
|
const auto ptr = self->m_event_replacement.object_ptr;
|
||||||
if (callback != nullptr) {
|
if (callback != nullptr) {
|
||||||
@ -102,8 +107,10 @@ AvPlayerState::AvPlayerState(const SceAvPlayerInitData& init_data)
|
|||||||
if (m_event_replacement.event_callback == nullptr || init_data.auto_start) {
|
if (m_event_replacement.event_callback == nullptr || init_data.auto_start) {
|
||||||
m_auto_start = true;
|
m_auto_start = true;
|
||||||
m_init_data.event_replacement.event_callback = &AvPlayerState::AutoPlayEventCallback;
|
m_init_data.event_replacement.event_callback = &AvPlayerState::AutoPlayEventCallback;
|
||||||
m_init_data.event_replacement.object_ptr = this;
|
} else {
|
||||||
|
m_init_data.event_replacement.event_callback = &AvPlayerState::DefaultEventCallback;
|
||||||
}
|
}
|
||||||
|
m_init_data.event_replacement.object_ptr = this;
|
||||||
if (init_data.default_language != nullptr) {
|
if (init_data.default_language != nullptr) {
|
||||||
std::memcpy(m_default_language, init_data.default_language, sizeof(m_default_language));
|
std::memcpy(m_default_language, init_data.default_language, sizeof(m_default_language));
|
||||||
}
|
}
|
||||||
@ -367,8 +374,7 @@ void AvPlayerState::EmitEvent(SceAvPlayerEvents event_id, void* event_data) {
|
|||||||
const auto callback = m_init_data.event_replacement.event_callback;
|
const auto callback = m_init_data.event_replacement.event_callback;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
const auto ptr = m_init_data.event_replacement.object_ptr;
|
const auto ptr = m_init_data.event_replacement.object_ptr;
|
||||||
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
callback(ptr, event_id, 0, event_data);
|
||||||
linker->ExecuteGuest(callback, ptr, event_id, 0, event_data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@ private:
|
|||||||
static void PS4_SYSV_ABI AutoPlayEventCallback(void* handle, SceAvPlayerEvents event_id,
|
static void PS4_SYSV_ABI AutoPlayEventCallback(void* handle, SceAvPlayerEvents event_id,
|
||||||
s32 source_id, void* event_data);
|
s32 source_id, void* event_data);
|
||||||
|
|
||||||
|
static void PS4_SYSV_ABI DefaultEventCallback(void* handle, SceAvPlayerEvents event_id,
|
||||||
|
s32 source_id, void* event_data);
|
||||||
|
|
||||||
void OnWarning(u32 id) override;
|
void OnWarning(u32 id) override;
|
||||||
void OnError() override;
|
void OnError() override;
|
||||||
void OnEOF() override;
|
void OnEOF() override;
|
||||||
|
@ -1,28 +1,75 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <magic_enum.hpp>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "ime_dialog.h"
|
#include "ime_dialog.h"
|
||||||
|
#include "ime_dialog_ui.h"
|
||||||
|
|
||||||
|
static constexpr std::array<float, 2> MAX_X_POSITIONS = {3840.0f, 1920.0f};
|
||||||
|
static constexpr std::array<float, 2> MAX_Y_POSITIONS = {2160.0f, 1080.0f};
|
||||||
|
|
||||||
namespace Libraries::ImeDialog {
|
namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
static OrbisImeDialogStatus g_ime_dlg_status = OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_NONE;
|
static OrbisImeDialogStatus g_ime_dlg_status = OrbisImeDialogStatus::NONE;
|
||||||
|
static OrbisImeDialogResult g_ime_dlg_result{};
|
||||||
|
static ImeDialogState g_ime_dlg_state{};
|
||||||
|
static ImeDialogUi g_ime_dlg_ui;
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogAbort() {
|
static bool IsValidOption(OrbisImeDialogOption option, OrbisImeType type) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
if (False(~option &
|
||||||
return ORBIS_OK;
|
(OrbisImeDialogOption::MULTILINE | OrbisImeDialogOption::NO_AUTO_COMPLETION))) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogForceClose() {
|
if (True(option & OrbisImeDialogOption::MULTILINE) && type != OrbisImeType::DEFAULT &&
|
||||||
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
type != OrbisImeType::BASIC_LATIN) {
|
||||||
return ORBIS_OK;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogForTestFunction() {
|
if (True(option & OrbisImeDialogOption::NO_AUTO_COMPLETION) && type != OrbisImeType::NUMBER &&
|
||||||
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
type != OrbisImeType::BASIC_LATIN) {
|
||||||
return ORBIS_OK;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error PS4_SYSV_ABI sceImeDialogAbort() {
|
||||||
|
if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "IME dialog not in use");
|
||||||
|
return Error::DIALOG_NOT_IN_USE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ime_dlg_status != OrbisImeDialogStatus::RUNNING) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "IME dialog not running");
|
||||||
|
return Error::DIALOG_NOT_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ime_dlg_status = OrbisImeDialogStatus::FINISHED;
|
||||||
|
g_ime_dlg_result.endstatus = OrbisImeDialogEndStatus::ABORTED;
|
||||||
|
|
||||||
|
return Error::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error PS4_SYSV_ABI sceImeDialogForceClose() {
|
||||||
|
if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "IME dialog not in use");
|
||||||
|
return Error::DIALOG_NOT_IN_USE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ime_dlg_status = OrbisImeDialogStatus::NONE;
|
||||||
|
g_ime_dlg_ui = ImeDialogUi();
|
||||||
|
g_ime_dlg_state = ImeDialogState();
|
||||||
|
|
||||||
|
return Error::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error PS4_SYSV_ABI sceImeDialogForTestFunction() {
|
||||||
|
return Error::INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState() {
|
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState() {
|
||||||
@ -45,26 +92,118 @@ int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result) {
|
Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result) {
|
||||||
result->endstatus = OrbisImeDialogEndStatus::ORBIS_IME_DIALOG_END_STATUS_OK;
|
if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
LOG_INFO(Lib_ImeDialog, "IME dialog is not running");
|
||||||
return ORBIS_OK;
|
return Error::DIALOG_NOT_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogGetStatus() {
|
if (result == nullptr) {
|
||||||
if (g_ime_dlg_status == OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_RUNNING) {
|
LOG_INFO(Lib_ImeDialog, "called with result (NULL)");
|
||||||
return OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_FINISHED;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result->endstatus = g_ime_dlg_result.endstatus;
|
||||||
|
|
||||||
|
if (g_ime_dlg_status == OrbisImeDialogStatus::RUNNING) {
|
||||||
|
return Error::DIALOG_NOT_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ime_dlg_state.CopyTextToOrbisBuffer();
|
||||||
|
return Error::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus() {
|
||||||
|
if (g_ime_dlg_status == OrbisImeDialogStatus::RUNNING) {
|
||||||
|
g_ime_dlg_state.CallTextFilter();
|
||||||
|
}
|
||||||
|
|
||||||
return g_ime_dlg_status;
|
return g_ime_dlg_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended) {
|
Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
if (g_ime_dlg_status != OrbisImeDialogStatus::NONE) {
|
||||||
const std::wstring_view text = L"shadPS4";
|
LOG_INFO(Lib_ImeDialog, "IME dialog is already running");
|
||||||
param->maxTextLength = text.size();
|
return Error::BUSY;
|
||||||
std::memcpy(param->inputTextBuffer, text.data(), text.size() * sizeof(wchar_t));
|
}
|
||||||
g_ime_dlg_status = OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_RUNNING;
|
|
||||||
return ORBIS_OK;
|
if (param == nullptr) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "called with param (NULL)");
|
||||||
|
return Error::INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->type)) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->type");
|
||||||
|
return Error::INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do correct param->option validation
|
||||||
|
// TODO: do correct param->supportedLanguages validation
|
||||||
|
|
||||||
|
if (param->posx < 0.0f ||
|
||||||
|
param->posx >=
|
||||||
|
MAX_X_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->posx");
|
||||||
|
return Error::INVALID_POSX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->posy < 0.0f ||
|
||||||
|
param->posy >=
|
||||||
|
MAX_Y_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->posy");
|
||||||
|
return Error::INVALID_POSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->horizontalAlignment)) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->horizontalAlignment");
|
||||||
|
return Error::INVALID_HORIZONTALIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->verticalAlignment)) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->verticalAlignment");
|
||||||
|
return Error::INVALID_VERTICALALIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidOption(param->option, param->type)) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->option");
|
||||||
|
return Error::INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->inputTextBuffer == nullptr) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->inputTextBuffer");
|
||||||
|
return Error::INVALID_INPUT_TEXT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extended) {
|
||||||
|
if (magic_enum::enum_contains(extended->priority)) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid extended->priority");
|
||||||
|
return Error::INVALID_EXTENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do correct extended->option validation
|
||||||
|
|
||||||
|
if ((extended->extKeyboardMode & 0xe3fffffc) != 0) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid extended->extKeyboardMode");
|
||||||
|
return Error::INVALID_EXTENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extended->disableDevice > 7) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid extended->disableDevice");
|
||||||
|
return Error::INVALID_EXTENDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->maxTextLength > ORBIS_IME_DIALOG_MAX_TEXT_LENGTH) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "Invalid param->maxTextLength");
|
||||||
|
return Error::INVALID_MAX_TEXT_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ime_dlg_result = {};
|
||||||
|
g_ime_dlg_state = ImeDialogState(param, extended);
|
||||||
|
g_ime_dlg_status = OrbisImeDialogStatus::RUNNING;
|
||||||
|
g_ime_dlg_ui = ImeDialogUi(&g_ime_dlg_state, &g_ime_dlg_status, &g_ime_dlg_result);
|
||||||
|
|
||||||
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogInitInternal() {
|
int PS4_SYSV_ABI sceImeDialogInitInternal() {
|
||||||
@ -87,10 +226,22 @@ int PS4_SYSV_ABI sceImeDialogSetPanelPosition() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogTerm() {
|
Error PS4_SYSV_ABI sceImeDialogTerm() {
|
||||||
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) {
|
||||||
g_ime_dlg_status = OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_NONE;
|
LOG_INFO(Lib_ImeDialog, "IME dialog not in use");
|
||||||
return ORBIS_OK;
|
return Error::DIALOG_NOT_IN_USE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ime_dlg_status == OrbisImeDialogStatus::RUNNING) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "IME dialog is still running");
|
||||||
|
return Error::DIALOG_NOT_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ime_dlg_status = OrbisImeDialogStatus::NONE;
|
||||||
|
g_ime_dlg_ui = ImeDialogUi();
|
||||||
|
g_ime_dlg_state = ImeDialogState();
|
||||||
|
|
||||||
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterlibSceImeDialog(Core::Loader::SymbolsResolver* sym) {
|
void RegisterlibSceImeDialog(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/enum.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
@ -11,71 +12,150 @@ class SymbolsResolver;
|
|||||||
|
|
||||||
namespace Libraries::ImeDialog {
|
namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
enum OrbisImeDialogStatus {
|
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 0x78;
|
||||||
ORBIS_IME_DIALOG_STATUS_NONE = 0,
|
|
||||||
ORBIS_IME_DIALOG_STATUS_RUNNING = 1,
|
enum class Error : u32 {
|
||||||
ORBIS_IME_DIALOG_STATUS_FINISHED = 2
|
OK = 0x0,
|
||||||
|
BUSY = 0x80bc0001,
|
||||||
|
NOT_OPENED = 0x80bc0002,
|
||||||
|
NO_MEMORY = 0x80bc0003,
|
||||||
|
CONNECTION_FAILED = 0x80bc0004,
|
||||||
|
TOO_MANY_REQUESTS = 0x80bc0005,
|
||||||
|
INVALID_TEXT = 0x80bc0006,
|
||||||
|
EVENT_OVERFLOW = 0x80bc0007,
|
||||||
|
NOT_ACTIVE = 0x80bc0008,
|
||||||
|
IME_SUSPENDING = 0x80bc0009,
|
||||||
|
DEVICE_IN_USE = 0x80bc000a,
|
||||||
|
INVALID_USER_ID = 0x80bc0010,
|
||||||
|
INVALID_TYPE = 0x80bc0011,
|
||||||
|
INVALID_SUPPORTED_LANGUAGES = 0x80bc0012,
|
||||||
|
INVALID_ENTER_LABEL = 0x80bc0013,
|
||||||
|
INVALID_INPUT_METHOD = 0x80bc0014,
|
||||||
|
INVALID_OPTION = 0x80bc0015,
|
||||||
|
INVALID_MAX_TEXT_LENGTH = 0x80bc0016,
|
||||||
|
INVALID_INPUT_TEXT_BUFFER = 0x80bc0017,
|
||||||
|
INVALID_POSX = 0x80bc0018,
|
||||||
|
INVALID_POSY = 0x80bc0019,
|
||||||
|
INVALID_HORIZONTALIGNMENT = 0x80bc001a,
|
||||||
|
INVALID_VERTICALALIGNMENT = 0x80bc001b,
|
||||||
|
INVALID_EXTENDED = 0x80bc001c,
|
||||||
|
INVALID_KEYBOARD_TYPE = 0x80bc001d,
|
||||||
|
INVALID_WORK = 0x80bc0020,
|
||||||
|
INVALID_ARG = 0x80bc0021,
|
||||||
|
INVALID_HANDLER = 0x80bc0022,
|
||||||
|
NO_RESOURCE_ID = 0x80bc0023,
|
||||||
|
INVALID_MODE = 0x80bc0024,
|
||||||
|
INVALID_PARAM = 0x80bc0030,
|
||||||
|
INVALID_ADDRESS = 0x80bc0031,
|
||||||
|
INVALID_RESERVED = 0x80bc0032,
|
||||||
|
INVALID_TIMING = 0x80bc0033,
|
||||||
|
INTERNAL = 0x80bc00ff,
|
||||||
|
DIALOG_INVALID_TITLE = 0x80bc0101,
|
||||||
|
DIALOG_NOT_RUNNING = 0x80bc0105,
|
||||||
|
DIALOG_NOT_FINISHED = 0x80bc0106,
|
||||||
|
DIALOG_NOT_IN_USE = 0x80bc0107,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OrbisImeDialogEndStatus {
|
enum class OrbisImeDialogStatus : u32 {
|
||||||
ORBIS_IME_DIALOG_END_STATUS_OK = 0,
|
NONE = 0,
|
||||||
ORBIS_IME_DIALOG_END_STATUS_USER_CANCELED = 1,
|
RUNNING = 1,
|
||||||
ORBIS_IME_DIALOG_END_STATUS_ABORTED = 2
|
FINISHED = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeDialogResult {
|
enum class OrbisImeDialogEndStatus : u32 {
|
||||||
OrbisImeDialogEndStatus endstatus;
|
OK = 0,
|
||||||
s32 reserved[12];
|
USER_CANCELED = 1,
|
||||||
|
ABORTED = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OrbisImeType {
|
enum class OrbisImeType : u32 {
|
||||||
ORBIS_IME_TYPE_DEFAULT = 0,
|
DEFAULT = 0,
|
||||||
ORBIS_IME_TYPE_BASIC_LATIN = 1,
|
BASIC_LATIN = 1,
|
||||||
ORBIS_IME_TYPE_URL = 2,
|
URL = 2,
|
||||||
ORBIS_IME_TYPE_MAIL = 3,
|
MAIL = 3,
|
||||||
ORBIS_IME_TYPE_NUMBER = 4
|
NUMBER = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OrbisImeEnterLabel {
|
enum class OrbisImeEnterLabel : u32 {
|
||||||
ORBIS_IME_ENTER_LABEL_DEFAULT = 0,
|
DEFAULT = 0,
|
||||||
ORBIS_IME_ENTER_LABEL_SEND = 1,
|
SEND = 1,
|
||||||
ORBIS_IME_ENTER_LABEL_SEARCH = 2,
|
SEARCH = 2,
|
||||||
ORBIS_IME_ENTER_LABEL_GO = 3
|
GO = 3,
|
||||||
};
|
|
||||||
enum OrbiImeInputMethod { ORBIS_IME_INPUT_METHOD_DEFAULT = 0 };
|
|
||||||
|
|
||||||
typedef int (*OrbisImeTextFilter)(wchar_t* outText, u32* outTextLength, const wchar_t* srcText,
|
|
||||||
u32 srcTextLength);
|
|
||||||
|
|
||||||
enum OrbisImeHorizontalAlignment {
|
|
||||||
ORBIS_IME_HALIGN_LEFT = 0,
|
|
||||||
ORBIS_IME_HALIGN_CENTER = 1,
|
|
||||||
ORBIS_IME_HALIGN_RIGHT = 2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OrbisImeVerticalAlignment {
|
enum class OrbisImeDialogOption : u32 {
|
||||||
ORBIS_IME_VALIGN_TOP = 0,
|
DEFAULT = 0,
|
||||||
ORBIS_IME_VALIGN_CENTER = 1,
|
MULTILINE = 1,
|
||||||
ORBIS_IME_VALIGN_BOTTOM = 2
|
NO_AUTO_CORRECTION = 2,
|
||||||
|
NO_AUTO_COMPLETION = 4,
|
||||||
|
// TODO: Document missing options
|
||||||
|
LARGE_RESOLUTION = 1024,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeDialogParam {
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDialogOption)
|
||||||
s32 userId;
|
|
||||||
OrbisImeType type;
|
enum class OrbisImeInputMethod : u32 {
|
||||||
u64 supportedLanguages;
|
DEFAULT = 0,
|
||||||
OrbisImeEnterLabel enterLabel;
|
};
|
||||||
OrbiImeInputMethod inputMethod;
|
|
||||||
OrbisImeTextFilter filter;
|
enum class OrbisImeHorizontalAlignment : u32 {
|
||||||
u32 option;
|
LEFT = 0,
|
||||||
u32 maxTextLength;
|
CENTER = 1,
|
||||||
wchar_t* inputTextBuffer;
|
RIGHT = 2,
|
||||||
float posx;
|
};
|
||||||
float posy;
|
|
||||||
OrbisImeHorizontalAlignment horizontalAlignment;
|
enum class OrbisImeVerticalAlignment : u32 {
|
||||||
OrbisImeVerticalAlignment verticalAlignment;
|
TOP = 0,
|
||||||
const wchar_t* placeholder;
|
CENTER = 1,
|
||||||
const wchar_t* title;
|
BOTTOM = 2,
|
||||||
s8 reserved[16];
|
};
|
||||||
|
|
||||||
|
enum class OrbisImePanelPriority : u32 {
|
||||||
|
DEFAULT = 0,
|
||||||
|
ALPHABET = 1,
|
||||||
|
SYMBOL = 2,
|
||||||
|
ACCENT = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OrbisImeKeyboardType : u32 {
|
||||||
|
NONE = 0,
|
||||||
|
DANISH = 1,
|
||||||
|
GERMAN = 2,
|
||||||
|
GERMAN_SW = 3,
|
||||||
|
ENGLISH_US = 4,
|
||||||
|
ENGLISH_GB = 5,
|
||||||
|
SPANISH = 6,
|
||||||
|
SPANISH_LA = 7,
|
||||||
|
FINNISH = 8,
|
||||||
|
FRENCH = 9,
|
||||||
|
FRENCH_BR = 10,
|
||||||
|
FRENCH_CA = 11,
|
||||||
|
FRENCH_SW = 12,
|
||||||
|
ITALIAN = 13,
|
||||||
|
DUTCH = 14,
|
||||||
|
NORWEGIAN = 15,
|
||||||
|
POLISH = 16,
|
||||||
|
PORTUGUESE_BR = 17,
|
||||||
|
PORTUGUESE_PT = 18,
|
||||||
|
RUSSIAN = 19,
|
||||||
|
SWEDISH = 20,
|
||||||
|
TURKISH = 21,
|
||||||
|
JAPANESE_ROMAN = 22,
|
||||||
|
JAPANESE_KANA = 23,
|
||||||
|
KOREAN = 24,
|
||||||
|
SM_CHINESE = 25,
|
||||||
|
TR_CHINESE_ZY = 26,
|
||||||
|
TR_CHINESE_PY_HK = 27,
|
||||||
|
TR_CHINESE_PY_TW = 28,
|
||||||
|
TR_CHINESE_CG = 29,
|
||||||
|
ARABIC_AR = 30,
|
||||||
|
THAI = 31,
|
||||||
|
CZECH = 32,
|
||||||
|
GREEK = 33,
|
||||||
|
INDONESIAN = 34,
|
||||||
|
VIETNAMESE = 35,
|
||||||
|
ROMANIAN = 36,
|
||||||
|
HUNGARIAN = 37,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeColor {
|
struct OrbisImeColor {
|
||||||
@ -85,57 +165,14 @@ struct OrbisImeColor {
|
|||||||
u8 a;
|
u8 a;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OrbisImePanelPriority {
|
struct OrbisImeDialogResult {
|
||||||
ORBIS_IME_PANEL_PRIORITY_DEFAULT = 0,
|
OrbisImeDialogEndStatus endstatus;
|
||||||
ORBIS_IME_PANEL_PRIORITY_ALPHABET = 1,
|
s32 reserved[12];
|
||||||
ORBIS_IME_PANEL_PRIORITY_SYMBOL = 2,
|
|
||||||
ORBIS_IME_PANEL_PRIORITY_ACCENT = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
enum OrbisImeKeyboardType {
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_NONE = 0,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_DANISH = 1,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_GERMAN = 2,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_GERMAN_SW = 3,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_ENGLISH_US = 4,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_ENGLISH_GB = 5,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_SPANISH = 6,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_SPANISH_LA = 7,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_FINNISH = 8,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_FRENCH = 9,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_FRENCH_BR = 10,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_FRENCH_CA = 11,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_FRENCH_SW = 12,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_ITALIAN = 13,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_DUTCH = 14,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_NORWEGIAN = 15,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_POLISH = 16,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_PORTUGUESE_BR = 17,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_PORTUGUESE_PT = 18,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_RUSSIAN = 19,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_SWEDISH = 20,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_TURKISH = 21,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_JAPANESE_ROMAN = 22,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_JAPANESE_KANA = 23,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_KOREAN = 24,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_SM_CHINESE = 25,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_TR_CHINESE_ZY = 26,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_TR_CHINESE_PY_HK = 27,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_TR_CHINESE_PY_TW = 28,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_TR_CHINESE_CG = 29,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_ARABIC_AR = 30,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_THAI = 31,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_CZECH = 32,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_GREEK = 33,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_INDONESIAN = 34,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_VIETNAMESE = 35,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_ROMANIAN = 36,
|
|
||||||
ORBIS_IME_KEYBOARD_TYPE_HUNGARIAN = 37
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeKeycode {
|
struct OrbisImeKeycode {
|
||||||
u16 keycode;
|
u16 keycode;
|
||||||
wchar_t character;
|
char16_t character;
|
||||||
u32 status;
|
u32 status;
|
||||||
OrbisImeKeyboardType type;
|
OrbisImeKeyboardType type;
|
||||||
s32 userId;
|
s32 userId;
|
||||||
@ -143,11 +180,34 @@ struct OrbisImeKeycode {
|
|||||||
u64 timestamp;
|
u64 timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*OrbisImeExtKeyboardFilter)(const OrbisImeKeycode* srcKeycode, u16* outKeycode,
|
typedef PS4_SYSV_ABI int (*OrbisImeTextFilter)(char16_t* outText, u32* outTextLength,
|
||||||
u32* outStatus, void* reserved);
|
const char16_t* srcText, u32 srcTextLength);
|
||||||
|
|
||||||
|
typedef PS4_SYSV_ABI int (*OrbisImeExtKeyboardFilter)(const OrbisImeKeycode* srcKeycode,
|
||||||
|
u16* outKeycode, u32* outStatus,
|
||||||
|
void* reserved);
|
||||||
|
|
||||||
|
struct OrbisImeDialogParam {
|
||||||
|
s32 userId;
|
||||||
|
OrbisImeType type;
|
||||||
|
u64 supportedLanguages;
|
||||||
|
OrbisImeEnterLabel enterLabel;
|
||||||
|
OrbisImeInputMethod inputMethod;
|
||||||
|
OrbisImeTextFilter filter;
|
||||||
|
OrbisImeDialogOption option;
|
||||||
|
u32 maxTextLength;
|
||||||
|
char16_t* inputTextBuffer;
|
||||||
|
float posx;
|
||||||
|
float posy;
|
||||||
|
OrbisImeHorizontalAlignment horizontalAlignment;
|
||||||
|
OrbisImeVerticalAlignment verticalAlignment;
|
||||||
|
const char16_t* placeholder;
|
||||||
|
const char16_t* title;
|
||||||
|
s8 reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
struct OrbisImeParamExtended {
|
struct OrbisImeParamExtended {
|
||||||
u32 option;
|
u32 option; // OrbisImeDialogOptionExtended
|
||||||
OrbisImeColor colorBase;
|
OrbisImeColor colorBase;
|
||||||
OrbisImeColor colorLine;
|
OrbisImeColor colorLine;
|
||||||
OrbisImeColor colorTextField;
|
OrbisImeColor colorTextField;
|
||||||
@ -165,21 +225,21 @@ struct OrbisImeParamExtended {
|
|||||||
int8_t reserved[60];
|
int8_t reserved[60];
|
||||||
};
|
};
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogAbort();
|
Error PS4_SYSV_ABI sceImeDialogAbort();
|
||||||
int PS4_SYSV_ABI sceImeDialogForceClose();
|
Error PS4_SYSV_ABI sceImeDialogForceClose();
|
||||||
int PS4_SYSV_ABI sceImeDialogForTestFunction();
|
Error PS4_SYSV_ABI sceImeDialogForTestFunction();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState();
|
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm();
|
int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetPanelSize();
|
int PS4_SYSV_ABI sceImeDialogGetPanelSize();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended();
|
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result);
|
Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result);
|
||||||
/*OrbisImeDialogStatus*/ int PS4_SYSV_ABI sceImeDialogGetStatus();
|
OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus();
|
||||||
int PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended);
|
Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended);
|
||||||
int PS4_SYSV_ABI sceImeDialogInitInternal();
|
int PS4_SYSV_ABI sceImeDialogInitInternal();
|
||||||
int PS4_SYSV_ABI sceImeDialogInitInternal2();
|
int PS4_SYSV_ABI sceImeDialogInitInternal2();
|
||||||
int PS4_SYSV_ABI sceImeDialogInitInternal3();
|
int PS4_SYSV_ABI sceImeDialogInitInternal3();
|
||||||
int PS4_SYSV_ABI sceImeDialogSetPanelPosition();
|
int PS4_SYSV_ABI sceImeDialogSetPanelPosition();
|
||||||
int PS4_SYSV_ABI sceImeDialogTerm();
|
Error PS4_SYSV_ABI sceImeDialogTerm();
|
||||||
|
|
||||||
void RegisterlibSceImeDialog(Core::Loader::SymbolsResolver* sym);
|
void RegisterlibSceImeDialog(Core::Loader::SymbolsResolver* sym);
|
||||||
} // namespace Libraries::ImeDialog
|
} // namespace Libraries::ImeDialog
|
390
src/core/libraries/dialogs/ime_dialog_ui.cpp
Normal file
390
src/core/libraries/dialogs/ime_dialog_ui.cpp
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <cwchar>
|
||||||
|
#include <string>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <magic_enum.hpp>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "core/libraries/dialogs/ime_dialog.h"
|
||||||
|
#include "core/libraries/dialogs/ime_dialog_ui.h"
|
||||||
|
#include "core/linker.h"
|
||||||
|
#include "imgui/imgui_std.h"
|
||||||
|
|
||||||
|
using namespace ImGui;
|
||||||
|
|
||||||
|
static constexpr ImVec2 BUTTON_SIZE{100.0f, 30.0f};
|
||||||
|
|
||||||
|
namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
|
ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param,
|
||||||
|
const OrbisImeParamExtended* extended) {
|
||||||
|
if (!param)
|
||||||
|
return;
|
||||||
|
|
||||||
|
userId = param->userId;
|
||||||
|
is_multiLine = True(param->option & OrbisImeDialogOption::MULTILINE);
|
||||||
|
is_numeric = param->type == OrbisImeType::NUMBER;
|
||||||
|
type = param->type;
|
||||||
|
enter_label = param->enterLabel;
|
||||||
|
text_filter = param->filter;
|
||||||
|
keyboard_filter = extended ? extended->extKeyboardFilter : nullptr;
|
||||||
|
max_text_length = param->maxTextLength;
|
||||||
|
text_buffer = param->inputTextBuffer;
|
||||||
|
|
||||||
|
if (param->title) {
|
||||||
|
std::size_t title_len = std::char_traits<char16_t>::length(param->title);
|
||||||
|
title.resize(title_len * 4 + 1);
|
||||||
|
title[title_len * 4] = '\0';
|
||||||
|
|
||||||
|
if (!ConvertOrbisToUTF8(param->title, title_len, &title[0], title_len * 4)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "Failed to convert title to utf8 encoding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->placeholder) {
|
||||||
|
std::size_t placeholder_len = std::char_traits<char16_t>::length(param->placeholder);
|
||||||
|
placeholder.resize(placeholder_len * 4 + 1);
|
||||||
|
placeholder[placeholder_len * 4] = '\0';
|
||||||
|
|
||||||
|
if (!ConvertOrbisToUTF8(param->placeholder, placeholder_len, &placeholder[0],
|
||||||
|
placeholder_len * 4)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "Failed to convert placeholder to utf8 encoding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t text_len = std::char_traits<char16_t>::length(text_buffer);
|
||||||
|
if (!ConvertOrbisToUTF8(text_buffer, text_len, current_text.begin(),
|
||||||
|
ORBIS_IME_DIALOG_MAX_TEXT_LENGTH * 4)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to utf8 encoding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImeDialogState::ImeDialogState(ImeDialogState&& other) noexcept
|
||||||
|
: input_changed(other.input_changed), userId(other.userId), is_multiLine(other.is_multiLine),
|
||||||
|
is_numeric(other.is_numeric), type(other.type), enter_label(other.enter_label),
|
||||||
|
text_filter(other.text_filter), keyboard_filter(other.keyboard_filter),
|
||||||
|
max_text_length(other.max_text_length), text_buffer(other.text_buffer),
|
||||||
|
title(std::move(other.title)), placeholder(std::move(other.placeholder)),
|
||||||
|
current_text(other.current_text) {
|
||||||
|
|
||||||
|
other.text_buffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImeDialogState& ImeDialogState::operator=(ImeDialogState&& other) {
|
||||||
|
if (this != &other) {
|
||||||
|
input_changed = other.input_changed;
|
||||||
|
userId = other.userId;
|
||||||
|
is_multiLine = other.is_multiLine;
|
||||||
|
is_numeric = other.is_numeric;
|
||||||
|
type = other.type;
|
||||||
|
enter_label = other.enter_label;
|
||||||
|
text_filter = other.text_filter;
|
||||||
|
keyboard_filter = other.keyboard_filter;
|
||||||
|
max_text_length = other.max_text_length;
|
||||||
|
text_buffer = other.text_buffer;
|
||||||
|
title = std::move(other.title);
|
||||||
|
placeholder = std::move(other.placeholder);
|
||||||
|
current_text = other.current_text;
|
||||||
|
|
||||||
|
other.text_buffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImeDialogState::CopyTextToOrbisBuffer() {
|
||||||
|
if (!text_buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConvertUTF8ToOrbis(current_text.begin(), current_text.capacity(), text_buffer,
|
||||||
|
max_text_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImeDialogState::CallTextFilter() {
|
||||||
|
if (!text_filter || !input_changed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_changed = false;
|
||||||
|
|
||||||
|
char16_t src_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0};
|
||||||
|
u32 src_text_length = current_text.size();
|
||||||
|
char16_t out_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0};
|
||||||
|
u32 out_text_length = ORBIS_IME_DIALOG_MAX_TEXT_LENGTH;
|
||||||
|
|
||||||
|
if (!ConvertUTF8ToOrbis(current_text.begin(), src_text_length, src_text,
|
||||||
|
ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to orbis encoding");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
int ret =
|
||||||
|
linker->ExecuteGuest(text_filter, out_text, &out_text_length, src_text, src_text_length);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConvertOrbisToUTF8(out_text, out_text_length, current_text.begin(),
|
||||||
|
ORBIS_IME_DIALOG_MAX_TEXT_LENGTH * 4)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to utf8 encoding");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImeDialogState::CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode,
|
||||||
|
u32* out_status) {
|
||||||
|
if (!keyboard_filter) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
int ret = linker->ExecuteGuest(keyboard_filter, src_keycode, out_keycode, out_status, nullptr);
|
||||||
|
|
||||||
|
return ret == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len,
|
||||||
|
char* utf8_text, std::size_t utf8_text_len) {
|
||||||
|
|
||||||
|
std::fill(utf8_text, utf8_text + utf8_text_len, '\0');
|
||||||
|
const ImWchar* orbis_text_ptr = reinterpret_cast<const ImWchar*>(orbis_text);
|
||||||
|
ImTextStrToUtf8(utf8_text, utf8_text_len, orbis_text_ptr, orbis_text_ptr + orbis_text_len);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_text_len,
|
||||||
|
char16_t* orbis_text, std::size_t orbis_text_len) {
|
||||||
|
|
||||||
|
std::fill(orbis_text, orbis_text + orbis_text_len, u'\0');
|
||||||
|
ImTextStrFromUtf8(reinterpret_cast<ImWchar*>(orbis_text), orbis_text_len, utf8_text, nullptr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImeDialogUi::ImeDialogUi(ImeDialogState* state, OrbisImeDialogStatus* status,
|
||||||
|
OrbisImeDialogResult* result)
|
||||||
|
: state(state), status(status), result(result) {
|
||||||
|
|
||||||
|
if (state && *status == OrbisImeDialogStatus::RUNNING) {
|
||||||
|
AddLayer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImeDialogUi::~ImeDialogUi() {
|
||||||
|
std::scoped_lock lock(draw_mutex);
|
||||||
|
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept
|
||||||
|
: state(other.state), status(other.status), result(other.result),
|
||||||
|
first_render(other.first_render) {
|
||||||
|
|
||||||
|
std::scoped_lock lock(draw_mutex, other.draw_mutex);
|
||||||
|
other.state = nullptr;
|
||||||
|
other.status = nullptr;
|
||||||
|
other.result = nullptr;
|
||||||
|
|
||||||
|
if (state && *status == OrbisImeDialogStatus::RUNNING) {
|
||||||
|
AddLayer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImeDialogUi& ImeDialogUi::operator=(ImeDialogUi&& other) {
|
||||||
|
std::scoped_lock lock(draw_mutex, other.draw_mutex);
|
||||||
|
Free();
|
||||||
|
|
||||||
|
state = other.state;
|
||||||
|
status = other.status;
|
||||||
|
result = other.result;
|
||||||
|
first_render = other.first_render;
|
||||||
|
other.state = nullptr;
|
||||||
|
other.status = nullptr;
|
||||||
|
other.result = nullptr;
|
||||||
|
|
||||||
|
if (state && *status == OrbisImeDialogStatus::RUNNING) {
|
||||||
|
AddLayer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImeDialogUi::Free() {
|
||||||
|
RemoveLayer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImeDialogUi::Draw() {
|
||||||
|
std::unique_lock lock{draw_mutex};
|
||||||
|
|
||||||
|
if (!state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status || *status != OrbisImeDialogStatus::RUNNING) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& ctx = *GetCurrentContext();
|
||||||
|
const auto& io = ctx.IO;
|
||||||
|
|
||||||
|
ImVec2 window_size;
|
||||||
|
|
||||||
|
if (state->is_multiLine) {
|
||||||
|
window_size = {500.0f, 300.0f};
|
||||||
|
} else {
|
||||||
|
window_size = {500.0f, 150.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
CentralizeWindow();
|
||||||
|
SetNextWindowSize(window_size);
|
||||||
|
SetNextWindowCollapsed(false);
|
||||||
|
|
||||||
|
if (first_render || !io.NavActive) {
|
||||||
|
SetNextWindowFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Begin("IME Dialog##ImeDialog", nullptr,
|
||||||
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings)) {
|
||||||
|
DrawPrettyBackground();
|
||||||
|
|
||||||
|
if (!state->title.empty()) {
|
||||||
|
SetWindowFontScale(1.7f);
|
||||||
|
TextUnformatted(state->title.data());
|
||||||
|
SetWindowFontScale(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->is_multiLine) {
|
||||||
|
DrawMultiLineInputText();
|
||||||
|
} else {
|
||||||
|
DrawInputText();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCursorPosY(GetCursorPosY() + 10.0f);
|
||||||
|
|
||||||
|
const char* button_text;
|
||||||
|
|
||||||
|
switch (state->enter_label) {
|
||||||
|
case OrbisImeEnterLabel::GO:
|
||||||
|
button_text = "Go##ImeDialogOK";
|
||||||
|
break;
|
||||||
|
case OrbisImeEnterLabel::SEARCH:
|
||||||
|
button_text = "Search##ImeDialogOK";
|
||||||
|
break;
|
||||||
|
case OrbisImeEnterLabel::SEND:
|
||||||
|
button_text = "Send##ImeDialogOK";
|
||||||
|
break;
|
||||||
|
case OrbisImeEnterLabel::DEFAULT:
|
||||||
|
default:
|
||||||
|
button_text = "OK##ImeDialogOK";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float button_spacing = 10.0f;
|
||||||
|
float total_button_width = BUTTON_SIZE.x * 2 + button_spacing;
|
||||||
|
float button_start_pos = (window_size.x - total_button_width) / 2.0f;
|
||||||
|
|
||||||
|
SetCursorPosX(button_start_pos);
|
||||||
|
|
||||||
|
if (Button(button_text, BUTTON_SIZE) ||
|
||||||
|
(!state->is_multiLine && IsKeyPressed(ImGuiKey_Enter))) {
|
||||||
|
*status = OrbisImeDialogStatus::FINISHED;
|
||||||
|
result->endstatus = OrbisImeDialogEndStatus::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SameLine(0.0f, button_spacing);
|
||||||
|
|
||||||
|
if (Button("Cancel##ImeDialogCancel", BUTTON_SIZE)) {
|
||||||
|
*status = OrbisImeDialogStatus::FINISHED;
|
||||||
|
result->endstatus = OrbisImeDialogEndStatus::USER_CANCELED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
End();
|
||||||
|
|
||||||
|
first_render = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImeDialogUi::DrawInputText() {
|
||||||
|
ImVec2 input_size = {GetWindowWidth() - 40.0f, 0.0f};
|
||||||
|
SetCursorPosX(20.0f);
|
||||||
|
if (first_render) {
|
||||||
|
SetKeyboardFocusHere();
|
||||||
|
}
|
||||||
|
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
|
||||||
|
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
|
||||||
|
state->max_text_length, input_size, ImGuiInputTextFlags_CallbackCharFilter,
|
||||||
|
InputTextCallback, this)) {
|
||||||
|
state->input_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImeDialogUi::DrawMultiLineInputText() {
|
||||||
|
ImVec2 input_size = {GetWindowWidth() - 40.0f, 200.0f};
|
||||||
|
SetCursorPosX(20.0f);
|
||||||
|
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackCharFilter |
|
||||||
|
static_cast<ImGuiInputTextFlags>(ImGuiInputTextFlags_Multiline);
|
||||||
|
if (first_render) {
|
||||||
|
SetKeyboardFocusHere();
|
||||||
|
}
|
||||||
|
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
|
||||||
|
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
|
||||||
|
state->max_text_length, input_size, flags, InputTextCallback, this)) {
|
||||||
|
state->input_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||||
|
ImeDialogUi* ui = static_cast<ImeDialogUi*>(data->UserData);
|
||||||
|
|
||||||
|
ASSERT(ui);
|
||||||
|
|
||||||
|
// Should we filter punctuation?
|
||||||
|
if (ui->state->is_numeric && (data->EventChar < '0' || data->EventChar > '9') &&
|
||||||
|
data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ui->state->keyboard_filter) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImGui encodes ImWchar32 as multi-byte UTF-8 characters
|
||||||
|
char* event_char = reinterpret_cast<char*>(&data->EventChar);
|
||||||
|
|
||||||
|
// Call the keyboard filter
|
||||||
|
OrbisImeKeycode src_keycode = {
|
||||||
|
.keycode = 0,
|
||||||
|
.character = 0,
|
||||||
|
.status = 1, // ??? 1 = key pressed, 0 = key released
|
||||||
|
.type = OrbisImeKeyboardType::ENGLISH_US, // TODO set this to the correct value (maybe use
|
||||||
|
// the current language?)
|
||||||
|
.userId = ui->state->userId,
|
||||||
|
.resourceId = 0,
|
||||||
|
.timestamp = 0};
|
||||||
|
|
||||||
|
if (!ui->state->ConvertUTF8ToOrbis(event_char, 4, &src_keycode.character, 1)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
src_keycode.keycode = src_keycode.character; // TODO set this to the correct value
|
||||||
|
|
||||||
|
u16 out_keycode;
|
||||||
|
u32 out_status;
|
||||||
|
|
||||||
|
ui->state->CallKeyboardFilter(&src_keycode, &out_keycode, &out_status);
|
||||||
|
|
||||||
|
// TODO. set the keycode
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Libraries::ImeDialog
|
84
src/core/libraries/dialogs/ime_dialog_ui.h
Normal file
84
src/core/libraries/dialogs/ime_dialog_ui.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "common/cstring.h"
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "core/libraries/dialogs/ime_dialog.h"
|
||||||
|
#include "imgui/imgui_layer.h"
|
||||||
|
|
||||||
|
namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
|
class ImeDialogUi;
|
||||||
|
|
||||||
|
class ImeDialogState final {
|
||||||
|
friend ImeDialogUi;
|
||||||
|
|
||||||
|
bool input_changed = false;
|
||||||
|
|
||||||
|
s32 userId{};
|
||||||
|
bool is_multiLine{};
|
||||||
|
bool is_numeric{};
|
||||||
|
OrbisImeType type{};
|
||||||
|
OrbisImeEnterLabel enter_label{};
|
||||||
|
OrbisImeTextFilter text_filter{};
|
||||||
|
OrbisImeExtKeyboardFilter keyboard_filter{};
|
||||||
|
u32 max_text_length{};
|
||||||
|
char16_t* text_buffer{};
|
||||||
|
std::vector<char> title;
|
||||||
|
std::vector<char> placeholder;
|
||||||
|
|
||||||
|
// A character can hold up to 4 bytes in UTF-8
|
||||||
|
Common::CString<ORBIS_IME_DIALOG_MAX_TEXT_LENGTH * 4> current_text;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ImeDialogState(const OrbisImeDialogParam* param = nullptr,
|
||||||
|
const OrbisImeParamExtended* extended = nullptr);
|
||||||
|
ImeDialogState(const ImeDialogState& other) = delete;
|
||||||
|
ImeDialogState(ImeDialogState&& other) noexcept;
|
||||||
|
ImeDialogState& operator=(ImeDialogState&& other);
|
||||||
|
|
||||||
|
bool CopyTextToOrbisBuffer();
|
||||||
|
bool CallTextFilter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode, u32* out_status);
|
||||||
|
|
||||||
|
bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text,
|
||||||
|
std::size_t native_text_len);
|
||||||
|
bool ConvertUTF8ToOrbis(const char* native_text, std::size_t utf8_text_len,
|
||||||
|
char16_t* orbis_text, std::size_t orbis_text_len);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImeDialogUi final : public ImGui::Layer {
|
||||||
|
ImeDialogState* state{};
|
||||||
|
OrbisImeDialogStatus* status{};
|
||||||
|
OrbisImeDialogResult* result{};
|
||||||
|
|
||||||
|
bool first_render = true;
|
||||||
|
std::mutex draw_mutex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ImeDialogUi(ImeDialogState* state = nullptr, OrbisImeDialogStatus* status = nullptr,
|
||||||
|
OrbisImeDialogResult* result = nullptr);
|
||||||
|
~ImeDialogUi() override;
|
||||||
|
ImeDialogUi(const ImeDialogUi& other) = delete;
|
||||||
|
ImeDialogUi(ImeDialogUi&& other) noexcept;
|
||||||
|
ImeDialogUi& operator=(ImeDialogUi&& other);
|
||||||
|
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Free();
|
||||||
|
|
||||||
|
void DrawInputText();
|
||||||
|
void DrawMultiLineInputText();
|
||||||
|
|
||||||
|
static int InputTextCallback(ImGuiInputTextCallbackData* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::ImeDialog
|
@ -499,3 +499,11 @@ constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF;
|
|||||||
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
|
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
|
||||||
constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007;
|
constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007;
|
||||||
constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005;
|
constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005;
|
||||||
|
|
||||||
|
// Fiber library
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_NULL = 0x80590001;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_ALIGNMENT = 0x80590002;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_RANGE = 0x80590003;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_INVALID = 0x80590004;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_PERMISSION = 0x80590005;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_STATE = 0x80590006;
|
284
src/core/libraries/fiber/fiber.cpp
Normal file
284
src/core/libraries/fiber/fiber.cpp
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "fiber.h"
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
#include "core/linker.h"
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Libraries::Fiber {
|
||||||
|
|
||||||
|
constexpr static u64 kFiberSignature = 0x054ad954;
|
||||||
|
|
||||||
|
thread_local SceFiber* gCurrentFiber = nullptr;
|
||||||
|
thread_local void* gFiberThread = nullptr;
|
||||||
|
|
||||||
|
void FiberEntry(void* param) {
|
||||||
|
SceFiber* fiber = static_cast<SceFiber*>(param);
|
||||||
|
u64 argRun = 0;
|
||||||
|
u64 argRet = 0;
|
||||||
|
|
||||||
|
gCurrentFiber = fiber;
|
||||||
|
|
||||||
|
if (fiber->pArgRun != nullptr) {
|
||||||
|
argRun = *fiber->pArgRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
linker->ExecuteGuest(fiber->entry, fiber->argOnInitialize, argRun);
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry,
|
||||||
|
u64 argOnInitialize, void* addrContext, u64 sizeContext,
|
||||||
|
const SceFiberOptParam* optParam) {
|
||||||
|
LOG_INFO(Lib_Fiber, "called: name = {}", name);
|
||||||
|
|
||||||
|
if (!fiber || !name || !entry) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber->signature = kFiberSignature;
|
||||||
|
|
||||||
|
fiber->entry = entry;
|
||||||
|
fiber->argOnInitialize = argOnInitialize;
|
||||||
|
|
||||||
|
fiber->argRun = 0;
|
||||||
|
fiber->pArgRun = &fiber->argRun;
|
||||||
|
fiber->argReturn = 0;
|
||||||
|
fiber->pArgReturn = &fiber->argReturn;
|
||||||
|
|
||||||
|
fiber->sizeContext = sizeContext;
|
||||||
|
|
||||||
|
fiber->state = FiberState::Init;
|
||||||
|
#ifdef _WIN64
|
||||||
|
fiber->handle = CreateFiber(sizeContext, FiberEntry, fiber);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH);
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam) {
|
||||||
|
LOG_ERROR(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!optParam) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
if (fiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
if (fiber->state != FiberState::Run) {
|
||||||
|
return ORBIS_FIBER_ERROR_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber->signature = 0;
|
||||||
|
fiber->state = FiberState::None;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
DeleteFiber(fiber->handle);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
if (fiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
if (fiber->state == FiberState::Run) {
|
||||||
|
return ORBIS_FIBER_ERROR_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gFiberThread == nullptr) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
gFiberThread = ConvertThreadToFiber(nullptr);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
gCurrentFiber = fiber;
|
||||||
|
|
||||||
|
if (fiber->pArgRun != nullptr) {
|
||||||
|
*fiber->pArgRun = argOnRunTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber->pArgReturn = argOnReturn;
|
||||||
|
fiber->state = FiberState::Run;
|
||||||
|
#ifdef _WIN64
|
||||||
|
SwitchToFiber(fiber->handle);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
if (fiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
if (gCurrentFiber == nullptr) {
|
||||||
|
return ORBIS_FIBER_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
|
if (fiber->state == FiberState::Run) {
|
||||||
|
return ORBIS_FIBER_ERROR_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gCurrentFiber->state = FiberState::Suspend;
|
||||||
|
|
||||||
|
// TODO: argOnRun
|
||||||
|
|
||||||
|
*fiber->pArgRun = argOnRunTo;
|
||||||
|
fiber->state = FiberState::Run;
|
||||||
|
|
||||||
|
gCurrentFiber = fiber;
|
||||||
|
#ifdef _WIN64
|
||||||
|
SwitchToFiber(fiber->handle);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber || !gCurrentFiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if (gCurrentFiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
*fiber = gCurrentFiber;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (gCurrentFiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gCurrentFiber->pArgReturn != nullptr) {
|
||||||
|
*gCurrentFiber->pArgReturn = argOnReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: argOnRun
|
||||||
|
gCurrentFiber->state = FiberState::Suspend;
|
||||||
|
gCurrentFiber = nullptr;
|
||||||
|
#ifdef _WIN64
|
||||||
|
SwitchToFiber(gFiberThread);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo) {
|
||||||
|
LOG_INFO(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber || !fiberInfo) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiberInfo->entry = fiber->entry;
|
||||||
|
fiberInfo->argOnInitialize = fiber->argOnInitialize;
|
||||||
|
fiberInfo->addrContext = nullptr;
|
||||||
|
fiberInfo->sizeContext = fiber->sizeContext;
|
||||||
|
fiberInfo->sizeContextMargin = 0;
|
||||||
|
|
||||||
|
strncpy(fiberInfo->name, fiber->name, ORBIS_FIBER_MAX_NAME_LENGTH);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags) {
|
||||||
|
LOG_ERROR(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (flags != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck() {
|
||||||
|
LOG_ERROR(Lib_Fiber, "called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name) {
|
||||||
|
LOG_INFO(Lib_Fiber, "called, name = {}", name);
|
||||||
|
|
||||||
|
if (!fiber || !name) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize);
|
||||||
|
LIB_FUNCTION("asjUJJ+aa8s", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberOptParamInitialize);
|
||||||
|
LIB_FUNCTION("JeNX5F-NzQU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberFinalize);
|
||||||
|
|
||||||
|
LIB_FUNCTION("a0LLrZWac0M", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberRun);
|
||||||
|
LIB_FUNCTION("PFT2S-tJ7Uk", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberSwitch);
|
||||||
|
LIB_FUNCTION("p+zLIOg27zU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberGetSelf);
|
||||||
|
LIB_FUNCTION("B0ZX2hx9DMw", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberReturnToThread);
|
||||||
|
|
||||||
|
LIB_FUNCTION("uq2Y5BFz0PE", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberGetInfo);
|
||||||
|
LIB_FUNCTION("Lcqty+QNWFc", "libSceFiber", 1, "libSceFiber", 1, 1,
|
||||||
|
sceFiberStartContextSizeCheck);
|
||||||
|
LIB_FUNCTION("Kj4nXMpnM8Y", "libSceFiber", 1, "libSceFiber", 1, 1,
|
||||||
|
sceFiberStopContextSizeCheck);
|
||||||
|
LIB_FUNCTION("JzyT91ucGDc", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberRename);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Libraries::Fiber
|
83
src/core/libraries/fiber/fiber.h
Normal file
83
src/core/libraries/fiber/fiber.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/types.h"
|
||||||
|
|
||||||
|
namespace Core::Loader {
|
||||||
|
class SymbolsResolver;
|
||||||
|
}
|
||||||
|
namespace Libraries::Fiber {
|
||||||
|
|
||||||
|
#define ORBIS_FIBER_MAX_NAME_LENGTH (31)
|
||||||
|
|
||||||
|
typedef void PS4_SYSV_ABI (*SceFiberEntry)(u64 argOnInitialize, u64 argOnRun);
|
||||||
|
|
||||||
|
enum FiberState : u32 {
|
||||||
|
None = 0u,
|
||||||
|
Init = 1u,
|
||||||
|
Run = 2u,
|
||||||
|
Suspend = 3u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceFiber {
|
||||||
|
u64 signature;
|
||||||
|
FiberState state;
|
||||||
|
SceFiberEntry entry;
|
||||||
|
|
||||||
|
u64 argOnInitialize;
|
||||||
|
|
||||||
|
u64 argRun;
|
||||||
|
u64* pArgRun;
|
||||||
|
|
||||||
|
u64 argReturn;
|
||||||
|
u64* pArgReturn;
|
||||||
|
|
||||||
|
u64 sizeContext;
|
||||||
|
|
||||||
|
char name[ORBIS_FIBER_MAX_NAME_LENGTH];
|
||||||
|
void* handle;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SceFiber) <= 256);
|
||||||
|
|
||||||
|
struct SceFiberInfo {
|
||||||
|
u64 size;
|
||||||
|
SceFiberEntry entry;
|
||||||
|
u64 argOnInitialize;
|
||||||
|
void* addrContext;
|
||||||
|
u64 sizeContext;
|
||||||
|
char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1];
|
||||||
|
u64 sizeContextMargin;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SceFiberInfo) <= 128);
|
||||||
|
|
||||||
|
typedef void* SceFiberOptParam;
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry,
|
||||||
|
u64 argOnInitialize, void* addrContext, u64 sizeContext,
|
||||||
|
const SceFiberOptParam* optParam);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck(void);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name);
|
||||||
|
|
||||||
|
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::Fiber
|
354
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
Normal file
354
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "gamelivestreaming.h"
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
namespace Libraries::GameLiveStreaming {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStartDebugBroadcast() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStopDebugBroadcast() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingApplySocialFeedbackMessageFilter() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingCheckCallback() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingClearPresetSocialFeedbackCommands() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingClearSocialFeedbackMessages() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingClearSpoilerTag() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingEnableLiveStreaming() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingEnableSocialFeedback() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetCurrentBroadcastScreenLayout() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetCurrentStatus(OrbisGameLiveStreamingStatus* status) {
|
||||||
|
memset(status, 0, sizeof(*status));
|
||||||
|
status->isOnAir = false;
|
||||||
|
LOG_DEBUG(Lib_GameLiveStreaming, "(STUBBED) called userid = {}", status->userId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetCurrentStatus2() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetProgramInfo() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetSocialFeedbackMessages() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetSocialFeedbackMessagesCount() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingInitialize() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingLaunchLiveViewer() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingLaunchLiveViewerA() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingPermitLiveStreaming() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingPermitServerSideRecording() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingPostSocialMessage() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingRegisterCallback() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenCloseSeparateMode() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenConfigureSeparateMode() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenInitialize() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenInitializeSeparateModeParameter() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenOpenSeparateMode() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenSetMode() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenTerminate() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetCameraFrameSetting() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetDefaultServiceProviderPermission() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetGuardAreas() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetInvitationSessionId() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetLinkCommentPreset() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetMaxBitrate() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetMetadata() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetPresetSocialFeedbackCommands() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetPresetSocialFeedbackCommandsDescription() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetServiceProviderPermission() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetSpoilerTag() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetStandbyScreenResource() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStartGenerateStandbyScreenResource() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStartSocialFeedbackMessageFiltering() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStopGenerateStandbyScreenResource() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStopSocialFeedbackMessageFiltering() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingTerminate() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingUnregisterCallback() {
|
||||||
|
LOG_ERROR(Lib_GameLiveStreaming, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceGameLiveStreaming(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("caqgDl+V9qA", "libSceGameLiveStreaming_debug", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingStartDebugBroadcast);
|
||||||
|
LIB_FUNCTION("0i8Lrllxwow", "libSceGameLiveStreaming_debug", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingStopDebugBroadcast);
|
||||||
|
LIB_FUNCTION("NqkTzemliC0", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingApplySocialFeedbackMessageFilter);
|
||||||
|
LIB_FUNCTION("PC4jq87+YQI", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingCheckCallback);
|
||||||
|
LIB_FUNCTION("FcHBfHjFXkA", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingClearPresetSocialFeedbackCommands);
|
||||||
|
LIB_FUNCTION("lZ2Sd0uEvpo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingClearSocialFeedbackMessages);
|
||||||
|
LIB_FUNCTION("6c2zGtThFww", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingClearSpoilerTag);
|
||||||
|
LIB_FUNCTION("dWM80AX39o4", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingEnableLiveStreaming);
|
||||||
|
LIB_FUNCTION("wBOQWjbWMfU", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingEnableSocialFeedback);
|
||||||
|
LIB_FUNCTION("aRSQNqbats4", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetCurrentBroadcastScreenLayout);
|
||||||
|
LIB_FUNCTION("CoPMx369EqM", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetCurrentStatus);
|
||||||
|
LIB_FUNCTION("lK8dLBNp9OE", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetCurrentStatus2);
|
||||||
|
LIB_FUNCTION("OIIm19xu+NM", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetProgramInfo);
|
||||||
|
LIB_FUNCTION("PMx7N4WqNdo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetSocialFeedbackMessages);
|
||||||
|
LIB_FUNCTION("yeQKjHETi40", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetSocialFeedbackMessagesCount);
|
||||||
|
LIB_FUNCTION("kvYEw2lBndk", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingInitialize);
|
||||||
|
LIB_FUNCTION("ysWfX5PPbfc", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingLaunchLiveViewer);
|
||||||
|
LIB_FUNCTION("cvRCb7DTAig", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingLaunchLiveViewerA);
|
||||||
|
LIB_FUNCTION("K0QxEbD7q+c", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingPermitLiveStreaming);
|
||||||
|
LIB_FUNCTION("-EHnU68gExU", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingPermitServerSideRecording);
|
||||||
|
LIB_FUNCTION("hggKhPySVgI", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingPostSocialMessage);
|
||||||
|
LIB_FUNCTION("nFP8qT9YXbo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingRegisterCallback);
|
||||||
|
LIB_FUNCTION("b5RaMD2J0So", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenCloseSeparateMode);
|
||||||
|
LIB_FUNCTION("hBdd8n6kuvE", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenConfigureSeparateMode);
|
||||||
|
LIB_FUNCTION("uhCmn81s-mU", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenInitialize);
|
||||||
|
LIB_FUNCTION("fo5B8RUaBxQ", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenInitializeSeparateModeParameter);
|
||||||
|
LIB_FUNCTION("iorzW0pKOiA", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenOpenSeparateMode);
|
||||||
|
LIB_FUNCTION("gDSvt78H3Oo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenSetMode);
|
||||||
|
LIB_FUNCTION("HE93dr-5rx4", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingScreenTerminate);
|
||||||
|
LIB_FUNCTION("3PSiwAzFISE", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetCameraFrameSetting);
|
||||||
|
LIB_FUNCTION("TwuUzTKKeek", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetDefaultServiceProviderPermission);
|
||||||
|
LIB_FUNCTION("Gw6S4oqlY7E", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetGuardAreas);
|
||||||
|
LIB_FUNCTION("QmQYwQ7OTJI", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetInvitationSessionId);
|
||||||
|
LIB_FUNCTION("Sb5bAXyUt5c", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetLinkCommentPreset);
|
||||||
|
LIB_FUNCTION("q-kxuaF7URU", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetMaxBitrate);
|
||||||
|
LIB_FUNCTION("hUY-mSOyGL0", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetMetadata);
|
||||||
|
LIB_FUNCTION("ycodiP2I0xo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetPresetSocialFeedbackCommands);
|
||||||
|
LIB_FUNCTION("x6deXUpQbBo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetPresetSocialFeedbackCommandsDescription);
|
||||||
|
LIB_FUNCTION("mCoz3k3zPmA", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetServiceProviderPermission);
|
||||||
|
LIB_FUNCTION("ZuX+zzz2DkA", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetSpoilerTag);
|
||||||
|
LIB_FUNCTION("MLvYI86FFAo", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingSetStandbyScreenResource);
|
||||||
|
LIB_FUNCTION("y0KkAydy9xE", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingStartGenerateStandbyScreenResource);
|
||||||
|
LIB_FUNCTION("Y1WxX7dPMCw", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingStartSocialFeedbackMessageFiltering);
|
||||||
|
LIB_FUNCTION("D7dg5QJ4FlE", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingStopGenerateStandbyScreenResource);
|
||||||
|
LIB_FUNCTION("bYuGUBuIsaY", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingStopSocialFeedbackMessageFiltering);
|
||||||
|
LIB_FUNCTION("9yK6Fk8mKOQ", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingTerminate);
|
||||||
|
LIB_FUNCTION("5XHaH3kL+bA", "libSceGameLiveStreaming", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingUnregisterCallback);
|
||||||
|
LIB_FUNCTION("caqgDl+V9qA", "libSceGameLiveStreaming_direct_streaming", 1,
|
||||||
|
"libSceGameLiveStreaming", 1, 1, sceGameLiveStreamingStartDebugBroadcast);
|
||||||
|
LIB_FUNCTION("0i8Lrllxwow", "libSceGameLiveStreaming_direct_streaming", 1,
|
||||||
|
"libSceGameLiveStreaming", 1, 1, sceGameLiveStreamingStopDebugBroadcast);
|
||||||
|
LIB_FUNCTION("CoPMx369EqM", "libSceGameLiveStreamingCompat", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingGetCurrentStatus);
|
||||||
|
LIB_FUNCTION("ysWfX5PPbfc", "libSceGameLiveStreamingCompat", 1, "libSceGameLiveStreaming", 1, 1,
|
||||||
|
sceGameLiveStreamingLaunchLiveViewer);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::GameLiveStreaming
|
81
src/core/libraries/game_live_streaming/gamelivestreaming.h
Normal file
81
src/core/libraries/game_live_streaming/gamelivestreaming.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// 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::GameLiveStreaming {
|
||||||
|
|
||||||
|
struct OrbisGameLiveStreamingStatus {
|
||||||
|
bool isOnAir;
|
||||||
|
u8 align[3];
|
||||||
|
u32 spectatorCounts;
|
||||||
|
s32 userId;
|
||||||
|
u8 reserved[60];
|
||||||
|
};
|
||||||
|
struct OrbisGameLiveStreamingStatus2 {
|
||||||
|
s32 userId;
|
||||||
|
bool isOnAir;
|
||||||
|
u8 align[3];
|
||||||
|
u32 spectatorCounts;
|
||||||
|
u32 textMessageCounts;
|
||||||
|
u32 commandMessageCounts;
|
||||||
|
u32 broadcastVideoResolution;
|
||||||
|
u8 reserved[48];
|
||||||
|
};
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStartDebugBroadcast();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStopDebugBroadcast();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingApplySocialFeedbackMessageFilter();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingCheckCallback();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingClearPresetSocialFeedbackCommands();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingClearSocialFeedbackMessages();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingClearSpoilerTag();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingEnableLiveStreaming();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingEnableSocialFeedback();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetCurrentBroadcastScreenLayout();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetCurrentStatus(OrbisGameLiveStreamingStatus* status);
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetCurrentStatus2();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetProgramInfo();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetSocialFeedbackMessages();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingGetSocialFeedbackMessagesCount();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingInitialize();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingLaunchLiveViewer();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingLaunchLiveViewerA();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingPermitLiveStreaming();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingPermitServerSideRecording();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingPostSocialMessage();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingRegisterCallback();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenCloseSeparateMode();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenConfigureSeparateMode();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenInitialize();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenInitializeSeparateModeParameter();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenOpenSeparateMode();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenSetMode();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingScreenTerminate();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetCameraFrameSetting();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetDefaultServiceProviderPermission();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetGuardAreas();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetInvitationSessionId();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetLinkCommentPreset();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetMaxBitrate();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetMetadata();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetPresetSocialFeedbackCommands();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetPresetSocialFeedbackCommandsDescription();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetServiceProviderPermission();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetSpoilerTag();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingSetStandbyScreenResource();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStartGenerateStandbyScreenResource();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStartSocialFeedbackMessageFiltering();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStopGenerateStandbyScreenResource();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingStopSocialFeedbackMessageFiltering();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingTerminate();
|
||||||
|
int PS4_SYSV_ABI sceGameLiveStreamingUnregisterCallback();
|
||||||
|
|
||||||
|
void RegisterlibSceGameLiveStreaming(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::GameLiveStreaming
|
@ -1076,10 +1076,28 @@ s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmInsertPushColorMarker() {
|
s32 PS4_SYSV_ABI sceGnmInsertPushColorMarker(u32* cmdbuf, u32 size, const char* marker, u32 color) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
|
if (cmdbuf && marker) {
|
||||||
|
const auto len = std::strlen(marker);
|
||||||
|
const u32 packet_size = ((len + 0xc) >> 2) + ((len + 0x10) >> 3) * 2;
|
||||||
|
if (packet_size + 2 == size) {
|
||||||
|
auto* nop = reinterpret_cast<PM4CmdNop*>(cmdbuf);
|
||||||
|
nop->header =
|
||||||
|
PM4Type3Header{PM4ItOpcode::Nop, packet_size, PM4ShaderType::ShaderGraphics};
|
||||||
|
nop->data_block[0] = PM4CmdNop::PayloadType::DebugColorMarkerPush;
|
||||||
|
const auto marker_len = len + 1;
|
||||||
|
std::memcpy(&nop->data_block[1], marker, marker_len);
|
||||||
|
*reinterpret_cast<u32*>(reinterpret_cast<u8*>(&nop->data_block[1]) + marker_len + 8) =
|
||||||
|
color;
|
||||||
|
std::memset(reinterpret_cast<u8*>(&nop->data_block[1]) + marker_len + 8 + sizeof(u32),
|
||||||
|
0, packet_size * 4 - marker_len - 8 - sizeof(u32));
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker) {
|
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker) {
|
||||||
LOG_TRACE(Lib_GnmDriver, "called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
@ -105,7 +105,7 @@ int PS4_SYSV_ABI sceGnmGpuPaDebugEnter();
|
|||||||
int PS4_SYSV_ABI sceGnmGpuPaDebugLeave();
|
int PS4_SYSV_ABI sceGnmGpuPaDebugLeave();
|
||||||
int PS4_SYSV_ABI sceGnmInsertDingDongMarker();
|
int PS4_SYSV_ABI sceGnmInsertDingDongMarker();
|
||||||
s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size);
|
s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size);
|
||||||
int PS4_SYSV_ABI sceGnmInsertPushColorMarker();
|
s32 PS4_SYSV_ABI sceGnmInsertPushColorMarker(u32* cmdbuf, u32 size, const char* marker, u32 color);
|
||||||
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker);
|
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker);
|
||||||
int PS4_SYSV_ABI sceGnmInsertSetColorMarker();
|
int PS4_SYSV_ABI sceGnmInsertSetColorMarker();
|
||||||
int PS4_SYSV_ABI sceGnmInsertSetMarker();
|
int PS4_SYSV_ABI sceGnmInsertSetMarker();
|
||||||
|
340
src/core/libraries/ime/ime.cpp
Normal file
340
src/core/libraries/ime/ime.cpp
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "ime.h"
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
namespace Libraries::Ime {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI FinalizeImeModule() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI InitializeImeModule() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeCheckFilterText() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeCheckRemoteEventParam() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeCheckUpdateTextInfo() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeClose() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeConfigGet() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeConfigSet() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeConfirmCandidate() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDicAddWord() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDicDeleteLearnDics() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDicDeleteUserDics() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDicDeleteWord() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDicGetWords() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDicReplaceWord() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeDisableController() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeFilterText() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeForTestFunction() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeGetPanelPositionAndForm() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeGetPanelSize() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardClose() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardGetInfo() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardGetResourceId() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardOpen() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardOpenInternal() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardSetMode() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardUpdate() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeOpen() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeOpenInternal() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeParamInit() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeSetCandidateIndex() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeSetCaret() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeSetText() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeSetTextGeometry() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeUpdate() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshClearPreedit() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshClose() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshConfirmPreedit() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshDisableController() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshGetPanelPositionAndForm() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshInformConfirmdString() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshInformConfirmdString2() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshOpen() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSendTextInfo() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetCaretGeometry() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetCaretIndexInPreedit() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetPanelPosition() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetParam() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetPreeditGeometry() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetSelectGeometry() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetSelectionText() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshUpdate() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshUpdateContext() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceImeVshUpdateContext2() {
|
||||||
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceIme(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("mN+ZoSN-8hQ", "libSceIme", 1, "libSceIme", 1, 1, FinalizeImeModule);
|
||||||
|
LIB_FUNCTION("uTW+63goeJs", "libSceIme", 1, "libSceIme", 1, 1, InitializeImeModule);
|
||||||
|
LIB_FUNCTION("Lf3DeGWC6xg", "libSceIme", 1, "libSceIme", 1, 1, sceImeCheckFilterText);
|
||||||
|
LIB_FUNCTION("zHuMUGb-AQI", "libSceIme", 1, "libSceIme", 1, 1, sceImeCheckRemoteEventParam);
|
||||||
|
LIB_FUNCTION("OTb0Mg+1i1k", "libSceIme", 1, "libSceIme", 1, 1, sceImeCheckUpdateTextInfo);
|
||||||
|
LIB_FUNCTION("TmVP8LzcFcY", "libSceIme", 1, "libSceIme", 1, 1, sceImeClose);
|
||||||
|
LIB_FUNCTION("Ho5NVQzpKHo", "libSceIme", 1, "libSceIme", 1, 1, sceImeConfigGet);
|
||||||
|
LIB_FUNCTION("P5dPeiLwm-M", "libSceIme", 1, "libSceIme", 1, 1, sceImeConfigSet);
|
||||||
|
LIB_FUNCTION("tKLmVIUkpyM", "libSceIme", 1, "libSceIme", 1, 1, sceImeConfirmCandidate);
|
||||||
|
LIB_FUNCTION("NYDsL9a0oEo", "libSceIme", 1, "libSceIme", 1, 1, sceImeDicAddWord);
|
||||||
|
LIB_FUNCTION("l01GKoyiQrY", "libSceIme", 1, "libSceIme", 1, 1, sceImeDicDeleteLearnDics);
|
||||||
|
LIB_FUNCTION("E2OcGgi-FPY", "libSceIme", 1, "libSceIme", 1, 1, sceImeDicDeleteUserDics);
|
||||||
|
LIB_FUNCTION("JAiMBkOTYKI", "libSceIme", 1, "libSceIme", 1, 1, sceImeDicDeleteWord);
|
||||||
|
LIB_FUNCTION("JoPdCUXOzMU", "libSceIme", 1, "libSceIme", 1, 1, sceImeDicGetWords);
|
||||||
|
LIB_FUNCTION("FuEl46uHDyo", "libSceIme", 1, "libSceIme", 1, 1, sceImeDicReplaceWord);
|
||||||
|
LIB_FUNCTION("E+f1n8e8DAw", "libSceIme", 1, "libSceIme", 1, 1, sceImeDisableController);
|
||||||
|
LIB_FUNCTION("evjOsE18yuI", "libSceIme", 1, "libSceIme", 1, 1, sceImeFilterText);
|
||||||
|
LIB_FUNCTION("wVkehxutK-U", "libSceIme", 1, "libSceIme", 1, 1, sceImeForTestFunction);
|
||||||
|
LIB_FUNCTION("T6FYjZXG93o", "libSceIme", 1, "libSceIme", 1, 1, sceImeGetPanelPositionAndForm);
|
||||||
|
LIB_FUNCTION("ziPDcIjO0Vk", "libSceIme", 1, "libSceIme", 1, 1, sceImeGetPanelSize);
|
||||||
|
LIB_FUNCTION("PMVehSlfZ94", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardClose);
|
||||||
|
LIB_FUNCTION("VkqLPArfFdc", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardGetInfo);
|
||||||
|
LIB_FUNCTION("dKadqZFgKKQ", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardGetResourceId);
|
||||||
|
LIB_FUNCTION("eaFXjfJv3xs", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardOpen);
|
||||||
|
LIB_FUNCTION("oYkJlMK51SA", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardOpenInternal);
|
||||||
|
LIB_FUNCTION("ua+13Hk9kKs", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardSetMode);
|
||||||
|
LIB_FUNCTION("3Hx2Uw9xnv8", "libSceIme", 1, "libSceIme", 1, 1, sceImeKeyboardUpdate);
|
||||||
|
LIB_FUNCTION("RPydv-Jr1bc", "libSceIme", 1, "libSceIme", 1, 1, sceImeOpen);
|
||||||
|
LIB_FUNCTION("16UI54cWRQk", "libSceIme", 1, "libSceIme", 1, 1, sceImeOpenInternal);
|
||||||
|
LIB_FUNCTION("WmYDzdC4EHI", "libSceIme", 1, "libSceIme", 1, 1, sceImeParamInit);
|
||||||
|
LIB_FUNCTION("TQaogSaqkEk", "libSceIme", 1, "libSceIme", 1, 1, sceImeSetCandidateIndex);
|
||||||
|
LIB_FUNCTION("WLxUN2WMim8", "libSceIme", 1, "libSceIme", 1, 1, sceImeSetCaret);
|
||||||
|
LIB_FUNCTION("ieCNrVrzKd4", "libSceIme", 1, "libSceIme", 1, 1, sceImeSetText);
|
||||||
|
LIB_FUNCTION("TXYHFRuL8UY", "libSceIme", 1, "libSceIme", 1, 1, sceImeSetTextGeometry);
|
||||||
|
LIB_FUNCTION("-4GCfYdNF1s", "libSceIme", 1, "libSceIme", 1, 1, sceImeUpdate);
|
||||||
|
LIB_FUNCTION("oOwl47ouxoM", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshClearPreedit);
|
||||||
|
LIB_FUNCTION("gtoTsGM9vEY", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshClose);
|
||||||
|
LIB_FUNCTION("wTKF4mUlSew", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshConfirmPreedit);
|
||||||
|
LIB_FUNCTION("rM-1hkuOhh0", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshDisableController);
|
||||||
|
LIB_FUNCTION("42xMaQ+GLeQ", "libSceIme", 1, "libSceIme", 1, 1,
|
||||||
|
sceImeVshGetPanelPositionAndForm);
|
||||||
|
LIB_FUNCTION("ZmmV6iukhyo", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshInformConfirmdString);
|
||||||
|
LIB_FUNCTION("EQBusz6Uhp8", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshInformConfirmdString2);
|
||||||
|
LIB_FUNCTION("LBicRa-hj3A", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshOpen);
|
||||||
|
LIB_FUNCTION("-IAOwd2nO7g", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSendTextInfo);
|
||||||
|
LIB_FUNCTION("qDagOjvJdNk", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetCaretGeometry);
|
||||||
|
LIB_FUNCTION("tNOlmxee-Nk", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetCaretIndexInPreedit);
|
||||||
|
LIB_FUNCTION("rASXozKkQ9g", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetPanelPosition);
|
||||||
|
LIB_FUNCTION("idvMaIu5H+k", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetParam);
|
||||||
|
LIB_FUNCTION("ga5GOgThbjo", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetPreeditGeometry);
|
||||||
|
LIB_FUNCTION("RuSca8rS6yA", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetSelectGeometry);
|
||||||
|
LIB_FUNCTION("J7COZrgSFRA", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshSetSelectionText);
|
||||||
|
LIB_FUNCTION("WqAayyok5p0", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshUpdate);
|
||||||
|
LIB_FUNCTION("O7Fdd+Oc-qQ", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshUpdateContext);
|
||||||
|
LIB_FUNCTION("fwcPR7+7Rks", "libSceIme", 1, "libSceIme", 1, 1, sceImeVshUpdateContext2);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::Ime
|
70
src/core/libraries/ime/ime.h
Normal file
70
src/core/libraries/ime/ime.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// 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::Ime {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI FinalizeImeModule();
|
||||||
|
int PS4_SYSV_ABI InitializeImeModule();
|
||||||
|
int PS4_SYSV_ABI sceImeCheckFilterText();
|
||||||
|
int PS4_SYSV_ABI sceImeCheckRemoteEventParam();
|
||||||
|
int PS4_SYSV_ABI sceImeCheckUpdateTextInfo();
|
||||||
|
int PS4_SYSV_ABI sceImeClose();
|
||||||
|
int PS4_SYSV_ABI sceImeConfigGet();
|
||||||
|
int PS4_SYSV_ABI sceImeConfigSet();
|
||||||
|
int PS4_SYSV_ABI sceImeConfirmCandidate();
|
||||||
|
int PS4_SYSV_ABI sceImeDicAddWord();
|
||||||
|
int PS4_SYSV_ABI sceImeDicDeleteLearnDics();
|
||||||
|
int PS4_SYSV_ABI sceImeDicDeleteUserDics();
|
||||||
|
int PS4_SYSV_ABI sceImeDicDeleteWord();
|
||||||
|
int PS4_SYSV_ABI sceImeDicGetWords();
|
||||||
|
int PS4_SYSV_ABI sceImeDicReplaceWord();
|
||||||
|
int PS4_SYSV_ABI sceImeDisableController();
|
||||||
|
int PS4_SYSV_ABI sceImeFilterText();
|
||||||
|
int PS4_SYSV_ABI sceImeForTestFunction();
|
||||||
|
int PS4_SYSV_ABI sceImeGetPanelPositionAndForm();
|
||||||
|
int PS4_SYSV_ABI sceImeGetPanelSize();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardClose();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardGetInfo();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardGetResourceId();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardOpen();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardOpenInternal();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardSetMode();
|
||||||
|
int PS4_SYSV_ABI sceImeKeyboardUpdate();
|
||||||
|
int PS4_SYSV_ABI sceImeOpen();
|
||||||
|
int PS4_SYSV_ABI sceImeOpenInternal();
|
||||||
|
int PS4_SYSV_ABI sceImeParamInit();
|
||||||
|
int PS4_SYSV_ABI sceImeSetCandidateIndex();
|
||||||
|
int PS4_SYSV_ABI sceImeSetCaret();
|
||||||
|
int PS4_SYSV_ABI sceImeSetText();
|
||||||
|
int PS4_SYSV_ABI sceImeSetTextGeometry();
|
||||||
|
int PS4_SYSV_ABI sceImeUpdate();
|
||||||
|
int PS4_SYSV_ABI sceImeVshClearPreedit();
|
||||||
|
int PS4_SYSV_ABI sceImeVshClose();
|
||||||
|
int PS4_SYSV_ABI sceImeVshConfirmPreedit();
|
||||||
|
int PS4_SYSV_ABI sceImeVshDisableController();
|
||||||
|
int PS4_SYSV_ABI sceImeVshGetPanelPositionAndForm();
|
||||||
|
int PS4_SYSV_ABI sceImeVshInformConfirmdString();
|
||||||
|
int PS4_SYSV_ABI sceImeVshInformConfirmdString2();
|
||||||
|
int PS4_SYSV_ABI sceImeVshOpen();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSendTextInfo();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetCaretGeometry();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetCaretIndexInPreedit();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetPanelPosition();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetParam();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetPreeditGeometry();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetSelectGeometry();
|
||||||
|
int PS4_SYSV_ABI sceImeVshSetSelectionText();
|
||||||
|
int PS4_SYSV_ABI sceImeVshUpdate();
|
||||||
|
int PS4_SYSV_ABI sceImeVshUpdateContext();
|
||||||
|
int PS4_SYSV_ABI sceImeVshUpdateContext2();
|
||||||
|
|
||||||
|
void RegisterlibSceIme(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::Ime
|
@ -148,7 +148,7 @@ int PS4_SYSV_ABI sceKernelGettimeofday(OrbisKernelTimeval* tp) {
|
|||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
FILETIME filetime;
|
FILETIME filetime;
|
||||||
GetSystemTimeAsFileTime(&filetime);
|
GetSystemTimePreciseAsFileTime(&filetime);
|
||||||
|
|
||||||
constexpr u64 UNIX_TIME_START = 0x295E9648864000;
|
constexpr u64 UNIX_TIME_START = 0x295E9648864000;
|
||||||
constexpr u64 TICKS_PER_SECOND = 1000000;
|
constexpr u64 TICKS_PER_SECOND = 1000000;
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
#include "core/libraries/dialogs/error_dialog.h"
|
#include "core/libraries/dialogs/error_dialog.h"
|
||||||
#include "core/libraries/dialogs/ime_dialog.h"
|
#include "core/libraries/dialogs/ime_dialog.h"
|
||||||
#include "core/libraries/disc_map/disc_map.h"
|
#include "core/libraries/disc_map/disc_map.h"
|
||||||
|
#include "core/libraries/game_live_streaming/gamelivestreaming.h"
|
||||||
#include "core/libraries/gnmdriver/gnmdriver.h"
|
#include "core/libraries/gnmdriver/gnmdriver.h"
|
||||||
|
#include "core/libraries/ime/ime.h"
|
||||||
#include "core/libraries/kernel/libkernel.h"
|
#include "core/libraries/kernel/libkernel.h"
|
||||||
#include "core/libraries/libc_internal/libc_internal.h"
|
#include "core/libraries/libc_internal/libc_internal.h"
|
||||||
#include "core/libraries/libpng/pngdec.h"
|
#include "core/libraries/libpng/pngdec.h"
|
||||||
@ -26,10 +28,12 @@
|
|||||||
#include "core/libraries/pad/pad.h"
|
#include "core/libraries/pad/pad.h"
|
||||||
#include "core/libraries/playgo/playgo.h"
|
#include "core/libraries/playgo/playgo.h"
|
||||||
#include "core/libraries/random/random.h"
|
#include "core/libraries/random/random.h"
|
||||||
|
#include "core/libraries/remote_play/remoteplay.h"
|
||||||
#include "core/libraries/rtc/rtc.h"
|
#include "core/libraries/rtc/rtc.h"
|
||||||
#include "core/libraries/save_data/dialog/savedatadialog.h"
|
#include "core/libraries/save_data/dialog/savedatadialog.h"
|
||||||
#include "core/libraries/save_data/savedata.h"
|
#include "core/libraries/save_data/savedata.h"
|
||||||
#include "core/libraries/screenshot/screenshot.h"
|
#include "core/libraries/screenshot/screenshot.h"
|
||||||
|
#include "core/libraries/share_play/shareplay.h"
|
||||||
#include "core/libraries/system/commondialog.h"
|
#include "core/libraries/system/commondialog.h"
|
||||||
#include "core/libraries/system/msgdialog.h"
|
#include "core/libraries/system/msgdialog.h"
|
||||||
#include "core/libraries/system/posix.h"
|
#include "core/libraries/system/posix.h"
|
||||||
@ -77,6 +81,10 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
|||||||
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
|
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
|
||||||
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
|
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
|
||||||
Libraries::Audio3d::RegisterlibSceAudio3d(sym);
|
Libraries::Audio3d::RegisterlibSceAudio3d(sym);
|
||||||
|
Libraries::Ime::RegisterlibSceIme(sym);
|
||||||
|
Libraries::GameLiveStreaming::RegisterlibSceGameLiveStreaming(sym);
|
||||||
|
Libraries::SharePlay::RegisterlibSceSharePlay(sym);
|
||||||
|
Libraries::Remoteplay::RegisterlibSceRemoteplay(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries
|
} // namespace Libraries
|
||||||
|
@ -734,9 +734,16 @@ int PS4_SYSV_ABI sceNetInetNtopWithScopeId() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetInetPton() {
|
int PS4_SYSV_ABI sceNetInetPton(int af, const char* src, void* dst) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
#ifdef WIN32
|
||||||
return ORBIS_OK;
|
int res = InetPtonA(af, src, dst);
|
||||||
|
#else
|
||||||
|
int res = inet_pton(af, src, dst);
|
||||||
|
#endif
|
||||||
|
if (res < 0) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetInetPtonEx() {
|
int PS4_SYSV_ABI sceNetInetPtonEx() {
|
||||||
|
@ -169,7 +169,7 @@ u64 PS4_SYSV_ABI sceNetHtonll(u64 host64);
|
|||||||
u16 PS4_SYSV_ABI sceNetHtons(u16 host16);
|
u16 PS4_SYSV_ABI sceNetHtons(u16 host16);
|
||||||
const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32 size);
|
const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32 size);
|
||||||
int PS4_SYSV_ABI sceNetInetNtopWithScopeId();
|
int PS4_SYSV_ABI sceNetInetNtopWithScopeId();
|
||||||
int PS4_SYSV_ABI sceNetInetPton();
|
int PS4_SYSV_ABI sceNetInetPton(int af, const char* src, void* dst);
|
||||||
int PS4_SYSV_ABI sceNetInetPtonEx();
|
int PS4_SYSV_ABI sceNetInetPtonEx();
|
||||||
int PS4_SYSV_ABI sceNetInetPtonWithScopeId();
|
int PS4_SYSV_ABI sceNetInetPtonWithScopeId();
|
||||||
int PS4_SYSV_ABI sceNetInfoDumpStart();
|
int PS4_SYSV_ABI sceNetInfoDumpStart();
|
||||||
|
@ -26,3 +26,11 @@ constexpr int ORBIS_NET_CTL_STATE_IPOBTAINED = 3;
|
|||||||
constexpr int ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED = 1;
|
constexpr int ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED = 1;
|
||||||
constexpr int ORBIS_SCE_NET_CTL_EVENT_TYPE_DISCONNECT_REQ_FINISHED = 2;
|
constexpr int ORBIS_SCE_NET_CTL_EVENT_TYPE_DISCONNECT_REQ_FINISHED = 2;
|
||||||
constexpr int ORBIS_NET_CTL_EVENT_TYPE_IPOBTAINED = 3;
|
constexpr int ORBIS_NET_CTL_EVENT_TYPE_IPOBTAINED = 3;
|
||||||
|
|
||||||
|
// get info codes
|
||||||
|
// device
|
||||||
|
constexpr int ORBIS_NET_CTL_DEVICE_WIRED = 0;
|
||||||
|
constexpr int ORBIS_NET_CTL_DEVICE_WIRELESS = 1;
|
||||||
|
// link
|
||||||
|
constexpr int ORBIS_NET_CTL_LINK_DISCONNECTED = 0;
|
||||||
|
constexpr int ORBIS_NET_CTL_LINK_CONNECTED = 1;
|
||||||
|
0
src/core/libraries/network/net_obj.cpp
Normal file
0
src/core/libraries/network/net_obj.cpp
Normal file
0
src/core/libraries/network/net_obj.h
Normal file
0
src/core/libraries/network/net_obj.h
Normal file
@ -1,6 +1,17 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
#include <Ws2tcpip.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
@ -149,15 +160,32 @@ int PS4_SYSV_ABI sceNetCtlGetIfStat() {
|
|||||||
int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) {
|
int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case ORBIS_NET_CTL_INFO_DEVICE:
|
case ORBIS_NET_CTL_INFO_DEVICE:
|
||||||
info->device = 0;
|
info->device = ORBIS_NET_CTL_DEVICE_WIRED;
|
||||||
break;
|
break;
|
||||||
case ORBIS_NET_CTL_INFO_LINK:
|
case ORBIS_NET_CTL_INFO_LINK:
|
||||||
info->link = 0; // disconnected
|
info->link = ORBIS_NET_CTL_LINK_DISCONNECTED;
|
||||||
break;
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_IP_ADDRESS: {
|
||||||
|
strcpy(info->ip_address,
|
||||||
|
"127.0.0.1"); // placeholder in case gethostbyname can't find another ip
|
||||||
|
char devname[80];
|
||||||
|
gethostname(devname, 80);
|
||||||
|
struct hostent* resolved = gethostbyname(devname);
|
||||||
|
for (int i = 0; resolved->h_addr_list[i] != nullptr; ++i) {
|
||||||
|
struct in_addr addrIn;
|
||||||
|
memcpy(&addrIn, resolved->h_addr_list[i], sizeof(u32));
|
||||||
|
char* addr = inet_ntoa(addrIn);
|
||||||
|
if (strcmp(addr, "127.0.0.1") != 0) {
|
||||||
|
strcpy(info->ip_address, addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Lib_NetCtl, "{} unsupported code", code);
|
LOG_ERROR(Lib_NetCtl, "{} unsupported code", code);
|
||||||
}
|
}
|
||||||
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
|
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +215,10 @@ int PS4_SYSV_ABI sceNetCtlGetNetEvConfigInfoIpcInt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlGetResult(int eventType, int* errorCode) {
|
int PS4_SYSV_ABI sceNetCtlGetResult(int eventType, int* errorCode) {
|
||||||
LOG_ERROR(Lib_NetCtl, "(STUBBED) called eventType = {} ", eventType);
|
if (!errorCode) {
|
||||||
|
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
|
||||||
|
}
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called eventType = {} ", eventType);
|
||||||
*errorCode = 0;
|
*errorCode = 0;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ typedef union OrbisNetCtlInfo {
|
|||||||
// GetInfo codes
|
// GetInfo codes
|
||||||
constexpr int ORBIS_NET_CTL_INFO_DEVICE = 1;
|
constexpr int ORBIS_NET_CTL_INFO_DEVICE = 1;
|
||||||
constexpr int ORBIS_NET_CTL_INFO_LINK = 4;
|
constexpr int ORBIS_NET_CTL_INFO_LINK = 4;
|
||||||
|
constexpr int ORBIS_NET_CTL_INFO_IP_ADDRESS = 14;
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetBweCheckCallbackIpcInt();
|
int PS4_SYSV_ABI sceNetBweCheckCallbackIpcInt();
|
||||||
int PS4_SYSV_ABI sceNetBweClearEventIpcInt();
|
int PS4_SYSV_ABI sceNetBweClearEventIpcInt();
|
||||||
|
@ -902,12 +902,13 @@ int PS4_SYSV_ABI sceNpCreateAsyncRequest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpCreateRequest() {
|
int PS4_SYSV_ABI sceNpCreateRequest() {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_ERROR(Lib_NpManager, "(DUMMY) called");
|
||||||
return ORBIS_OK;
|
static int id = 0;
|
||||||
|
return ++id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpDeleteRequest() {
|
int PS4_SYSV_ABI sceNpDeleteRequest(int reqId) {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_ERROR(Lib_NpManager, "(DUMMY) called reqId = {}", reqId);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ int PS4_SYSV_ABI sceNpCheckNpReachability();
|
|||||||
int PS4_SYSV_ABI sceNpCheckPlus();
|
int PS4_SYSV_ABI sceNpCheckPlus();
|
||||||
int PS4_SYSV_ABI sceNpCreateAsyncRequest();
|
int PS4_SYSV_ABI sceNpCreateAsyncRequest();
|
||||||
int PS4_SYSV_ABI sceNpCreateRequest();
|
int PS4_SYSV_ABI sceNpCreateRequest();
|
||||||
int PS4_SYSV_ABI sceNpDeleteRequest();
|
int PS4_SYSV_ABI sceNpDeleteRequest(int reqId);
|
||||||
int PS4_SYSV_ABI sceNpGetAccountAge();
|
int PS4_SYSV_ABI sceNpGetAccountAge();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountCountry();
|
int PS4_SYSV_ABI sceNpGetAccountCountry();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountCountryA();
|
int PS4_SYSV_ABI sceNpGetAccountCountryA();
|
||||||
|
@ -88,7 +88,7 @@ int PS4_SYSV_ABI scePadGetCapability() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerInformation* pInfo) {
|
int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerInformation* pInfo) {
|
||||||
LOG_INFO(Lib_Pad, "called handle = {}", handle);
|
LOG_DEBUG(Lib_Pad, "called handle = {}", handle);
|
||||||
if (handle < 0) {
|
if (handle < 0) {
|
||||||
pInfo->touchPadInfo.pixelDensity = 1;
|
pInfo->touchPadInfo.pixelDensity = 1;
|
||||||
pInfo->touchPadInfo.resolution.x = 1920;
|
pInfo->touchPadInfo.resolution.x = 1920;
|
||||||
|
309
src/core/libraries/remote_play/remoteplay.cpp
Normal file
309
src/core/libraries/remote_play/remoteplay.cpp
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "remoteplay.h"
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
namespace Libraries::Remoteplay {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayApprove() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayChangeEnterKey() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayClearAllRegistData() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayClearConnectHistory() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayConfirmDeviceRegist() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayDisconnect() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGeneratePinCode() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetApMode() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetConnectHistory() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetConnectionStatus(s32 userId, int* pStatus) {
|
||||||
|
*pStatus = ORBIS_REMOTEPLAY_CONNECTION_STATUS_DISCONNECT;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetConnectUserId() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetMbusDeviceInfo() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetOperationStatus() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetRemoteplayStatus() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetRpMode() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeClose() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeFilterResult() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeGetEvent() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeNotify() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeNotifyEventResult() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeOpen() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeSetCaret() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeSetText() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayInitialize() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayIsRemoteOskReady() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayIsRemotePlaying() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyMbusDeviceRegistComplete() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyNpPushWakeup() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyPinCodeError() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyUserDelete() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayPrintAllRegistData() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayProhibit() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayProhibitStreaming() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayServerLock() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayServerUnLock() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetApMode() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetLogLevel() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetProhibition() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetProhibitionForVsh() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetRpMode() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayTerminate() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI Func_1D5EE365ED5FADB3() {
|
||||||
|
LOG_ERROR(Lib_Remoteplay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceRemoteplay(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("xQeIryTX7dY", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayApprove);
|
||||||
|
LIB_FUNCTION("IYZ+Mu+8tPo", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayChangeEnterKey);
|
||||||
|
LIB_FUNCTION("ZYUsJtcAnqA", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayClearAllRegistData);
|
||||||
|
LIB_FUNCTION("cCheyCbF7qw", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayClearConnectHistory);
|
||||||
|
LIB_FUNCTION("tPYT-kGbZh8", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayConfirmDeviceRegist);
|
||||||
|
LIB_FUNCTION("6Lg4BNleJWc", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayDisconnect);
|
||||||
|
LIB_FUNCTION("j98LdSGy4eY", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGeneratePinCode);
|
||||||
|
LIB_FUNCTION("L+cL-M-DP3w", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetApMode);
|
||||||
|
LIB_FUNCTION("g4K51cY+PEw", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetConnectHistory);
|
||||||
|
LIB_FUNCTION("g3PNjYKWqnQ", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetConnectionStatus);
|
||||||
|
LIB_FUNCTION("3eBNV9A0BUM", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetConnectUserId);
|
||||||
|
LIB_FUNCTION("ufesWMVX6iU", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetMbusDeviceInfo);
|
||||||
|
LIB_FUNCTION("DxU4JGh4S2k", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetOperationStatus);
|
||||||
|
LIB_FUNCTION("n5OxFJEvPlc", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetRemoteplayStatus);
|
||||||
|
LIB_FUNCTION("Cekhs6LSHC0", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayGetRpMode);
|
||||||
|
LIB_FUNCTION("ig1ocbR7Ptw", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeClose);
|
||||||
|
LIB_FUNCTION("gV9-8cJPM3I", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeFilterResult);
|
||||||
|
LIB_FUNCTION("cMk57DZXe6c", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeGetEvent);
|
||||||
|
LIB_FUNCTION("-gwkQpOCl68", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeNotify);
|
||||||
|
LIB_FUNCTION("58v9tSlRxc8", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeNotifyEventResult);
|
||||||
|
LIB_FUNCTION("C3r2zT5ebMg", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeOpen);
|
||||||
|
LIB_FUNCTION("oB730zwoz0s", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeSetCaret);
|
||||||
|
LIB_FUNCTION("rOTg1Nljp8w", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayImeSetText);
|
||||||
|
LIB_FUNCTION("k1SwgkMSOM8", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayInitialize);
|
||||||
|
LIB_FUNCTION("R8RZC1ZIkzU", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayIsRemoteOskReady);
|
||||||
|
LIB_FUNCTION("uYhiELUtLgA", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayIsRemotePlaying);
|
||||||
|
LIB_FUNCTION("d-BBSEq1nfc", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayNotifyMbusDeviceRegistComplete);
|
||||||
|
LIB_FUNCTION("Yytq7NE38R8", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayNotifyNpPushWakeup);
|
||||||
|
LIB_FUNCTION("Wg-w8xjMZA4", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayNotifyPinCodeError);
|
||||||
|
LIB_FUNCTION("yheulqylKwI", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayNotifyUserDelete);
|
||||||
|
LIB_FUNCTION("t5ZvUiZ1hpE", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayPrintAllRegistData);
|
||||||
|
LIB_FUNCTION("mrNh78tBpmg", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayProhibit);
|
||||||
|
LIB_FUNCTION("7QLrixwVHcU", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayProhibitStreaming);
|
||||||
|
LIB_FUNCTION("-ThIlThsN80", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayServerLock);
|
||||||
|
LIB_FUNCTION("0Z-Pm5rZJOI", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayServerUnLock);
|
||||||
|
LIB_FUNCTION("xSrhtSLIjOc", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplaySetApMode);
|
||||||
|
LIB_FUNCTION("5-2agAeaE+c", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplaySetLogLevel);
|
||||||
|
LIB_FUNCTION("Rf0XMVR7xPw", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplaySetProhibition);
|
||||||
|
LIB_FUNCTION("n4l3FTZtNQM", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplaySetProhibitionForVsh);
|
||||||
|
LIB_FUNCTION("-BPcEQ1w8xc", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplaySetRpMode);
|
||||||
|
LIB_FUNCTION("BOwybKVa3Do", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
sceRemoteplayTerminate);
|
||||||
|
LIB_FUNCTION("HV7jZe1frbM", "libSceRemoteplay", 1, "libSceRemoteplay", 0, 0,
|
||||||
|
Func_1D5EE365ED5FADB3);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::Remoteplay
|
62
src/core/libraries/remote_play/remoteplay.h
Normal file
62
src/core/libraries/remote_play/remoteplay.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returning codes in sceRemoteplayGetConnectionStatus pstatus
|
||||||
|
constexpr int ORBIS_REMOTEPLAY_CONNECTION_STATUS_DISCONNECT = 0;
|
||||||
|
constexpr int ORBIS_REMOTEPLAY_CONNECTION_STATUS_CONNECT = 1;
|
||||||
|
|
||||||
|
namespace Libraries::Remoteplay {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayApprove();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayChangeEnterKey();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayClearAllRegistData();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayClearConnectHistory();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayConfirmDeviceRegist();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayDisconnect();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGeneratePinCode();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetApMode();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetConnectHistory();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetConnectionStatus(s32 userId, int* pStatus);
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetConnectUserId();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetMbusDeviceInfo();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetOperationStatus();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetRemoteplayStatus();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayGetRpMode();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeClose();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeFilterResult();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeGetEvent();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeNotify();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeNotifyEventResult();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeOpen();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeSetCaret();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayImeSetText();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayInitialize();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayIsRemoteOskReady();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayIsRemotePlaying();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyMbusDeviceRegistComplete();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyNpPushWakeup();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyPinCodeError();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayNotifyUserDelete();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayPrintAllRegistData();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayProhibit();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayProhibitStreaming();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayServerLock();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayServerUnLock();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetApMode();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetLogLevel();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetProhibition();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetProhibitionForVsh();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplaySetRpMode();
|
||||||
|
int PS4_SYSV_ABI sceRemoteplayTerminate();
|
||||||
|
int PS4_SYSV_ABI Func_1D5EE365ED5FADB3();
|
||||||
|
|
||||||
|
void RegisterlibSceRemoteplay(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::Remoteplay
|
186
src/core/libraries/share_play/shareplay.cpp
Normal file
186
src/core/libraries/share_play/shareplay.cpp
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "shareplay.h"
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
namespace Libraries::SharePlay {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayCrashDaemon() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetCurrentConnectionInfo(OrbisSharePlayConnectionInfo* pInfo) {
|
||||||
|
memset(pInfo, 0, sizeof(*pInfo));
|
||||||
|
pInfo->status = ORBIS_SHARE_PLAY_CONNECTION_STATUS_DORMANT;
|
||||||
|
LOG_DEBUG(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetCurrentConnectionInfoA() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetCurrentInfo() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetEvent() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayInitialize() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayNotifyDialogOpen() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayNotifyForceCloseForCdlg() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayNotifyOpenQuickMenu() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayResumeScreenForCdlg() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayServerLock() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayServerUnLock() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlaySetMode() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlaySetProhibition() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlaySetProhibitionModeWithAppId() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStartStandby() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStartStreaming() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStopStandby() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStopStreaming() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayTerminate() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI Func_2E93C0EA6A6B67C4() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI Func_C1C236728D88E177() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI Func_E9E80C474781F115() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI Func_F3DD6199DA15ED44() {
|
||||||
|
LOG_ERROR(Lib_SharePlay, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceSharePlay(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("ggnCfalLU-8", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayCrashDaemon);
|
||||||
|
LIB_FUNCTION("OOrLKB0bSDs", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayGetCurrentConnectionInfo);
|
||||||
|
LIB_FUNCTION("+MCXJlWdi+s", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayGetCurrentConnectionInfoA);
|
||||||
|
LIB_FUNCTION("vUMkWXQff3w", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayGetCurrentInfo);
|
||||||
|
LIB_FUNCTION("Md7Mdkr8LBc", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayGetEvent);
|
||||||
|
LIB_FUNCTION("isruqthpYcw", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayInitialize);
|
||||||
|
LIB_FUNCTION("9zwJpai7jGc", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayNotifyDialogOpen);
|
||||||
|
LIB_FUNCTION("VUW2V9cUTP4", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayNotifyForceCloseForCdlg);
|
||||||
|
LIB_FUNCTION("XL0WwUJoQPg", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayNotifyOpenQuickMenu);
|
||||||
|
LIB_FUNCTION("6-1fKaa5HlY", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayResumeScreenForCdlg);
|
||||||
|
LIB_FUNCTION("U28jAuLHj6c", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayServerLock);
|
||||||
|
LIB_FUNCTION("3Oaux9ITEtY", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayServerUnLock);
|
||||||
|
LIB_FUNCTION("QZy+KmyqKPU", "libSceSharePlay", 1, "libSceSharePlay", 0, 0, sceSharePlaySetMode);
|
||||||
|
LIB_FUNCTION("co2NCj--pnc", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlaySetProhibition);
|
||||||
|
LIB_FUNCTION("KADsbjNCgPo", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlaySetProhibitionModeWithAppId);
|
||||||
|
LIB_FUNCTION("-F6NddfUsa4", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayStartStandby);
|
||||||
|
LIB_FUNCTION("rWVNHNnEx6g", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayStartStreaming);
|
||||||
|
LIB_FUNCTION("zEDkUWLVwFI", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayStopStandby);
|
||||||
|
LIB_FUNCTION("aGlema+JxUU", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayStopStreaming);
|
||||||
|
LIB_FUNCTION("UaLjloJinow", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayTerminate);
|
||||||
|
LIB_FUNCTION("LpPA6mprZ8Q", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
Func_2E93C0EA6A6B67C4);
|
||||||
|
LIB_FUNCTION("wcI2co2I4Xc", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
Func_C1C236728D88E177);
|
||||||
|
LIB_FUNCTION("6egMR0eB8RU", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
Func_E9E80C474781F115);
|
||||||
|
LIB_FUNCTION("891hmdoV7UQ", "libSceSharePlay", 1, "libSceSharePlay", 0, 0,
|
||||||
|
Func_F3DD6199DA15ED44);
|
||||||
|
LIB_FUNCTION("OOrLKB0bSDs", "libSceSharePlayCompat", 1, "libSceSharePlay", 0, 0,
|
||||||
|
sceSharePlayGetCurrentConnectionInfo);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::SharePlay
|
54
src/core/libraries/share_play/shareplay.h
Normal file
54
src/core/libraries/share_play/shareplay.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <core/libraries/np_manager/np_manager.h>
|
||||||
|
#include "common/types.h"
|
||||||
|
|
||||||
|
namespace Core::Loader {
|
||||||
|
class SymbolsResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Libraries::SharePlay {
|
||||||
|
|
||||||
|
constexpr int ORBIS_SHARE_PLAY_CONNECTION_STATUS_DORMANT = 0x00;
|
||||||
|
constexpr int ORBIS_SHARE_PLAY_CONNECTION_STATUS_READY = 0x01;
|
||||||
|
constexpr int ORBIS_SHARE_PLAY_CONNECTION_STATUS_CONNECTED = 0x02;
|
||||||
|
|
||||||
|
struct OrbisSharePlayConnectionInfo {
|
||||||
|
int status;
|
||||||
|
int mode;
|
||||||
|
Libraries::NpManager::OrbisNpOnlineId hostOnlineId;
|
||||||
|
Libraries::NpManager::OrbisNpOnlineId visitorOnlineId;
|
||||||
|
s32 hostUserId;
|
||||||
|
s32 visitorUserId;
|
||||||
|
};
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSharePlayCrashDaemon();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetCurrentConnectionInfo(OrbisSharePlayConnectionInfo* pInfo);
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetCurrentConnectionInfoA();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetCurrentInfo();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayGetEvent();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayInitialize();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayNotifyDialogOpen();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayNotifyForceCloseForCdlg();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayNotifyOpenQuickMenu();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayResumeScreenForCdlg();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayServerLock();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayServerUnLock();
|
||||||
|
int PS4_SYSV_ABI sceSharePlaySetMode();
|
||||||
|
int PS4_SYSV_ABI sceSharePlaySetProhibition();
|
||||||
|
int PS4_SYSV_ABI sceSharePlaySetProhibitionModeWithAppId();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStartStandby();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStartStreaming();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStopStandby();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayStopStreaming();
|
||||||
|
int PS4_SYSV_ABI sceSharePlayTerminate();
|
||||||
|
int PS4_SYSV_ABI Func_2E93C0EA6A6B67C4();
|
||||||
|
int PS4_SYSV_ABI Func_C1C236728D88E177();
|
||||||
|
int PS4_SYSV_ABI Func_E9E80C474781F115();
|
||||||
|
int PS4_SYSV_ABI Func_F3DD6199DA15ED44();
|
||||||
|
|
||||||
|
void RegisterlibSceSharePlay(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::SharePlay
|
@ -491,7 +491,7 @@ int PS4_SYSV_ABI sceUserServiceGetImeRunCount() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(int* user_id) {
|
s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(int* user_id) {
|
||||||
LOG_INFO(Lib_UserService, "called");
|
LOG_DEBUG(Lib_UserService, "called");
|
||||||
if (user_id == nullptr) {
|
if (user_id == nullptr) {
|
||||||
LOG_ERROR(Lib_UserService, "user_id is null");
|
LOG_ERROR(Lib_UserService, "user_id is null");
|
||||||
return ORBIS_USER_SERVICE_ERROR_INVALID_ARGUMENT;
|
return ORBIS_USER_SERVICE_ERROR_INVALID_ARGUMENT;
|
||||||
|
@ -245,6 +245,7 @@ int MemoryManager::PoolCommit(VAddr virtual_addr, size_t size, MemoryProt prot)
|
|||||||
new_vma.is_exec = false;
|
new_vma.is_exec = false;
|
||||||
new_vma.phys_base = 0;
|
new_vma.phys_base = 0;
|
||||||
|
|
||||||
|
rasterizer->MapMemory(mapped_addr, size);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#ifdef ENABLE_QT_GUI
|
#ifdef ENABLE_QT_GUI
|
||||||
|
#include <QtCore>
|
||||||
#include "common/memory_patcher.h"
|
#include "common/memory_patcher.h"
|
||||||
#endif
|
#endif
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
@ -25,6 +26,7 @@
|
|||||||
#include "core/file_format/trp.h"
|
#include "core/file_format/trp.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/disc_map/disc_map.h"
|
#include "core/libraries/disc_map/disc_map.h"
|
||||||
|
#include "core/libraries/fiber/fiber.h"
|
||||||
#include "core/libraries/kernel/thread_management.h"
|
#include "core/libraries/kernel/thread_management.h"
|
||||||
#include "core/libraries/libc_internal/libc_internal.h"
|
#include "core/libraries/libc_internal/libc_internal.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
@ -79,6 +81,17 @@ Emulator::Emulator() {
|
|||||||
|
|
||||||
// Load renderdoc module.
|
// Load renderdoc module.
|
||||||
VideoCore::LoadRenderDoc();
|
VideoCore::LoadRenderDoc();
|
||||||
|
|
||||||
|
// Start the timer (Play Time)
|
||||||
|
#ifdef ENABLE_QT_GUI
|
||||||
|
start_time = std::chrono::steady_clock::now();
|
||||||
|
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||||
|
QString filePath = QString::fromStdString((user_dir / "play_time.txt").string());
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||||
|
LOG_INFO(Loader, "Error opening or creating play_time.txt");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Emulator::~Emulator() {
|
Emulator::~Emulator() {
|
||||||
@ -122,6 +135,14 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||||||
}
|
}
|
||||||
#ifdef ENABLE_QT_GUI
|
#ifdef ENABLE_QT_GUI
|
||||||
MemoryPatcher::g_game_serial = id;
|
MemoryPatcher::g_game_serial = id;
|
||||||
|
|
||||||
|
// Timer for 'Play Time'
|
||||||
|
QTimer* timer = new QTimer();
|
||||||
|
QObject::connect(timer, &QTimer::timeout, [this, id]() {
|
||||||
|
UpdatePlayTime(id);
|
||||||
|
start_time = std::chrono::steady_clock::now();
|
||||||
|
});
|
||||||
|
timer->start(60000); // 60000 ms = 1 minute
|
||||||
#endif
|
#endif
|
||||||
title = param_sfo->GetString("TITLE").value_or("Unknown title");
|
title = param_sfo->GetString("TITLE").value_or("Unknown title");
|
||||||
LOG_INFO(Loader, "Game id: {} Title: {}", id, title);
|
LOG_INFO(Loader, "Game id: {} Title: {}", id, title);
|
||||||
@ -228,6 +249,10 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||||||
window->waitEvent();
|
window->waitEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_QT_GUI
|
||||||
|
UpdatePlayTime(id);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +267,7 @@ void Emulator::Run(int& argc, char* argv[]) {
|
|||||||
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
|
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
|
||||||
constexpr std::array<SysModules, 13> ModulesToLoad{
|
constexpr std::array<SysModules, 13> ModulesToLoad{
|
||||||
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
||||||
{"libSceFiber.sprx", nullptr},
|
{"libSceFiber.sprx", &Libraries::Fiber::RegisterlibSceFiber},
|
||||||
{"libSceUlt.sprx", nullptr},
|
{"libSceUlt.sprx", nullptr},
|
||||||
{"libSceJson.sprx", nullptr},
|
{"libSceJson.sprx", nullptr},
|
||||||
{"libSceJson2.sprx", nullptr},
|
{"libSceJson2.sprx", nullptr},
|
||||||
@ -277,4 +302,74 @@ void Emulator::LoadSystemModules(const std::filesystem::path& file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_QT_GUI
|
||||||
|
void Emulator::UpdatePlayTime(const std::string& serial) {
|
||||||
|
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||||
|
QString filePath = QString::fromStdString((user_dir / "play_time.txt").string());
|
||||||
|
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||||
|
LOG_INFO(Loader, "Error opening play_time.txt");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end_time = std::chrono::steady_clock::now();
|
||||||
|
auto duration = std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time);
|
||||||
|
int totalSeconds = duration.count();
|
||||||
|
|
||||||
|
QTextStream in(&file);
|
||||||
|
QStringList lines;
|
||||||
|
QString content;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
content += in.readLine() + "\n";
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
QStringList existingLines = content.split('\n', Qt::SkipEmptyParts);
|
||||||
|
int accumulatedSeconds = 0;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (const QString& line : existingLines) {
|
||||||
|
QStringList parts = line.split(' ');
|
||||||
|
if (parts.size() == 2 && parts[0] == QString::fromStdString(serial)) {
|
||||||
|
QStringList timeParts = parts[1].split(':');
|
||||||
|
if (timeParts.size() == 3) {
|
||||||
|
int hours = timeParts[0].toInt();
|
||||||
|
int minutes = timeParts[1].toInt();
|
||||||
|
int seconds = timeParts[2].toInt();
|
||||||
|
accumulatedSeconds = hours * 3600 + minutes * 60 + seconds;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accumulatedSeconds += totalSeconds;
|
||||||
|
int hours = accumulatedSeconds / 3600;
|
||||||
|
int minutes = (accumulatedSeconds % 3600) / 60;
|
||||||
|
int seconds = accumulatedSeconds % 60;
|
||||||
|
QString playTimeSaved = QString::number(hours) + ":" +
|
||||||
|
QString::number(minutes).rightJustified(2, '0') + ":" +
|
||||||
|
QString::number(seconds).rightJustified(2, '0');
|
||||||
|
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
QTextStream out(&file);
|
||||||
|
bool lineUpdated = false;
|
||||||
|
|
||||||
|
for (const QString& line : existingLines) {
|
||||||
|
if (line.startsWith(QString::fromStdString(serial))) {
|
||||||
|
out << QString::fromStdString(serial) + " " + playTimeSaved + "\n";
|
||||||
|
lineUpdated = true;
|
||||||
|
} else {
|
||||||
|
out << line << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lineUpdated) {
|
||||||
|
out << QString::fromStdString(serial) + " " + playTimeSaved + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_INFO(Loader, "Playing time for {}: {}", serial, playTimeSaved.toStdString());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@ -27,6 +27,7 @@ public:
|
|||||||
|
|
||||||
void Run(const std::filesystem::path& file);
|
void Run(const std::filesystem::path& file);
|
||||||
void Run(int& argc, char* argv[]);
|
void Run(int& argc, char* argv[]);
|
||||||
|
void UpdatePlayTime(const std::string& serial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadSystemModules(const std::filesystem::path& file);
|
void LoadSystemModules(const std::filesystem::path& file);
|
||||||
@ -35,6 +36,7 @@ private:
|
|||||||
Input::GameController* controller;
|
Input::GameController* controller;
|
||||||
Core::Linker* linker;
|
Core::Linker* linker;
|
||||||
std::unique_ptr<Frontend::WindowSDL> window;
|
std::unique_ptr<Frontend::WindowSDL> window;
|
||||||
|
std::chrono::steady_clock::time_point start_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@ -21,7 +21,6 @@ extern void assert_fail_debug_msg(const char* msg);
|
|||||||
} \
|
} \
|
||||||
}())
|
}())
|
||||||
|
|
||||||
#define IMGUI_USE_WCHAR32
|
|
||||||
#define IMGUI_ENABLE_STB_TRUETYPE
|
#define IMGUI_ENABLE_STB_TRUETYPE
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
@ -30,3 +29,7 @@ extern void assert_fail_debug_msg(const char* msg);
|
|||||||
|
|
||||||
#define IM_VEC4_CLASS_EXTRA \
|
#define IM_VEC4_CLASS_EXTRA \
|
||||||
constexpr ImVec4(float _v) : x(_v), y(_v), z(_v), w(_v) {}
|
constexpr ImVec4(float _v) : x(_v), y(_v), z(_v), w(_v) {}
|
||||||
|
|
||||||
|
#ifdef IMGUI_USE_WCHAR32
|
||||||
|
#error "This project uses 16 bits wchar standard like Orbis"
|
||||||
|
#endif
|
@ -10,9 +10,10 @@ GameInfoClass::GameInfoClass() = default;
|
|||||||
GameInfoClass::~GameInfoClass() = default;
|
GameInfoClass::~GameInfoClass() = default;
|
||||||
|
|
||||||
void GameInfoClass::GetGameInfo(QWidget* parent) {
|
void GameInfoClass::GetGameInfo(QWidget* parent) {
|
||||||
QString installDir;
|
|
||||||
Common::FS::PathToQString(installDir, Config::getGameInstallDir());
|
|
||||||
QStringList filePaths;
|
QStringList filePaths;
|
||||||
|
for (const auto& installLoc : Config::getGameInstallDirs()) {
|
||||||
|
QString installDir;
|
||||||
|
Common::FS::PathToQString(installDir, installLoc);
|
||||||
QDir parentFolder(installDir);
|
QDir parentFolder(installDir);
|
||||||
QFileInfoList fileList = parentFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
QFileInfoList fileList = parentFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
for (const auto& fileInfo : fileList) {
|
for (const auto& fileInfo : fileList) {
|
||||||
@ -20,6 +21,7 @@ void GameInfoClass::GetGameInfo(QWidget* parent) {
|
|||||||
filePaths.append(fileInfo.absoluteFilePath());
|
filePaths.append(fileInfo.absoluteFilePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_games = QtConcurrent::mapped(filePaths, [&](const QString& path) {
|
m_games = QtConcurrent::mapped(filePaths, [&](const QString& path) {
|
||||||
return readGameInfo(Common::FS::PathFromQString(path));
|
return readGameInfo(Common::FS::PathFromQString(path));
|
||||||
}).results();
|
}).results();
|
||||||
|
@ -60,6 +60,9 @@ public:
|
|||||||
if (auto app_ver = psf.GetString("APP_VER"); app_ver.has_value()) {
|
if (auto app_ver = psf.GetString("APP_VER"); app_ver.has_value()) {
|
||||||
game.version = *app_ver;
|
game.version = *app_ver;
|
||||||
}
|
}
|
||||||
|
if (const auto play_time = psf.GetString("PLAY_TIME"); play_time.has_value()) {
|
||||||
|
game.play_time = *play_time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,9 @@ QWidget* GameInstallDialog::SetupGamesDirectory() {
|
|||||||
// Input.
|
// Input.
|
||||||
m_gamesDirectory = new QLineEdit();
|
m_gamesDirectory = new QLineEdit();
|
||||||
QString install_dir;
|
QString install_dir;
|
||||||
Common::FS::PathToQString(install_dir, Config::getGameInstallDir());
|
std::filesystem::path install_path =
|
||||||
|
Config::getGameInstallDirs().empty() ? "" : Config::getGameInstallDirs().front();
|
||||||
|
Common::FS::PathToQString(install_dir, install_path);
|
||||||
m_gamesDirectory->setText(install_dir);
|
m_gamesDirectory->setText(install_dir);
|
||||||
m_gamesDirectory->setMinimumWidth(400);
|
m_gamesDirectory->setMinimumWidth(400);
|
||||||
|
|
||||||
@ -124,8 +126,7 @@ void GameInstallDialog::Save() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Config::addGameInstallDir(Common::FS::PathFromQString(gamesDirectory));
|
||||||
Config::setGameInstallDir(Common::FS::PathFromQString(gamesDirectory));
|
|
||||||
Config::setAddonInstallDir(Common::FS::PathFromQString(addonsDirectory));
|
Config::setAddonInstallDir(Common::FS::PathFromQString(addonsDirectory));
|
||||||
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||||
Config::save(config_dir / "config.toml");
|
Config::save(config_dir / "config.toml");
|
||||||
|
@ -24,16 +24,17 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidg
|
|||||||
this->horizontalHeader()->setSortIndicatorShown(true);
|
this->horizontalHeader()->setSortIndicatorShown(true);
|
||||||
this->horizontalHeader()->setStretchLastSection(true);
|
this->horizontalHeader()->setStretchLastSection(true);
|
||||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
this->setColumnCount(8);
|
this->setColumnCount(9);
|
||||||
this->setColumnWidth(1, 300); // Name
|
this->setColumnWidth(1, 300); // Name
|
||||||
this->setColumnWidth(2, 120); // Serial
|
this->setColumnWidth(2, 120); // Serial
|
||||||
this->setColumnWidth(3, 90); // Region
|
this->setColumnWidth(3, 90); // Region
|
||||||
this->setColumnWidth(4, 90); // Firmware
|
this->setColumnWidth(4, 90); // Firmware
|
||||||
this->setColumnWidth(5, 90); // Size
|
this->setColumnWidth(5, 90); // Size
|
||||||
this->setColumnWidth(6, 90); // Version
|
this->setColumnWidth(6, 90); // Version
|
||||||
|
this->setColumnWidth(7, 100); // Play Time
|
||||||
QStringList headers;
|
QStringList headers;
|
||||||
headers << tr("Icon") << tr("Name") << tr("Serial") << tr("Region") << tr("Firmware")
|
headers << tr("Icon") << tr("Name") << tr("Serial") << tr("Region") << tr("Firmware")
|
||||||
<< tr("Size") << tr("Version") << tr("Path");
|
<< tr("Size") << tr("Version") << tr("Play Time") << tr("Path");
|
||||||
this->setHorizontalHeaderLabels(headers);
|
this->setHorizontalHeaderLabels(headers);
|
||||||
this->horizontalHeader()->setSortIndicatorShown(true);
|
this->horizontalHeader()->setSortIndicatorShown(true);
|
||||||
this->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
this->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||||
@ -100,9 +101,37 @@ void GameListFrame::PopulateGameList() {
|
|||||||
SetTableItem(i, 4, QString::fromStdString(m_game_info->m_games[i].fw));
|
SetTableItem(i, 4, QString::fromStdString(m_game_info->m_games[i].fw));
|
||||||
SetTableItem(i, 5, QString::fromStdString(m_game_info->m_games[i].size));
|
SetTableItem(i, 5, QString::fromStdString(m_game_info->m_games[i].size));
|
||||||
SetTableItem(i, 6, QString::fromStdString(m_game_info->m_games[i].version));
|
SetTableItem(i, 6, QString::fromStdString(m_game_info->m_games[i].version));
|
||||||
|
|
||||||
|
QString playTime = GetPlayTime(m_game_info->m_games[i].serial);
|
||||||
|
if (playTime.isEmpty()) {
|
||||||
|
m_game_info->m_games[i].play_time = "0:00:00";
|
||||||
|
SetTableItem(i, 7, "0");
|
||||||
|
} else {
|
||||||
|
QStringList timeParts = playTime.split(':');
|
||||||
|
int hours = timeParts[0].toInt();
|
||||||
|
int minutes = timeParts[1].toInt();
|
||||||
|
int seconds = timeParts[2].toInt();
|
||||||
|
|
||||||
|
QString formattedPlayTime;
|
||||||
|
if (hours > 0) {
|
||||||
|
formattedPlayTime += QString("%1h ").arg(hours);
|
||||||
|
}
|
||||||
|
if (minutes > 0) {
|
||||||
|
formattedPlayTime += QString("%1m ").arg(minutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedPlayTime = formattedPlayTime.trimmed();
|
||||||
|
m_game_info->m_games[i].play_time = playTime.toStdString();
|
||||||
|
if (formattedPlayTime.isEmpty()) {
|
||||||
|
SetTableItem(i, 7, "0");
|
||||||
|
} else {
|
||||||
|
SetTableItem(i, 7, formattedPlayTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString path;
|
QString path;
|
||||||
Common::FS::PathToQString(path, m_game_info->m_games[i].path);
|
Common::FS::PathToQString(path, m_game_info->m_games[i].path);
|
||||||
SetTableItem(i, 7, path);
|
SetTableItem(i, 8, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +200,7 @@ void GameListFrame::ResizeIcons(int iconSize) {
|
|||||||
this->setItem(index, 0, iconItem);
|
this->setItem(index, 0, iconItem);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
this->horizontalHeader()->setSectionResizeMode(7, QHeaderView::ResizeToContents);
|
this->horizontalHeader()->setSectionResizeMode(8, QHeaderView::ResizeToContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListFrame::SetTableItem(int row, int column, QString itemStr) {
|
void GameListFrame::SetTableItem(int row, int column, QString itemStr) {
|
||||||
@ -224,3 +253,33 @@ void GameListFrame::SetRegionFlag(int row, int column, QString itemStr) {
|
|||||||
this->setItem(row, column, item);
|
this->setItem(row, column, item);
|
||||||
this->setCellWidget(row, column, widget);
|
this->setCellWidget(row, column, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GameListFrame::GetPlayTime(const std::string& serial) {
|
||||||
|
QString playTime;
|
||||||
|
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||||
|
QString filePath = QString::fromStdString((user_dir / "play_time.txt").string());
|
||||||
|
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
return playTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!file.atEnd()) {
|
||||||
|
QByteArray line = file.readLine();
|
||||||
|
QString lineStr = QString::fromUtf8(line).trimmed();
|
||||||
|
|
||||||
|
QStringList parts = lineStr.split(' ');
|
||||||
|
if (parts.size() >= 2) {
|
||||||
|
QString fileSerial = parts[0];
|
||||||
|
QString time = parts[1];
|
||||||
|
|
||||||
|
if (fileSerial == QString::fromStdString(serial)) {
|
||||||
|
playTime = time;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
return playTime;
|
||||||
|
}
|
||||||
|
@ -29,6 +29,7 @@ public Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
void SetTableItem(int row, int column, QString itemStr);
|
void SetTableItem(int row, int column, QString itemStr);
|
||||||
void SetRegionFlag(int row, int column, QString itemStr);
|
void SetRegionFlag(int row, int column, QString itemStr);
|
||||||
|
QString GetPlayTime(const std::string& serial);
|
||||||
QList<QAction*> m_columnActs;
|
QList<QAction*> m_columnActs;
|
||||||
GameInfoClass* game_inf_get = nullptr;
|
GameInfoClass* game_inf_get = nullptr;
|
||||||
bool ListSortedAsc = true;
|
bool ListSortedAsc = true;
|
||||||
@ -68,6 +69,8 @@ public:
|
|||||||
case 6:
|
case 6:
|
||||||
return a.version < b.version;
|
return a.version < b.version;
|
||||||
case 7:
|
case 7:
|
||||||
|
return a.play_time < b.play_time;
|
||||||
|
case 8:
|
||||||
return a.path < b.path;
|
return a.path < b.path;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -89,6 +92,8 @@ public:
|
|||||||
case 6:
|
case 6:
|
||||||
return a.version > b.version;
|
return a.version > b.version;
|
||||||
case 7:
|
case 7:
|
||||||
|
return a.play_time > b.play_time;
|
||||||
|
case 8:
|
||||||
return a.path > b.path;
|
return a.path > b.path;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -19,6 +19,8 @@ struct GameInfo {
|
|||||||
std::string version = "Unknown";
|
std::string version = "Unknown";
|
||||||
std::string region = "Unknown";
|
std::string region = "Unknown";
|
||||||
std::string fw = "Unknown";
|
std::string fw = "Unknown";
|
||||||
|
|
||||||
|
std::string play_time = "Unknown";
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameListUtils {
|
class GameListUtils {
|
||||||
|
76
src/qt_gui/install_dir_select.cpp
Normal file
76
src/qt_gui/install_dir_select.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "install_dir_select.h"
|
||||||
|
|
||||||
|
InstallDirSelect::InstallDirSelect() : selected_dir() {
|
||||||
|
selected_dir = Config::getGameInstallDirs().empty() ? "" : Config::getGameInstallDirs().front();
|
||||||
|
|
||||||
|
if (!Config::getGameInstallDirs().empty() && Config::getGameInstallDirs().size() == 1) {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
layout->addWidget(SetupInstallDirList());
|
||||||
|
layout->addStretch();
|
||||||
|
layout->addWidget(SetupDialogActions());
|
||||||
|
|
||||||
|
setWindowTitle(tr("shadPS4 - Choose directory"));
|
||||||
|
setWindowIcon(QIcon(":images/shadps4.ico"));
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallDirSelect::~InstallDirSelect() {}
|
||||||
|
|
||||||
|
QWidget* InstallDirSelect::SetupInstallDirList() {
|
||||||
|
auto group = new QGroupBox(tr("Select which directory you want to install to."));
|
||||||
|
auto vlayout = new QVBoxLayout();
|
||||||
|
|
||||||
|
auto m_path_list = new QListWidget();
|
||||||
|
QList<QString> qt_list;
|
||||||
|
for (const auto& str : Config::getGameInstallDirs()) {
|
||||||
|
QString installDirPath;
|
||||||
|
Common::FS::PathToQString(installDirPath, str);
|
||||||
|
qt_list.append(installDirPath);
|
||||||
|
}
|
||||||
|
m_path_list->insertItems(0, qt_list);
|
||||||
|
m_path_list->setSpacing(1);
|
||||||
|
|
||||||
|
connect(m_path_list, &QListWidget::itemClicked, this, &InstallDirSelect::setSelectedDirectory);
|
||||||
|
connect(m_path_list, &QListWidget::itemActivated, this,
|
||||||
|
&InstallDirSelect::setSelectedDirectory);
|
||||||
|
|
||||||
|
vlayout->addWidget(m_path_list);
|
||||||
|
|
||||||
|
group->setLayout(vlayout);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstallDirSelect::setSelectedDirectory(QListWidgetItem* item) {
|
||||||
|
if (item) {
|
||||||
|
const auto highlighted_path = Common::FS::PathFromQString(item->text());
|
||||||
|
if (!highlighted_path.empty()) {
|
||||||
|
selected_dir = highlighted_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* InstallDirSelect::SetupDialogActions() {
|
||||||
|
auto actions = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
|
||||||
|
connect(actions, &QDialogButtonBox::accepted, this, &InstallDirSelect::accept);
|
||||||
|
connect(actions, &QDialogButtonBox::rejected, this, &InstallDirSelect::reject);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
31
src/qt_gui/install_dir_select.h
Normal file
31
src/qt_gui/install_dir_select.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QListWidget>
|
||||||
|
|
||||||
|
#include "common/config.h"
|
||||||
|
#include "common/path_util.h"
|
||||||
|
|
||||||
|
class QLineEdit;
|
||||||
|
|
||||||
|
class InstallDirSelect final : public QDialog {
|
||||||
|
public:
|
||||||
|
InstallDirSelect();
|
||||||
|
~InstallDirSelect();
|
||||||
|
|
||||||
|
std::filesystem::path getSelectedDirectory() {
|
||||||
|
return selected_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void BrowseGamesDirectory();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget* SetupInstallDirList();
|
||||||
|
QWidget* SetupDialogActions();
|
||||||
|
void setSelectedDirectory(QListWidgetItem* item);
|
||||||
|
std::filesystem::path selected_dir;
|
||||||
|
};
|
@ -29,7 +29,7 @@ int main(int argc, char* argv[]) {
|
|||||||
bool has_command_line_argument = argc > 1;
|
bool has_command_line_argument = argc > 1;
|
||||||
|
|
||||||
// Check if the game install directory is set
|
// Check if the game install directory is set
|
||||||
if (Config::getGameInstallDir().empty() && !has_command_line_argument) {
|
if (Config::getGameInstallDirs().empty() && !has_command_line_argument) {
|
||||||
GameInstallDialog dlg;
|
GameInstallDialog dlg;
|
||||||
dlg.exec();
|
dlg.exec();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "core/file_format/pkg.h"
|
#include "core/file_format/pkg.h"
|
||||||
#include "core/loader.h"
|
#include "core/loader.h"
|
||||||
#include "game_install_dialog.h"
|
#include "game_install_dialog.h"
|
||||||
|
#include "install_dir_select.h"
|
||||||
#include "main_window.h"
|
#include "main_window.h"
|
||||||
#include "settings_dialog.h"
|
#include "settings_dialog.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
@ -58,6 +59,7 @@ bool MainWindow::Init() {
|
|||||||
this->show();
|
this->show();
|
||||||
// load game list
|
// load game list
|
||||||
LoadGameLists();
|
LoadGameLists();
|
||||||
|
// Check for update
|
||||||
CheckUpdateMain(true);
|
CheckUpdateMain(true);
|
||||||
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end = std::chrono::steady_clock::now();
|
||||||
@ -671,7 +673,10 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||||||
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
|
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto extract_path = Config::getGameInstallDir() / pkg.GetTitleID();
|
InstallDirSelect ids;
|
||||||
|
ids.exec();
|
||||||
|
auto game_install_dir = ids.getSelectedDirectory();
|
||||||
|
auto extract_path = game_install_dir / pkg.GetTitleID();
|
||||||
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
||||||
QString gameDirPath;
|
QString gameDirPath;
|
||||||
Common::FS::PathToQString(gameDirPath, extract_path);
|
Common::FS::PathToQString(gameDirPath, extract_path);
|
||||||
@ -820,7 +825,7 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||||||
connect(&futureWatcher, &QFutureWatcher<void>::finished, this, [=, this]() {
|
connect(&futureWatcher, &QFutureWatcher<void>::finished, this, [=, this]() {
|
||||||
if (pkgNum == nPkg) {
|
if (pkgNum == nPkg) {
|
||||||
QString path;
|
QString path;
|
||||||
Common::FS::PathToQString(path, Config::getGameInstallDir());
|
Common::FS::PathToQString(path, game_install_dir);
|
||||||
QMessageBox extractMsgBox(this);
|
QMessageBox extractMsgBox(this);
|
||||||
extractMsgBox.setWindowTitle(tr("Extraction Finished"));
|
extractMsgBox.setWindowTitle(tr("Extraction Finished"));
|
||||||
extractMsgBox.setText(
|
extractMsgBox.setText(
|
||||||
|
@ -47,8 +47,6 @@ QStringList languageNames = {"Arabic",
|
|||||||
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0,
|
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0,
|
||||||
9, 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 28};
|
9, 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 28};
|
||||||
|
|
||||||
QStringList hideCursorStates = {"Never", "Idle", "Always"};
|
|
||||||
|
|
||||||
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent)
|
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent)
|
||||||
: QDialog(parent), ui(new Ui::SettingsDialog) {
|
: QDialog(parent), ui(new Ui::SettingsDialog) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -69,7 +67,14 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
ui->consoleLanguageComboBox->setCompleter(completer);
|
ui->consoleLanguageComboBox->setCompleter(completer);
|
||||||
|
|
||||||
ui->hideCursorComboBox->addItems(hideCursorStates);
|
ui->hideCursorComboBox->addItem(tr("Never"));
|
||||||
|
ui->hideCursorComboBox->addItem(tr("Idle"));
|
||||||
|
ui->hideCursorComboBox->addItem(tr("Always"));
|
||||||
|
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left");
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center");
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right");
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("None"), "none");
|
||||||
|
|
||||||
InitializeEmulatorLanguages();
|
InitializeEmulatorLanguages();
|
||||||
LoadValuesFromConfig();
|
LoadValuesFromConfig();
|
||||||
@ -102,15 +107,6 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
|
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
|
||||||
ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
|
ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
|
||||||
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left");
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center");
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right");
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("None"), "none");
|
|
||||||
|
|
||||||
QString currentBackButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
|
|
||||||
int index = ui->backButtonBehaviorComboBox->findData(currentBackButtonBehavior);
|
|
||||||
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
|
|
||||||
|
|
||||||
connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this,
|
connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this,
|
||||||
[this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); });
|
[this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); });
|
||||||
|
|
||||||
@ -175,14 +171,6 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
rpc->shutdown();
|
rpc->shutdown();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->backButtonBehaviorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
||||||
this, [this](int index) {
|
|
||||||
if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) {
|
|
||||||
QString data = ui->backButtonBehaviorComboBox->itemData(index).toString();
|
|
||||||
Config::setBackButtonBehavior(data.toStdString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input TAB
|
// Input TAB
|
||||||
@ -195,6 +183,14 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
|
|
||||||
connect(ui->idleTimeoutSpinBox, &QSpinBox::valueChanged, this,
|
connect(ui->idleTimeoutSpinBox, &QSpinBox::valueChanged, this,
|
||||||
[](int index) { Config::setCursorHideTimeout(index); });
|
[](int index) { Config::setCursorHideTimeout(index); });
|
||||||
|
|
||||||
|
connect(ui->backButtonBehaviorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||||
|
this, [this](int index) {
|
||||||
|
if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) {
|
||||||
|
QString data = ui->backButtonBehaviorComboBox->itemData(index).toString();
|
||||||
|
Config::setBackButtonBehavior(data.toStdString());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// GPU TAB
|
// GPU TAB
|
||||||
@ -220,6 +216,35 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
[](int val) { Config::setNullGpu(val); });
|
[](int val) { Config::setNullGpu(val); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PATH TAB
|
||||||
|
{
|
||||||
|
connect(ui->addFolderButton, &QPushButton::clicked, this, [this]() {
|
||||||
|
const auto config_dir = Config::getGameInstallDirs();
|
||||||
|
QString file_path_string =
|
||||||
|
QFileDialog::getExistingDirectory(this, tr("Directory to install games"));
|
||||||
|
auto file_path = Common::FS::PathFromQString(file_path_string);
|
||||||
|
if (!file_path.empty() && Config::addGameInstallDir(file_path)) {
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(file_path_string);
|
||||||
|
ui->gameFoldersListWidget->addItem(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->gameFoldersListWidget, &QListWidget::itemSelectionChanged, this, [this]() {
|
||||||
|
ui->removeFolderButton->setEnabled(
|
||||||
|
!ui->gameFoldersListWidget->selectedItems().isEmpty());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->removeFolderButton, &QPushButton::clicked, this, [this]() {
|
||||||
|
QListWidgetItem* selected_item = ui->gameFoldersListWidget->currentItem();
|
||||||
|
QString item_path_string = selected_item ? selected_item->text() : QString();
|
||||||
|
if (!item_path_string.isEmpty()) {
|
||||||
|
auto file_path = Common::FS::PathFromQString(item_path_string);
|
||||||
|
Config::removeGameInstallDir(file_path);
|
||||||
|
delete selected_item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// DEBUG TAB
|
// DEBUG TAB
|
||||||
{
|
{
|
||||||
connect(ui->debugDump, &QCheckBox::stateChanged, this,
|
connect(ui->debugDump, &QCheckBox::stateChanged, this,
|
||||||
@ -248,6 +273,11 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
ui->logFilter->installEventFilter(this);
|
ui->logFilter->installEventFilter(this);
|
||||||
ui->updaterGroupBox->installEventFilter(this);
|
ui->updaterGroupBox->installEventFilter(this);
|
||||||
ui->GUIgroupBox->installEventFilter(this);
|
ui->GUIgroupBox->installEventFilter(this);
|
||||||
|
|
||||||
|
// Input
|
||||||
|
ui->cursorGroupBox->installEventFilter(this);
|
||||||
|
ui->hideCursorGroupBox->installEventFilter(this);
|
||||||
|
ui->idleTimeoutGroupBox->installEventFilter(this);
|
||||||
ui->backButtonBehaviorGroupBox->installEventFilter(this);
|
ui->backButtonBehaviorGroupBox->installEventFilter(this);
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
@ -258,6 +288,12 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
ui->dumpShadersCheckBox->installEventFilter(this);
|
ui->dumpShadersCheckBox->installEventFilter(this);
|
||||||
ui->nullGpuCheckBox->installEventFilter(this);
|
ui->nullGpuCheckBox->installEventFilter(this);
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
ui->gameFoldersGroupBox->installEventFilter(this);
|
||||||
|
ui->gameFoldersListWidget->installEventFilter(this);
|
||||||
|
ui->addFolderButton->installEventFilter(this);
|
||||||
|
ui->removeFolderButton->installEventFilter(this);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
ui->debugDump->installEventFilter(this);
|
ui->debugDump->installEventFilter(this);
|
||||||
ui->vkValidationCheckBox->installEventFilter(this);
|
ui->vkValidationCheckBox->installEventFilter(this);
|
||||||
@ -308,9 +344,18 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||||||
}
|
}
|
||||||
ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel));
|
ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel));
|
||||||
|
|
||||||
|
for (const auto& dir : Config::getGameInstallDirs()) {
|
||||||
|
QString path_string;
|
||||||
|
Common::FS::PathToQString(path_string, dir);
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(path_string);
|
||||||
|
ui->gameFoldersListWidget->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
|
QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
|
||||||
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
|
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
|
||||||
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
|
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
|
||||||
|
|
||||||
|
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::InitializeEmulatorLanguages() {
|
void SettingsDialog::InitializeEmulatorLanguages() {
|
||||||
@ -384,6 +429,15 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
|||||||
text = tr("updaterGroupBox");
|
text = tr("updaterGroupBox");
|
||||||
} else if (elementName == "GUIgroupBox") {
|
} else if (elementName == "GUIgroupBox") {
|
||||||
text = tr("GUIgroupBox");
|
text = tr("GUIgroupBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input
|
||||||
|
if (elementName == "cursorGroupBox") {
|
||||||
|
text = tr("cursorGroupBox");
|
||||||
|
} else if (elementName == "hideCursorGroupBox") {
|
||||||
|
text = tr("hideCursorGroupBox");
|
||||||
|
} else if (elementName == "idleTimeoutGroupBox") {
|
||||||
|
text = tr("idleTimeoutGroupBox");
|
||||||
} else if (elementName == "backButtonBehaviorGroupBox") {
|
} else if (elementName == "backButtonBehaviorGroupBox") {
|
||||||
text = tr("backButtonBehaviorGroupBox");
|
text = tr("backButtonBehaviorGroupBox");
|
||||||
}
|
}
|
||||||
@ -403,6 +457,15 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
|||||||
text = tr("nullGpuCheckBox");
|
text = tr("nullGpuCheckBox");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Path
|
||||||
|
if (elementName == "gameFoldersGroupBox" || elementName == "gameFoldersListWidget") {
|
||||||
|
text = tr("gameFoldersBox");
|
||||||
|
} else if (elementName == "addFolderButton") {
|
||||||
|
text = tr("addFolderButton");
|
||||||
|
} else if (elementName == "removeFolderButton") {
|
||||||
|
text = tr("removeFolderButton");
|
||||||
|
}
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
if (elementName == "debugDump") {
|
if (elementName == "debugDump") {
|
||||||
text = tr("debugDump");
|
text = tr("debugDump");
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>854</width>
|
<width>854</width>
|
||||||
<height>570</height>
|
<height>605</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -71,7 +71,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="generalTab">
|
<widget class="QWidget" name="generalTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -274,6 +274,9 @@
|
|||||||
<layout class="QHBoxLayout" name="generalTabHLayout_2">
|
<layout class="QHBoxLayout" name="generalTabHLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="updaterTabLayoutLeft">
|
<layout class="QVBoxLayout" name="updaterTabLayoutLeft">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -286,56 +289,88 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||||
<widget class="QGroupBox" name="updaterGroupBox">
|
<widget class="QGroupBox" name="updaterGroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>265</width>
|
<width>275</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Update</string>
|
<string>Update</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QCheckBox" name="updateCheckBox">
|
<layout class="QVBoxLayout" name="UpdateLayout" stretch="0,0,0">
|
||||||
<property name="geometry">
|
<property name="spacing">
|
||||||
<rect>
|
<number>5</number>
|
||||||
<x>10</x>
|
|
||||||
<y>130</y>
|
|
||||||
<width>261</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="topMargin">
|
||||||
<string>Check for Updates at Startup</string>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="rightMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
<widget class="QGroupBox" name="updaterComboBox">
|
<widget class="QGroupBox" name="updaterComboBox">
|
||||||
<property name="geometry">
|
<property name="sizePolicy">
|
||||||
<rect>
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<x>12</x>
|
<horstretch>0</horstretch>
|
||||||
<y>30</y>
|
<verstretch>0</verstretch>
|
||||||
<width>241</width>
|
</sizepolicy>
|
||||||
<height>65</height>
|
</property>
|
||||||
</rect>
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>75</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Update Channel</string>
|
<string>Update Channel</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="UpdateChannelLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
<widget class="QComboBox" name="updateComboBox">
|
<widget class="QComboBox" name="updateComboBox">
|
||||||
<property name="geometry">
|
<property name="sizePolicy">
|
||||||
<rect>
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<x>12</x>
|
<horstretch>0</horstretch>
|
||||||
<y>30</y>
|
<verstretch>0</verstretch>
|
||||||
<width>217</width>
|
</sizepolicy>
|
||||||
<height>28</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -348,47 +383,93 @@
|
|||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QPushButton" name="checkUpdateButton">
|
<widget class="QPushButton" name="checkUpdateButton">
|
||||||
<property name="geometry">
|
<property name="sizePolicy">
|
||||||
<rect>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
<x>25</x>
|
<horstretch>0</horstretch>
|
||||||
<y>100</y>
|
<verstretch>0</verstretch>
|
||||||
<width>215</width>
|
</sizepolicy>
|
||||||
<height>24</height>
|
</property>
|
||||||
</rect>
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>197</width>
|
||||||
|
<height>28</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Check for Updates</string>
|
<string>Check for Updates</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="updateCheckBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Check for Updates at Startup</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="1">
|
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
|
||||||
<item>
|
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||||
<widget class="QGroupBox" name="GUIgroupBox">
|
<widget class="QGroupBox" name="GUIgroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>GUI Settings</string>
|
<string>GUI Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="verticalLayoutWidget_3">
|
<layout class="QVBoxLayout" name="GUILayout">
|
||||||
<property name="geometry">
|
<property name="topMargin">
|
||||||
<rect>
|
<number>1</number>
|
||||||
<x>10</x>
|
</property>
|
||||||
<y>30</y>
|
<property name="bottomMargin">
|
||||||
<width>241</width>
|
<number>11</number>
|
||||||
<height>92</height>
|
</property>
|
||||||
</rect>
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="GUIMusicLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="playBGMCheckBox">
|
<widget class="QCheckBox" name="playBGMCheckBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -403,11 +484,35 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<spacer name="GUIverticalSpacer_2">
|
||||||
<item>
|
<property name="orientation">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<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>2</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<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">
|
<property name="text">
|
||||||
<string>Volume</string>
|
<string>Volume</string>
|
||||||
</property>
|
</property>
|
||||||
@ -449,51 +554,35 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item>
|
||||||
|
<widget class="QWidget" name="GUIwidgetSpacer" native="true">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>61</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="ControllerTabLayoutRight" stretch="1">
|
<layout class="QVBoxLayout" name="EmptyTabLayoutRight">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="ControllerGroupBox">
|
<spacer name="emptyHorizontalSpacer">
|
||||||
<property name="sizePolicy">
|
<property name="orientation">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="sizeHint" stdset="0">
|
||||||
<string>Controller Settings</string>
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QGroupBox" name="backButtonBehaviorGroupBox">
|
</spacer>
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>12</x>
|
|
||||||
<y>30</y>
|
|
||||||
<width>241</width>
|
|
||||||
<height>65</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Back Button Behavior</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QComboBox" name="backButtonBehaviorComboBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>12</x>
|
|
||||||
<y>30</y>
|
|
||||||
<width>217</width>
|
|
||||||
<height>28</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
@ -510,18 +599,48 @@
|
|||||||
<layout class="QHBoxLayout" name="inputTabHLayoutTop" stretch="1,1,1">
|
<layout class="QHBoxLayout" name="inputTabHLayoutTop" stretch="1,1,1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="cursorTabLayoutLeft">
|
<layout class="QVBoxLayout" name="cursorTabLayoutLeft">
|
||||||
<item>
|
<property name="spacing">
|
||||||
<widget class="QGroupBox" name="HideCursor">
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||||
|
<widget class="QGroupBox" name="cursorGroupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Cursor</string>
|
<string>Cursor</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="inputCursorLayout">
|
<layout class="QVBoxLayout" name="inputCursorLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="hideCursorGroupBox">
|
<widget class="QGroupBox" name="hideCursorGroupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Hide Cursor</string>
|
<string>Hide Cursor</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="hideCursorLayout">
|
<layout class="QVBoxLayout" name="hideCursorLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="hideCursorComboBox"/>
|
<widget class="QComboBox" name="hideCursorComboBox"/>
|
||||||
</item>
|
</item>
|
||||||
@ -533,10 +652,16 @@
|
|||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
<height>85</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -549,19 +674,28 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="IdleTimeoutLayout" stretch="0,0">
|
<layout class="QHBoxLayout" name="IdleTimeoutLayout" stretch="0,0">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>70</number>
|
<number>70</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>11</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
<widget class="QSpinBox" name="idleTimeoutSpinBox">
|
<widget class="QSpinBox" name="idleTimeoutSpinBox">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
@ -620,26 +754,80 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="emptyTabLayoutMiddle">
|
<layout class="QVBoxLayout" name="ControllerTabLayoutMiddle">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="emptyHorizontalSpacerMiddle">
|
<widget class="QGroupBox" name="ControllerGroupBox">
|
||||||
<property name="orientation">
|
<property name="sizePolicy">
|
||||||
<enum>Qt::Orientation::Horizontal</enum>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="title">
|
||||||
|
<string>Controller</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="ControllerLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="backButtonBehaviorGroupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>237</width>
|
||||||
<height>20</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
<property name="title">
|
||||||
|
<string>Back Button Behavior</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="BackButtonLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="backButtonBehaviorComboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="controllerWidgetSpacer" native="true">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="emptyTabLayoutRight">
|
<layout class="QVBoxLayout" name="emptyTabLayoutRight">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="emptyHorizontalSpacerRight">
|
<spacer name="emptyhorizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Orientation::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -918,6 +1106,76 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="pathsTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Paths</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="gameFoldersGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Game Folders</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QListWidget" name="gameFoldersListWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>401</width>
|
||||||
|
<height>331</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="addFolderButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>100</x>
|
||||||
|
<y>360</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="removeFolderButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>210</x>
|
||||||
|
<y>360</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::Preferred</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="debugTab">
|
<widget class="QWidget" name="debugTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Debug</string>
|
<string>Debug</string>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>مسار</translation>
|
<translation>مسار</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>وقت اللعب</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Sti</translation>
|
<translation>Sti</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Spilletid</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Pfad</translation>
|
<translation>Pfad</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Spielzeit</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Διαδρομή</translation>
|
<translation>Διαδρομή</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Χρόνος παιχνιδιού</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -434,6 +434,41 @@
|
|||||||
<source>Log Filter</source>
|
<source>Log Filter</source>
|
||||||
<translation>Log Filter</translation>
|
<translation>Log Filter</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="595"/>
|
||||||
|
<source>Input</source>
|
||||||
|
<translation>Input</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="611"/>
|
||||||
|
<source>Cursor</source>
|
||||||
|
<translation>Cursor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="635"/>
|
||||||
|
<source>Hide Cursor</source>
|
||||||
|
<translation>Hide Cursor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="668"/>
|
||||||
|
<source>Hide Cursor Idle Timeout</source>
|
||||||
|
<translation>Hide Cursor Idle Timeout</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="595"/>
|
||||||
|
<source>Input</source>
|
||||||
|
<translation>Input</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="767"/>
|
||||||
|
<source>Controller</source>
|
||||||
|
<translation>Controller</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="797"/>
|
||||||
|
<source>Back Button Behavior</source>
|
||||||
|
<translation>Back Button Behavior</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settings_dialog.ui" line="272"/>
|
<location filename="../settings_dialog.ui" line="272"/>
|
||||||
<source>Graphics</source>
|
<source>Graphics</source>
|
||||||
@ -534,16 +569,6 @@
|
|||||||
<source>Volume</source>
|
<source>Volume</source>
|
||||||
<translation>Volume</translation>
|
<translation>Volume</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../settings_dialog.ui" line="455"/>
|
|
||||||
<source>Controller Settings</source>
|
|
||||||
<translation>Controller Settings</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settings_dialog.ui" line="467"/>
|
|
||||||
<source>Back Button Behavior</source>
|
|
||||||
<translation>Back Button Behavior</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MainWindow</name>
|
<name>MainWindow</name>
|
||||||
@ -1033,6 +1058,41 @@
|
|||||||
<source>GUIgroupBox</source>
|
<source>GUIgroupBox</source>
|
||||||
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
|
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="392"/>
|
||||||
|
<source>cursorGroupBox</source>
|
||||||
|
<translation>Cursor:\nChange settings related to the cursor.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="394"/>
|
||||||
|
<source>hideCursorGroupBox</source>
|
||||||
|
<translation>Hide Cursor:\nSet cursor hiding behavior.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="396"/>
|
||||||
|
<source>idleTimeoutGroupBox</source>
|
||||||
|
<translation>Hide Idle Cursor Timeout:\nThe duration (seconds) after which the cursor that has been idle hides itself.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="70"/>
|
||||||
|
<source>Never</source>
|
||||||
|
<translation>Never</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="71"/>
|
||||||
|
<source>Idle</source>
|
||||||
|
<translation>Idle</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="72"/>
|
||||||
|
<source>Always</source>
|
||||||
|
<translation>Always</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="330"/>
|
||||||
|
<source>backButtonBehaviorGroupBox</source>
|
||||||
|
<translation>Back Button Behavior:\nAllows setting which part of the touchpad the back button will emulate a touch on.</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settings_dialog.cpp" line="330"/>
|
<location filename="../settings_dialog.cpp" line="330"/>
|
||||||
<source>backButtonBehaviorGroupBox</source>
|
<source>backButtonBehaviorGroupBox</source>
|
||||||
@ -1083,6 +1143,21 @@
|
|||||||
<source>nullGpuCheckBox</source>
|
<source>nullGpuCheckBox</source>
|
||||||
<translation>Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card.</translation>
|
<translation>Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="465"/>
|
||||||
|
<source>gameFoldersBox</source>
|
||||||
|
<translation>Game Folders: The list of folders to check for installed games.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="465"/>
|
||||||
|
<source>addFolderButton</source>
|
||||||
|
<translation>Add: Add a folder to the list.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="465"/>
|
||||||
|
<source>removeFolderButton</source>
|
||||||
|
<translation>Remove: Remove a folder from the list.</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settings_dialog.cpp" line="329"/>
|
<location filename="../settings_dialog.cpp" line="329"/>
|
||||||
<source>debugDump</source>
|
<source>debugDump</source>
|
||||||
@ -1146,6 +1221,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Path</translation>
|
<translation>Path</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Play Time</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Ruta</translation>
|
<translation>Ruta</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Tiempo de Juego</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>مسیر</translation>
|
<translation>مسیر</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>زمان بازی</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Polku</translation>
|
<translation>Polku</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Peliaika</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Répertoire</translation>
|
<translation>Répertoire</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Temps de jeu</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Útvonal</translation>
|
<translation>Útvonal</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Játékidő</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Jalur</translation>
|
<translation>Jalur</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Waktu Bermain</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Percorso</translation>
|
<translation>Percorso</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Tempo di Gioco</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>パス</translation>
|
<translation>パス</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>プレイ時間</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Path</translation>
|
<translation>Path</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Play Time</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Kelias</translation>
|
<translation>Kelias</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Žaidimo laikas</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Sti</translation>
|
<translation>Sti</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Spilletid</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Pad</translation>
|
<translation>Pad</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Speeltijd</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Ścieżka</translation>
|
<translation>Ścieżka</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Czas gry</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Diretório</translation>
|
<translation>Diretório</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Horas Jogadas</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Drum</translation>
|
<translation>Drum</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Timp de Joacă</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Путь</translation>
|
<translation>Путь</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Время Игры</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Shtegu</translation>
|
<translation>Shtegu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Kohë Lojë</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Yol</translation>
|
<translation>Yol</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Oynama Süresi</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Đường dẫn</translation>
|
<translation>Đường dẫn</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>Thời gian chơi</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>路径</translation>
|
<translation>路径</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>游戏时间</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -1111,6 +1111,11 @@
|
|||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>路徑</translation>
|
<translation>路徑</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../game_list_frame.cpp" line="38"/>
|
||||||
|
<source>Play Time</source>
|
||||||
|
<translation>遊玩時間</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CheckUpdate</name>
|
<name>CheckUpdate</name>
|
||||||
|
@ -206,10 +206,7 @@ Id DefineMain(EmitContext& ctx, const IR::Program& program) {
|
|||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
void SetupCapabilities(const Info& info, EmitContext& ctx) {
|
||||||
const auto& info = program.info;
|
|
||||||
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
|
|
||||||
spv::ExecutionModel execution_model{};
|
|
||||||
ctx.AddCapability(spv::Capability::Image1D);
|
ctx.AddCapability(spv::Capability::Image1D);
|
||||||
ctx.AddCapability(spv::Capability::Sampled1D);
|
ctx.AddCapability(spv::Capability::Sampled1D);
|
||||||
ctx.AddCapability(spv::Capability::ImageQuery);
|
ctx.AddCapability(spv::Capability::ImageQuery);
|
||||||
@ -247,6 +244,19 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||||||
if (info.uses_group_ballot) {
|
if (info.uses_group_ballot) {
|
||||||
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
|
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
|
||||||
}
|
}
|
||||||
|
if (info.stage == Stage::Export || info.stage == Stage::Vertex) {
|
||||||
|
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
|
||||||
|
ctx.AddCapability(spv::Capability::DrawParameters);
|
||||||
|
}
|
||||||
|
if (info.stage == Stage::Geometry) {
|
||||||
|
ctx.AddCapability(spv::Capability::Geometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
||||||
|
const auto& info = program.info;
|
||||||
|
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
|
||||||
|
spv::ExecutionModel execution_model{};
|
||||||
switch (program.info.stage) {
|
switch (program.info.stage) {
|
||||||
case Stage::Compute: {
|
case Stage::Compute: {
|
||||||
const std::array<u32, 3> workgroup_size{ctx.runtime_info.cs_info.workgroup_size};
|
const std::array<u32, 3> workgroup_size{ctx.runtime_info.cs_info.workgroup_size};
|
||||||
@ -290,6 +300,24 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||||||
ctx.AddEntryPoint(execution_model, main, "main", interfaces);
|
ctx.AddEntryPoint(execution_model, main, "main", interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupFloatMode(EmitContext& ctx, const Profile& profile, const RuntimeInfo& runtime_info,
|
||||||
|
Id main_func) {
|
||||||
|
ctx.AddExtension("SPV_KHR_float_controls");
|
||||||
|
const auto fp_denorm_mode = runtime_info.fp_denorm_mode32;
|
||||||
|
if (fp_denorm_mode == AmdGpu::FpDenormMode::InOutFlush) {
|
||||||
|
if (profile.support_fp32_denorm_flush) {
|
||||||
|
ctx.AddCapability(spv::Capability::DenormFlushToZero);
|
||||||
|
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 32U);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Unknown FP denorm mode {}", u32(fp_denorm_mode));
|
||||||
|
}
|
||||||
|
const auto fp_round_mode = runtime_info.fp_round_mode32;
|
||||||
|
if (fp_round_mode != AmdGpu::FpRoundMode::NearestEven) {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Unknown FP rounding mode {}", u32(fp_round_mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PatchPhiNodes(const IR::Program& program, EmitContext& ctx) {
|
void PatchPhiNodes(const IR::Program& program, EmitContext& ctx) {
|
||||||
auto inst{program.blocks.front()->begin()};
|
auto inst{program.blocks.front()->begin()};
|
||||||
size_t block_index{0};
|
size_t block_index{0};
|
||||||
@ -314,18 +342,8 @@ std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_in
|
|||||||
EmitContext ctx{profile, runtime_info, program.info, binding};
|
EmitContext ctx{profile, runtime_info, program.info, binding};
|
||||||
const Id main{DefineMain(ctx, program)};
|
const Id main{DefineMain(ctx, program)};
|
||||||
DefineEntryPoint(program, ctx, main);
|
DefineEntryPoint(program, ctx, main);
|
||||||
switch (program.info.stage) {
|
SetupCapabilities(program.info, ctx);
|
||||||
case Stage::Export:
|
SetupFloatMode(ctx, profile, runtime_info, main);
|
||||||
case Stage::Vertex:
|
|
||||||
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
|
|
||||||
ctx.AddCapability(spv::Capability::DrawParameters);
|
|
||||||
break;
|
|
||||||
case Stage::Geometry:
|
|
||||||
ctx.AddCapability(spv::Capability::Geometry);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PatchPhiNodes(program, ctx);
|
PatchPhiNodes(program, ctx);
|
||||||
binding.user_data += program.info.ud_mask.NumRegs();
|
binding.user_data += program.info.ud_mask.NumRegs();
|
||||||
return ctx.Assemble();
|
return ctx.Assemble();
|
||||||
|
@ -59,19 +59,22 @@ struct ImageOperands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDerivatives(EmitContext& ctx, Id derivatives) {
|
void AddDerivatives(EmitContext& ctx, Id derivatives_dx, Id derivatives_dy) {
|
||||||
if (!Sirit::ValidId(derivatives)) {
|
if (!Sirit::ValidId(derivatives_dx) || !Sirit::ValidId(derivatives_dy)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Id dx{ctx.OpVectorShuffle(ctx.F32[2], derivatives, derivatives, 0, 1)};
|
Add(spv::ImageOperandsMask::Grad, derivatives_dx, derivatives_dy);
|
||||||
const Id dy{ctx.OpVectorShuffle(ctx.F32[2], derivatives, derivatives, 2, 3)};
|
|
||||||
Add(spv::ImageOperandsMask::Grad, dx, dy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spv::ImageOperandsMask mask{};
|
spv::ImageOperandsMask mask{};
|
||||||
boost::container::static_vector<Id, 4> operands;
|
boost::container::static_vector<Id, 4> operands;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Id EmitImageSampleRaw(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address1, Id address2,
|
||||||
|
Id address3, Id address4) {
|
||||||
|
UNREACHABLE_MSG("Unreachable instruction");
|
||||||
|
}
|
||||||
|
|
||||||
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id bias,
|
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id bias,
|
||||||
const IR::Value& offset) {
|
const IR::Value& offset) {
|
||||||
const auto& texture = ctx.images[handle & 0xFFFF];
|
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||||
@ -114,7 +117,9 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle,
|
|||||||
operands.AddOffset(ctx, offset);
|
operands.AddOffset(ctx, offset);
|
||||||
const Id sample = ctx.OpImageSampleDrefImplicitLod(result_type, sampled_image, coords, dref,
|
const Id sample = ctx.OpImageSampleDrefImplicitLod(result_type, sampled_image, coords, dref,
|
||||||
operands.mask, operands.operands);
|
operands.mask, operands.operands);
|
||||||
return texture.is_integer ? ctx.OpBitcast(ctx.F32[1], sample) : sample;
|
const Id sample_typed = texture.is_integer ? ctx.OpBitcast(ctx.F32[1], sample) : sample;
|
||||||
|
return ctx.OpCompositeConstruct(ctx.F32[4], sample_typed, ctx.f32_zero_value,
|
||||||
|
ctx.f32_zero_value, ctx.f32_zero_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref,
|
Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref,
|
||||||
@ -129,7 +134,9 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle,
|
|||||||
operands.Add(spv::ImageOperandsMask::Lod, lod);
|
operands.Add(spv::ImageOperandsMask::Lod, lod);
|
||||||
const Id sample = ctx.OpImageSampleDrefExplicitLod(result_type, sampled_image, coords, dref,
|
const Id sample = ctx.OpImageSampleDrefExplicitLod(result_type, sampled_image, coords, dref,
|
||||||
operands.mask, operands.operands);
|
operands.mask, operands.operands);
|
||||||
return texture.is_integer ? ctx.OpBitcast(ctx.F32[1], sample) : sample;
|
const Id sample_typed = texture.is_integer ? ctx.OpBitcast(ctx.F32[1], sample) : sample;
|
||||||
|
return ctx.OpCompositeConstruct(ctx.F32[4], sample_typed, ctx.f32_zero_value,
|
||||||
|
ctx.f32_zero_value, ctx.f32_zero_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
|
Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
|
||||||
@ -212,15 +219,15 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords) {
|
|||||||
return ctx.OpImageQueryLod(ctx.F32[2], sampled_image, coords);
|
return ctx.OpImageQueryLod(ctx.F32[2], sampled_image, coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives,
|
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives_dx,
|
||||||
const IR::Value& offset, Id lod_clamp) {
|
Id derivatives_dy, const IR::Value& offset, const IR::Value& lod_clamp) {
|
||||||
const auto& texture = ctx.images[handle & 0xFFFF];
|
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||||
const Id image = ctx.OpLoad(texture.image_type, texture.id);
|
const Id image = ctx.OpLoad(texture.image_type, texture.id);
|
||||||
const Id result_type = texture.data_types->Get(4);
|
const Id result_type = texture.data_types->Get(4);
|
||||||
const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]);
|
const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]);
|
||||||
const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler);
|
const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler);
|
||||||
ImageOperands operands;
|
ImageOperands operands;
|
||||||
operands.AddDerivatives(ctx, derivatives);
|
operands.AddDerivatives(ctx, derivatives_dx, derivatives_dy);
|
||||||
operands.AddOffset(ctx, offset);
|
operands.AddOffset(ctx, offset);
|
||||||
const Id sample = ctx.OpImageSampleExplicitLod(result_type, sampled_image, coords,
|
const Id sample = ctx.OpImageSampleExplicitLod(result_type, sampled_image, coords,
|
||||||
operands.mask, operands.operands);
|
operands.mask, operands.operands);
|
||||||
|
@ -368,6 +368,8 @@ Id EmitConvertF64U64(EmitContext& ctx, Id value);
|
|||||||
Id EmitConvertU16U32(EmitContext& ctx, Id value);
|
Id EmitConvertU16U32(EmitContext& ctx, Id value);
|
||||||
Id EmitConvertU32U16(EmitContext& ctx, Id value);
|
Id EmitConvertU32U16(EmitContext& ctx, Id value);
|
||||||
|
|
||||||
|
Id EmitImageSampleRaw(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address1, Id address2,
|
||||||
|
Id address3, Id address4);
|
||||||
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id bias,
|
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id bias,
|
||||||
const IR::Value& offset);
|
const IR::Value& offset);
|
||||||
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod,
|
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod,
|
||||||
@ -384,8 +386,8 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, const
|
|||||||
Id lod, Id ms);
|
Id lod, Id ms);
|
||||||
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips);
|
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips);
|
||||||
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords);
|
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords);
|
||||||
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives,
|
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives_dx,
|
||||||
const IR::Value& offset, Id lod_clamp);
|
Id derivatives_dy, const IR::Value& offset, const IR::Value& lod_clamp);
|
||||||
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords);
|
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords);
|
||||||
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id color);
|
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id color);
|
||||||
|
|
||||||
|
@ -284,7 +284,8 @@ void EmitContext::DefineInputs() {
|
|||||||
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
||||||
frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output);
|
frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output);
|
||||||
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
||||||
for (const auto& input : runtime_info.fs_info.inputs) {
|
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
||||||
|
const auto& input = runtime_info.fs_info.inputs[i];
|
||||||
const u32 semantic = input.param_index;
|
const u32 semantic = input.param_index;
|
||||||
ASSERT(semantic < IR::NumParams);
|
ASSERT(semantic < IR::NumParams);
|
||||||
if (input.is_default && !input.is_flat) {
|
if (input.is_default && !input.is_flat) {
|
||||||
@ -333,7 +334,6 @@ void EmitContext::DefineInputs() {
|
|||||||
|
|
||||||
const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u;
|
const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u;
|
||||||
for (int param_id = 0; param_id < num_params; ++param_id) {
|
for (int param_id = 0; param_id < num_params; ++param_id) {
|
||||||
const IR::Attribute param{IR::Attribute::Param0 + param_id};
|
|
||||||
const Id type{TypeArray(F32[4], ConstU32(num_verts_in))};
|
const Id type{TypeArray(F32[4], ConstU32(num_verts_in))};
|
||||||
const Id id{DefineInput(type, param_id)};
|
const Id id{DefineInput(type, param_id)};
|
||||||
Name(id, fmt::format("in_attr{}", param_id));
|
Name(id, fmt::format("in_attr{}", param_id));
|
||||||
@ -394,8 +394,7 @@ void EmitContext::DefineOutputs() {
|
|||||||
case Stage::Geometry: {
|
case Stage::Geometry: {
|
||||||
output_position = DefineVariable(F32[4], spv::BuiltIn::Position, spv::StorageClass::Output);
|
output_position = DefineVariable(F32[4], spv::BuiltIn::Position, spv::StorageClass::Output);
|
||||||
|
|
||||||
for (u32 attr_id = 0; attr_id < runtime_info.gs_info.copy_data.num_attrs; attr_id++) {
|
for (u32 attr_id = 0; attr_id < info.gs_copy_data.num_attrs; attr_id++) {
|
||||||
const IR::Attribute param{IR::Attribute::Param0 + attr_id};
|
|
||||||
const Id id{DefineOutput(F32[4], attr_id)};
|
const Id id{DefineOutput(F32[4], attr_id)};
|
||||||
Name(id, fmt::format("out_attr{}", attr_id));
|
Name(id, fmt::format("out_attr{}", attr_id));
|
||||||
output_params[attr_id] = {id, output_f32, F32[1], 4u};
|
output_params[attr_id] = {id, output_f32, F32[1], 4u};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
CopyShaderData ParseCopyShader(const std::span<const u32>& code) {
|
CopyShaderData ParseCopyShader(std::span<const u32> code) {
|
||||||
Gcn::GcnCodeSlice code_slice{code.data(), code.data() + code.size()};
|
Gcn::GcnCodeSlice code_slice{code.data(), code.data() + code.size()};
|
||||||
Gcn::GcnDecodeContext decoder;
|
Gcn::GcnDecodeContext decoder;
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ struct CopyShaderData {
|
|||||||
u32 num_attrs{0};
|
u32 num_attrs{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
CopyShaderData ParseCopyShader(const std::span<const u32>& code);
|
CopyShaderData ParseCopyShader(std::span<const u32> code);
|
||||||
|
|
||||||
} // namespace Shader
|
} // namespace Shader
|
||||||
|
@ -654,7 +654,7 @@ void GcnDecodeContext::decodeInstructionVOP3(uint64_t hexInstruction) {
|
|||||||
|
|
||||||
OpcodeVOP3 vop3Op = static_cast<OpcodeVOP3>(op);
|
OpcodeVOP3 vop3Op = static_cast<OpcodeVOP3>(op);
|
||||||
if (IsVop3BEncoding(m_instruction.opcode)) {
|
if (IsVop3BEncoding(m_instruction.opcode)) {
|
||||||
m_instruction.dst[1].field = OperandField::ScalarGPR;
|
m_instruction.dst[1].field = getOperandField(sdst);
|
||||||
m_instruction.dst[1].type = ScalarType::Uint64;
|
m_instruction.dst[1].type = ScalarType::Uint64;
|
||||||
m_instruction.dst[1].code = sdst;
|
m_instruction.dst[1].code = sdst;
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,6 +155,8 @@ public:
|
|||||||
void V_SUB_I32(const GcnInst& inst);
|
void V_SUB_I32(const GcnInst& inst);
|
||||||
void V_SUBREV_I32(const GcnInst& inst);
|
void V_SUBREV_I32(const GcnInst& inst);
|
||||||
void V_ADDC_U32(const GcnInst& inst);
|
void V_ADDC_U32(const GcnInst& inst);
|
||||||
|
void V_SUBB_U32(const GcnInst& inst);
|
||||||
|
void V_SUBBREV_U32(const GcnInst& inst);
|
||||||
void V_LDEXP_F32(const GcnInst& inst);
|
void V_LDEXP_F32(const GcnInst& inst);
|
||||||
void V_CVT_PKNORM_U16_F32(const GcnInst& inst);
|
void V_CVT_PKNORM_U16_F32(const GcnInst& inst);
|
||||||
void V_CVT_PKRTZ_F16_F32(const GcnInst& inst);
|
void V_CVT_PKRTZ_F16_F32(const GcnInst& inst);
|
||||||
@ -273,7 +275,9 @@ private:
|
|||||||
void SetDst(const InstOperand& operand, const IR::U32F32& value);
|
void SetDst(const InstOperand& operand, const IR::U32F32& value);
|
||||||
void SetDst64(const InstOperand& operand, const IR::U64F64& value_raw);
|
void SetDst64(const InstOperand& operand, const IR::U64F64& value_raw);
|
||||||
|
|
||||||
// Vector ALU Helprers
|
// Vector ALU Helpers
|
||||||
|
IR::U32 GetCarryIn(const GcnInst& inst);
|
||||||
|
void SetCarryOut(const GcnInst& inst, const IR::U1& carry);
|
||||||
IR::U32 VMovRelSHelper(u32 src_vgprno, const IR::U32 m0);
|
IR::U32 VMovRelSHelper(u32 src_vgprno, const IR::U32 m0);
|
||||||
void VMovRelDHelper(u32 dst_vgprno, const IR::U32 src_val, const IR::U32 m0);
|
void VMovRelDHelper(u32 dst_vgprno, const IR::U32 src_val, const IR::U32 m0);
|
||||||
|
|
||||||
|
@ -87,6 +87,10 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
|||||||
return V_SUBREV_I32(inst);
|
return V_SUBREV_I32(inst);
|
||||||
case Opcode::V_ADDC_U32:
|
case Opcode::V_ADDC_U32:
|
||||||
return V_ADDC_U32(inst);
|
return V_ADDC_U32(inst);
|
||||||
|
case Opcode::V_SUBB_U32:
|
||||||
|
return V_SUBB_U32(inst);
|
||||||
|
case Opcode::V_SUBBREV_U32:
|
||||||
|
return V_SUBBREV_U32(inst);
|
||||||
case Opcode::V_LDEXP_F32:
|
case Opcode::V_LDEXP_F32:
|
||||||
return V_LDEXP_F32(inst);
|
return V_LDEXP_F32(inst);
|
||||||
case Opcode::V_CVT_PKNORM_U16_F32:
|
case Opcode::V_CVT_PKNORM_U16_F32:
|
||||||
@ -546,51 +550,71 @@ void Translator::V_MBCNT_U32_B32(bool is_low, const GcnInst& inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_ADD_I32(const GcnInst& inst) {
|
void Translator::V_ADD_I32(const GcnInst& inst) {
|
||||||
|
// Signed or unsigned components
|
||||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
const IR::U32 src1{ir.GetVectorReg(IR::VectorReg(inst.src[1].code))};
|
const IR::U32 src1{ir.GetVectorReg(IR::VectorReg(inst.src[1].code))};
|
||||||
SetDst(inst.dst[0], ir.IAdd(src0, src1));
|
const IR::U32 result{ir.IAdd(src0, src1)};
|
||||||
// TODO: Carry
|
SetDst(inst.dst[0], result);
|
||||||
|
|
||||||
|
// TODO: Carry-out with signed or unsigned components
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SUB_I32(const GcnInst& inst) {
|
void Translator::V_SUB_I32(const GcnInst& inst) {
|
||||||
|
// Unsigned components
|
||||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.ISub(src0, src1));
|
const IR::U32 result{ir.ISub(src0, src1)};
|
||||||
|
SetDst(inst.dst[0], result);
|
||||||
|
|
||||||
|
const IR::U1 did_underflow{ir.IGreaterThan(src1, src0, false)};
|
||||||
|
SetCarryOut(inst, did_underflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SUBREV_I32(const GcnInst& inst) {
|
void Translator::V_SUBREV_I32(const GcnInst& inst) {
|
||||||
|
// Unsigned components
|
||||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
SetDst(inst.dst[0], ir.ISub(src1, src0));
|
const IR::U32 result{ir.ISub(src1, src0)};
|
||||||
// TODO: Carry-out
|
SetDst(inst.dst[0], result);
|
||||||
|
|
||||||
|
const IR::U1 did_underflow{ir.IGreaterThan(src0, src1, false)};
|
||||||
|
SetCarryOut(inst, did_underflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_ADDC_U32(const GcnInst& inst) {
|
void Translator::V_ADDC_U32(const GcnInst& inst) {
|
||||||
const auto src0 = GetSrc<IR::U32>(inst.src[0]);
|
// Unsigned components
|
||||||
const auto src1 = GetSrc<IR::U32>(inst.src[1]);
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
IR::U1 carry;
|
const IR::U32 carry{GetCarryIn(inst)};
|
||||||
if (inst.src_count == 3) { // VOP3
|
const IR::U32 result{ir.IAdd(ir.IAdd(src0, src1), carry)};
|
||||||
if (inst.src[2].field == OperandField::VccLo) {
|
|
||||||
carry = ir.GetVcc();
|
|
||||||
} else if (inst.src[2].field == OperandField::ScalarGPR) {
|
|
||||||
carry = ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[2].code));
|
|
||||||
} else {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
} else { // VOP2
|
|
||||||
carry = ir.GetVcc();
|
|
||||||
}
|
|
||||||
|
|
||||||
const IR::U32 scarry = IR::U32{ir.Select(carry, ir.Imm32(1), ir.Imm32(0))};
|
|
||||||
const IR::U32 result = ir.IAdd(ir.IAdd(src0, src1), scarry);
|
|
||||||
|
|
||||||
SetDst(inst.dst[0], result);
|
SetDst(inst.dst[0], result);
|
||||||
|
|
||||||
const IR::U1 less_src0 = ir.ILessThan(result, src0, false);
|
const IR::U1 less_src0{ir.ILessThan(result, src0, false)};
|
||||||
const IR::U1 less_src1 = ir.ILessThan(result, src1, false);
|
const IR::U1 less_src1{ir.ILessThan(result, src1, false)};
|
||||||
const IR::U1 did_overflow = ir.LogicalOr(less_src0, less_src1);
|
const IR::U1 did_overflow{ir.LogicalOr(less_src0, less_src1)};
|
||||||
ir.SetVcc(did_overflow);
|
SetCarryOut(inst, did_overflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::V_SUBB_U32(const GcnInst& inst) {
|
||||||
|
// Signed or unsigned components
|
||||||
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
|
const IR::U32 carry{GetCarryIn(inst)};
|
||||||
|
const IR::U32 result{ir.ISub(ir.ISub(src0, src1), carry)};
|
||||||
|
SetDst(inst.dst[0], result);
|
||||||
|
|
||||||
|
// TODO: Carry-out with signed or unsigned components
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::V_SUBBREV_U32(const GcnInst& inst) {
|
||||||
|
// Signed or unsigned components
|
||||||
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
|
const IR::U32 carry{GetCarryIn(inst)};
|
||||||
|
const IR::U32 result{ir.ISub(ir.ISub(src1, src0), carry)};
|
||||||
|
SetDst(inst.dst[0], result);
|
||||||
|
|
||||||
|
// TODO: Carry-out with signed or unsigned components
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_LDEXP_F32(const GcnInst& inst) {
|
void Translator::V_LDEXP_F32(const GcnInst& inst) {
|
||||||
@ -1152,6 +1176,37 @@ void Translator::V_MAD_U64_U32(const GcnInst& inst) {
|
|||||||
ir.SetVcc(did_overflow);
|
ir.SetVcc(did_overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IR::U32 Translator::GetCarryIn(const GcnInst& inst) {
|
||||||
|
IR::U1 carry;
|
||||||
|
if (inst.src_count == 3) { // VOP3
|
||||||
|
if (inst.src[2].field == OperandField::VccLo) {
|
||||||
|
carry = ir.GetVcc();
|
||||||
|
} else if (inst.src[2].field == OperandField::ScalarGPR) {
|
||||||
|
carry = ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[2].code));
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
} else { // VOP2
|
||||||
|
carry = ir.GetVcc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return IR::U32{ir.Select(carry, ir.Imm32(1), ir.Imm32(0))};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::SetCarryOut(const GcnInst& inst, const IR::U1& carry) {
|
||||||
|
if (inst.dst_count == 2) { // VOP3
|
||||||
|
if (inst.dst[1].field == OperandField::VccLo) {
|
||||||
|
ir.SetVcc(carry);
|
||||||
|
} else if (inst.dst[1].field == OperandField::ScalarGPR) {
|
||||||
|
ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[1].code), carry);
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
} else { // VOP2
|
||||||
|
ir.SetVcc(carry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: add range analysis pass to hopefully put an upper bound on m0, and only select one of
|
// TODO: add range analysis pass to hopefully put an upper bound on m0, and only select one of
|
||||||
// [src_vgprno, src_vgprno + max_m0]. Same for dst regs we may write back to
|
// [src_vgprno, src_vgprno + max_m0]. Same for dst regs we may write back to
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) {
|
|||||||
ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3));
|
ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3));
|
||||||
|
|
||||||
IR::TextureInstInfo info{};
|
IR::TextureInstInfo info{};
|
||||||
info.explicit_lod.Assign(has_mip);
|
info.has_lod.Assign(has_mip);
|
||||||
const IR::Value texel = ir.ImageFetch(handle, body, {}, {}, {}, info);
|
const IR::Value texel = ir.ImageFetch(handle, body, {}, {}, {}, info);
|
||||||
|
|
||||||
for (u32 i = 0; i < 4; i++) {
|
for (u32 i = 0; i < 4; i++) {
|
||||||
@ -513,6 +513,76 @@ void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IR::Value EmitImageSample(IR::IREmitter& ir, const GcnInst& inst, const IR::ScalarReg tsharp_reg,
|
||||||
|
const IR::ScalarReg sampler_reg, const IR::VectorReg addr_reg,
|
||||||
|
bool gather) {
|
||||||
|
const auto& mimg = inst.control.mimg;
|
||||||
|
const auto flags = MimgModifierFlags(mimg.mod);
|
||||||
|
|
||||||
|
IR::TextureInstInfo info{};
|
||||||
|
info.is_depth.Assign(flags.test(MimgModifier::Pcf));
|
||||||
|
info.has_bias.Assign(flags.test(MimgModifier::LodBias));
|
||||||
|
info.has_lod_clamp.Assign(flags.test(MimgModifier::LodClamp));
|
||||||
|
info.force_level0.Assign(flags.test(MimgModifier::Level0));
|
||||||
|
info.has_offset.Assign(flags.test(MimgModifier::Offset));
|
||||||
|
info.has_lod.Assign(flags.any(MimgModifier::Lod));
|
||||||
|
info.is_array.Assign(mimg.da);
|
||||||
|
|
||||||
|
if (gather) {
|
||||||
|
info.gather_comp.Assign(std::bit_width(mimg.dmask) - 1);
|
||||||
|
info.is_gather.Assign(true);
|
||||||
|
} else {
|
||||||
|
info.has_derivatives.Assign(flags.test(MimgModifier::Derivative));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load first dword of T# and S#. We will use them as the handle that will guide resource
|
||||||
|
// tracking pass where to read the sharps. This will later also get patched to the SPIRV texture
|
||||||
|
// binding index.
|
||||||
|
const IR::Value handle =
|
||||||
|
ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(sampler_reg));
|
||||||
|
|
||||||
|
// Determine how many address registers need to be passed.
|
||||||
|
// The image type is unknown, so add all 4 possible base registers and resolve later.
|
||||||
|
int num_addr_regs = 4;
|
||||||
|
if (info.has_offset) {
|
||||||
|
++num_addr_regs;
|
||||||
|
}
|
||||||
|
if (info.has_bias) {
|
||||||
|
++num_addr_regs;
|
||||||
|
}
|
||||||
|
if (info.is_depth) {
|
||||||
|
++num_addr_regs;
|
||||||
|
}
|
||||||
|
if (info.has_derivatives) {
|
||||||
|
// The image type is unknown, so add all 6 possible derivative registers and resolve later.
|
||||||
|
num_addr_regs += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch all the address registers to pass in the IR instruction. There can be up to 13
|
||||||
|
// registers.
|
||||||
|
const auto get_addr_reg = [&](int index) -> IR::F32 {
|
||||||
|
if (index >= num_addr_regs) {
|
||||||
|
return ir.Imm32(0.f);
|
||||||
|
}
|
||||||
|
return ir.GetVectorReg<IR::F32>(addr_reg + index);
|
||||||
|
};
|
||||||
|
const IR::Value address1 =
|
||||||
|
ir.CompositeConstruct(get_addr_reg(0), get_addr_reg(1), get_addr_reg(2), get_addr_reg(3));
|
||||||
|
const IR::Value address2 =
|
||||||
|
ir.CompositeConstruct(get_addr_reg(4), get_addr_reg(5), get_addr_reg(6), get_addr_reg(7));
|
||||||
|
const IR::Value address3 =
|
||||||
|
ir.CompositeConstruct(get_addr_reg(8), get_addr_reg(9), get_addr_reg(10), get_addr_reg(11));
|
||||||
|
const IR::Value address4 = get_addr_reg(12);
|
||||||
|
|
||||||
|
// Issue the placeholder IR instruction.
|
||||||
|
IR::Value texel = ir.ImageSampleRaw(handle, address1, address2, address3, address4, info);
|
||||||
|
if (info.is_depth && !gather) {
|
||||||
|
// For non-gather depth sampling, only return a single value.
|
||||||
|
texel = ir.CompositeExtract(texel, 0);
|
||||||
|
}
|
||||||
|
return texel;
|
||||||
|
}
|
||||||
|
|
||||||
void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
||||||
const auto& mimg = inst.control.mimg;
|
const auto& mimg = inst.control.mimg;
|
||||||
IR::VectorReg addr_reg{inst.src[0].code};
|
IR::VectorReg addr_reg{inst.src[0].code};
|
||||||
@ -521,72 +591,7 @@ void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
|||||||
const IR::ScalarReg sampler_reg{inst.src[3].code * 4};
|
const IR::ScalarReg sampler_reg{inst.src[3].code * 4};
|
||||||
const auto flags = MimgModifierFlags(mimg.mod);
|
const auto flags = MimgModifierFlags(mimg.mod);
|
||||||
|
|
||||||
// Load first dword of T# and S#. We will use them as the handle that will guide resource
|
const IR::Value texel = EmitImageSample(ir, inst, tsharp_reg, sampler_reg, addr_reg, false);
|
||||||
// tracking pass where to read the sharps. This will later also get patched to the SPIRV texture
|
|
||||||
// binding index.
|
|
||||||
const IR::Value handle =
|
|
||||||
ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(sampler_reg));
|
|
||||||
|
|
||||||
// Load first address components as denoted in 8.2.4 VGPR Usage Sea Islands Series Instruction
|
|
||||||
// Set Architecture
|
|
||||||
const IR::U32 offset =
|
|
||||||
flags.test(MimgModifier::Offset) ? ir.GetVectorReg<IR::U32>(addr_reg++) : IR::U32{};
|
|
||||||
const IR::F32 bias =
|
|
||||||
flags.test(MimgModifier::LodBias) ? ir.GetVectorReg<IR::F32>(addr_reg++) : IR::F32{};
|
|
||||||
const IR::F32 dref =
|
|
||||||
flags.test(MimgModifier::Pcf) ? ir.GetVectorReg<IR::F32>(addr_reg++) : IR::F32{};
|
|
||||||
const IR::Value derivatives = [&] -> IR::Value {
|
|
||||||
if (!flags.test(MimgModifier::Derivative)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
addr_reg = addr_reg + 4;
|
|
||||||
return ir.CompositeConstruct(
|
|
||||||
ir.GetVectorReg<IR::F32>(addr_reg - 4), ir.GetVectorReg<IR::F32>(addr_reg - 3),
|
|
||||||
ir.GetVectorReg<IR::F32>(addr_reg - 2), ir.GetVectorReg<IR::F32>(addr_reg - 1));
|
|
||||||
}();
|
|
||||||
|
|
||||||
// Now we can load body components as noted in Table 8.9 Image Opcodes with Sampler
|
|
||||||
// Since these are at most 4 dwords, we load them into a single uvec4 and place them
|
|
||||||
// in coords field of the instruction. Then the resource tracking pass will patch the
|
|
||||||
// IR instruction to fill in lod_clamp field.
|
|
||||||
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));
|
|
||||||
|
|
||||||
// Derivatives are tricky because their number depends on the texture type which is located in
|
|
||||||
// T#. We don't have access to T# though until resource tracking pass. For now assume if
|
|
||||||
// derivatives are present, that a 2D image is bound.
|
|
||||||
const bool has_derivatives = flags.test(MimgModifier::Derivative);
|
|
||||||
const bool explicit_lod = flags.any(MimgModifier::Level0, MimgModifier::Lod);
|
|
||||||
|
|
||||||
IR::TextureInstInfo info{};
|
|
||||||
info.is_depth.Assign(flags.test(MimgModifier::Pcf));
|
|
||||||
info.has_bias.Assign(flags.test(MimgModifier::LodBias));
|
|
||||||
info.has_lod_clamp.Assign(flags.test(MimgModifier::LodClamp));
|
|
||||||
info.force_level0.Assign(flags.test(MimgModifier::Level0));
|
|
||||||
info.has_offset.Assign(flags.test(MimgModifier::Offset));
|
|
||||||
info.explicit_lod.Assign(explicit_lod);
|
|
||||||
info.has_derivatives.Assign(has_derivatives);
|
|
||||||
info.is_array.Assign(mimg.da);
|
|
||||||
|
|
||||||
// Issue IR instruction, leaving unknown fields blank to patch later.
|
|
||||||
const IR::Value texel = [&]() -> IR::Value {
|
|
||||||
if (has_derivatives) {
|
|
||||||
return ir.ImageGradient(handle, body, derivatives, offset, {}, info);
|
|
||||||
}
|
|
||||||
if (!flags.test(MimgModifier::Pcf)) {
|
|
||||||
if (explicit_lod) {
|
|
||||||
return ir.ImageSampleExplicitLod(handle, body, offset, info);
|
|
||||||
} else {
|
|
||||||
return ir.ImageSampleImplicitLod(handle, body, bias, offset, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (explicit_lod) {
|
|
||||||
return ir.ImageSampleDrefExplicitLod(handle, body, dref, offset, info);
|
|
||||||
}
|
|
||||||
return ir.ImageSampleDrefImplicitLod(handle, body, dref, bias, offset, info);
|
|
||||||
}();
|
|
||||||
|
|
||||||
for (u32 i = 0; i < 4; i++) {
|
for (u32 i = 0; i < 4; i++) {
|
||||||
if (((mimg.dmask >> i) & 1) == 0) {
|
if (((mimg.dmask >> i) & 1) == 0) {
|
||||||
continue;
|
continue;
|
||||||
@ -609,60 +614,13 @@ void Translator::IMAGE_GATHER(const GcnInst& inst) {
|
|||||||
const IR::ScalarReg sampler_reg{inst.src[3].code * 4};
|
const IR::ScalarReg sampler_reg{inst.src[3].code * 4};
|
||||||
const auto flags = MimgModifierFlags(mimg.mod);
|
const auto flags = MimgModifierFlags(mimg.mod);
|
||||||
|
|
||||||
// Load first dword of T# and S#. We will use them as the handle that will guide resource
|
|
||||||
// tracking pass where to read the sharps. This will later also get patched to the SPIRV texture
|
|
||||||
// binding index.
|
|
||||||
const IR::Value handle =
|
|
||||||
ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(sampler_reg));
|
|
||||||
|
|
||||||
// Load first address components as denoted in 8.2.4 VGPR Usage Sea Islands Series Instruction
|
|
||||||
// Set Architecture
|
|
||||||
const IR::Value offset =
|
|
||||||
flags.test(MimgModifier::Offset) ? ir.GetVectorReg(addr_reg++) : IR::Value{};
|
|
||||||
const IR::F32 bias =
|
|
||||||
flags.test(MimgModifier::LodBias) ? ir.GetVectorReg<IR::F32>(addr_reg++) : IR::F32{};
|
|
||||||
const IR::F32 dref =
|
|
||||||
flags.test(MimgModifier::Pcf) ? ir.GetVectorReg<IR::F32>(addr_reg++) : IR::F32{};
|
|
||||||
|
|
||||||
// Derivatives are tricky because their number depends on the texture type which is located in
|
|
||||||
// T#. We don't have access to T# though until resource tracking pass. For now assume no
|
|
||||||
// derivatives are present, otherwise we don't know where coordinates are placed in the address
|
|
||||||
// stream.
|
|
||||||
ASSERT_MSG(!flags.test(MimgModifier::Derivative), "Derivative image instruction");
|
|
||||||
|
|
||||||
// Now we can load body components as noted in Table 8.9 Image Opcodes with Sampler
|
|
||||||
// Since these are at most 4 dwords, we load them into a single uvec4 and place them
|
|
||||||
// in coords field of the instruction. Then the resource tracking pass will patch the
|
|
||||||
// IR instruction to fill in lod_clamp field.
|
|
||||||
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 bool explicit_lod = flags.any(MimgModifier::Level0, MimgModifier::Lod);
|
|
||||||
|
|
||||||
IR::TextureInstInfo info{};
|
|
||||||
info.is_depth.Assign(flags.test(MimgModifier::Pcf));
|
|
||||||
info.has_bias.Assign(flags.test(MimgModifier::LodBias));
|
|
||||||
info.has_lod_clamp.Assign(flags.test(MimgModifier::LodClamp));
|
|
||||||
info.force_level0.Assign(flags.test(MimgModifier::Level0));
|
|
||||||
info.has_offset.Assign(flags.test(MimgModifier::Offset));
|
|
||||||
// info.explicit_lod.Assign(explicit_lod);
|
|
||||||
info.gather_comp.Assign(std::bit_width(mimg.dmask) - 1);
|
|
||||||
info.is_array.Assign(mimg.da);
|
|
||||||
|
|
||||||
// Issue IR instruction, leaving unknown fields blank to patch later.
|
|
||||||
const IR::Value texel = [&]() -> IR::Value {
|
|
||||||
const IR::F32 lod = flags.test(MimgModifier::Level0) ? ir.Imm32(0.f) : IR::F32{};
|
|
||||||
if (!flags.test(MimgModifier::Pcf)) {
|
|
||||||
return ir.ImageGather(handle, body, offset, info);
|
|
||||||
}
|
|
||||||
ASSERT(mimg.dmask & 1); // should be always 1st (R) component
|
|
||||||
return ir.ImageGatherDref(handle, body, offset, dref, info);
|
|
||||||
}();
|
|
||||||
|
|
||||||
// For gather4 instructions dmask selects which component to read and must have
|
// For gather4 instructions dmask selects which component to read and must have
|
||||||
// only one bit set to 1
|
// only one bit set to 1
|
||||||
ASSERT_MSG(std::popcount(mimg.dmask) == 1, "Unexpected bits in gather dmask");
|
ASSERT_MSG(std::popcount(mimg.dmask) == 1, "Unexpected bits in gather dmask");
|
||||||
|
// should be always 1st (R) component for depth
|
||||||
|
ASSERT(!flags.test(MimgModifier::Pcf) || mimg.dmask & 1);
|
||||||
|
|
||||||
|
const IR::Value texel = EmitImageSample(ir, inst, tsharp_reg, sampler_reg, addr_reg, true);
|
||||||
for (u32 i = 0; i < 4; i++) {
|
for (u32 i = 0; i < 4; i++) {
|
||||||
const IR::F32 value = IR::F32{ir.CompositeExtract(texel, i)};
|
const IR::F32 value = IR::F32{ir.CompositeExtract(texel, i)};
|
||||||
ir.SetVectorReg(dest_reg++, value);
|
ir.SetVectorReg(dest_reg++, value);
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "shader_recompiler/backend/bindings.h"
|
#include "shader_recompiler/backend/bindings.h"
|
||||||
|
#include "shader_recompiler/frontend/copy_shader.h"
|
||||||
#include "shader_recompiler/ir/attribute.h"
|
#include "shader_recompiler/ir/attribute.h"
|
||||||
#include "shader_recompiler/ir/reg.h"
|
#include "shader_recompiler/ir/reg.h"
|
||||||
#include "shader_recompiler/ir/type.h"
|
#include "shader_recompiler/ir/type.h"
|
||||||
@ -170,6 +170,8 @@ struct Info {
|
|||||||
};
|
};
|
||||||
UserDataMask ud_mask{};
|
UserDataMask ud_mask{};
|
||||||
|
|
||||||
|
CopyShaderData gs_copy_data;
|
||||||
|
|
||||||
s8 vertex_offset_sgpr = -1;
|
s8 vertex_offset_sgpr = -1;
|
||||||
s8 instance_offset_sgpr = -1;
|
s8 instance_offset_sgpr = -1;
|
||||||
|
|
||||||
|
@ -130,19 +130,23 @@ void IREmitter::DeviceMemoryBarrier() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
U32 IREmitter::GetUserData(IR::ScalarReg reg) {
|
U32 IREmitter::GetUserData(IR::ScalarReg reg) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumScalarRegs);
|
||||||
return Inst<U32>(Opcode::GetUserData, reg);
|
return Inst<U32>(Opcode::GetUserData, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
U1 IREmitter::GetThreadBitScalarReg(IR::ScalarReg reg) {
|
U1 IREmitter::GetThreadBitScalarReg(IR::ScalarReg reg) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumScalarRegs);
|
||||||
return Inst<U1>(Opcode::GetThreadBitScalarReg, reg);
|
return Inst<U1>(Opcode::GetThreadBitScalarReg, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IREmitter::SetThreadBitScalarReg(IR::ScalarReg reg, const U1& value) {
|
void IREmitter::SetThreadBitScalarReg(IR::ScalarReg reg, const U1& value) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumScalarRegs);
|
||||||
Inst(Opcode::SetThreadBitScalarReg, reg, value);
|
Inst(Opcode::SetThreadBitScalarReg, reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
U32 IREmitter::GetScalarReg(IR::ScalarReg reg) {
|
U32 IREmitter::GetScalarReg(IR::ScalarReg reg) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumScalarRegs);
|
||||||
return Inst<U32>(Opcode::GetScalarRegister, reg);
|
return Inst<U32>(Opcode::GetScalarRegister, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +157,7 @@ F32 IREmitter::GetScalarReg(IR::ScalarReg reg) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
U32 IREmitter::GetVectorReg(IR::VectorReg reg) {
|
U32 IREmitter::GetVectorReg(IR::VectorReg reg) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumVectorRegs);
|
||||||
return Inst<U32>(Opcode::GetVectorRegister, reg);
|
return Inst<U32>(Opcode::GetVectorRegister, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,11 +167,13 @@ F32 IREmitter::GetVectorReg(IR::VectorReg reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IREmitter::SetScalarReg(IR::ScalarReg reg, const U32F32& value) {
|
void IREmitter::SetScalarReg(IR::ScalarReg reg, const U32F32& value) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumScalarRegs);
|
||||||
const U32 value_typed = value.Type() == Type::F32 ? BitCast<U32>(F32{value}) : U32{value};
|
const U32 value_typed = value.Type() == Type::F32 ? BitCast<U32>(F32{value}) : U32{value};
|
||||||
Inst(Opcode::SetScalarRegister, reg, value_typed);
|
Inst(Opcode::SetScalarRegister, reg, value_typed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IREmitter::SetVectorReg(IR::VectorReg reg, const U32F32& value) {
|
void IREmitter::SetVectorReg(IR::VectorReg reg, const U32F32& value) {
|
||||||
|
ASSERT(static_cast<u32>(reg) < IR::NumVectorRegs);
|
||||||
const U32 value_typed = value.Type() == Type::F32 ? BitCast<U32>(F32{value}) : U32{value};
|
const U32 value_typed = value.Type() == Type::F32 ? BitCast<U32>(F32{value}) : U32{value};
|
||||||
Inst(Opcode::SetVectorRegister, reg, value_typed);
|
Inst(Opcode::SetVectorRegister, reg, value_typed);
|
||||||
}
|
}
|
||||||
@ -1492,27 +1499,34 @@ Value IREmitter::ImageAtomicExchange(const Value& handle, const Value& coords, c
|
|||||||
return Inst(Opcode::ImageAtomicExchange32, Flags{info}, handle, coords, value);
|
return Inst(Opcode::ImageAtomicExchange32, Flags{info}, handle, coords, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageSampleImplicitLod(const Value& handle, const Value& body, const F32& bias,
|
Value IREmitter::ImageSampleRaw(const Value& handle, const Value& address1, const Value& address2,
|
||||||
const U32& offset, TextureInstInfo info) {
|
const Value& address3, const Value& address4,
|
||||||
return Inst(Opcode::ImageSampleImplicitLod, Flags{info}, handle, body, bias, offset);
|
TextureInstInfo info) {
|
||||||
|
return Inst(Opcode::ImageSampleRaw, Flags{info}, handle, address1, address2, address3,
|
||||||
|
address4);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageSampleExplicitLod(const Value& handle, const Value& body, const U32& offset,
|
Value IREmitter::ImageSampleImplicitLod(const Value& handle, const Value& coords, const F32& bias,
|
||||||
TextureInstInfo info) {
|
const Value& offset, TextureInstInfo info) {
|
||||||
return Inst(Opcode::ImageSampleExplicitLod, Flags{info}, handle, body, IR::F32{}, offset);
|
return Inst(Opcode::ImageSampleImplicitLod, Flags{info}, handle, coords, bias, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 IREmitter::ImageSampleDrefImplicitLod(const Value& handle, const Value& body, const F32& dref,
|
Value IREmitter::ImageSampleExplicitLod(const Value& handle, const Value& coords, const F32& lod,
|
||||||
const F32& bias, const U32& offset,
|
const Value& offset, TextureInstInfo info) {
|
||||||
|
return Inst(Opcode::ImageSampleExplicitLod, Flags{info}, handle, coords, lod, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value IREmitter::ImageSampleDrefImplicitLod(const Value& handle, const Value& coords,
|
||||||
|
const F32& dref, const F32& bias, const Value& offset,
|
||||||
TextureInstInfo info) {
|
TextureInstInfo info) {
|
||||||
return Inst<F32>(Opcode::ImageSampleDrefImplicitLod, Flags{info}, handle, body, dref, bias,
|
return Inst(Opcode::ImageSampleDrefImplicitLod, Flags{info}, handle, coords, dref, bias,
|
||||||
offset);
|
offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 IREmitter::ImageSampleDrefExplicitLod(const Value& handle, const Value& body, const F32& dref,
|
Value IREmitter::ImageSampleDrefExplicitLod(const Value& handle, const Value& coords,
|
||||||
const U32& offset, TextureInstInfo info) {
|
const F32& dref, const F32& lod, const Value& offset,
|
||||||
return Inst<F32>(Opcode::ImageSampleDrefExplicitLod, Flags{info}, handle, body, dref, IR::F32{},
|
TextureInstInfo info) {
|
||||||
offset);
|
return Inst(Opcode::ImageSampleDrefExplicitLod, Flags{info}, handle, coords, dref, lod, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageGather(const Value& handle, const Value& coords, const Value& offset,
|
Value IREmitter::ImageGather(const Value& handle, const Value& coords, const Value& offset,
|
||||||
@ -1544,9 +1558,11 @@ Value IREmitter::ImageQueryLod(const Value& handle, const Value& coords, Texture
|
|||||||
return Inst(Opcode::ImageQueryLod, Flags{info}, handle, coords);
|
return Inst(Opcode::ImageQueryLod, Flags{info}, handle, coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageGradient(const Value& handle, const Value& coords, const Value& derivatives,
|
Value IREmitter::ImageGradient(const Value& handle, const Value& coords,
|
||||||
|
const Value& derivatives_dx, const Value& derivatives_dy,
|
||||||
const Value& offset, const F32& lod_clamp, TextureInstInfo info) {
|
const Value& offset, const F32& lod_clamp, TextureInstInfo info) {
|
||||||
return Inst(Opcode::ImageGradient, Flags{info}, handle, coords, derivatives, offset, lod_clamp);
|
return Inst(Opcode::ImageGradient, Flags{info}, handle, coords, derivatives_dx, derivatives_dy,
|
||||||
|
offset, lod_clamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageRead(const Value& handle, const Value& coords, TextureInstInfo info) {
|
Value IREmitter::ImageRead(const Value& handle, const Value& coords, TextureInstInfo info) {
|
||||||
|
@ -277,21 +277,26 @@ public:
|
|||||||
[[nodiscard]] Value ImageAtomicExchange(const Value& handle, const Value& coords,
|
[[nodiscard]] Value ImageAtomicExchange(const Value& handle, const Value& coords,
|
||||||
const Value& value, TextureInstInfo info);
|
const Value& value, TextureInstInfo info);
|
||||||
|
|
||||||
|
[[nodiscard]] Value ImageSampleRaw(const Value& handle, const Value& address1,
|
||||||
|
const Value& address2, const Value& address3,
|
||||||
|
const Value& address4, TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] Value ImageSampleImplicitLod(const Value& handle, const Value& body,
|
[[nodiscard]] Value ImageSampleImplicitLod(const Value& handle, const Value& body,
|
||||||
const F32& bias, const U32& offset,
|
const F32& bias, const Value& offset,
|
||||||
TextureInstInfo info);
|
TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] Value ImageSampleExplicitLod(const Value& handle, const Value& body,
|
[[nodiscard]] Value ImageSampleExplicitLod(const Value& handle, const Value& body,
|
||||||
const U32& offset, TextureInstInfo info);
|
const F32& lod, const Value& offset,
|
||||||
|
|
||||||
[[nodiscard]] F32 ImageSampleDrefImplicitLod(const Value& handle, const Value& body,
|
|
||||||
const F32& dref, const F32& bias,
|
|
||||||
const U32& offset, TextureInstInfo info);
|
|
||||||
|
|
||||||
[[nodiscard]] F32 ImageSampleDrefExplicitLod(const Value& handle, const Value& body,
|
|
||||||
const F32& dref, const U32& offset,
|
|
||||||
TextureInstInfo info);
|
TextureInstInfo info);
|
||||||
|
|
||||||
|
[[nodiscard]] Value ImageSampleDrefImplicitLod(const Value& handle, const Value& body,
|
||||||
|
const F32& dref, const F32& bias,
|
||||||
|
const Value& offset, TextureInstInfo info);
|
||||||
|
|
||||||
|
[[nodiscard]] Value ImageSampleDrefExplicitLod(const Value& handle, const Value& body,
|
||||||
|
const F32& dref, const F32& lod,
|
||||||
|
const Value& offset, TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod,
|
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod,
|
||||||
const U1& skip_mips);
|
const U1& skip_mips);
|
||||||
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod,
|
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod,
|
||||||
@ -306,8 +311,9 @@ public:
|
|||||||
[[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const Value& offset,
|
[[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const Value& offset,
|
||||||
const U32& lod, const U32& multisampling, TextureInstInfo info);
|
const U32& lod, const U32& multisampling, TextureInstInfo info);
|
||||||
[[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords,
|
[[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords,
|
||||||
const Value& derivatives, const Value& offset,
|
const Value& derivatives_dx, const Value& derivatives_dy,
|
||||||
const F32& lod_clamp, TextureInstInfo info);
|
const Value& offset, const F32& lod_clamp,
|
||||||
|
TextureInstInfo info);
|
||||||
[[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, TextureInstInfo info);
|
[[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, TextureInstInfo info);
|
||||||
void ImageWrite(const Value& handle, const Value& coords, const Value& color,
|
void ImageWrite(const Value& handle, const Value& coords, const Value& color,
|
||||||
TextureInstInfo info);
|
TextureInstInfo info);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user