Merge branch 'shadps4-emu:main' into allocate-fixes

This commit is contained in:
Stephen Miller 2025-01-23 16:01:47 -06:00 committed by GitHub
commit 5d3e2d80b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
145 changed files with 4255 additions and 1412 deletions

View file

@ -390,7 +390,7 @@ jobs:
- name: Cache CMake Configuration
uses: actions/cache@v4
env:
cache-name: ${{ runner.os }}-sdl-cache-cmake-configuration
cache-name: ${{ runner.os }}-sdl-gcc-cache-cmake-configuration
with:
path: |
${{github.workspace}}/build
@ -401,7 +401,7 @@ jobs:
- name: Cache CMake Build
uses: hendrikmuhs/ccache-action@v1.2.14
env:
cache-name: ${{ runner.os }}-sdl-cache-cmake-build
cache-name: ${{ runner.os }}-sdl-gcc-cache-cmake-build
with:
append-timestamp: false
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
@ -426,7 +426,7 @@ jobs:
- name: Cache CMake Configuration
uses: actions/cache@v4
env:
cache-name: ${{ runner.os }}-qt-cache-cmake-configuration
cache-name: ${{ runner.os }}-qt-gcc-cache-cmake-configuration
with:
path: |
${{github.workspace}}/build
@ -437,7 +437,7 @@ jobs:
- name: Cache CMake Build
uses: hendrikmuhs/ccache-action@v1.2.14
env:
cache-name: ${{ runner.os }}-qt-cache-cmake-build
cache-name: ${{ runner.os }}-qt-gcc-cache-cmake-build
with:
append-timestamp: false
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}

View file

@ -120,7 +120,7 @@ find_package(SDL3 3.1.2 CONFIG)
find_package(stb MODULE)
find_package(toml11 4.2.0 CONFIG)
find_package(tsl-robin-map 1.3.0 CONFIG)
find_package(VulkanHeaders 1.4.303 CONFIG)
find_package(VulkanHeaders 1.4.305 CONFIG)
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
find_package(xbyak 7.07 CONFIG)
find_package(xxHash 0.8.2 MODULE)
@ -250,6 +250,8 @@ set(KERNEL_LIB src/core/libraries/kernel/sync/mutex.cpp
src/core/libraries/kernel/time.h
src/core/libraries/kernel/orbis_error.h
src/core/libraries/kernel/posix_error.h
src/core/libraries/kernel/aio.cpp
src/core/libraries/kernel/aio.h
)
set(NETWORK_LIBS src/core/libraries/network/http.cpp
@ -555,6 +557,16 @@ set(CORE src/core/aerolib/stubs.cpp
src/core/devices/logger.cpp
src/core/devices/logger.h
src/core/devices/nop_device.h
src/core/devices/console_device.cpp
src/core/devices/console_device.h
src/core/devices/deci_tty6_device.cpp
src/core/devices/deci_tty6_device.h
src/core/devices/random_device.cpp
src/core/devices/random_device.h
src/core/devices/urandom_device.cpp
src/core/devices/urandom_device.h
src/core/devices/srandom_device.cpp
src/core/devices/srandom_device.h
src/core/file_format/pfs.h
src/core/file_format/pkg.cpp
src/core/file_format/pkg.h

View file

@ -14,6 +14,7 @@ path = [
"documents/changelog.md",
"documents/Quickstart/2.png",
"documents/Screenshots/*",
"documents/Screenshots/Linux/*",
"externals/MoltenVK/MoltenVK_icd.json",
"scripts/ps4_names.txt",
"src/images/about_icon.png",

Binary file not shown.

After

(image error) Size: 11 KiB

Binary file not shown.

After

(image error) Size: 20 KiB

Binary file not shown.

After

(image error) Size: 25 KiB

Binary file not shown.

After

(image error) Size: 16 KiB

Binary file not shown.

After

(image error) Size: 26 KiB

View file

@ -3,59 +3,131 @@ SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later
-->
## Build shadPS4 for Linux
## Build shadPS4 for Linux
### Install the necessary tools to build shadPS4:
First and foremost, Clang 18 is the **recommended compiler** as it is used for official builds and CI. If you build with GCC, you might encounter issues — please report any you find. Additionally, if you choose to use GCC, please build shadPS4 with Clang at least once before creating an `[APP BUG]` issue or submitting a pull request.
## Preparatory steps
### Installing dependencies
#### Debian & Ubuntu
```
sudo apt install build-essential clang git cmake libasound2-dev libpulse-dev libopenal-dev libssl-dev zlib1g-dev libedit-dev libudev-dev libevdev-dev libsdl2-dev libjack-dev libsndio-dev qt6-base-dev qt6-tools-dev qt6-multimedia-dev libvulkan-dev vulkan-validationlayers
```
#### Fedora
```
sudo dnf install clang git cmake libatomic alsa-lib-devel pipewire-jack-audio-connection-kit-devel openal-devel openssl-devel libevdev-devel libudev-devel libXext-devel qt6-qtbase-devel qt6-qtbase-private-devel qt6-qtmultimedia-devel qt6-qtsvg-devel qt6-qttools-devel vulkan-devel vulkan-validation-layers
```
#### Arch Linux
```
sudo pacman -S base-devel clang git cmake sndio jack2 openal qt6-base qt6-declarative qt6-multimedia sdl2 vulkan-validation-layers
```
#### OpenSUSE
**Note** : The `shadps4-git` AUR package is not maintained by any of the developers, and it uses the default compiler, which is often set to GCC. Use at your own discretion.#### OpenSUSE
```
sudo zypper install clang git cmake libasound2 libpulse-devel libsndio7 libjack-devel openal-soft-devel libopenssl-devel zlib-devel libedit-devel systemd-devel libevdev-devel qt6-base-devel qt6-multimedia-devel qt6-svg-devel qt6-linguist-devel qt6-gui-private-devel vulkan-devel vulkan-validationlayers
```
### Cloning and compiling:
Clone the repository recursively:
#### Other Linux distributions
You can try one of two methods:
- Search the packages by name and install them with your package manager, or
- Install [distrobox](https://distrobox.it/), create a container using any of the distributions cited above as a base, for Arch Linux you'd do:
```
distrobox create --name archlinux --init --image archlinux:latest
```
and install the dependencies on that container as cited above.
This option is **highly recommended** for NixOS and distributions with immutable/atomic filesystems (example: Fedora Kinoite, SteamOS).
### Cloning
```
git clone --recursive https://github.com/shadps4-emu/shadPS4.git
cd shadPS4
```
Generate the build directory in the shadPS4 directory. To disable the QT GUI, remove the ```-DENABLE_QT_GUI=ON``` flag:
## Building
There are 3 options you can choose from. Option 1 is **highly recommended**.
#### Option 1: Terminal-only
1. Generate the build directory in the shadPS4 directory.
**Note**: Clang is the compiler used for official builds and CI. If you build with GCC, you might encounter issues—please report any you find. If you choose to use GCC, we recommend building with Clang at least once before submitting a pull request.
```
cmake -S . -B build/ -DENABLE_QT_GUI=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
```
Enter the directory:
To disable the Qt GUI, remove the `-DENABLE_QT_GUI=ON` flag. To change the build type (for debugging), add `-DCMAKE_BUILD_TYPE=Debug`.
2. Use CMake to build the project:
```
cd build/
cmake --build ./build --parallel$(nproc)
```
Use make to build the project:
If your computer freezes during this step, this could be caused by excessive system resource usage. In that case, remove `--parallel$(nproc)`.
Now run the emulator. If Qt was enabled at configure time:
```
cmake --build . --parallel$(nproc)
./build/shadps4
```
Now run the emulator. If QT is enabled:
```
./shadps4
```
Otherwise, specify the path to your PKG's boot file:
```
./shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
./build/shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
```
You can also specify the Game ID as an argument for which game to boot, as long as the folder containing the games is specified in config.toml (example: Bloodborne (US) is CUSA00900).
#### Option 2: Configuring with cmake-gui
`cmake-gui` should be installed by default alongside `cmake`, if not search for the package in your package manager and install it.
Open `cmake-gui` and specify the source code and build directories. If you cloned the source code to your Home directory, it would be `/home/user/shadPS4` and `/home/user/shadPS4/build`.
Click on Configure, select "Unix Makefiles", select "Specify native compilers", click Next and choose `clang` and `clang++` as the C and CXX compilers. Usually they are located in `/bin/clang` and `/bin/clang++`. Click on Finish and let it configure the project.
Now every option should be displayed in red. Change anything you want, then click on Generate to make the changes permanent, then open a terminal window and do step 2 of Option 1.
#### Option 3: Visual Studio Code
This option is pretty convoluted and should only be used if you have VSCode as your default IDE, or just prefer building and debugging projects through it. This also assumes that you're using an Arch Linux environment, as the naming for some options might differ from other distros.
[Download Visual Studio Code for your platform](https://code.visualstudio.com/download), or use [Code - OSS](https://github.com/microsoft/vscode) if you'd like. Code - OSS is available on most Linux distributions' package repositories (on Arch Linux it is simply named `code`).
Once set up, go to Extensions and install "CMake Tools":
![image](https://raw.githubusercontent.com/shadps4-emu/shadPS4/refs/heads/main/documents/Screenshots/Linux/3.png)
You can also install other CMake and Clang related extensions if you'd like, but this one is what enables you to configure and build CMake projects directly within VSCode.
Go to Settings, filter by `@ext:ms-vscode.cmake-tools configure` and disable this option:
![image](https://raw.githubusercontent.com/shadps4-emu/shadPS4/refs/heads/main/documents/Screenshots/Linux/1.png)
If you wish to build with the Qt GUI, add `-DENABLE_QT_GUI=ON` to the configure arguments:
![image](https://raw.githubusercontent.com/shadps4-emu/shadPS4/refs/heads/main/documents/Screenshots/Linux/2.png)
On the CMake tab, change the options as you wish, but make sure that it looks similar to or exactly like this:
![image](https://raw.githubusercontent.com/shadps4-emu/shadPS4/refs/heads/main/documents/Screenshots/Linux/4.png)
When hovering over Project Status > Configure, there should be an icon titled "Configure". Click on it and let it configure the project, then do the same for Project Status > Build.
If you want to debug it, change the build type under Project Status > Configure to Debug (it should be the default) and compile it, then click on the icon in Project Status > Debug. If you simply want to launch the shadPS4 executable from within VSCode, click on the icon in Project Status > Launch.
Don't forget to change the launch target for both options to the shadPS4 executable inside shadPS4/build:
![image](https://raw.githubusercontent.com/shadps4-emu/shadPS4/refs/heads/main/documents/Screenshots/Linux/5.png)

@ -1 +1 @@
Subproject commit 9f0b616d9e2c39464d2a859b79dbc655c4a30e7e
Subproject commit 2473ce6f0ab7d5d8a49aa91b2e37f3447a939f18

2
externals/sdl3 vendored

@ -1 +1 @@
Subproject commit 22422f7748d5128135995ed34c8f8012861c7332
Subproject commit a336b62d8b0b97b09214e053203e442e2b6e2be5

@ -1 +1 @@
Subproject commit 6a74a7d65cafa19e38ec116651436cce6efd5b2e
Subproject commit a03d2f6d5753b365d704d58161825890baad0755

View file

@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#ifdef __linux__
#include <pthread.h>
#endif
namespace Common {
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
class AdaptiveMutex {
public:
void lock() {
pthread_mutex_lock(&mutex);
}
void unlock() {
pthread_mutex_unlock(&mutex);
}
private:
pthread_mutex_t mutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
};
#endif // PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
} // namespace Common

View file

@ -45,6 +45,9 @@ static std::string logFilter;
static std::string logType = "async";
static std::string userName = "shadPS4";
static std::string updateChannel;
static std::string chooseHomeTab;
static u16 deadZoneLeft = 2.0;
static u16 deadZoneRight = 2.0;
static std::string backButtonBehavior = "left";
static bool useSpecialPad = false;
static int specialPadClass = 1;
@ -61,9 +64,10 @@ static u32 vblankDivider = 1;
static bool vkValidation = false;
static bool vkValidationSync = false;
static bool vkValidationGpu = false;
static bool rdocEnable = false;
static bool vkMarkers = false;
static bool vkCrashDiagnostic = false;
static bool vkHostMarkers = false;
static bool vkGuestMarkers = false;
static bool rdocEnable = false;
static s16 cursorState = HideCursorState::Idle;
static int cursorHideTimeout = 5; // 5 seconds (default)
static bool separateupdatefolder = false;
@ -75,6 +79,7 @@ static std::string trophyKey;
static bool load_game_size = true;
std::vector<std::filesystem::path> settings_install_dirs = {};
std::filesystem::path settings_addon_install_dir = {};
std::filesystem::path save_data_path = {};
u32 main_window_geometry_x = 400;
u32 main_window_geometry_y = 400;
u32 main_window_geometry_w = 1280;
@ -107,6 +112,13 @@ bool GetLoadGameSizeEnabled() {
return load_game_size;
}
std::filesystem::path GetSaveDataPath() {
if (save_data_path.empty()) {
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir);
}
return save_data_path;
}
void setLoadGameSizeEnabled(bool enable) {
load_game_size = enable;
}
@ -139,6 +151,14 @@ bool getEnableDiscordRPC() {
return enableDiscordRPC;
}
u16 leftDeadZone() {
return deadZoneLeft;
}
u16 rightDeadZone() {
return deadZoneRight;
}
s16 getCursorState() {
return cursorState;
}
@ -175,6 +195,10 @@ std::string getUpdateChannel() {
return updateChannel;
}
std::string getChooseHomeTab() {
return chooseHomeTab;
}
std::string getBackButtonBehavior() {
return backButtonBehavior;
}
@ -227,10 +251,6 @@ bool isRdocEnabled() {
return rdocEnable;
}
bool isMarkersEnabled() {
return vkMarkers;
}
u32 vblankDiv() {
return vblankDivider;
}
@ -247,14 +267,20 @@ bool vkValidationGpuEnabled() {
return vkValidationGpu;
}
bool vkMarkersEnabled() {
return vkMarkers || vkCrashDiagnostic; // Crash diagnostic forces markers on
}
bool vkCrashDiagnosticEnabled() {
return vkCrashDiagnostic;
}
bool vkHostMarkersEnabled() {
// Forced on when crash diagnostic enabled.
return vkHostMarkers || vkCrashDiagnostic;
}
bool vkGuestMarkersEnabled() {
// Forced on when crash diagnostic enabled.
return vkGuestMarkers || vkCrashDiagnostic;
}
bool getSeparateUpdateEnabled() {
return separateupdatefolder;
}
@ -378,6 +404,9 @@ void setUserName(const std::string& type) {
void setUpdateChannel(const std::string& type) {
updateChannel = type;
}
void setChooseHomeTab(const std::string& type) {
chooseHomeTab = type;
}
void setBackButtonBehavior(const std::string& type) {
backButtonBehavior = type;
@ -489,6 +518,10 @@ void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_insta
settings_install_dirs = settings_install_dirs_config;
}
void setSaveDataPath(const std::filesystem::path& path) {
save_data_path = path;
}
u32 getMainWindowGeometryX() {
return main_window_geometry_x;
}
@ -612,11 +645,14 @@ void load(const std::filesystem::path& path) {
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false);
checkCompatibilityOnStartup =
toml::find_or<bool>(general, "checkCompatibilityOnStartup", false);
chooseHomeTab = toml::find_or<std::string>(general, "chooseHomeTab", "Release");
}
if (data.contains("Input")) {
const toml::value& input = data.at("Input");
deadZoneLeft = toml::find_or<float>(input, "deadZoneLeft", 2.0);
deadZoneRight = toml::find_or<float>(input, "deadZoneRight", 2.0);
cursorState = toml::find_or<int>(input, "cursorState", HideCursorState::Idle);
cursorHideTimeout = toml::find_or<int>(input, "cursorHideTimeout", 5);
backButtonBehavior = toml::find_or<std::string>(input, "backButtonBehavior", "left");
@ -644,9 +680,10 @@ void load(const std::filesystem::path& path) {
vkValidation = toml::find_or<bool>(vk, "validation", false);
vkValidationSync = toml::find_or<bool>(vk, "validation_sync", false);
vkValidationGpu = toml::find_or<bool>(vk, "validation_gpu", true);
rdocEnable = toml::find_or<bool>(vk, "rdocEnable", false);
vkMarkers = toml::find_or<bool>(vk, "rdocMarkersEnable", false);
vkCrashDiagnostic = toml::find_or<bool>(vk, "crashDiagnostic", false);
vkHostMarkers = toml::find_or<bool>(vk, "hostMarkers", false);
vkGuestMarkers = toml::find_or<bool>(vk, "guestMarkers", false);
rdocEnable = toml::find_or<bool>(vk, "rdocEnable", false);
}
if (data.contains("Debug")) {
@ -674,6 +711,8 @@ void load(const std::filesystem::path& path) {
addGameInstallDir(std::filesystem::path{dir});
}
save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {});
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_y = toml::find_or<int>(gui, "geometry_y", 0);
@ -730,11 +769,14 @@ void save(const std::filesystem::path& path) {
data["General"]["logType"] = logType;
data["General"]["userName"] = userName;
data["General"]["updateChannel"] = updateChannel;
data["General"]["chooseHomeTab"] = chooseHomeTab;
data["General"]["showSplash"] = isShowSplash;
data["General"]["autoUpdate"] = isAutoUpdate;
data["General"]["separateUpdateEnabled"] = separateupdatefolder;
data["General"]["compatibilityEnabled"] = compatibilityData;
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
data["Input"]["deadZoneLeft"] = deadZoneLeft;
data["Input"]["deadZoneRight"] = deadZoneRight;
data["Input"]["cursorState"] = cursorState;
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
data["Input"]["backButtonBehavior"] = backButtonBehavior;
@ -752,9 +794,10 @@ void save(const std::filesystem::path& path) {
data["Vulkan"]["validation"] = vkValidation;
data["Vulkan"]["validation_sync"] = vkValidationSync;
data["Vulkan"]["validation_gpu"] = vkValidationGpu;
data["Vulkan"]["rdocEnable"] = rdocEnable;
data["Vulkan"]["rdocMarkersEnable"] = vkMarkers;
data["Vulkan"]["crashDiagnostic"] = vkCrashDiagnostic;
data["Vulkan"]["hostMarkers"] = vkHostMarkers;
data["Vulkan"]["guestMarkers"] = vkGuestMarkers;
data["Vulkan"]["rdocEnable"] = rdocEnable;
data["Debug"]["DebugDump"] = isDebugDump;
data["Debug"]["CollectShader"] = isShaderDebug;
@ -765,6 +808,7 @@ void save(const std::filesystem::path& path) {
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
}
data["GUI"]["installDirs"] = install_dirs;
data["GUI"]["saveDataPath"] = std::string{fmt::UTF(save_data_path.u8string()).data};
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
data["GUI"]["addonInstallDir"] =
@ -837,6 +881,7 @@ void setDefaultValues() {
} else {
updateChannel = "Nightly";
}
chooseHomeTab = "General";
cursorState = HideCursorState::Idle;
cursorHideTimeout = 5;
backButtonBehavior = "left";
@ -852,9 +897,10 @@ void setDefaultValues() {
vkValidation = false;
vkValidationSync = false;
vkValidationGpu = false;
rdocEnable = false;
vkMarkers = false;
vkCrashDiagnostic = false;
vkHostMarkers = false;
vkGuestMarkers = false;
rdocEnable = false;
emulator_language = "en";
m_language = 1;
gpuId = -1;
@ -863,4 +909,4 @@ void setDefaultValues() {
checkCompatibilityOnStartup = false;
}
} // namespace Config
} // namespace Config

View file

@ -18,6 +18,7 @@ void saveMainWindow(const std::filesystem::path& path);
std::string getTrophyKey();
void setTrophyKey(std::string key);
bool GetLoadGameSizeEnabled();
std::filesystem::path GetSaveDataPath();
void setLoadGameSizeEnabled(bool enable);
bool getIsFullscreen();
std::string getFullscreenMode();
@ -34,7 +35,10 @@ std::string getLogFilter();
std::string getLogType();
std::string getUserName();
std::string getUpdateChannel();
std::string getChooseHomeTab();
u16 leftDeadZone();
u16 rightDeadZone();
s16 getCursorState();
int getCursorHideTimeout();
std::string getBackButtonBehavior();
@ -78,8 +82,10 @@ void setLanguage(u32 language);
void setNeoMode(bool enable);
void setUserName(const std::string& type);
void setUpdateChannel(const std::string& type);
void setChooseHomeTab(const std::string& type);
void setSeparateUpdateEnabled(bool use);
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config);
void setSaveDataPath(const std::filesystem::path& path);
void setCompatibilityEnabled(bool use);
void setCheckCompatibilityOnStartup(bool use);
@ -100,8 +106,9 @@ void setRdocEnabled(bool enable);
bool vkValidationEnabled();
bool vkValidationSyncEnabled();
bool vkValidationGpuEnabled();
bool vkMarkersEnabled();
bool vkCrashDiagnosticEnabled();
bool vkHostMarkersEnabled();
bool vkGuestMarkersEnabled();
// Gui
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);

View file

@ -37,6 +37,10 @@ public:
void Start();
void End();
std::chrono::nanoseconds GetTotalWait() const {
return total_wait;
}
};
} // namespace Common

View file

@ -67,28 +67,25 @@ struct AddressSpace::Impl {
static constexpr size_t ReductionOnFail = 1_GB;
static constexpr size_t MaxReductions = 10;
size_t reduction = 0;
size_t virtual_size = SystemManagedSize + SystemReservedSize + UserSize;
for (u32 i = 0; i < MaxReductions; i++) {
virtual_base = static_cast<u8*>(VirtualAlloc2(process, NULL, virtual_size - reduction,
virtual_base = static_cast<u8*>(VirtualAlloc2(process, NULL, virtual_size,
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, &param, 1));
if (virtual_base) {
break;
}
reduction += ReductionOnFail;
virtual_size -= ReductionOnFail;
}
ASSERT_MSG(virtual_base, "Unable to reserve virtual address space: {}",
Common::GetLastErrorMsg());
// Take the reduction off of the system managed area, and leave the others unchanged.
reduction = size_t(virtual_base - SYSTEM_MANAGED_MIN);
system_managed_base = virtual_base;
system_managed_size = SystemManagedSize - reduction;
system_reserved_base = reinterpret_cast<u8*>(SYSTEM_RESERVED_MIN);
system_reserved_size = SystemReservedSize;
system_managed_base = virtual_base;
system_managed_size = system_reserved_base - virtual_base;
user_base = reinterpret_cast<u8*>(USER_MIN);
user_size = UserSize;
user_size = virtual_base + virtual_size - user_base;
LOG_INFO(Kernel_Vmm, "System managed virtual memory region: {} - {}",
fmt::ptr(system_managed_base),
@ -101,10 +98,8 @@ struct AddressSpace::Impl {
// Initializer placeholder tracker
const uintptr_t system_managed_addr = reinterpret_cast<uintptr_t>(system_managed_base);
const uintptr_t system_reserved_addr = reinterpret_cast<uintptr_t>(system_reserved_base);
const uintptr_t user_addr = reinterpret_cast<uintptr_t>(user_base);
regions.emplace(system_managed_addr,
MemoryRegion{system_managed_addr, virtual_size - reduction, false});
MemoryRegion{system_managed_addr, virtual_size, false});
// Allocate backing file that represents the total physical memory.
backing_handle =

View file

@ -17,6 +17,8 @@ using namespace DebugStateType;
DebugStateImpl& DebugState = *Common::Singleton<DebugStateImpl>::Instance();
bool DebugStateType::showing_debug_menu_bar = false;
static ThreadID ThisThreadID() {
#ifdef _WIN32
return GetCurrentThreadId();

View file

@ -35,6 +35,8 @@ class ShaderList;
namespace DebugStateType {
extern bool showing_debug_menu_bar;
enum class QueueType {
dcb = 0,
ccb = 1,
@ -153,6 +155,9 @@ class DebugStateImpl {
std::vector<ShaderDump> shader_dump_list{};
public:
float Framerate = 1.0f / 60.0f;
float FrameDeltaTime;
void ShowDebugMessage(std::string message) {
if (message.empty()) {
return;
@ -160,6 +165,10 @@ public:
debug_message_popup.push(std::move(message));
}
bool& IsShowingDebugMenuBar() {
return showing_debug_menu_bar;
}
void AddCurrentThreadToGuestList();
void RemoveCurrentThreadFromGuestList();

View file

@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "base_device.h"

View file

@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

View file

@ -0,0 +1,74 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "console_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> ConsoleDevice::Create(u32 handle, const char*, int, u16) {
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new ConsoleDevice(handle)));
}
int ConsoleDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t ConsoleDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t ConsoleDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::read(void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int ConsoleDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 ConsoleDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int ConsoleDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int ConsoleDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
namespace Core::Devices {
class ConsoleDevice final : BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit ConsoleDevice(u32 handle) : handle(handle) {}
~ConsoleDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
};
} // namespace Core::Devices

View file

@ -0,0 +1,74 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "deci_tty6_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> DeciTty6Device::Create(u32 handle, const char*, int, u16) {
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new DeciTty6Device(handle)));
}
int DeciTty6Device::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t DeciTty6Device::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t DeciTty6Device::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::read(void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int DeciTty6Device::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 DeciTty6Device::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int DeciTty6Device::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int DeciTty6Device::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
namespace Core::Devices {
class DeciTty6Device final : BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit DeciTty6Device(u32 handle) : handle(handle) {}
~DeciTty6Device() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
};
} // namespace Core::Devices

View file

@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

View file

@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/libraries/kernel/file_system.h"
@ -17,10 +17,12 @@ s64 Logger::write(const void* buf, size_t nbytes) {
}
size_t Logger::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
size_t total_written = 0;
for (int i = 0; i < iovcnt; i++) {
log(static_cast<const char*>(iov[i].iov_base), iov[i].iov_len);
total_written += iov[i].iov_len;
}
return iovcnt;
return total_written;
}
s64 Logger::pwrite(const void* buf, size_t nbytes, u64 offset) {

View file

@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

View file

@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "base_device.h"
@ -17,36 +17,47 @@ public:
int ioctl(u64 cmd, Common::VaCtx* args) override {
return 0;
}
s64 write(const void* buf, size_t nbytes) override {
return 0;
}
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override {
return 0;
}
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override {
return 0;
}
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override {
return 0;
}
s64 lseek(s64 offset, int whence) override {
return 0;
}
s64 read(void* buf, size_t nbytes) override {
return 0;
}
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
return 0;
}
s32 fsync() override {
return 0;
}
int ftruncate(s64 length) override {
return 0;
}
int getdents(void* buf, u32 nbytes, s64* basep) override {
return 0;
}
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override {
return 0;
}

View file

@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include "common/logging/log.h"
#include "random_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> RandomDevice::Create(u32 handle, const char*, int, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new RandomDevice(handle)));
}
int RandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t RandomDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t RandomDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::lseek(s64 offset, int whence) {
return 0;
}
s64 RandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return nbytes;
}
int RandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 RandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int RandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int RandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
namespace Core::Devices {
class RandomDevice final : BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit RandomDevice(u32 handle) : handle(handle) {}
~RandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
};
} // namespace Core::Devices

View file

@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include "common/logging/log.h"
#include "srandom_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> SRandomDevice::Create(u32 handle, const char*, int, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new SRandomDevice(handle)));
}
int SRandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t SRandomDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t SRandomDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
rbuf[i] = std::rand();
}
return nbytes;
}
int SRandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 SRandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return s32();
}
int SRandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int SRandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
namespace Core::Devices {
class SRandomDevice final : BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit SRandomDevice(u32 handle) : handle(handle) {}
~SRandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
};
} // namespace Core::Devices

View file

@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include "common/logging/log.h"
#include "urandom_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> URandomDevice::Create(u32 handle, const char*, int, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new URandomDevice(handle)));
}
int URandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t URandomDevice::writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t URandomDevice::readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return nbytes;
}
int URandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 URandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int URandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int URandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
namespace Core::Devices {
class URandomDevice final : BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit URandomDevice(u32 handle) : handle(handle) {}
~URandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
};
} // namespace Core::Devices

View file

@ -28,7 +28,6 @@ static bool show_simple_fps = false;
static bool visibility_toggled = false;
static float fps_scale = 1.0f;
static bool show_advanced_debug = false;
static int dump_frame_count = 1;
static Widget::FrameGraph frame_graph;
@ -94,6 +93,12 @@ void L::DrawMenuBar() {
}
ImGui::EndMenu();
}
SameLine(ImGui::GetWindowWidth() - 30.0f);
if (Button("X", ImVec2(25, 25))) {
DebugState.IsShowingDebugMenuBar() = false;
}
EndMainMenuBar();
}
@ -253,8 +258,8 @@ void L::DrawAdvanced() {
}
void L::DrawSimple() {
const auto io = GetIO();
Text("%.1f FPS (%.2f ms)", io.Framerate, 1000.0f / io.Framerate);
const float frameRate = DebugState.Framerate;
Text("%d FPS (%.1f ms)", static_cast<int>(std::round(frameRate)), 1000.0f / frameRate);
}
static void LoadSettings(const char* line) {
@ -265,7 +270,7 @@ static void LoadSettings(const char* line) {
return;
}
if (sscanf(line, "show_advanced_debug=%d", &i) == 1) {
show_advanced_debug = i != 0;
DebugState.IsShowingDebugMenuBar() = i != 0;
return;
}
if (sscanf(line, "show_frame_graph=%d", &i) == 1) {
@ -310,7 +315,7 @@ void L::SetupSettings() {
handler.WriteAllFn = [](ImGuiContext*, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) {
buf->appendf("[%s][Data]\n", handler->TypeName);
buf->appendf("fps_scale=%f\n", fps_scale);
buf->appendf("show_advanced_debug=%d\n", show_advanced_debug);
buf->appendf("show_advanced_debug=%d\n", DebugState.IsShowingDebugMenuBar());
buf->appendf("show_frame_graph=%d\n", frame_graph.is_open);
buf->appendf("dump_frame_count=%d\n", dump_frame_count);
buf->append("\n");
@ -336,12 +341,12 @@ void L::Draw() {
if (!DebugState.IsGuestThreadsPaused()) {
const auto fn = DebugState.flip_frame_count.load();
frame_graph.AddFrame(fn, io.DeltaTime);
frame_graph.AddFrame(fn, DebugState.FrameDeltaTime);
}
if (IsKeyPressed(ImGuiKey_F10, false)) {
if (io.KeyCtrl) {
show_advanced_debug = !show_advanced_debug;
DebugState.IsShowingDebugMenuBar() ^= true;
} else {
show_simple_fps = !show_simple_fps;
}
@ -376,7 +381,7 @@ void L::Draw() {
End();
}
if (show_advanced_debug) {
if (DebugState.IsShowingDebugMenuBar()) {
PushFont(io.Fonts->Fonts[IMGUI_FONT_MONO]);
PushID("DevtoolsLayer");
DrawAdvanced();

View file

@ -83,15 +83,13 @@ void FrameGraph::Draw() {
auto isSystemPaused = DebugState.IsGuestThreadsPaused();
static float deltaTime;
static float frameRate;
if (!isSystemPaused) {
deltaTime = io.DeltaTime * 1000.0f;
deltaTime = DebugState.FrameDeltaTime * 1000.0f;
frameRate = 1000.0f / deltaTime;
}
Text("Frame time: %.3f ms (%.1f FPS)", deltaTime, frameRate);
Text("Presenter time: %.3f ms (%.1f FPS)", io.DeltaTime * 1000.0f, 1.0f / io.DeltaTime);
Text("Flip frame: %d Gnm submit frame: %d", DebugState.flip_frame_count.load(),
DebugState.gnm_frame_count.load());

View file

@ -16,6 +16,9 @@ class FrameGraph {
std::array<FrameInfo, FRAME_BUFFER_SIZE> frame_list{};
float deltaTime{};
float frameRate{};
void DrawFrameGraph();
public:

View file

@ -24,16 +24,33 @@ using namespace ImGui;
namespace Core::Devtools::Widget {
ShaderList::Selection::Selection(int index) : index(index) {
isa_editor.SetPalette(TextEditor::GetDarkPalette());
isa_editor.SetReadOnly(true);
glsl_editor.SetPalette(TextEditor::GetDarkPalette());
glsl_editor.SetLanguageDefinition(TextEditor::LanguageDefinition::GLSL());
ShaderList::Selection::Selection(int index)
: index(index), isa_editor(std::make_unique<TextEditor>()),
glsl_editor(std::make_unique<TextEditor>()) {
isa_editor->SetPalette(TextEditor::GetDarkPalette());
isa_editor->SetReadOnly(true);
glsl_editor->SetPalette(TextEditor::GetDarkPalette());
glsl_editor->SetLanguageDefinition(TextEditor::LanguageDefinition::GLSL());
presenter->GetWindow().RequestKeyboard();
}
ShaderList::Selection::~Selection() {
presenter->GetWindow().ReleaseKeyboard();
if (index >= 0) {
presenter->GetWindow().ReleaseKeyboard();
}
}
ShaderList::Selection::Selection(Selection&& other) noexcept
: index{other.index}, isa_editor{std::move(other.isa_editor)},
glsl_editor{std::move(other.glsl_editor)}, open{other.open}, showing_bin{other.showing_bin},
patch_path{std::move(other.patch_path)}, patch_bin_path{std::move(other.patch_bin_path)} {
other.index = -1;
}
ShaderList::Selection& ShaderList::Selection::operator=(Selection other) {
using std::swap;
swap(*this, other);
return *this;
}
void ShaderList::Selection::ReloadShader(DebugStateType::ShaderDump& value) {
@ -72,13 +89,13 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
value.is_patched = !value.patch_spv.empty();
if (!value.is_patched) { // No patch
isa_editor.SetText(value.cache_isa_disasm);
glsl_editor.SetText(value.cache_spv_disasm);
isa_editor->SetText(value.cache_isa_disasm);
glsl_editor->SetText(value.cache_spv_disasm);
} else {
isa_editor.SetText(value.cache_patch_disasm);
isa_editor.SetLanguageDefinition(TextEditor::LanguageDefinition::SPIRV());
glsl_editor.SetText(value.patch_source);
glsl_editor.SetReadOnly(false);
isa_editor->SetText(value.cache_patch_disasm);
isa_editor->SetLanguageDefinition(TextEditor::LanguageDefinition::SPIRV());
glsl_editor->SetText(value.patch_source);
glsl_editor->SetReadOnly(false);
}
}
@ -97,18 +114,18 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
if (value.patch_source.empty()) {
value.patch_source = value.cache_spv_disasm;
}
isa_editor.SetText(value.cache_patch_disasm);
isa_editor.SetLanguageDefinition(TextEditor::LanguageDefinition::SPIRV());
glsl_editor.SetText(value.patch_source);
glsl_editor.SetReadOnly(false);
isa_editor->SetText(value.cache_patch_disasm);
isa_editor->SetLanguageDefinition(TextEditor::LanguageDefinition::SPIRV());
glsl_editor->SetText(value.patch_source);
glsl_editor->SetReadOnly(false);
if (!value.patch_spv.empty()) {
ReloadShader(value);
}
} else {
isa_editor.SetText(value.cache_isa_disasm);
isa_editor.SetLanguageDefinition(TextEditor::LanguageDefinition());
glsl_editor.SetText(value.cache_spv_disasm);
glsl_editor.SetReadOnly(true);
isa_editor->SetText(value.cache_isa_disasm);
isa_editor->SetLanguageDefinition(TextEditor::LanguageDefinition());
glsl_editor->SetText(value.cache_spv_disasm);
glsl_editor->SetReadOnly(true);
ReloadShader(value);
}
}
@ -154,7 +171,7 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
compile = true;
}
if (save) {
value.patch_source = glsl_editor.GetText();
value.patch_source = glsl_editor->GetText();
std::ofstream file{patch_path, std::ios::binary | std::ios::trunc};
file << value.patch_source;
std::string msg = "Patch saved to ";
@ -192,7 +209,7 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
DebugState.ShowDebugMessage("Decompilation failed (Compile was ok):\n" +
res);
} else {
isa_editor.SetText(value.cache_patch_disasm);
isa_editor->SetText(value.cache_patch_disasm);
ReloadShader(value);
}
}
@ -201,9 +218,9 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
}
if (showing_bin) {
isa_editor.Render(value.is_patched ? "SPIRV" : "ISA", GetContentRegionAvail());
isa_editor->Render(value.is_patched ? "SPIRV" : "ISA", GetContentRegionAvail());
} else {
glsl_editor.Render("GLSL", GetContentRegionAvail());
glsl_editor->Render("GLSL", GetContentRegionAvail());
}
End();

View file

@ -14,14 +14,17 @@ class ShaderList {
struct Selection {
explicit Selection(int index);
~Selection();
Selection(const Selection& other) = delete;
Selection(Selection&& other) noexcept;
Selection& operator=(Selection other);
void ReloadShader(DebugStateType::ShaderDump& value);
bool DrawShader(DebugStateType::ShaderDump& value);
int index;
TextEditor isa_editor{};
TextEditor glsl_editor{};
int index{-1};
std::unique_ptr<TextEditor> isa_editor{};
std::unique_ptr<TextEditor> glsl_editor{};
bool open = true;
bool showing_bin = false;

View file

@ -233,7 +233,7 @@ void HandleTable::CreateStdHandles() {
std::shared_ptr<Devices::BaseDevice>{reinterpret_cast<Devices::BaseDevice*>(device)};
};
// order matters
setup("/dev/stdin", new Devices::NopDevice(0)); // stdin
setup("/dev/stdin", new Devices::Logger("stdin", false)); // stdin
setup("/dev/stdout", new Devices::Logger("stdout", false)); // stdout
setup("/dev/stderr", new Devices::Logger("stderr", true)); // stderr
}

View file

@ -0,0 +1,339 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <thread>
#include "aio.h"
#include "common/assert.h"
#include "common/debug.h"
#include "common/logging/log.h"
#include "core/libraries/kernel/equeue.h"
#include "core/libraries/kernel/orbis_error.h"
#include "core/libraries/libs.h"
#include "file_system.h"
namespace Libraries::Kernel {
#define MAX_QUEUE 512
static s32* id_state;
static s32 id_index;
s32 sceKernelAioInitializeImpl(void* p, s32 size) {
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioDeleteRequest(OrbisKernelAioSubmitId id, s32* ret) {
if (ret == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
id_state[id] = ORBIS_KERNEL_AIO_STATE_ABORTED;
*ret = 0;
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioDeleteRequests(OrbisKernelAioSubmitId id[], s32 num, s32 ret[]) {
if (ret == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
for (s32 i = 0; i < num; i++) {
id_state[id[i]] = ORBIS_KERNEL_AIO_STATE_ABORTED;
ret[i] = 0;
}
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioPollRequest(OrbisKernelAioSubmitId id, s32* state) {
if (state == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
*state = id_state[id];
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioPollRequests(OrbisKernelAioSubmitId id[], s32 num, s32 state[]) {
if (state == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
for (s32 i = 0; i < num; i++) {
state[i] = id_state[id[i]];
}
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioCancelRequest(OrbisKernelAioSubmitId id, s32* state) {
if (state == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (id) {
id_state[id] = ORBIS_KERNEL_AIO_STATE_ABORTED;
*state = ORBIS_KERNEL_AIO_STATE_ABORTED;
} else {
*state = ORBIS_KERNEL_AIO_STATE_PROCESSING;
}
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioCancelRequests(OrbisKernelAioSubmitId id[], s32 num, s32 state[]) {
if (state == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
for (s32 i = 0; i < num; i++) {
if (id[i]) {
id_state[id[i]] = ORBIS_KERNEL_AIO_STATE_ABORTED;
state[i] = ORBIS_KERNEL_AIO_STATE_ABORTED;
} else {
state[i] = ORBIS_KERNEL_AIO_STATE_PROCESSING;
}
}
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioWaitRequest(OrbisKernelAioSubmitId id, s32* state, u32* usec) {
if (state == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
u32 timer = 0;
s32 timeout = 0;
while (id_state[id] == ORBIS_KERNEL_AIO_STATE_PROCESSING) {
sceKernelUsleep(10);
timer += 10;
if (*usec) {
if (timer > *usec) {
timeout = 1;
break;
}
}
}
*state = id_state[id];
if (timeout)
return ORBIS_KERNEL_ERROR_ETIMEDOUT;
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioWaitRequests(OrbisKernelAioSubmitId id[], s32 num, s32 state[],
u32 mode, u32* usec) {
if (state == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
u32 timer = 0;
s32 timeout = 0;
s32 completion = 0;
for (s32 i = 0; i < num; i++) {
if (!completion && !timeout) {
while (id_state[id[i]] == ORBIS_KERNEL_AIO_STATE_PROCESSING) {
sceKernelUsleep(10);
timer += 10;
if (*usec) {
if (timer > *usec) {
timeout = 1;
break;
}
}
}
}
if (mode == 0x02) {
if (id_state[id[i]] == ORBIS_KERNEL_AIO_STATE_COMPLETED)
completion = 1;
}
state[i] = id_state[id[i]];
}
if (timeout)
return ORBIS_KERNEL_ERROR_ETIMEDOUT;
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioSubmitReadCommands(OrbisKernelAioRWRequest req[], s32 size, s32 prio,
OrbisKernelAioSubmitId* id) {
if (req == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (id == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_PROCESSING;
for (s32 i = 0; i < size; i++) {
s64 ret = sceKernelPread(req[i].fd, req[i].buf, req[i].nbyte, req[i].offset);
if (ret < 0) {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_ABORTED;
req[i].result->returnValue = ret;
} else {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_COMPLETED;
req[i].result->returnValue = ret;
}
}
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_COMPLETED;
*id = id_index;
id_index = (id_index + 1) % MAX_QUEUE;
if (!id_index)
id_index++;
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioSubmitReadCommandsMultiple(OrbisKernelAioRWRequest req[], s32 size,
s32 prio, OrbisKernelAioSubmitId id[]) {
if (req == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (id == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
for (s32 i = 0; i < size; i++) {
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_PROCESSING;
s64 ret = sceKernelPread(req[i].fd, req[i].buf, req[i].nbyte, req[i].offset);
if (ret < 0) {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_ABORTED;
req[i].result->returnValue = ret;
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_ABORTED;
} else {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_COMPLETED;
req[i].result->returnValue = ret;
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_COMPLETED;
}
id[i] = id_index;
id_index = (id_index + 1) % MAX_QUEUE;
if (!id_index)
id_index++;
}
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioSubmitWriteCommands(OrbisKernelAioRWRequest req[], s32 size, s32 prio,
OrbisKernelAioSubmitId* id) {
if (req == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (id == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
for (s32 i = 0; i < size; i++) {
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_PROCESSING;
s64 ret = sceKernelPwrite(req[i].fd, req[i].buf, req[i].nbyte, req[i].offset);
if (ret < 0) {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_ABORTED;
req[i].result->returnValue = ret;
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_ABORTED;
} else {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_COMPLETED;
req[i].result->returnValue = ret;
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_COMPLETED;
}
}
*id = id_index;
id_index = (id_index + 1) % MAX_QUEUE;
// skip id_index equals 0 , because sceKernelAioCancelRequest will submit id
// equal to 0
if (!id_index)
id_index++;
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioSubmitWriteCommandsMultiple(OrbisKernelAioRWRequest req[], s32 size,
s32 prio, OrbisKernelAioSubmitId id[]) {
if (req == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (id == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
for (s32 i = 0; i < size; i++) {
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_PROCESSING;
s64 ret = sceKernelPwrite(req[i].fd, req[i].buf, req[i].nbyte, req[i].offset);
if (ret < 0) {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_ABORTED;
req[i].result->returnValue = ret;
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_ABORTED;
} else {
req[i].result->state = ORBIS_KERNEL_AIO_STATE_COMPLETED;
req[i].result->returnValue = ret;
id_state[id_index] = ORBIS_KERNEL_AIO_STATE_COMPLETED;
}
id[i] = id_index;
id_index = (id_index + 1) % MAX_QUEUE;
if (!id_index)
id_index++;
}
return 0;
}
s32 PS4_SYSV_ABI sceKernelAioSetParam() {
LOG_ERROR(Kernel, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceKernelAioInitializeParam() {
LOG_ERROR(Kernel, "(STUBBED) called");
return ORBIS_OK;
}
void RegisterAio(Core::Loader::SymbolsResolver* sym) {
id_index = 1;
id_state = (int*)malloc(sizeof(int) * MAX_QUEUE);
memset(id_state, 0, sizeof(sizeof(int) * MAX_QUEUE));
LIB_FUNCTION("fR521KIGgb8", "libkernel", 1, "libkernel", 1, 1, sceKernelAioCancelRequest);
LIB_FUNCTION("3Lca1XBrQdY", "libkernel", 1, "libkernel", 1, 1, sceKernelAioCancelRequests);
LIB_FUNCTION("5TgME6AYty4", "libkernel", 1, "libkernel", 1, 1, sceKernelAioDeleteRequest);
LIB_FUNCTION("Ft3EtsZzAoY", "libkernel", 1, "libkernel", 1, 1, sceKernelAioDeleteRequests);
LIB_FUNCTION("vYU8P9Td2Zo", "libkernel", 1, "libkernel", 1, 1, sceKernelAioInitializeImpl);
LIB_FUNCTION("nu4a0-arQis", "libkernel", 1, "libkernel", 1, 1, sceKernelAioInitializeParam);
LIB_FUNCTION("2pOuoWoCxdk", "libkernel", 1, "libkernel", 1, 1, sceKernelAioPollRequest);
LIB_FUNCTION("o7O4z3jwKzo", "libkernel", 1, "libkernel", 1, 1, sceKernelAioPollRequests);
LIB_FUNCTION("9WK-vhNXimw", "libkernel", 1, "libkernel", 1, 1, sceKernelAioSetParam);
LIB_FUNCTION("HgX7+AORI58", "libkernel", 1, "libkernel", 1, 1, sceKernelAioSubmitReadCommands);
LIB_FUNCTION("lXT0m3P-vs4", "libkernel", 1, "libkernel", 1, 1,
sceKernelAioSubmitReadCommandsMultiple);
LIB_FUNCTION("XQ8C8y+de+E", "libkernel", 1, "libkernel", 1, 1, sceKernelAioSubmitWriteCommands);
LIB_FUNCTION("xT3Cpz0yh6Y", "libkernel", 1, "libkernel", 1, 1,
sceKernelAioSubmitWriteCommandsMultiple);
LIB_FUNCTION("KOF-oJbQVvc", "libkernel", 1, "libkernel", 1, 1, sceKernelAioWaitRequest);
LIB_FUNCTION("lgK+oIWkJyA", "libkernel", 1, "libkernel", 1, 1, sceKernelAioWaitRequests);
}
} // namespace Libraries::Kernel

View file

@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <condition_variable>
#include <mutex>
#include <string>
#include <vector>
#include <boost/asio/steady_timer.hpp>
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Kernel {
enum AioState {
ORBIS_KERNEL_AIO_STATE_SUBMITTED = 1,
ORBIS_KERNEL_AIO_STATE_PROCESSING = 2,
ORBIS_KERNEL_AIO_STATE_COMPLETED = 3,
ORBIS_KERNEL_AIO_STATE_ABORTED = 4
};
struct OrbisKernelAioResult {
s64 returnValue;
u32 state;
};
typedef s32 OrbisKernelAioSubmitId;
struct OrbisKernelAioRWRequest {
s64 offset;
s64 nbyte;
void* buf;
OrbisKernelAioResult* result;
s32 fd;
};
void RegisterAio(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Kernel

View file

@ -8,8 +8,13 @@
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/singleton.h"
#include "core/devices/console_device.h"
#include "core/devices/deci_tty6_device.h"
#include "core/devices/logger.h"
#include "core/devices/nop_device.h"
#include "core/devices/random_device.h"
#include "core/devices/srandom_device.h"
#include "core/devices/urandom_device.h"
#include "core/file_sys/fs.h"
#include "core/libraries/kernel/file_system.h"
#include "core/libraries/kernel/orbis_error.h"
@ -41,6 +46,12 @@ static std::map<std::string, FactoryDevice> available_device = {
{"/dev/deci_stderr", GET_DEVICE_FD(2)},
{"/dev/null", GET_DEVICE_FD(0)}, // fd0 (stdin) is a nop device
{"/dev/urandom", &D::URandomDevice::Create },
{"/dev/random", &D::RandomDevice::Create },
{"/dev/srandom", &D::SRandomDevice::Create },
{"/dev/console", &D::ConsoleDevice::Create },
{"/dev/deci_tty6",&D::DeciTty6Device::Create }
// clang-format on
};
@ -67,17 +78,6 @@ int PS4_SYSV_ABI sceKernelOpen(const char* raw_path, int flags, u16 mode) {
bool directory = (flags & ORBIS_KERNEL_O_DIRECTORY) != 0;
std::string_view path{raw_path};
if (path == "/dev/console") {
return 2000;
}
if (path == "/dev/deci_tty6") {
return 2001;
}
if (path == "/dev/urandom") {
return 2003;
}
u32 handle = h->CreateHandle();
auto* file = h->GetFile(handle);
@ -167,9 +167,6 @@ int PS4_SYSV_ABI sceKernelClose(int d) {
if (d < 3) { // d probably hold an error code
return ORBIS_KERNEL_ERROR_EPERM;
}
if (d == 2003) { // dev/urandom case
return ORBIS_OK;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
if (file == nullptr) {
@ -273,13 +270,6 @@ size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) {
}
size_t PS4_SYSV_ABI _writev(int fd, const SceKernelIovec* iov, int iovcn) {
if (fd == 1) {
size_t total_written = 0;
for (int i = 0; i < iovcn; i++) {
total_written += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout);
}
return total_written;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(fd);
if (file == nullptr) {
@ -337,13 +327,6 @@ s64 PS4_SYSV_ABI posix_lseek(int d, s64 offset, int whence) {
}
s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) {
if (d == 2003) // dev urandom case
{
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++)
rbuf[i] = std::rand() & 0xFF;
return nbytes;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
if (file == nullptr) {
@ -757,7 +740,6 @@ s32 PS4_SYSV_ABI sceKernelRename(const char* from, const char* to) {
}
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
std::srand(std::time(nullptr));
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
LIB_FUNCTION("wuCroIGjt2g", "libkernel", 1, "libkernel", 1, 1, open);

View file

@ -67,7 +67,8 @@ constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000;
s64 PS4_SYSV_ABI sceKernelWrite(int d, const void* buf, size_t nbytes);
s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes);
s64 PS4_SYSV_ABI sceKernelPread(int d, void* buf, size_t nbytes, s64 offset);
s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset);
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Kernel

View file

@ -28,6 +28,7 @@
#include <Rpc.h>
#endif
#include <common/singleton.h>
#include "aio.h"
namespace Libraries::Kernel {
@ -59,7 +60,7 @@ static void KernelServiceThread(std::stop_token stoken) {
}
io_context.run();
io_context.reset();
io_context.restart();
asio_requests = 0;
}
@ -218,6 +219,7 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
Libraries::Kernel::RegisterEventQueue(sym);
Libraries::Kernel::RegisterProcess(sym);
Libraries::Kernel::RegisterException(sym);
Libraries::Kernel::RegisterAio(sym);
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
LIB_FUNCTION("PfccT7qURYE", "libkernel", 1, "libkernel", 1, 1, kernel_ioctl);

View file

@ -153,6 +153,11 @@ int PS4_SYSV_ABI sceKernelDebugRaiseException() {
return 0;
}
int PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode() {
UNREACHABLE();
return 0;
}
void RegisterException(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("il03nluKfMk", "libkernel_unity", 1, "libkernel", 1, 1, sceKernelRaiseException);
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel", 1, 1,
@ -160,6 +165,8 @@ void RegisterException(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel_unity", 1, "libkernel", 1, 1,
sceKernelRemoveExceptionHandler)
LIB_FUNCTION("OMDRKKAZ8I4", "libkernel", 1, "libkernel", 1, 1, sceKernelDebugRaiseException);
LIB_FUNCTION("zE-wXIZjLoM", "libkernel", 1, "libkernel", 1, 1,
sceKernelDebugRaiseExceptionOnReleaseMode);
}
} // namespace Libraries::Kernel

View file

@ -82,6 +82,7 @@ int PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2,
int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, OrbisTimesec* st,
u64* dst_sec);
int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds);
void RegisterTime(Core::Loader::SymbolsResolver* sym);

View file

@ -93,7 +93,7 @@ int PS4_SYSV_ABI sceNetCtlUnregisterCallbackV6() {
}
int PS4_SYSV_ABI sceNetCtlCheckCallback() {
netctl.CheckCallback();
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called");
return ORBIS_OK;
}
@ -373,7 +373,7 @@ int PS4_SYSV_ABI Func_D8DCB6973537A3DC() {
}
int PS4_SYSV_ABI sceNetCtlCheckCallbackForNpToolkit() {
netctl.CheckNpToolkitCallback();
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called");
return ORBIS_OK;
}

View file

@ -5,6 +5,7 @@
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "core/libraries/np_manager/np_manager.h"
#include "core/libraries/np_manager/np_manager_error.h"
#include "core/tls.h"
namespace Libraries::NpManager {
@ -935,14 +936,22 @@ int PS4_SYSV_ABI sceNpGetAccountDateOfBirthA() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpGetAccountId() {
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
return ORBIS_OK;
int PS4_SYSV_ABI sceNpGetAccountId(OrbisNpOnlineId* online_id, u64* account_id) {
LOG_DEBUG(Lib_NpManager, "called");
if (online_id == nullptr || account_id == nullptr) {
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
}
*account_id = 0;
return ORBIS_NP_ERROR_SIGNED_OUT;
}
int PS4_SYSV_ABI sceNpGetAccountIdA() {
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
return ORBIS_OK;
int PS4_SYSV_ABI sceNpGetAccountIdA(OrbisUserServiceUserId user_id, u64* account_id) {
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
if (account_id == nullptr) {
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
}
*account_id = 0;
return ORBIS_NP_ERROR_SIGNED_OUT;
}
int PS4_SYSV_ABI sceNpGetAccountLanguage() {
@ -972,6 +981,9 @@ int PS4_SYSV_ABI sceNpGetGamePresenceStatusA() {
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id) {
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
if (np_id == nullptr) {
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
}
return ORBIS_NP_ERROR_SIGNED_OUT;
}
@ -980,8 +992,11 @@ int PS4_SYSV_ABI sceNpGetNpReachabilityState() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpGetOnlineId(s32 user_id, OrbisNpOnlineId* online_id) {
int PS4_SYSV_ABI sceNpGetOnlineId(OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id) {
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
if (online_id == nullptr) {
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
}
return ORBIS_NP_ERROR_SIGNED_OUT;
}
@ -995,7 +1010,10 @@ int PS4_SYSV_ABI sceNpGetParentalControlInfoA() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpGetState(s32 userId, OrbisNpState* state) {
int PS4_SYSV_ABI sceNpGetState(OrbisUserServiceUserId user_id, OrbisNpState* state) {
if (state == nullptr) {
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
}
*state = OrbisNpState::SignedOut;
LOG_DEBUG(Lib_NpManager, "Signed out");
return ORBIS_OK;
@ -1011,8 +1029,12 @@ int PS4_SYSV_ABI sceNpGetUserIdByOnlineId() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpHasSignedUp() {
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
int PS4_SYSV_ABI sceNpHasSignedUp(OrbisUserServiceUserId user_id, bool* has_signed_up) {
LOG_DEBUG(Lib_NpManager, "called");
if (has_signed_up == nullptr) {
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
}
*has_signed_up = false;
return ORBIS_OK;
}
@ -2509,7 +2531,7 @@ struct NpStateCallbackForNpToolkit {
NpStateCallbackForNpToolkit NpStateCbForNp;
int PS4_SYSV_ABI sceNpCheckCallbackForLib() {
Core::ExecuteGuest(NpStateCbForNp.func, 1, OrbisNpState::SignedOut, NpStateCbForNp.userdata);
LOG_DEBUG(Lib_NpManager, "(STUBBED) called");
return ORBIS_OK;
}

View file

@ -11,8 +11,6 @@ class SymbolsResolver;
namespace Libraries::NpManager {
constexpr int ORBIS_NP_ERROR_SIGNED_OUT = 0x80550006;
enum class OrbisNpState : u32 { Unknown = 0, SignedOut, SignedIn };
using OrbisNpStateCallbackForNpToolkit = PS4_SYSV_ABI void (*)(s32 userId, OrbisNpState state,
@ -220,22 +218,22 @@ int PS4_SYSV_ABI sceNpGetAccountCountry();
int PS4_SYSV_ABI sceNpGetAccountCountryA();
int PS4_SYSV_ABI sceNpGetAccountDateOfBirth();
int PS4_SYSV_ABI sceNpGetAccountDateOfBirthA();
int PS4_SYSV_ABI sceNpGetAccountId();
int PS4_SYSV_ABI sceNpGetAccountIdA();
int PS4_SYSV_ABI sceNpGetAccountId(OrbisNpOnlineId* online_id, u64* account_id);
int PS4_SYSV_ABI sceNpGetAccountIdA(OrbisUserServiceUserId user_id, u64* account_id);
int PS4_SYSV_ABI sceNpGetAccountLanguage();
int PS4_SYSV_ABI sceNpGetAccountLanguage2();
int PS4_SYSV_ABI sceNpGetAccountLanguageA();
int PS4_SYSV_ABI sceNpGetGamePresenceStatus();
int PS4_SYSV_ABI sceNpGetGamePresenceStatusA();
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId userId, OrbisNpId* npId);
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id);
int PS4_SYSV_ABI sceNpGetNpReachabilityState();
int PS4_SYSV_ABI sceNpGetOnlineId(s32 userId, OrbisNpOnlineId* onlineId);
int PS4_SYSV_ABI sceNpGetOnlineId(OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id);
int PS4_SYSV_ABI sceNpGetParentalControlInfo();
int PS4_SYSV_ABI sceNpGetParentalControlInfoA();
int PS4_SYSV_ABI sceNpGetState(s32 userId, OrbisNpState* state);
int PS4_SYSV_ABI sceNpGetState(OrbisUserServiceUserId user_id, OrbisNpState* state);
int PS4_SYSV_ABI sceNpGetUserIdByAccountId();
int PS4_SYSV_ABI sceNpGetUserIdByOnlineId();
int PS4_SYSV_ABI sceNpHasSignedUp();
int PS4_SYSV_ABI sceNpHasSignedUp(OrbisUserServiceUserId user_id, bool* has_signed_up);
int PS4_SYSV_ABI sceNpIdMapperAbortRequest();
int PS4_SYSV_ABI sceNpIdMapperAccountIdToNpId();
int PS4_SYSV_ABI sceNpIdMapperAccountIdToOnlineId();

View file

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

View file

@ -11,6 +11,8 @@
namespace Libraries::Pad {
using Input::GameController;
int PS4_SYSV_ABI scePadClose(s32 handle) {
LOG_ERROR(Lib_Pad, "(STUBBED) called");
return ORBIS_OK;
@ -93,8 +95,8 @@ int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerIn
pInfo->touchPadInfo.pixelDensity = 1;
pInfo->touchPadInfo.resolution.x = 1920;
pInfo->touchPadInfo.resolution.y = 950;
pInfo->stickInfo.deadZoneLeft = 2;
pInfo->stickInfo.deadZoneRight = 2;
pInfo->stickInfo.deadZoneLeft = Config::leftDeadZone();
pInfo->stickInfo.deadZoneRight = Config::rightDeadZone();
pInfo->connectionType = ORBIS_PAD_PORT_TYPE_STANDARD;
pInfo->connectedCount = 1;
pInfo->connected = false;
@ -104,8 +106,8 @@ int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerIn
pInfo->touchPadInfo.pixelDensity = 1;
pInfo->touchPadInfo.resolution.x = 1920;
pInfo->touchPadInfo.resolution.y = 950;
pInfo->stickInfo.deadZoneLeft = 2;
pInfo->stickInfo.deadZoneRight = 2;
pInfo->stickInfo.deadZoneLeft = Config::leftDeadZone();
pInfo->stickInfo.deadZoneRight = Config::rightDeadZone();
pInfo->connectionType = ORBIS_PAD_PORT_TYPE_STANDARD;
pInfo->connectedCount = 1;
pInfo->connected = true;
@ -290,7 +292,8 @@ int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
int connected_count = 0;
bool connected = false;
Input::State states[64];
auto* controller = Common::Singleton<Input::GameController>::Instance();
auto* controller = Common::Singleton<GameController>::Instance();
const auto* engine = controller->GetEngine();
int ret_num = controller->ReadStates(states, num, &connected, &connected_count);
if (!connected) {
@ -311,9 +314,14 @@ int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
pData[i].angularVelocity.x = states[i].angularVelocity.x;
pData[i].angularVelocity.y = states[i].angularVelocity.y;
pData[i].angularVelocity.z = states[i].angularVelocity.z;
Input::GameController::CalculateOrientation(pData[i].acceleration, pData[i].angularVelocity,
1.0f / controller->accel_poll_rate,
pData[i].orientation);
if (engine) {
const auto accel_poll_rate = engine->GetAccelPollRate();
if (accel_poll_rate != 0.0f) {
GameController::CalculateOrientation(pData[i].acceleration,
pData[i].angularVelocity,
1.0f / accel_poll_rate, pData[i].orientation);
}
}
pData[i].touchData.touchNum =
(states[i].touchpad[0].state ? 1 : 0) + (states[i].touchpad[1].state ? 1 : 0);
pData[i].touchData.touch[0].x = states[i].touchpad[0].x;
@ -356,7 +364,8 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
if (handle == ORBIS_PAD_ERROR_DEVICE_NO_HANDLE) {
return ORBIS_PAD_ERROR_INVALID_HANDLE;
}
auto* controller = Common::Singleton<Input::GameController>::Instance();
auto* controller = Common::Singleton<GameController>::Instance();
const auto* engine = controller->GetEngine();
int connectedCount = 0;
bool isConnected = false;
Input::State state;
@ -374,9 +383,13 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
pData->angularVelocity.x = state.angularVelocity.x;
pData->angularVelocity.y = state.angularVelocity.y;
pData->angularVelocity.z = state.angularVelocity.z;
Input::GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity,
1.0f / controller->accel_poll_rate,
pData->orientation);
if (engine) {
const auto accel_poll_rate = engine->GetAccelPollRate();
if (accel_poll_rate != 0.0f) {
GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity,
1.0f / accel_poll_rate, pData->orientation);
}
}
pData->touchData.touchNum =
(state.touchpad[0].state ? 1 : 0) + (state.touchpad[1].state ? 1 : 0);
pData->touchData.touch[0].x = state.touchpad[0].x;
@ -468,7 +481,7 @@ int PS4_SYSV_ABI scePadSetLightBar(s32 handle, const OrbisPadLightBarParam* pPar
return ORBIS_PAD_ERROR_INVALID_LIGHTBAR_SETTING;
}
auto* controller = Common::Singleton<Input::GameController>::Instance();
auto* controller = Common::Singleton<GameController>::Instance();
controller->SetLightBarRGB(pParam->r, pParam->g, pParam->b);
return ORBIS_OK;
}
@ -536,7 +549,7 @@ int PS4_SYSV_ABI scePadSetVibration(s32 handle, const OrbisPadVibrationParam* pP
if (pParam != nullptr) {
LOG_DEBUG(Lib_Pad, "scePadSetVibration called handle = {} data = {} , {}", handle,
pParam->smallMotor, pParam->largeMotor);
auto* controller = Common::Singleton<Input::GameController>::Instance();
auto* controller = Common::Singleton<GameController>::Instance();
controller->SetVibration(pParam->smallMotor, pParam->largeMotor);
return ORBIS_OK;
}

View file

@ -47,15 +47,13 @@ namespace Libraries::SaveData {
std::filesystem::path SaveInstance::MakeTitleSavePath(OrbisUserServiceUserId user_id,
std::string_view game_serial) {
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
game_serial;
return Config::GetSaveDataPath() / std::to_string(user_id) / game_serial;
}
std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_id,
std::string_view game_serial,
std::string_view dir_name) {
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
game_serial / dir_name;
return Config::GetSaveDataPath() / std::to_string(user_id) / game_serial / dir_name;
}
uint64_t SaveInstance::GetMaxBlockFromSFO(const PSF& psf) {

View file

@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <imgui.h>
#include "common/assert.h"
#include "common/config.h"
#include "common/debug.h"
@ -11,6 +9,7 @@
#include "core/libraries/kernel/time.h"
#include "core/libraries/videoout/driver.h"
#include "core/libraries/videoout/videoout_error.h"
#include "imgui/renderer/imgui_core.h"
#include "video_core/renderer_vulkan/vk_presenter.h"
extern std::unique_ptr<Vulkan::Presenter> presenter;
@ -207,6 +206,13 @@ void VideoOutDriver::DrawBlankFrame() {
presenter->Present(empty_frame);
}
void VideoOutDriver::DrawLastFrame() {
const auto frame = presenter->PrepareLastFrame();
if (frame != nullptr) {
presenter->Present(frame, true);
}
}
bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
bool is_eop /*= false*/) {
{
@ -278,17 +284,26 @@ void VideoOutDriver::PresentThread(std::stop_token token) {
return {};
};
auto delay = std::chrono::microseconds{0};
while (!token.stop_requested()) {
timer.Start();
if (DebugState.IsGuestThreadsPaused()) {
DrawLastFrame();
timer.End();
continue;
}
// Check if it's time to take a request.
auto& vblank_status = main_port.vblank_status;
if (vblank_status.count % (main_port.flip_rate + 1) == 0) {
const auto request = receive_request();
if (!request) {
if (!main_port.is_open || DebugState.IsGuestThreadsPaused()) {
DrawBlankFrame();
if (timer.GetTotalWait().count() < 0) { // Dont draw too fast
if (!main_port.is_open) {
DrawBlankFrame();
} else if (ImGui::Core::MustKeepDrawing()) {
DrawLastFrame();
}
}
} else {
Flip(request);

View file

@ -102,7 +102,8 @@ private:
};
void Flip(const Request& req);
void DrawBlankFrame(); // Used when there is no flip request to keep ImGui up to date
void DrawBlankFrame(); // Video port out not open
void DrawLastFrame(); // Used when there is no flip request
void SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop = false);
void PresentThread(std::stop_token token);

View file

@ -52,7 +52,7 @@ Linker::Linker() : memory{Memory::Instance()} {}
Linker::~Linker() = default;
void Linker::Execute() {
void Linker::Execute(const std::vector<std::string> args) {
if (Config::debugDump()) {
DebugDump();
}
@ -101,7 +101,7 @@ void Linker::Execute() {
memory->SetupMemoryRegions(fmem_size, use_extended_mem1, use_extended_mem2);
main_thread.Run([this, module](std::stop_token) {
main_thread.Run([this, module, args](std::stop_token) {
Common::SetCurrentThreadName("GAME_MainThread");
LoadSharedLibraries();
@ -109,6 +109,12 @@ void Linker::Execute() {
EntryParams params{};
params.argc = 1;
params.argv[0] = "eboot.bin";
if (!args.empty()) {
params.argc = args.size() + 1;
for (int i = 0; i < args.size() && i < 32; i++) {
params.argv[i + 1] = args[i].c_str();
}
}
params.entry_addr = module->GetEntryAddress();
RunMainEntry(&params);
});

View file

@ -49,7 +49,7 @@ class Linker;
struct EntryParams {
int argc;
u32 padding;
const char* argv[3];
const char* argv[33];
VAddr entry_addr;
};
@ -143,7 +143,7 @@ public:
void Relocate(Module* module);
bool Resolve(const std::string& name, Loader::SymbolType type, Module* module,
Loader::SymbolRecord* return_info);
void Execute();
void Execute(const std::vector<std::string> args = {});
void DebugDump();
private:

View file

@ -532,8 +532,8 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags,
info->is_flexible.Assign(vma.type == VMAType::Flexible);
info->is_direct.Assign(vma.type == VMAType::Direct);
info->is_stack.Assign(vma.type == VMAType::Stack);
info->is_pooled.Assign(vma.type == VMAType::PoolReserved);
info->is_committed.Assign(vma.type == VMAType::Pooled);
info->is_pooled.Assign(vma.type == VMAType::PoolReserved || vma.type == VMAType::Pooled);
info->is_committed.Assign(vma.IsMapped());
vma.name.copy(info->name.data(), std::min(info->name.size(), vma.name.size()));
if (vma.type == VMAType::Direct) {
const auto dmem_it = FindDmemArea(vma.phys_base);

View file

@ -66,9 +66,10 @@ Emulator::Emulator() {
LOG_INFO(Config, "Vulkan vkValidation: {}", Config::vkValidationEnabled());
LOG_INFO(Config, "Vulkan vkValidationSync: {}", Config::vkValidationSyncEnabled());
LOG_INFO(Config, "Vulkan vkValidationGpu: {}", Config::vkValidationGpuEnabled());
LOG_INFO(Config, "Vulkan rdocEnable: {}", Config::isRdocEnabled());
LOG_INFO(Config, "Vulkan rdocMarkersEnable: {}", Config::vkMarkersEnabled());
LOG_INFO(Config, "Vulkan crashDiagnostics: {}", Config::vkCrashDiagnosticEnabled());
LOG_INFO(Config, "Vulkan hostMarkers: {}", Config::vkHostMarkersEnabled());
LOG_INFO(Config, "Vulkan guestMarkers: {}", Config::vkGuestMarkersEnabled());
LOG_INFO(Config, "Vulkan rdocEnable: {}", Config::isRdocEnabled());
// Create stdin/stdout/stderr
Common::Singleton<FileSys::HandleTable>::Instance()->CreateStdHandles();
@ -98,7 +99,7 @@ Emulator::~Emulator() {
Config::saveMainWindow(config_dir / "config.toml");
}
void Emulator::Run(const std::filesystem::path& file) {
void Emulator::Run(const std::filesystem::path& file, const std::vector<std::string> args) {
// Applications expect to be run from /app0 so mount the file's parent path as app0.
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const auto game_folder = file.parent_path();
@ -151,6 +152,15 @@ void Emulator::Run(const std::filesystem::path& file) {
if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) {
psf_attributes.raw = *raw_attributes;
}
if (!args.empty()) {
int argc = std::min<int>(args.size(), 32);
for (int i = 0; i < argc; i++) {
LOG_INFO(Loader, "Game argument {}: {}", i, args[i]);
}
if (args.size() > 32) {
LOG_ERROR(Loader, "Too many game arguments, only passing the first 32");
}
}
}
const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png");
@ -238,7 +248,7 @@ void Emulator::Run(const std::filesystem::path& file) {
}
#endif
linker->Execute();
linker->Execute(args);
window->InitTimers();
while (window->IsOpen()) {

View file

@ -25,7 +25,7 @@ public:
Emulator();
~Emulator();
void Run(const std::filesystem::path& file);
void Run(const std::filesystem::path& file, const std::vector<std::string> args = {});
void UpdatePlayTime(const std::string& serial);
private:

View file

@ -30,6 +30,12 @@ extern void assert_fail_debug_msg(const char* msg);
#define IM_VEC4_CLASS_EXTRA \
constexpr ImVec4(float _v) : x(_v), y(_v), z(_v), w(_v) {}
namespace ImGui {
struct Texture;
}
#define ImTextureID ImTextureID
using ImTextureID = ::ImGui::Texture*;
#ifdef IMGUI_USE_WCHAR32
#error "This project uses 16 bits wchar standard like Orbis"
#endif

View file

@ -6,6 +6,7 @@
#include "common/config.h"
#include "common/path_util.h"
#include "core/debug_state.h"
#include "core/devtools/layer.h"
#include "imgui/imgui_layer.h"
#include "imgui_core.h"
@ -167,7 +168,7 @@ bool ProcessEvent(SDL_Event* event) {
}
}
void NewFrame() {
ImGuiID NewFrame(bool is_reusing_frame) {
{
std::scoped_lock lock{change_layers_mutex};
while (!change_layers.empty()) {
@ -182,24 +183,32 @@ void NewFrame() {
}
}
Sdl::NewFrame();
Sdl::NewFrame(is_reusing_frame);
ImGui::NewFrame();
DockSpaceOverViewport(0, GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
ImGuiWindowFlags flags =
ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_AutoHideTabBar;
if (!DebugState.IsShowingDebugMenuBar()) {
flags |= ImGuiDockNodeFlags_NoTabBar;
}
ImGuiID dockId = DockSpaceOverViewport(0, GetMainViewport(), flags);
for (auto* layer : layers) {
layer->Draw();
}
return dockId;
}
void Render(const vk::CommandBuffer& cmdbuf, ::Vulkan::Frame* frame) {
void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view,
const vk::Extent2D& extent) {
ImGui::Render();
ImDrawData* draw_data = GetDrawData();
if (draw_data->CmdListsCount == 0) {
return;
}
if (Config::vkMarkersEnabled()) {
if (Config::vkHostMarkersEnabled()) {
cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
.pLabelName = "ImGui Render",
});
@ -207,16 +216,16 @@ void Render(const vk::CommandBuffer& cmdbuf, ::Vulkan::Frame* frame) {
vk::RenderingAttachmentInfo color_attachments[1]{
{
.imageView = frame->image_view,
.imageView = image_view,
.imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
.loadOp = vk::AttachmentLoadOp::eLoad,
.loadOp = vk::AttachmentLoadOp::eClear,
.storeOp = vk::AttachmentStoreOp::eStore,
},
};
vk::RenderingInfo render_info{};
render_info.renderArea = vk::Rect2D{
.offset = {0, 0},
.extent = {frame->width, frame->height},
.extent = extent,
};
render_info.layerCount = 1;
render_info.colorAttachmentCount = 1;
@ -224,11 +233,15 @@ void Render(const vk::CommandBuffer& cmdbuf, ::Vulkan::Frame* frame) {
cmdbuf.beginRendering(render_info);
Vulkan::RenderDrawData(*draw_data, cmdbuf);
cmdbuf.endRendering();
if (Config::vkMarkersEnabled()) {
if (Config::vkHostMarkersEnabled()) {
cmdbuf.endDebugUtilsLabelEXT();
}
}
bool MustKeepDrawing() {
return layers.size() > 1 || DebugState.IsShowingDebugMenuBar();
}
} // namespace Core
void Layer::AddLayer(Layer* layer) {

View file

@ -3,6 +3,8 @@
#pragma once
#include <imgui.h>
#include "video_core/renderer_vulkan/vk_instance.h"
#include "vulkan/vulkan_handles.hpp"
@ -24,8 +26,11 @@ void Shutdown(const vk::Device& device);
bool ProcessEvent(SDL_Event* event);
void NewFrame();
ImGuiID NewFrame(bool is_reusing_frame = false);
void Render(const vk::CommandBuffer& cmdbuf, Vulkan::Frame* frame);
void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view,
const vk::Extent2D& extent);
bool MustKeepDrawing(); // Force the emulator redraw
} // namespace ImGui::Core

View file

@ -5,6 +5,7 @@
#include <imgui.h>
#include "common/config.h"
#include "core/debug_state.h"
#include "imgui_impl_sdl3.h"
// SDL
@ -26,6 +27,7 @@ struct SdlData {
SDL_Window* window{};
SDL_WindowID window_id{};
Uint64 time{};
Uint64 nonReusedtime{};
const char* clipboard_text_data{};
// IME handling
@ -44,6 +46,11 @@ struct SdlData {
ImVector<SDL_Gamepad*> gamepads{};
GamepadMode gamepad_mode{};
bool want_update_gamepads_list{};
// Framerate counting (based on ImGui impl)
std::array<float, 60> framerateSecPerFrame;
int framerateSecPerFrameIdx{};
float framerateSecPerFrameAcc{};
};
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui
@ -785,7 +792,7 @@ static void UpdateGamepads() {
+thumb_dead_zone, +32767);
}
void NewFrame() {
void NewFrame(bool is_reusing_frame) {
SdlData* bd = GetBackendData();
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
@ -798,9 +805,29 @@ void NewFrame() {
if (current_time <= bd->time)
current_time = bd->time + 1;
io.DeltaTime = bd->time > 0 ? (float)((double)(current_time - bd->time) / (double)frequency)
: (float)(1.0f / 60.0f);
: 1.0f / 60.0f;
bd->time = current_time;
if (!is_reusing_frame) {
if (current_time <= bd->nonReusedtime)
current_time = bd->nonReusedtime + 1;
float deltaTime =
bd->nonReusedtime > 0
? (float)((double)(current_time - bd->nonReusedtime) / (double)frequency)
: 1.0f / 60.0f;
bd->nonReusedtime = current_time;
DebugState.FrameDeltaTime = deltaTime;
int& frameIdx = bd->framerateSecPerFrameIdx;
float& framerateSec = bd->framerateSecPerFrame[frameIdx];
float& acc = bd->framerateSecPerFrameAcc;
int count = bd->framerateSecPerFrame.size();
acc += deltaTime - framerateSec;
framerateSec = deltaTime;
frameIdx = (frameIdx + 1) % count;
DebugState.Framerate = acc > 0.0f ? 1.0f / (acc / (float)count) : FLT_MAX;
}
if (bd->mouse_pending_leave_frame && bd->mouse_pending_leave_frame >= ImGui::GetFrameCount() &&
bd->mouse_buttons_down == 0) {
bd->mouse_window_id = 0;

View file

@ -14,7 +14,7 @@ namespace ImGui::Sdl {
bool Init(SDL_Window* window);
void Shutdown();
void NewFrame();
void NewFrame(bool is_reusing);
bool ProcessEvent(const SDL_Event* event);
void OnResize();

View file

@ -57,11 +57,12 @@ struct VkData {
vk::DeviceMemory font_memory{};
vk::Image font_image{};
vk::ImageView font_view{};
vk::DescriptorSet font_descriptor_set{};
ImTextureID font_texture{};
vk::CommandBuffer font_command_buffer{};
// Render buffers
WindowRenderBuffers render_buffers{};
bool enabled_blending{true};
VkData(const InitInfo init_info) : init_info(init_info) {
render_buffers.count = init_info.image_count;
@ -252,8 +253,8 @@ void UploadTextureData::Destroy() {
const InitInfo& v = bd->init_info;
CheckVkErr(v.device.waitIdle());
RemoveTexture(descriptor_set);
descriptor_set = VK_NULL_HANDLE;
RemoveTexture(im_texture);
im_texture = nullptr;
v.device.destroyImageView(image_view, v.allocator);
image_view = VK_NULL_HANDLE;
@ -264,8 +265,8 @@ void UploadTextureData::Destroy() {
}
// Register a texture
vk::DescriptorSet AddTexture(vk::ImageView image_view, vk::ImageLayout image_layout,
vk::Sampler sampler) {
ImTextureID AddTexture(vk::ImageView image_view, vk::ImageLayout image_layout,
vk::Sampler sampler) {
VkData* bd = GetBackendData();
const InitInfo& v = bd->init_info;
@ -303,7 +304,9 @@ vk::DescriptorSet AddTexture(vk::ImageView image_view, vk::ImageLayout image_lay
};
v.device.updateDescriptorSets({write_desc}, {});
}
return descriptor_set;
return new Texture{
.descriptor_set = descriptor_set,
};
}
UploadTextureData UploadTexture(const void* data, vk::Format format, u32 width, u32 height,
size_t size) {
@ -370,7 +373,7 @@ UploadTextureData UploadTexture(const void* data, vk::Format format, u32 width,
}
// Create descriptor set (ImTextureID)
info.descriptor_set = AddTexture(info.image_view, vk::ImageLayout::eShaderReadOnlyOptimal);
info.im_texture = AddTexture(info.image_view, vk::ImageLayout::eShaderReadOnlyOptimal);
// Create Upload Buffer
{
@ -464,10 +467,12 @@ UploadTextureData UploadTexture(const void* data, vk::Format format, u32 width,
return info;
}
void RemoveTexture(vk::DescriptorSet descriptor_set) {
void RemoveTexture(ImTextureID texture) {
IM_ASSERT(texture != nullptr);
VkData* bd = GetBackendData();
const InitInfo& v = bd->init_info;
v.device.freeDescriptorSets(bd->descriptor_pool, {descriptor_set});
v.device.freeDescriptorSets(bd->descriptor_pool, {texture->descriptor_set});
delete texture;
}
static void CreateOrResizeBuffer(RenderBuffer& rb, size_t new_size, vk::BufferUsageFlagBits usage) {
@ -679,13 +684,7 @@ void RenderDrawData(ImDrawData& draw_data, vk::CommandBuffer command_buffer,
command_buffer.setScissor(0, 1, &scissor);
// Bind DescriptorSet with font or user texture
vk::DescriptorSet desc_set[1]{(VkDescriptorSet)pcmd->TextureId};
if (sizeof(ImTextureID) < sizeof(ImU64)) {
// We don't support texture switches if ImTextureID hasn't been redefined to be
// 64-bit. Do a flaky check that other textures haven't been used.
IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->font_descriptor_set);
desc_set[0] = bd->font_descriptor_set;
}
vk::DescriptorSet desc_set[1]{pcmd->TextureId->descriptor_set};
command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics,
bd->pipeline_layout, 0, {desc_set}, {});
@ -709,7 +708,7 @@ static bool CreateFontsTexture() {
const InitInfo& v = bd->init_info;
// Destroy existing texture (if any)
if (bd->font_view || bd->font_image || bd->font_memory || bd->font_descriptor_set) {
if (bd->font_view || bd->font_image || bd->font_memory || bd->font_texture) {
CheckVkErr(v.queue.waitIdle());
DestroyFontsTexture();
}
@ -782,7 +781,7 @@ static bool CreateFontsTexture() {
}
// Create the Descriptor Set:
bd->font_descriptor_set = AddTexture(bd->font_view, vk::ImageLayout::eShaderReadOnlyOptimal);
bd->font_texture = AddTexture(bd->font_view, vk::ImageLayout::eShaderReadOnlyOptimal);
// Create the Upload Buffer:
vk::DeviceMemory upload_buffer_memory{};
@ -874,7 +873,7 @@ static bool CreateFontsTexture() {
}
// Store our identifier
io.Fonts->SetTexID(bd->font_descriptor_set);
io.Fonts->SetTexID(bd->font_texture);
// End command buffer
vk::SubmitInfo end_info = {};
@ -898,9 +897,9 @@ static void DestroyFontsTexture() {
VkData* bd = GetBackendData();
const InitInfo& v = bd->init_info;
if (bd->font_descriptor_set) {
RemoveTexture(bd->font_descriptor_set);
bd->font_descriptor_set = VK_NULL_HANDLE;
if (bd->font_texture) {
RemoveTexture(bd->font_texture);
bd->font_texture = nullptr;
io.Fonts->SetTexID(nullptr);
}

View file

@ -10,6 +10,12 @@
struct ImDrawData;
namespace ImGui {
struct Texture {
vk::DescriptorSet descriptor_set{nullptr};
};
} // namespace ImGui
namespace ImGui::Vulkan {
struct InitInfo {
@ -34,29 +40,32 @@ struct InitInfo {
struct UploadTextureData {
vk::Image image;
vk::ImageView image_view;
vk::DescriptorSet descriptor_set;
vk::DeviceMemory image_memory;
vk::CommandBuffer command_buffer; // Submit to the queue
vk::Buffer upload_buffer;
vk::DeviceMemory upload_buffer_memory;
ImTextureID im_texture;
void Upload();
void Destroy();
};
vk::DescriptorSet AddTexture(vk::ImageView image_view, vk::ImageLayout image_layout,
vk::Sampler sampler = VK_NULL_HANDLE);
ImTextureID AddTexture(vk::ImageView image_view, vk::ImageLayout image_layout,
vk::Sampler sampler = VK_NULL_HANDLE);
UploadTextureData UploadTexture(const void* data, vk::Format format, u32 width, u32 height,
size_t size);
void RemoveTexture(vk::DescriptorSet descriptor_set);
void RemoveTexture(ImTextureID descriptor_set);
bool Init(InitInfo info);
void Shutdown();
void RenderDrawData(ImDrawData& draw_data, vk::CommandBuffer command_buffer,
vk::Pipeline pipeline = VK_NULL_HANDLE);
void SetBlendEnabled(bool enabled);
} // namespace ImGui::Vulkan

View file

@ -4,6 +4,7 @@
#include <deque>
#include <utility>
#include <imgui.h>
#include "common/assert.h"
#include "common/config.h"
#include "common/io_file.h"
@ -123,7 +124,7 @@ static std::deque<UploadJob> g_upload_list;
namespace Core::TextureManager {
Inner::~Inner() {
if (upload_data.descriptor_set != nullptr) {
if (upload_data.im_texture != nullptr) {
std::unique_lock lk{g_upload_mtx};
g_upload_list.emplace_back(UploadJob{
.data = this->upload_data,
@ -239,7 +240,7 @@ void Submit() {
}
if (upload.core != nullptr) {
upload.core->upload_data.Upload();
upload.core->texture_id = upload.core->upload_data.descriptor_set;
upload.core->texture_id = upload.core->upload_data.im_texture;
if (upload.core->count.fetch_sub(1) == 1) {
delete upload.core;
}

View file

@ -10,6 +10,55 @@
namespace Input {
using Libraries::Pad::OrbisPadButtonDataOffset;
void State::OnButton(OrbisPadButtonDataOffset button, bool isPressed) {
if (isPressed) {
buttonsState |= button;
} else {
buttonsState &= ~button;
}
}
void State::OnAxis(Axis axis, int value) {
const auto toggle = [&](const auto button) {
if (value > 0) {
buttonsState |= button;
} else {
buttonsState &= ~button;
}
};
switch (axis) {
case Axis::TriggerLeft:
toggle(OrbisPadButtonDataOffset::L2);
break;
case Axis::TriggerRight:
toggle(OrbisPadButtonDataOffset::R2);
break;
default:
break;
}
axes[static_cast<int>(axis)] = value;
}
void State::OnTouchpad(int touchIndex, bool isDown, float x, float y) {
touchpad[touchIndex].state = isDown;
touchpad[touchIndex].x = static_cast<u16>(x * 1920);
touchpad[touchIndex].y = static_cast<u16>(y * 941);
}
void State::OnGyro(const float gyro[3]) {
angularVelocity.x = gyro[0];
angularVelocity.y = gyro[1];
angularVelocity.z = gyro[2];
}
void State::OnAccel(const float accel[3]) {
acceleration.x = accel[0];
acceleration.y = accel[1];
acceleration.z = accel[2];
}
GameController::GameController() {
m_states_num = 0;
m_last_state = State();
@ -75,45 +124,22 @@ void GameController::AddState(const State& state) {
m_states_num++;
}
void GameController::CheckButton(int id, Libraries::Pad::OrbisPadButtonDataOffset button,
bool is_pressed) {
void GameController::CheckButton(int id, OrbisPadButtonDataOffset button, bool is_pressed) {
std::scoped_lock lock{m_mutex};
auto state = GetLastState();
state.time = Libraries::Kernel::sceKernelGetProcessTime();
if (is_pressed) {
state.buttonsState |= button;
} else {
state.buttonsState &= ~button;
}
state.OnButton(button, is_pressed);
AddState(state);
}
void GameController::Axis(int id, Input::Axis axis, int value) {
using Libraries::Pad::OrbisPadButtonDataOffset;
std::scoped_lock lock{m_mutex};
auto state = GetLastState();
state.time = Libraries::Kernel::sceKernelGetProcessTime();
int axis_id = static_cast<int>(axis);
state.axes[axis_id] = value;
if (axis == Input::Axis::TriggerLeft) {
if (value > 0) {
state.buttonsState |= OrbisPadButtonDataOffset::L2;
} else {
state.buttonsState &= ~OrbisPadButtonDataOffset::L2;
}
}
if (axis == Input::Axis::TriggerRight) {
if (value > 0) {
state.buttonsState |= OrbisPadButtonDataOffset::R2;
} else {
state.buttonsState &= ~OrbisPadButtonDataOffset::R2;
}
}
state.OnAxis(axis, value);
AddState(state);
}
@ -124,9 +150,7 @@ void GameController::Gyro(int id, const float gyro[3]) {
state.time = Libraries::Kernel::sceKernelGetProcessTime();
// Update the angular velocity (gyro data)
state.angularVelocity.x = gyro[0]; // X-axis
state.angularVelocity.y = gyro[1]; // Y-axis
state.angularVelocity.z = gyro[2]; // Z-axis
state.OnGyro(gyro);
AddState(state);
}
@ -136,9 +160,7 @@ void GameController::Acceleration(int id, const float acceleration[3]) {
state.time = Libraries::Kernel::sceKernelGetProcessTime();
// Update the acceleration values
state.acceleration.x = acceleration[0]; // X-axis
state.acceleration.y = acceleration[1]; // Y-axis
state.acceleration.z = acceleration[2]; // Z-axis
state.OnAccel(acceleration);
AddState(state);
}
@ -211,62 +233,48 @@ void GameController::CalculateOrientation(Libraries::Pad::OrbisFVector3& acceler
}
void GameController::SetLightBarRGB(u8 r, u8 g, u8 b) {
if (m_sdl_gamepad != nullptr) {
SDL_SetGamepadLED(m_sdl_gamepad, r, g, b);
if (!m_engine) {
return;
}
std::scoped_lock _{m_mutex};
m_engine->SetLightBarRGB(r, g, b);
}
bool GameController::SetVibration(u8 smallMotor, u8 largeMotor) {
if (m_sdl_gamepad != nullptr) {
return SDL_RumbleGamepad(m_sdl_gamepad, (smallMotor / 255.0f) * 0xFFFF,
(largeMotor / 255.0f) * 0xFFFF, -1);
void GameController::SetVibration(u8 smallMotor, u8 largeMotor) {
if (!m_engine) {
return;
}
return true;
std::scoped_lock _{m_mutex};
m_engine->SetVibration(smallMotor, largeMotor);
}
void GameController::SetTouchpadState(int touchIndex, bool touchDown, float x, float y) {
if (touchIndex < 2) {
std::scoped_lock lock{m_mutex};
auto state = GetLastState();
state.time = Libraries::Kernel::sceKernelGetProcessTime();
state.touchpad[touchIndex].state = touchDown;
state.touchpad[touchIndex].x = static_cast<u16>(x * 1920);
state.touchpad[touchIndex].y = static_cast<u16>(y * 941);
state.time = Libraries::Kernel::sceKernelGetProcessTime();
state.OnTouchpad(touchIndex, touchDown, x, y);
AddState(state);
}
}
void GameController::TryOpenSDLController() {
if (m_sdl_gamepad == nullptr || !SDL_GamepadConnected(m_sdl_gamepad)) {
int gamepad_count;
SDL_JoystickID* gamepads = SDL_GetGamepads(&gamepad_count);
m_sdl_gamepad = gamepad_count > 0 ? SDL_OpenGamepad(gamepads[0]) : nullptr;
if (Config::getIsMotionControlsEnabled()) {
if (SDL_SetGamepadSensorEnabled(m_sdl_gamepad, SDL_SENSOR_GYRO, true)) {
gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_sdl_gamepad, SDL_SENSOR_GYRO);
LOG_INFO(Input, "Gyro initialized, poll rate: {}", gyro_poll_rate);
} else {
LOG_ERROR(Input, "Failed to initialize gyro controls for gamepad");
}
if (SDL_SetGamepadSensorEnabled(m_sdl_gamepad, SDL_SENSOR_ACCEL, true)) {
accel_poll_rate = SDL_GetGamepadSensorDataRate(m_sdl_gamepad, SDL_SENSOR_ACCEL);
LOG_INFO(Input, "Accel initialized, poll rate: {}", accel_poll_rate);
} else {
LOG_ERROR(Input, "Failed to initialize accel controls for gamepad");
}
}
SDL_free(gamepads);
SetLightBarRGB(0, 0, 255);
void GameController::SetEngine(std::unique_ptr<Engine> engine) {
std::scoped_lock _{m_mutex};
m_engine = std::move(engine);
if (m_engine) {
m_engine->Init();
}
}
Engine* GameController::GetEngine() {
return m_engine.get();
}
u32 GameController::Poll() {
std::scoped_lock lock{m_mutex};
if (m_connected) {
std::scoped_lock lock{m_mutex};
auto time = Libraries::Kernel::sceKernelGetProcessTime();
if (m_states_num == 0) {
auto diff = (time - m_last_state.time) / 1000;

View file

@ -3,12 +3,12 @@
#pragma once
#include <algorithm>
#include <memory>
#include <mutex>
#include "common/types.h"
#include "core/libraries/pad/pad.h"
struct SDL_Gamepad;
namespace Input {
enum class Axis {
@ -28,7 +28,14 @@ struct TouchpadEntry {
u16 y{};
};
struct State {
class State {
public:
void OnButton(Libraries::Pad::OrbisPadButtonDataOffset, bool);
void OnAxis(Axis, int);
void OnTouchpad(int touchIndex, bool isDown, float x, float y);
void OnGyro(const float[3]);
void OnAccel(const float[3]);
Libraries::Pad::OrbisPadButtonDataOffset buttonsState{};
u64 time = 0;
int axes[static_cast<int>(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0};
@ -38,9 +45,19 @@ struct State {
Libraries::Pad::OrbisFQuaternion orientation = {0.0f, 0.0f, 0.0f, 1.0f};
};
class Engine {
public:
virtual ~Engine() = default;
virtual void Init() = 0;
virtual void SetLightBarRGB(u8 r, u8 g, u8 b) = 0;
virtual void SetVibration(u8 smallMotor, u8 largeMotor) = 0;
virtual State ReadState() = 0;
virtual float GetAccelPollRate() const = 0;
virtual float GetGyroPollRate() const = 0;
};
inline int GetAxis(int min, int max, int value) {
int v = (255 * (value - min)) / (max - min);
return (v < 0 ? 0 : (v > 255 ? 255 : v));
return std::clamp((255 * (value - min)) / (max - min), 0, 255);
}
constexpr u32 MAX_STATES = 64;
@ -59,13 +76,12 @@ public:
void Gyro(int id, const float gyro[3]);
void Acceleration(int id, const float acceleration[3]);
void SetLightBarRGB(u8 r, u8 g, u8 b);
bool SetVibration(u8 smallMotor, u8 largeMotor);
void SetVibration(u8 smallMotor, u8 largeMotor);
void SetTouchpadState(int touchIndex, bool touchDown, float x, float y);
void TryOpenSDLController();
void SetEngine(std::unique_ptr<Engine>);
Engine* GetEngine();
u32 Poll();
float gyro_poll_rate;
float accel_poll_rate;
static void CalculateOrientation(Libraries::Pad::OrbisFVector3& acceleration,
Libraries::Pad::OrbisFVector3& angularVelocity,
float deltaTime,
@ -85,7 +101,7 @@ private:
std::array<State, MAX_STATES> m_states;
std::array<StateInternal, MAX_STATES> m_private;
SDL_Gamepad* m_sdl_gamepad = nullptr;
std::unique_ptr<Engine> m_engine = nullptr;
};
} // namespace Input

View file

@ -29,6 +29,7 @@ int main(int argc, char* argv[]) {
bool has_game_argument = false;
std::string game_path;
std::vector<std::string> game_args{};
// Map of argument strings to lambda functions
std::unordered_map<std::string, std::function<void(int&)>> arg_map = {
@ -37,6 +38,9 @@ int main(int argc, char* argv[]) {
std::cout << "Usage: shadps4 [options] <elf or eboot.bin path>\n"
"Options:\n"
" -g, --game <path|ID> Specify game path to launch\n"
" -- ... Parameters passed to the game ELF. "
"Needs to be at the end of the line, and everything after \"--\" is a "
"game argument.\n"
" -p, --patch <patch_file> Apply specified patch file\n"
" -f, --fullscreen <true|false> Specify window initial fullscreen "
"state. Does not overwrite the config file.\n"
@ -126,6 +130,21 @@ int main(int argc, char* argv[]) {
// Assume the last argument is the game file if not specified via -g/--game
game_path = argv[i];
has_game_argument = true;
} else if (std::string(argv[i]) == "--") {
if (i + 1 == argc) {
std::cerr << "Warning: -- is set, but no game arguments are added!\n";
break;
}
for (int j = i + 1; j < argc; j++) {
game_args.push_back(argv[j]);
}
break;
} else if (i + 1 < argc && std::string(argv[i + 1]) == "--") {
if (!has_game_argument) {
game_path = argv[i];
has_game_argument = true;
}
break;
} else {
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
return 1;
@ -166,7 +185,7 @@ int main(int argc, char* argv[]) {
// Run the emulator with the resolved eboot path
Core::Emulator emulator;
emulator.Run(eboot_path);
emulator.Run(eboot_path, game_args);
return 0;
}

View file

@ -188,8 +188,12 @@ void CheatsPatches::setupUI() {
}
});
QPushButton* closeButton = new QPushButton(tr("Close"));
connect(closeButton, &QPushButton::clicked, [this]() { QWidget::close(); });
controlLayout->addWidget(downloadButton);
controlLayout->addWidget(deleteCheatButton);
controlLayout->addWidget(closeButton);
cheatsLayout->addLayout(controlLayout);
cheatsTab->setLayout(cheatsLayout);
@ -464,6 +468,8 @@ void CheatsPatches::onSaveButtonClicked() {
} else {
QMessageBox::information(this, tr("Success"), tr("Options saved successfully."));
}
QWidget::close();
}
QCheckBox* CheatsPatches::findCheckBoxByName(const QString& name) {

View file

@ -33,6 +33,7 @@ int main(int argc, char* argv[]) {
bool has_command_line_argument = argc > 1;
bool show_gui = false, has_game_argument = false;
std::string game_path;
std::vector<std::string> game_args{};
// Map of argument strings to lambda functions
std::unordered_map<std::string, std::function<void(int&)>> arg_map = {
@ -43,6 +44,9 @@ int main(int argc, char* argv[]) {
" No arguments: Opens the GUI.\n"
" -g, --game <path|ID> Specify <eboot.bin or elf path> or "
"<game ID (CUSAXXXXX)> to launch\n"
" -- ... Parameters passed to the game ELF. "
"Needs to be at the end of the line, and everything after \"--\" is a "
"game argument.\n"
" -p, --patch <patch_file> Apply specified patch file\n"
" -s, --show-gui Show the GUI\n"
" -f, --fullscreen <true|false> Specify window initial fullscreen "
@ -131,6 +135,20 @@ int main(int argc, char* argv[]) {
// Assume the last argument is the game file if not specified via -g/--game
game_path = argv[i];
has_game_argument = true;
} else if (std::string(argv[i]) == "--") {
if (i + 1 == argc) {
std::cerr << "Warning: -- is set, but no game arguments are added!\n";
break;
}
for (int j = i + 1; j < argc; j++) {
game_args.push_back(argv[j]);
}
break;
} else if (i + 1 < argc && std::string(argv[i + 1]) == "--") {
if (!has_game_argument) {
game_path = argv[i];
has_game_argument = true;
}
} else {
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
return 1;
@ -181,7 +199,7 @@ int main(int argc, char* argv[]) {
// Run the emulator with the resolved game path
Core::Emulator emulator;
emulator.Run(game_file_path.string());
emulator.Run(game_file_path.string(), game_args);
if (!show_gui) {
return 0; // Exit after running the emulator without showing the GUI
}

View file

@ -247,6 +247,12 @@ void MainWindow::CreateConnects() {
}
});
connect(ui->shadFolderAct, &QAction::triggered, this, [this]() {
QString userPath;
Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir));
QDesktopServices::openUrl(QUrl::fromLocalFile(userPath));
});
connect(ui->playButton, &QPushButton::clicked, this, &MainWindow::StartGame);
connect(m_game_grid_frame.get(), &QTableWidget::cellDoubleClicked, this,
&MainWindow::StartGame);
@ -982,6 +988,7 @@ QIcon MainWindow::RecolorIcon(const QIcon& icon, bool isWhite) {
void MainWindow::SetUiIcons(bool isWhite) {
ui->bootInstallPkgAct->setIcon(RecolorIcon(ui->bootInstallPkgAct->icon(), isWhite));
ui->bootGameAct->setIcon(RecolorIcon(ui->bootGameAct->icon(), isWhite));
ui->shadFolderAct->setIcon(RecolorIcon(ui->shadFolderAct->icon(), isWhite));
ui->exitAct->setIcon(RecolorIcon(ui->exitAct->icon(), isWhite));
#ifdef ENABLE_UPDATER
ui->updaterAct->setIcon(RecolorIcon(ui->updaterAct->icon(), isWhite));

View file

@ -12,6 +12,7 @@ public:
QAction* bootInstallPkgAct;
QAction* bootGameAct;
QAction* addElfFolderAct;
QAction* shadFolderAct;
QAction* exitAct;
QAction* showGameListAct;
QAction* refreshGameListAct;
@ -89,6 +90,9 @@ public:
addElfFolderAct = new QAction(MainWindow);
addElfFolderAct->setObjectName("addElfFolderAct");
addElfFolderAct->setIcon(QIcon(":images/folder_icon.png"));
shadFolderAct = new QAction(MainWindow);
shadFolderAct->setObjectName("shadFolderAct");
shadFolderAct->setIcon(QIcon(":images/folder_icon.png"));
exitAct = new QAction(MainWindow);
exitAct->setObjectName("exitAct");
exitAct->setIcon(QIcon(":images/exit_icon.png"));
@ -274,7 +278,9 @@ public:
menuBar->addAction(menuHelp->menuAction());
menuFile->addAction(bootInstallPkgAct);
menuFile->addAction(bootGameAct);
menuFile->addSeparator();
menuFile->addAction(addElfFolderAct);
menuFile->addAction(shadFolderAct);
menuFile->addSeparator();
menuFile->addAction(menuRecent->menuAction());
menuFile->addSeparator();
@ -333,6 +339,8 @@ public:
"MainWindow", "Install application from a .pkg file", nullptr));
#endif // QT_CONFIG(tooltip)
menuRecent->setTitle(QCoreApplication::translate("MainWindow", "Recent Games", nullptr));
shadFolderAct->setText(
QCoreApplication::translate("MainWindow", "Open shadPS4 Folder", nullptr));
exitAct->setText(QCoreApplication::translate("MainWindow", "Exit", nullptr));
#if QT_CONFIG(tooltip)
exitAct->setToolTip(QCoreApplication::translate("MainWindow", "Exit shadPS4", nullptr));

View file

@ -65,6 +65,7 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
: QDialog(parent), ui(new Ui::SettingsDialog) {
ui->setupUi(this);
ui->tabWidgetSettings->setUsesScrollButtons(false);
initialHeight = this->height();
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
@ -150,7 +151,6 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
});
#else
ui->updaterGroupBox->setVisible(false);
ui->GUIgroupBox->setMaximumSize(265, 16777215);
#endif
connect(ui->updateCompatibilityButton, &QPushButton::clicked, this,
[this, parent, m_compat_info]() {
@ -169,6 +169,11 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
});
}
// Gui TAB
{
connect(ui->chooseHomeTabComboBox, &QComboBox::currentTextChanged, this,
[](const QString& hometab) { Config::setChooseHomeTab(hometab.toStdString()); });
}
// Input TAB
{
connect(ui->hideCursorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
@ -202,6 +207,21 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
delete selected_item;
}
});
connect(ui->browseButton, &QPushButton::clicked, this, [this]() {
const auto save_data_path = Config::GetSaveDataPath();
QString initial_path;
Common::FS::PathToQString(initial_path, save_data_path);
QString save_data_path_string =
QFileDialog::getExistingDirectory(this, tr("Directory to save data"), initial_path);
auto file_path = Common::FS::PathFromQString(save_data_path_string);
if (!file_path.empty()) {
Config::setSaveDataPath(file_path);
ui->currentSaveDataPath->setText(save_data_path_string);
}
});
}
// DEBUG TAB
@ -231,7 +251,7 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
#ifdef ENABLE_UPDATER
ui->updaterGroupBox->installEventFilter(this);
#endif
ui->GUIgroupBox->installEventFilter(this);
ui->GUIMusicGroupBox->installEventFilter(this);
ui->disableTrophycheckBox->installEventFilter(this);
ui->enableCompatibilityCheckBox->installEventFilter(this);
ui->checkCompatibilityOnStartupCheckBox->installEventFilter(this);
@ -256,6 +276,10 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
ui->addFolderButton->installEventFilter(this);
ui->removeFolderButton->installEventFilter(this);
ui->saveDataGroupBox->installEventFilter(this);
ui->currentSaveDataPath->installEventFilter(this);
ui->browseButton->installEventFilter(this);
// Debug
ui->debugDump->installEventFilter(this);
ui->vkValidationCheckBox->installEventFilter(this);
@ -286,6 +310,11 @@ void SettingsDialog::LoadValuesFromConfig() {
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, 30, 28};
const auto save_data_path = Config::GetSaveDataPath();
QString save_data_path_string;
Common::FS::PathToQString(save_data_path_string, save_data_path);
ui->currentSaveDataPath->setText(save_data_path_string);
ui->consoleLanguageComboBox->setCurrentIndex(
std::distance(languageIndexes.begin(),
std::find(languageIndexes.begin(), languageIndexes.end(),
@ -349,6 +378,15 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel));
#endif
std::string chooseHomeTab = toml::find_or<std::string>(data, "General", "chooseHomeTab", "");
ui->chooseHomeTabComboBox->setCurrentText(QString::fromStdString(chooseHomeTab));
QStringList tabNames = {tr("General"), tr("Gui"), tr("Graphics"), tr("User"),
tr("Input"), tr("Paths"), tr("Debug")};
QString chooseHomeTabQString = QString::fromStdString(chooseHomeTab);
int indexTab = tabNames.indexOf(chooseHomeTabQString);
indexTab = (indexTab == -1) ? 0 : indexTab;
ui->tabWidgetSettings->setCurrentIndex(indexTab);
QString backButtonBehavior = QString::fromStdString(
toml::find_or<std::string>(data, "Input", "backButtonBehavior", "left"));
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
@ -452,8 +490,8 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
} else if (elementName == "updaterGroupBox") {
text = tr("updaterGroupBox");
#endif
} else if (elementName == "GUIgroupBox") {
text = tr("GUIgroupBox");
} else if (elementName == "GUIMusicGroupBox") {
text = tr("GUIMusicGroupBox");
} else if (elementName == "disableTrophycheckBox") {
text = tr("disableTrophycheckBox");
} else if (elementName == "enableCompatibilityCheckBox") {
@ -497,6 +535,13 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
text = tr("removeFolderButton");
}
// Save Data
if (elementName == "saveDataGroupBox" || elementName == "currentSaveDataPath") {
text = tr("saveDataBox");
} else if (elementName == "browseButton") {
text = tr("browseButton");
}
// Debug
if (elementName == "debugDump") {
text = tr("debugDump");
@ -522,22 +567,6 @@ bool SettingsDialog::eventFilter(QObject* obj, QEvent* event) {
} else {
ui->descriptionText->setText(defaultTextEdit);
}
// if the text exceeds the size of the box, it will increase the size
QRect currentGeometry = this->geometry();
int newWidth = currentGeometry.width();
int documentHeight = ui->descriptionText->document()->size().height();
int visibleHeight = ui->descriptionText->viewport()->height();
if (documentHeight > visibleHeight) {
ui->descriptionText->setMaximumSize(16777215, 110);
this->setGeometry(currentGeometry.x(), currentGeometry.y(), newWidth,
currentGeometry.height() + 40);
} else {
ui->descriptionText->setMaximumSize(16777215, 70);
this->setGeometry(currentGeometry.x(), currentGeometry.y(), newWidth,
initialHeight);
}
return true;
}
}
@ -577,6 +606,7 @@ void SettingsDialog::UpdateSettings() {
Config::setRdocEnabled(ui->rdocCheckBox->isChecked());
Config::setAutoUpdate(ui->updateCheckBox->isChecked());
Config::setUpdateChannel(ui->updateComboBox->currentText().toStdString());
Config::setChooseHomeTab(ui->chooseHomeTabComboBox->currentText().toStdString());
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
Config::setCheckCompatibilityOnStartup(ui->checkCompatibilityOnStartupCheckBox->isChecked());
@ -619,4 +649,4 @@ void SettingsDialog::ResetInstallFolders() {
}
Config::setGameInstallDirs(settings_install_dirs_config);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>الألعاب الأخيرة</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>خروج</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>تمكين ملء الشاشة</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>وضع ملء الشاشة</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>علامة التبويب الافتراضية عند فتح الإعدادات</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>عرض حجم اللعبة في القائمة</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>الرسومات</translation>
</message>
<message>
<source>Gui</source>
<translation>واجهة</translation>
</message>
<message>
<source>User</source>
<translation>مستخدم</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>جهاز الرسومات</translation>
@ -801,7 +821,7 @@
<translation>تحديث: Release: إصدارات رسمية تصدر شهريًا، قد تكون قديمة بعض الشيء، لكنها أكثر استقرارًا واختبارًا. Nightly: إصدارات تطوير تحتوي على أحدث الميزات والإصلاحات، لكنها قد تحتوي على أخطاء وأقل استقرارًا.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>تشغيل موسيقى العنوان:\nإذا كانت اللعبة تدعم ذلك، قم بتمكين تشغيل موسيقى خاصة عند اختيار اللعبة في واجهة المستخدم.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Fuldskærmstilstand</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Standardfaneblad ved åbning af indstillinger</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Vis vis spilstørrelse i listen</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Interface</translation>
</message>
<message>
<source>User</source>
<translation>Bruger</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Opdatering:\nRelease: Officielle builds, der frigives månedligt, som kan være meget ældre, men mere stabile og testet.\nNightly: Udviklerbuilds med de nyeste funktioner og rettelser, men som kan indeholde fejl og være mindre stabile.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Titelsmusikafspilning:\nHvis spillet understøtter det, aktiver speciel musik, når spillet vælges i brugergrænsefladen.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Zuletzt gespielt</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Beenden</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Vollbild aktivieren</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Vollbildmodus</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Standardregisterkarte beim Öffnen der Einstellungen</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Zeigen Sie die Spielgröße in der Liste</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
<source>Gui</source>
<translation>Benutzeroberfläche</translation>
</message>
<message>
<source>User</source>
<translation>Benutzer</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Grafikgerät</translation>
@ -801,7 +821,7 @@
<translation>Update:\nRelease: Offizielle Builds, die monatlich veröffentlicht werden, können viel älter sein, aber stabiler und getestet.\nNightly: Entwickler-Builds, die die neuesten Funktionen und Fehlerbehebungen enthalten, aber Fehler enthalten und weniger stabil sein können.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Wiedergabe der Titelmusik:\nWenn das Spiel dies unterstützt, wird beim Auswählen des Spiels in der Benutzeroberfläche spezielle Musik abgespielt.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Λειτουργία Πλήρους Οθόνης</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Προεπιλεγμένη καρτέλα κατά την ανοίγμα των ρυθμίσεων</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Εμφάνιση Μεγέθους Παιχνιδιού στη Λίστα</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Διεπαφή</translation>
</message>
<message>
<source>User</source>
<translation>Χρήστης</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Ενημερώσεις:\nRelease: Επίσημες εκδόσεις που κυκλοφορούν μηνιαίως, είναι παλαιότερες αλλά πιο σταθερές και δοκιμασμένες.\nNightly: Εκδόσεις προγραμματιστών με νέες δυνατότητες και διορθώσεις, αλλά μπορεί να περιέχουν σφάλματα και να είναι λιγότερο σταθερές.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Αναπαραγωγή Μουσικής Τίτλων:\nΕάν το παιχνίδι το υποστηρίζει, ενεργοποιεί ειδική μουσική κατά την επιλογή του παιχνιδιού από τη διεπαφή χρήστη.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Fullscreen Mode</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Default tab when opening settings</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Show Game Size In List</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Gui</translation>
</message>
<message>
<source>User</source>
<translation>User</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Update:\nRelease: Official versions released every month that may be very outdated, but are more reliable and tested.\nNightly: Development versions that have all the latest features and fixes, but may contain bugs and are less stable.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
</message>
<message>
@ -908,6 +928,14 @@
<source>rdocCheckBox</source>
<translation>Enable RenderDoc Debugging:\nIf enabled, the emulator will provide compatibility with Renderdoc to allow capture and analysis of the currently rendered frame.</translation>
</message>
<message>
<source>saveDataBox</source>
<translation>Save Data Path:\nThe folder where game save data will be saved.</translation>
</message>
<message>
<source>browseButton</source>
<translation>Browse:\nBrowse for a folder to set as the save data path.</translation>
</message>
</context>
<context>
<name>CheatsPatches</name>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Juegos recientes</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Salir</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Habilitar pantalla completa</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Modo de Pantalla Completa</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Pestaña predeterminada al abrir la configuración</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Mostrar Tamaño del Juego en la Lista</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
<source>Gui</source>
<translation>Interfaz</translation>
</message>
<message>
<source>User</source>
<translation>Usuario</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Dispositivo gráfico</translation>
@ -801,7 +821,7 @@
<translation>Actualización:\nRelease: Versiones oficiales lanzadas cada mes que pueden estar muy desactualizadas, pero son más confiables y están probadas.\nNightly: Versiones de desarrollo que tienen todas las últimas funciones y correcciones, pero pueden contener errores y son menos estables.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Reproducir Música del Título:\nSi un juego lo admite, habilita la reproducción de música especial al seleccionar el juego en la interfaz gráfica.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>بازی های اخیر</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>خروج</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>تمام صفحه</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>حالت تمام صفحه</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>فعالسازی پوشه جداگانه برای بهروزرسانی</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>زبان پیشفرض هنگام باز کردن تنظیمات</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>نمایش اندازه بازی در لیست</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>گرافیک</translation>
</message>
<message>
<source>Gui</source>
<translation>رابط کاربری</translation>
</message>
<message>
<source>User</source>
<translation>کاربر</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>کارت گرافیک مورداستفاده</translation>
@ -801,7 +821,7 @@
<translation>بهروزرسانی:\nانتشار: نسخه‌های رسمی که هر ماه منتشر میشوند و ممکن است بسیار قدیمی باشند، اما پایدارتر و تست شدهتر هستند.\nشبانه: نسخه‌های توسعهای که شامل جدیدترین ویژگیها و اصلاحات هستند، اما ممکن است دارای اشکال باشند و کمتر پایدار باشند.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>پخش موسیقی عنوان:\nIدر صورتی که بازی از آن پشتیبانی کند، پخش موسیقی ویژه هنگام انتخاب بازی در رابط کاربری را فعال میکند.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Viimeisimmät Pelit</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Sulje</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Ota Käyttöön Koko Ruudun Tila</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Koko näytön tila</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Ota Käyttöön Erillinen Päivityshakemisto</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Oletusvälilehti avattaessa asetuksia</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Näytä pelin koko luettelossa</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafiikka</translation>
</message>
<message>
<source>Gui</source>
<translation>Rajapinta</translation>
</message>
<message>
<source>User</source>
<translation>Käyttäjä</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Näytönohjain</translation>
@ -801,7 +821,7 @@
<translation>Päivitys:\nRelease: Viralliset versiot, jotka julkaistaan kuukausittain ja saattavat olla hyvin vanhoja, mutta ovat luotettavampia ja testatumpia.\nNightly: Kehitysversiot, joissa on kaikki uusimmat ominaisuudet ja korjaukset, mutta ne saattavat sisältää virheitä ja ovat vähemmän vakaita.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Soita Otsikkomusiikkia:\nJos peli tukee sitä, ota käyttöön erityisen musiikin soittaminen pelin valinnan yhteydessä käyttöliittymässä.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Jeux récents</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Ouvrir le dossier de shadPS4</translation>
</message>
<message>
<source>Exit</source>
<translation>Fermer</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Plein écran</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Mode Plein Écran</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Dossier séparé pour les mises à jours</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Onglet par défaut lors de l'ouverture des paramètres</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Afficher la taille du jeu dans la liste</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphismes</translation>
</message>
<message>
<source>Gui</source>
<translation>Interface</translation>
</message>
<message>
<source>User</source>
<translation>Utilisateur</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Carte graphique</translation>
@ -801,7 +821,7 @@
<translation>Mise à jour:\nRelease: versions officielles publiées chaque mois qui peuvent être très anciennes, mais plus fiables et testées.\nNightly: versions de développement avec toutes les dernières fonctionnalités et correctifs, mais pouvant avoir des bogues et être moins stables.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Jouer de la musique de titre:\nSi le jeu le prend en charge, cela active la musique spéciale lorsque vous sélectionnez le jeu dans l'interface utilisateur.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Legutóbbi Játékok</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Kilépés</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Teljes Képernyő Engedélyezése</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Teljes képernyős mód</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Külön Frissítési Mappa Engedélyezése</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Alapértelmezett fül a beállítások megnyitásakor</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Játékméret megjelenítése a listában</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
<source>Gui</source>
<translation>Felület</translation>
</message>
<message>
<source>User</source>
<translation>Felhasználó</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Grafikai Eszköz</translation>
@ -801,7 +821,7 @@
<translation>Frissítés:\nRelease: Hivatalos verziók, amelyeket havonta adnak ki, és amelyek nagyon elavultak lehetnek, de megbízhatóbbak és teszteltek.\nNightly: Fejlesztési verziók, amelyek az összes legújabb funkciót és javítást tartalmazzák, de hibákat tartalmazhatnak és kevésbé stabilak.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Játék címzene lejátszása:\nHa a játék támogatja, engedélyezze egy speciális zene lejátszását, amikor a játékot kiválasztja a GUI-ban.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Mode Layar Penuh</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Tab default saat membuka pengaturan</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Tampilkan Ukuran Game di Daftar</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Antarmuka</translation>
</message>
<message>
<source>User</source>
<translation>Pengguna</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Pembaruan:\nRelease: Versi resmi yang dirilis setiap bulan yang mungkin sangat ketinggalan zaman, tetapi lebih dapat diandalkan dan teruji.\nNightly: Versi pengembangan yang memiliki semua fitur dan perbaikan terbaru, tetapi mungkin mengandung bug dan kurang stabil.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Putar Musik Judul Permainan:\nJika permainan mendukungnya, aktifkan pemutaran musik khusus saat memilih permainan di GUI.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Giochi Recenti</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Uscita</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Abilita Schermo Intero</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Modalità Schermo Intero</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Abilita Cartella Aggiornamenti Separata</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Scheda predefinita all'apertura delle impostazioni</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Mostra la dimensione del gioco nell'elenco</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafica</translation>
</message>
<message>
<source>Gui</source>
<translation>Interfaccia</translation>
</message>
<message>
<source>User</source>
<translation>Utente</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Scheda Grafica</translation>
@ -801,7 +821,7 @@
<translation>Aggiornamento:\nRelease: Versioni ufficiali rilasciate ogni mese che potrebbero essere molto datate, ma sono più affidabili e testate.\nNightly: Versioni di sviluppo che hanno tutte le ultime funzionalità e correzioni, ma potrebbero contenere bug e sono meno stabili.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Riproduci Musica del Titolo:\nSe un gioco lo supporta, attiva la riproduzione di musica speciale quando selezioni il gioco nell'interfaccia grafica.</translation>
</message>
<message>

View file

@ -19,7 +19,7 @@
</message>
<message>
<source>This software should not be used to play games you have not legally obtained.</source>
<translation>使</translation>
<translation>使</translation>
</message>
</context>
<context>
@ -33,7 +33,7 @@
<name>GameInfoClass</name>
<message>
<source>Loading game list, please wait :3</source>
<translation>お待ちください :3</translation>
<translation>しばらくお待ちください :3</translation>
</message>
<message>
<source>Cancel</source>
@ -52,7 +52,7 @@
</message>
<message>
<source>Select which directory you want to install to.</source>
<translation>Select which directory you want to install to.</translation>
<translation></translation>
</message>
</context>
<context>
@ -75,7 +75,7 @@
</message>
<message>
<source>The value for location to install games is not valid.</source>
<translation></translation>
<translation></translation>
</message>
</context>
<context>
@ -130,35 +130,35 @@
</message>
<message>
<source>Delete...</source>
<translation>Delete...</translation>
<translation>...</translation>
</message>
<message>
<source>Delete Game</source>
<translation>Delete Game</translation>
<translation></translation>
</message>
<message>
<source>Delete Update</source>
<translation>Delete Update</translation>
<translation></translation>
</message>
<message>
<source>Delete DLC</source>
<translation>Delete DLC</translation>
<translation>DLCを削除</translation>
</message>
<message>
<source>Compatibility...</source>
<translation>Compatibility...</translation>
<translation>...</translation>
</message>
<message>
<source>Update database</source>
<translation>Update database</translation>
<translation></translation>
</message>
<message>
<source>View report</source>
<translation>View report</translation>
<translation></translation>
</message>
<message>
<source>Submit a report</source>
<translation>Submit a report</translation>
<translation></translation>
</message>
<message>
<source>Shortcut creation</source>
@ -182,23 +182,23 @@
</message>
<message>
<source>Game</source>
<translation>Game</translation>
<translation></translation>
</message>
<message>
<source>requiresEnableSeparateUpdateFolder_MSG</source>
<translation>This feature requires the 'Enable Separate Update Folder' config option to work. If you want to use this feature, please enable it.</translation>
<translation> 'アップデートフォルダの分離を有効化' </translation>
</message>
<message>
<source>This game has no update to delete!</source>
<translation>This game has no update to delete!</translation>
<translation>!</translation>
</message>
<message>
<source>Update</source>
<translation>Update</translation>
<translation></translation>
</message>
<message>
<source>This game has no DLC to delete!</source>
<translation>This game has no DLC to delete!</translation>
<translation>DLCがないため削除することができません!</translation>
</message>
<message>
<source>DLC</source>
@ -206,11 +206,11 @@
</message>
<message>
<source>Delete %1</source>
<translation>Delete %1</translation>
<translation>%1 </translation>
</message>
<message>
<source>Are you sure you want to delete %1's %2 directory?</source>
<translation>Are you sure you want to delete %1's %2 directory?</translation>
<translation>%1 %2 ?</translation>
</message>
</context>
<context>
@ -241,11 +241,15 @@
</message>
<message>
<source>Install application from a .pkg file</source>
<translation>.pkgファイルからアプリケーションをインストールする</translation>
<translation>.pkgファイルからアプリケーションをインストール</translation>
</message>
<message>
<source>Recent Games</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>shadPS4フォルダを開く</translation>
</message>
<message>
<source>Exit</source>
@ -269,7 +273,7 @@
</message>
<message>
<source>Tiny</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Small</source>
@ -293,7 +297,7 @@
</message>
<message>
<source>Elf Viewer</source>
<translation>Elfビュ</translation>
<translation>Elfビューア</translation>
</message>
<message>
<source>Game Install Directory</source>
@ -393,11 +397,11 @@
</message>
<message>
<source>You have downloaded cheats for all the games you have installed.</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Patches Downloaded Successfully!</source>
<translation></translation>
<translation>!</translation>
</message>
<message>
<source>All Patches available for all games have been downloaded.</source>
@ -421,11 +425,11 @@
</message>
<message>
<source>Only one file can be selected!</source>
<translation>1</translation>
<translation>1!</translation>
</message>
<message>
<source>PKG Extraction</source>
<translation>PKG抽出</translation>
<translation>PKG抽出</translation>
</message>
<message>
<source>Patch detected!</source>
@ -469,7 +473,7 @@
</message>
<message>
<source>PKG is a patch, please install the game first!</source>
<translation>PKGはパッチです</translation>
<translation>PKGはパッチです!</translation>
</message>
<message>
<source>PKG ERROR</source>
@ -522,11 +526,11 @@
</message>
<message>
<source>Console Language</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Emulator Language</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Emulator</source>
@ -536,9 +540,17 @@
<source>Enable Fullscreen</source>
<translation></translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation></translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
<translation></translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation></translation>
</message>
<message>
<source>Show Game Size In List</source>
@ -546,7 +558,7 @@
</message>
<message>
<source>Show Splash</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Is PS4 Pro</source>
@ -562,11 +574,11 @@
</message>
<message>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
<translation></translation>
</message>
<message>
<source>Trophy</source>
<translation>Trophy</translation>
<translation></translation>
</message>
<message>
<source>Logger</source>
@ -598,7 +610,7 @@
</message>
<message>
<source>Hide Cursor Idle Timeout</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>s</source>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation></translation>
</message>
<message>
<source>Gui</source>
<translation></translation>
</message>
<message>
<source>User</source>
<translation></translation>
</message>
<message>
<source>Graphics Device</source>
<translation></translation>
@ -702,7 +722,7 @@
</message>
<message>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
<translation></translation>
</message>
<message>
<source>Play title music</source>
@ -710,19 +730,19 @@
</message>
<message>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
<translation></translation>
</message>
<message>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
<translation></translation>
</message>
<message>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
<translation></translation>
</message>
<message>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
<translation></translation>
</message>
<message>
<source>Volume</source>
@ -730,7 +750,7 @@
</message>
<message>
<source>Audio Backend</source>
<translation>Audio Backend</translation>
<translation> </translation>
</message>
<message>
<source>Save</source>
@ -750,15 +770,15 @@
</message>
<message>
<source>Point your mouse at an option to display its description.</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>consoleLanguageGroupBox</source>
<translation>:\nPS4ゲームが使用する言語を設定します\nこれはゲームがサポートする言語に設定することをお勧めしますが</translation>
<translation>:\nPS4ゲームが使用する言語を設定します\nゲームでサポートされている言語に設定することをお勧めしますが</translation>
</message>
<message>
<source>emulatorLanguageGroupBox</source>
<translation>:\nエミュレーターのユーザーインターフェースの言語を設定します</translation>
<translation>:\nエミュレーターのユーザーインターフェースの言語を設定します</translation>
</message>
<message>
<source>fullscreenCheckBox</source>
@ -766,7 +786,7 @@
</message>
<message>
<source>separateUpdatesCheckBox</source>
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
<translation>Enable Separate Update Folder:\nゲームのアップデートを別のフォルダにインストールすることで</translation>
</message>
<message>
<source>showSplashCheckBox</source>
@ -774,7 +794,7 @@
</message>
<message>
<source>ps4proCheckBox</source>
<translation>PS4 Proです:\nエミュレーターがPS4 PROとして動作するようにし</translation>
<translation>PS4 Pro :\nエミュレーターがPS4 PROとして動作するようになりPS4 PROをサポートする一部のゲームで特別な機能が有効化される場合がありま</translation>
</message>
<message>
<source>discordRPCCheckbox</source>
@ -786,7 +806,7 @@
</message>
<message>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
<translation>:\nトロフィーの復号に使用されるキーです\n16進数のみを受け入れます</translation>
</message>
<message>
<source>logTypeGroupBox</source>
@ -794,27 +814,27 @@
</message>
<message>
<source>logFilter</source>
<translation>:\n特定の情報のみを印刷するようにログをフィルタリングします\n例: "Core:Trace" "Lib.Pad:Debug Common.Filesystem:Error" "*:Critical" レベル: Trace, Debug, Info, Warning, Error, Critical - </translation>
<translation>:\n特定の情報のみを印刷するようにログをフィルタリングします\n例: "Core:Trace" "Lib.Pad:Debug Common.Filesystem:Error" "*:Critical" \nレベル: Trace, Debug, Info, Warning, Error, Critical - </translation>
</message>
<message>
<source>updaterGroupBox</source>
<translation>:\nRelease: 非常に古いかもしれない\nNightly: 最新の機能と修正がすべて含まれていますが</translation>
<translation>:\nRelease: 最新の機能を利用できない可能性があります\nNightly: 最新の機能と修正がすべて含まれていますが</translation>
</message>
<message>
<source>GUIgroupBox</source>
<translation>:\nゲームがそれをサポートしている場合GUIでゲームを選択したときに特別な音楽を再生することを有効にします</translation>
<source>GUIMusicGroupBox</source>
<translation>:\nゲームでサポートされている場合にGUIでゲームを選択したときに特別な音楽を再生する機能を有効にします</translation>
</message>
<message>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
<translation>:\nゲーム内でのトロフィー通知を無効化します 使()</translation>
</message>
<message>
<source>hideCursorGroupBox</source>
<translation>:\nカーソルが消えるタイミングを選択してください:\n決して: いつでもマウスが見えます\nアイドル: アイダルの後に消えるまでの時間を設定します\n常に: マウスは決して見えません</translation>
<translation>:\nカーソルが消えるタイミングを選択してください:\n無効: 常にカーソルが表示されます\n非アクティブ時: カーソルの非アクティブ期間が指定した時間を超えた場合にカーソルを隠します\n常に: カーソルは常に隠れた状態になります</translation>
</message>
<message>
<source>idleTimeoutGroupBox</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>backButtonBehaviorGroupBox</source>
@ -822,23 +842,23 @@
</message>
<message>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
<translation>:\nゲームの互換性に関する情報を表として表示します"起動時に互換性データベースを更新する" </translation>
</message>
<message>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
<translation>:\nshadPS4の起動時に自動で互換性データベースを更新します</translation>
</message>
<message>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
<translation>:\n今すぐ互換性データベースを更新します</translation>
</message>
<message>
<source>Never</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Idle</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Always</source>
@ -846,11 +866,11 @@
</message>
<message>
<source>Touchpad Left</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Touchpad Right</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Touchpad Center</source>
@ -862,15 +882,15 @@
</message>
<message>
<source>graphicsAdapterGroupBox</source>
<translation>:\n複数のGPUシステムで使GPUを選択するか\n</translation>
<translation>:\nシステムに複数のGPUが搭載されている場合使GPUを選択するか\n</translation>
</message>
<message>
<source>resolutionLayout</source>
<translation>/:\n起動時にエミュレーターウィンドウのサイズを設定します\nこれはゲーム内の解像度とは異なります</translation>
<translation>/:\n起動時にエミュレーターウィンドウのサイズを設定します\nこれはゲーム内の解像度とは異なります</translation>
</message>
<message>
<source>heightDivider</source>
<translation>Vblankディバイダー:\nエミュレーターが更新されるフレームレートにこの数を掛けます</translation>
<translation>Vblankディバイダー:\nエミュレーターが更新されるフレームレートにこの数を掛けます!</translation>
</message>
<message>
<source>dumpShadersCheckBox</source>
@ -913,11 +933,11 @@
<name>CheatsPatches</name>
<message>
<source>Cheats / Patches for </source>
<translation>Cheats / Patches for </translation>
<translation>/</translation>
</message>
<message>
<source>defaultTextEdit_MSG</source>
<translation>/\n使用には注意してください\n\nリポジトリを選択し\nPatches使\n\nチート/\n問題があればチートの作者に報告してください\n\n新しいチートを作成しましたか\nhttps://github.com/shadps4-emu/ps4_cheats を訪問してください。</translation>
<translation>/\n使用には注意してください\n\nリポジトリを選択し\nPatches使\n\nチート/\n問題があればチートの作者に報告してください\n\n新しいチートを作成しましたか\nhttps://github.com/shadps4-emu/ps4_cheats を訪問してください。</translation>
</message>
<message>
<source>No Image Available</source>
@ -993,7 +1013,7 @@
</message>
<message>
<source>Unable to open files.json for reading.</source>
<translation>files.jsonを読み込み用に開けません</translation>
<translation>files.jsonを読み取りのために開く事が出来ませんでした</translation>
</message>
<message>
<source>No patch file found for the current serial.</source>
@ -1001,11 +1021,11 @@
</message>
<message>
<source>Unable to open the file for reading.</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Unable to open the file for writing.</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Failed to parse XML: </source>
@ -1025,7 +1045,7 @@
</message>
<message>
<source>The selected source is invalid.</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>File Exists</source>
@ -1109,7 +1129,7 @@
</message>
<message>
<source>Failed to open files.json for writing</source>
<translation>files.jsonを記録用に開けません</translation>
<translation>files.jsonを読み取りのために開く事が出来ませんでした</translation>
</message>
<message>
<source>Author: </source>
@ -1121,7 +1141,7 @@
</message>
<message>
<source>Failed to open files.json for reading.</source>
<translation>files.jsonを読み込み用に開けません</translation>
<translation>files.jsonを読み取りのために開く事が出来ませんでした</translation>
</message>
<message>
<source>Name:</source>
@ -1176,43 +1196,43 @@
</message>
<message>
<source>Never Played</source>
<translation>Never Played</translation>
<translation></translation>
</message>
<message>
<source>h</source>
<translation>h</translation>
<translation></translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation></translation>
</message>
<message>
<source>s</source>
<translation>s</translation>
<translation></translation>
</message>
<message>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
<translation></translation>
</message>
<message>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
<translation>/</translation>
</message>
<message>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
<translation></translation>
</message>
<message>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
<translation></translation>
</message>
<message>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
<translation></translation>
</message>
<message>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
<translation></translation>
</message>
</context>
<context>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation> </translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation> </translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation> </translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation></translation>
</message>
<message>
<source>User</source>
<translation></translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Update:\nRelease: Official versions released every month that may be very outdated, but are more reliable and tested.\nNightly: Development versions that have all the latest features and fixes, but may contain bugs and are less stable.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Viso ekranas</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Numatytoji kortelė atidarius nustatymus</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Rodyti žaidimo dydį sąraše</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Interfeisa</translation>
</message>
<message>
<source>User</source>
<translation>Naudotojas</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Atnaujinti:\nRelease: Oficialios versijos, išleidžiamos kiekvieną mėnesį, kurios gali būti labai pasenusios, tačiau yra patikimos ir išbandytos.\nNightly: Vystymo versijos, kuriose yra visos naujausios funkcijos ir taisymai, tačiau gali turėti klaidų ir būti mažiau stabilios.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Groti antraščių muziką:\nJei žaidimas tai palaiko, įjungia specialios muzikos grojimą, kai pasirinkite žaidimą GUI.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Nylige spill</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Avslutt</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Aktiver fullskjerm</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Fullskjermmodus</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Aktiver seperat oppdateringsmappe</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Standardfanen når innstillingene åpnes</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Vis spillstørrelse i listen</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafikk</translation>
</message>
<message>
<source>Gui</source>
<translation>Grensesnitt</translation>
</message>
<message>
<source>User</source>
<translation>Bruker</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Grafikkenhet</translation>
@ -801,7 +821,7 @@
<translation>Oppdatering:\nRelease: Offisielle versjoner utgitt hver måned som kan være veldig utdaterte, men er mer pålitelige og testet.\nNightly: Utviklingsversjoner som har alle de nyeste funksjonene og feilrettingene, men som kan inneholde feil og er mindre stabile.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Spille tittelmusikk:\nHvis et spill støtter det, aktiveres det spesiell musikk når du velger spillet i menyen.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Volledig schermmodus</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Standaardtabblad bij het openen van instellingen</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Toon grootte van het spel in de lijst</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Interface</translation>
</message>
<message>
<source>User</source>
<translation>Gebruiker</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Updateren:\nRelease: Officiële versies die elke maand worden uitgebracht, die zeer verouderd kunnen zijn, maar betrouwbaar en getest zijn.\nNightly: Ontwikkelingsversies die alle nieuwste functies en bugfixes bevatten, maar mogelijk bugs bevatten en minder stabiel zijn.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Speel titelsong:\nAls een game dit ondersteunt, wordt speciale muziek afgespeeld wanneer je het spel in de GUI selecteert.</translation>
</message>
<message>

View file

@ -52,7 +52,7 @@
</message>
<message>
<source>Select which directory you want to install to.</source>
<translation>Select which directory you want to install to.</translation>
<translation>Wybierz katalog, do którego chcesz zainstalować.</translation>
</message>
</context>
<context>
@ -130,35 +130,35 @@
</message>
<message>
<source>Delete...</source>
<translation>Delete...</translation>
<translation>Usuń...</translation>
</message>
<message>
<source>Delete Game</source>
<translation>Delete Game</translation>
<translation>Usuń Grę</translation>
</message>
<message>
<source>Delete Update</source>
<translation>Delete Update</translation>
<translation>Usuń Aktualizację</translation>
</message>
<message>
<source>Delete DLC</source>
<translation>Delete DLC</translation>
<translation>Usuń DLC</translation>
</message>
<message>
<source>Compatibility...</source>
<translation>Compatibility...</translation>
<translation>kompatybilność...</translation>
</message>
<message>
<source>Update database</source>
<translation>Update database</translation>
<translation>Zaktualizuj bazę danych</translation>
</message>
<message>
<source>View report</source>
<translation>View report</translation>
<translation>Wyświetl zgłoszenie</translation>
</message>
<message>
<source>Submit a report</source>
<translation>Submit a report</translation>
<translation>Wyślij zgłoszenie</translation>
</message>
<message>
<source>Shortcut creation</source>
@ -182,23 +182,23 @@
</message>
<message>
<source>Game</source>
<translation>Game</translation>
<translation>Gra</translation>
</message>
<message>
<source>requiresEnableSeparateUpdateFolder_MSG</source>
<translation>This feature requires the 'Enable Separate Update Folder' config option to work. If you want to use this feature, please enable it.</translation>
<translation>Ta funkcja wymaga do działania opcji Włącz oddzielny folder aktualizacji. Jeśli chcesz korzystać z tej funkcji, włącz .</translation>
</message>
<message>
<source>This game has no update to delete!</source>
<translation>This game has no update to delete!</translation>
<translation>Ta gra nie ma aktualizacji do usunięcia!</translation>
</message>
<message>
<source>Update</source>
<translation>Update</translation>
<translation>Aktualizacja</translation>
</message>
<message>
<source>This game has no DLC to delete!</source>
<translation>This game has no DLC to delete!</translation>
<translation>Ta gra nie ma DLC do usunięcia!</translation>
</message>
<message>
<source>DLC</source>
@ -206,11 +206,11 @@
</message>
<message>
<source>Delete %1</source>
<translation>Delete %1</translation>
<translation>Usuń %1</translation>
</message>
<message>
<source>Are you sure you want to delete %1's %2 directory?</source>
<translation>Are you sure you want to delete %1's %2 directory?</translation>
<translation>Czy na pewno chcesz usunąć katalog %1 z %2?</translation>
</message>
</context>
<context>
@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Ostatnie gry</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Otwórz folder shadPS4</translation>
</message>
<message>
<source>Exit</source>
<translation>Wyjdź</translation>
@ -536,9 +540,17 @@
<source>Enable Fullscreen</source>
<translation>Włącz pełny ekran</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Tryb Pełnoekranowy</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
<translation>Włącz oddzielny folder aktualizacji</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Domyślna zakładka podczas otwierania ustawień</translation>
</message>
<message>
<source>Show Game Size In List</source>
@ -562,11 +574,11 @@
</message>
<message>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
<translation>Klucz trofeów</translation>
</message>
<message>
<source>Trophy</source>
<translation>Trophy</translation>
<translation>Trofeum</translation>
</message>
<message>
<source>Logger</source>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
<source>Gui</source>
<translation>Interfejs</translation>
</message>
<message>
<source>User</source>
<translation>Użytkownik</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Karta graficzna</translation>
@ -702,7 +722,7 @@
</message>
<message>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
<translation>Wyłącz wyskakujące okienka trofeów</translation>
</message>
<message>
<source>Play title music</source>
@ -710,19 +730,19 @@
</message>
<message>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
<translation>Aktualizuj bazę danych zgodności podczas uruchamiania</translation>
</message>
<message>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
<translation>Kompatybilność gier</translation>
</message>
<message>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
<translation>Wyświetl dane zgodności</translation>
</message>
<message>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
<translation>Aktualizuj bazę danych zgodności</translation>
</message>
<message>
<source>Volume</source>
@ -730,7 +750,7 @@
</message>
<message>
<source>Audio Backend</source>
<translation>Audio Backend</translation>
<translation>Zaplecze audio</translation>
</message>
<message>
<source>Save</source>
@ -766,7 +786,7 @@
</message>
<message>
<source>separateUpdatesCheckBox</source>
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
<translation>Włącz oddzielny folder aktualizacji:\nUmożliwia instalowanie aktualizacji gier w oddzielnym folderze w celu łatwego zarządzania.</translation>
</message>
<message>
<source>showSplashCheckBox</source>
@ -778,7 +798,7 @@
</message>
<message>
<source>discordRPCCheckbox</source>
<translation>Włącz Discord Rich Presence:\nWyświetla ikonę emuladora i odpowiednie informacje na twoim profilu Discord.</translation>
<translation>Włącz Discord Rich Presence:\nWyświetla ikonę emulatora i odpowiednie informacje na twoim profilu Discord.</translation>
</message>
<message>
<source>userName</source>
@ -786,7 +806,7 @@
</message>
<message>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
<translation>Klucz trofeów:\nKlucz używany do odszyfrowywania trofeów. Musi być uzyskany z konsoli po jailbreaku. Musi zawierać tylko znaki w kodzie szesnastkowym.</translation>
</message>
<message>
<source>logTypeGroupBox</source>
@ -801,12 +821,12 @@
<translation>Aktualizator:\nRelease: Oficjalne wersje wydawane co miesiąc, które mogą być bardzo przestarzałe, ale niezawodne i przetestowane.\nNightly: Wersje rozwojowe, które zawierają wszystkie najnowsze funkcje i poprawki błędów, ale mogą mieć błędy i być mniej stabilne.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Odtwórz muzykę tytułową:\nJeśli gra to obsługuje, aktywuje odtwarzanie specjalnej muzyki podczas wybierania gry w GUI.</translation>
</message>
<message>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
<translation>Wyłącz wyskakujące okienka trofeów:\nWyłącz powiadomienia o trofeach w grze. Postępy w zdobywaniu trofeów można nadal śledzić za pomocą przeglądarki trofeów (kliknij prawym przyciskiem myszy grę w oknie głównym).</translation>
</message>
<message>
<source>hideCursorGroupBox</source>
@ -822,15 +842,15 @@
</message>
<message>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
<translation>Wyświetl dane zgodności:\nWyświetla informacje o kompatybilności gry w widoku tabeli. Włącz opcję Aktualizuj zgodność przy uruchomieniu, aby uzyskać aktualne informacje.</translation>
</message>
<message>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
<translation>Aktualizuj zgodność przy uruchomieniu:\nAutomatycznie aktualizuj bazę danych kompatybilności podczas uruchamiania shadPS4.</translation>
</message>
<message>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
<translation>Zaktualizuj bazę danych zgodności:\nNatychmiast zaktualizuj bazę danych zgodności.</translation>
</message>
<message>
<source>Never</source>
@ -913,7 +933,7 @@
<name>CheatsPatches</name>
<message>
<source>Cheats / Patches for </source>
<translation>Cheats / Patches for </translation>
<translation>Kody / Łatki dla </translation>
</message>
<message>
<source>defaultTextEdit_MSG</source>
@ -1125,7 +1145,7 @@
</message>
<message>
<source>Failed to parse JSON:</source>
<translation>Nie udało się przeanlizować JSON:</translation>
<translation>Nie udało się przeanalizować JSON:</translation>
</message>
<message>
<source>Can't apply cheats before the game is started</source>
@ -1148,7 +1168,7 @@
</message>
<message>
<source>Compatibility</source>
<translation>Compatibility</translation>
<translation>Zgodność</translation>
</message>
<message>
<source>Region</source>
@ -1176,7 +1196,7 @@
</message>
<message>
<source>Never Played</source>
<translation>Never Played</translation>
<translation>Nigdy nie grane</translation>
</message>
<message>
<source>h</source>
@ -1192,27 +1212,27 @@
</message>
<message>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
<translation>Kompatybilność nie została przetestowana</translation>
</message>
<message>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
<translation>Gra nie inicjuje się poprawnie / zawiesza się emulator</translation>
</message>
<message>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
<translation>Gra uruchamia się, ale wyświetla tylko pusty ekran</translation>
</message>
<message>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
<translation>Gra wyświetla obraz, ale nie przechodzi do menu</translation>
</message>
<message>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
<translation>Gra ma usterki przerywające rozgrywkę lub niegrywalną wydajność</translation>
</message>
<message>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
<translation>Gmożna ukończyć z grywalną wydajnością i bez większych usterek</translation>
</message>
</context>
<context>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Jogos Recentes</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Abrir pasta shadPS4</translation>
</message>
<message>
<source>Exit</source>
<translation>Sair</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Ativar Tela Cheia</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Modo de Tela Cheia</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Habilitar pasta de atualização separada</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Aba padrão ao abrir as configurações</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Mostrar Tamanho do Jogo na Lista</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
<source>Gui</source>
<translation>Interface</translation>
</message>
<message>
<source>User</source>
<translation>Usuário</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Placa de Vídeo</translation>
@ -762,7 +782,7 @@
</message>
<message>
<source>fullscreenCheckBox</source>
<translation>Ativar Tela Cheia:\nMove automaticamente a janela do jogo para o modo tela cheia.\nIsso pode ser alterado pressionando a tecla F11.</translation>
<translation>Ativar Tela Cheia:\nAltera a janela do jogo para o modo tela cheia.\nIsso pode ser alterado pressionando a tecla F11.</translation>
</message>
<message>
<source>separateUpdatesCheckBox</source>
@ -801,7 +821,11 @@
<translation>Atualizações:\nRelease: Versões oficiais que são lançadas todo mês e podem ser bastante antigas, mas são mais confiáveis e testadas.\nNightly: Versões de desenvolvimento que têm todos os novos recursos e correções, mas podem ter bugs e ser instáveis.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>chooseHomeTabGroupBox</source>
<translation>do menu.</translation>
</message>
<message>
<source>GUIMusicGroupBox</source>
<translation>Reproduzir música de abertura:\nSe o jogo suportar, ativa a reprodução de uma música especial ao selecionar o jogo na interface do menu.</translation>
</message>
<message>
@ -1341,4 +1365,4 @@
<translation>TB</translation>
</message>
</context>
</TS>
</TS>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Recent Games</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Exit</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Enable Fullscreen</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Mod Ecran Complet</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Tab-ul implicit la deschiderea setărilor</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Afișează dimensiunea jocului în listă</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
<source>Gui</source>
<translation>Interfață</translation>
</message>
<message>
<source>User</source>
<translation>Utilizator</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Graphics Device</translation>
@ -801,7 +821,7 @@
<translation>Actualizare:\nRelease: Versiuni oficiale lansate în fiecare lună, care pot fi foarte învechite, dar sunt mai fiabile și testate.\nNightly: Versiuni de dezvoltare care conțin toate cele mai recente funcții și corecții, dar pot conține erori și sunt mai puțin stabile.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Redă muzica titlului:\nDacă un joc o suportă, activează redarea muzicii speciale când selectezi jocul în GUI.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Недавние игры</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Выход</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Полноэкранный режим</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Режим Полного Экран</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Отдельная папка обновлений</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Вкладка по умолчанию при открытии настроек</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Показать размер игры в списке</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Графика</translation>
</message>
<message>
<source>Gui</source>
<translation>Интерфейс</translation>
</message>
<message>
<source>User</source>
<translation>Пользователь</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Графическое устройство</translation>
@ -801,7 +821,7 @@
<translation>Обновление:\nRelease: Официальные версии, которые выпускаются каждый месяц и могут быть очень старыми, но они более надежные и проверенные.\nNightly: Версии разработки, которые содержат все последние функции и исправления, но могут содержать ошибки и менее стабильны.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Играть заглавную музыку:\nВключает воспроизведение специальной музыки при выборе игры в списке, если она это поддерживает.</translation>
</message>
<message>

View file

@ -247,6 +247,10 @@
<source>Recent Games</source>
<translation>Lojërat e fundit</translation>
</message>
<message>
<source>Open shadPS4 Folder</source>
<translation>Open shadPS4 Folder</translation>
</message>
<message>
<source>Exit</source>
<translation>Dil</translation>
@ -536,10 +540,18 @@
<source>Enable Fullscreen</source>
<translation>Aktivizo Ekranin e plotë</translation>
</message>
<message>
<source>Fullscreen Mode</source>
<translation>Modaliteti i Plotë</translation>
</message>
<message>
<source>Enable Separate Update Folder</source>
<translation>Aktivizo dosjen e ndarë përditësimit</translation>
</message>
<message>
<source>Default tab when opening settings</source>
<translation>Skeda e parazgjedhur kur hapni cilësimet</translation>
</message>
<message>
<source>Show Game Size In List</source>
<translation>Shfaq madhësinë e lojës listë</translation>
@ -616,6 +628,14 @@
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
<source>Gui</source>
<translation>Ndërfaqe</translation>
</message>
<message>
<source>User</source>
<translation>Përdorues</translation>
</message>
<message>
<source>Graphics Device</source>
<translation>Pajisja e Grafikës</translation>
@ -801,7 +821,7 @@
<translation>Përditësimi:\nRelease: Versionet zyrtare lëshuara çdo muaj mund jenë shumë vjetra, por janë besueshme dhe provuara.\nNightly: Versionet e zhvillimit kanë gjitha veçoritë dhe rregullimet fundit, por mund përmbajnë gabime dhe janë pak qëndrueshme.</translation>
</message>
<message>
<source>GUIgroupBox</source>
<source>GUIMusicGroupBox</source>
<translation>Luaj muzikën e titullit:\nNëse një lojë e mbështet, aktivizohet luajtja e muzikës veçantë kur zgjidhësh lojën GUI.</translation>
</message>
<message>

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