Merge branch 'shadps4-emu:main' into fix-bb-lighting

This commit is contained in:
Vladislav Mikhalin 2024-09-30 18:46:47 +03:00 committed by GitHub
commit de4eb75cf0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 213 additions and 95 deletions

View file

@ -14,11 +14,12 @@ export PATH="$Qt6_DIR/bin:$PATH"
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-checkrt/releases/download/continuous/linuxdeploy-plugin-checkrt-x86_64.sh
wget -q https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gstreamer/master/linuxdeploy-plugin-gstreamer.sh
chmod a+x linuxdeploy-x86_64.AppImage
chmod a+x linuxdeploy-plugin-qt-x86_64.AppImage
chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
chmod a+x linuxdeploy-plugin-gstreamer.sh
# Build AppImage
./linuxdeploy-x86_64.AppImage --appdir AppDir
@ -26,5 +27,5 @@ chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
cp -a "$GITHUB_WORKSPACE/build/translations" AppDir/usr/bin
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/.github/shadps4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/.github/shadps4.png --plugin qt --output appimage
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/.github/shadps4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/.github/shadps4.png --plugin qt --plugin gstreamer --output appimage
mv Shadps4-x86_64.AppImage Shadps4-qt.AppImage

View file

@ -3,28 +3,28 @@ 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:
#### Debian & Ubuntu
```
sudo apt-get install build-essential libasound2-dev libpulse-dev libopenal-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git libevdev-dev libsdl2-2.0 libsdl2-dev libjack-dev libsndio-dev qt6-base-dev qt6-tools-dev
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 alsa-lib-devel cmake libatomic libevdev-devel libudev-devel openal-devel qt6-qtbase-devel qt6-qtbase-private-devel vulkan-devel pipewire-jack-audio-connection-kit-devel qt6-qtmultimedia-devel qt6-qtsvg-devel
sudo dnf install clang cmake libatomic alsa-lib-devel pipewire-jack-audio-connection-kit-devel openal-devel openssl-devel libevdev-devel libudev-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 openal cmake vulkan-validation-layers qt6-base qt6-declarative qt6-multimedia sdl2 sndio jack2 base-devel
sudo pacman -S base-devel clang git cmake sndio jack2 openal qt6-base qt6-declarative qt6-multimedia sdl2 vulkan-validation-layers
```
#### OpenSUSE
```
sudo zypper install git cmake libasound2 libpulse-devel openal-soft-devel zlib-devel libedit-devel vulkan-devel libudev-devel libqt6-qtbase-devel libqt6-qtmultimedia-devel libqt6-qtsvg-devel libQt6Gui-private-headers-devel libevdev-devel libsndio7_1 libjack-devel
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:
@ -34,9 +34,11 @@ git clone --recursive https://github.com/shadps4-emu/shadPS4.git
cd shadPS4
```
Generate the build directory in the shadPS4 directory. To enable the QT GUI, pass the ```-DENABLE_QT_GUI=ON``` flag:
Generate the build directory in the shadPS4 directory. To disable the QT GUI, remove the ```-DENABLE_QT_GUI=ON``` flag:
**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
cmake -S . -B build/ -DENABLE_QT_GUI=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
```
Enter the directory:

View file

@ -101,14 +101,14 @@ s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) {
return 0;
}
// TODO mixing channels
int result = SDL_PutAudioStreamData(port.stream, ptr,
port.samples_num * port.sample_size * port.channels_num);
SDL_bool result = SDL_PutAudioStreamData(
port.stream, ptr, port.samples_num * port.sample_size * port.channels_num);
// TODO find a correct value 8192 is estimated
while (SDL_GetAudioStreamAvailable(port.stream) > 65536) {
SDL_Delay(0);
}
return result;
return result ? ORBIS_OK : -1;
}
bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) {

View file

@ -192,8 +192,9 @@ int IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileS
#endif
if (!IsOpen()) {
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}",
PathToUTF8String(file_path));
const auto ec = std::error_code{result, std::generic_category()};
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, error_message={}",
PathToUTF8String(file_path), ec.message());
}
return result;
@ -372,6 +373,18 @@ bool IOFile::Seek(s64 offset, SeekOrigin origin) const {
return false;
}
u64 size = GetSize();
if (origin == SeekOrigin::CurrentPosition && Tell() + offset > size) {
LOG_ERROR(Common_Filesystem, "Seeking past the end of the file");
return false;
} else if (origin == SeekOrigin::SetOrigin && (u64)offset > size) {
LOG_ERROR(Common_Filesystem, "Seeking past the end of the file");
return false;
} else if (origin == SeekOrigin::End && offset > 0) {
LOG_ERROR(Common_Filesystem, "Seeking past the end of the file");
return false;
}
errno = 0;
const auto seek_result = fseeko(file, offset, ToSeekOrigin(origin)) == 0;

View file

@ -44,7 +44,7 @@ PKG::PKG() = default;
PKG::~PKG() = default;
bool PKG::Open(const std::filesystem::path& filepath) {
bool PKG::Open(const std::filesystem::path& filepath, std::string& failreason) {
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
if (!file.IsOpen()) {
return false;
@ -70,7 +70,11 @@ bool PKG::Open(const std::filesystem::path& filepath) {
u32 offset = pkgheader.pkg_table_entry_offset;
u32 n_files = pkgheader.pkg_table_entry_count;
file.Seek(offset);
if (!file.Seek(offset)) {
failreason = "Failed to seek to PKG table entry offset";
return false;
}
for (int i = 0; i < n_files; i++) {
PKGEntry entry{};
file.Read(entry.id);
@ -85,7 +89,10 @@ bool PKG::Open(const std::filesystem::path& filepath) {
const auto name = GetEntryNameByType(entry.id);
if (name == "param.sfo") {
sfo.clear();
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to param.sfo offset";
return false;
}
sfo.resize(entry.size);
file.ReadRaw<u8>(sfo.data(), entry.size);
}
@ -127,7 +134,11 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
std::array<std::array<u8, 256>, 7> key1;
std::array<u8, 256> imgkeydata;
file.Seek(offset);
if (!file.Seek(offset)) {
failreason = "Failed to seek to PKG table entry offset";
return false;
}
for (int i = 0; i < n_files; i++) {
PKGEntry entry{};
file.Read(entry.id);
@ -149,7 +160,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
// Just print with id
Common::FS::IOFile out(extract_path / "sce_sys" / std::to_string(entry.id),
Common::FS::FileAccessMode::Write);
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to PKG entry offset";
return false;
}
std::vector<u8> data;
data.resize(entry.size);
@ -195,7 +209,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
}
Common::FS::IOFile out(extract_path / "sce_sys" / name, Common::FS::FileAccessMode::Write);
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to PKG entry offset";
return false;
}
std::vector<u8> data;
data.resize(entry.size);
@ -207,7 +224,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
if (entry.id == 0x400 || entry.id == 0x401 || entry.id == 0x402 ||
entry.id == 0x403) { // somehow 0x401 is not decrypting
decNp.resize(entry.size);
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to PKG entry offset";
return false;
}
std::vector<u8> data;
data.resize(entry.size);
@ -237,7 +257,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
// Read the seed
std::array<u8, 16> seed;
file.Seek(pkgheader.pfs_image_offset + 0x370);
if (!file.Seek(pkgheader.pfs_image_offset + 0x370)) {
failreason = "Failed to seek to PFS image offset";
return false;
}
file.Read(seed);
// Get data and tweak keys.

View file

@ -103,7 +103,7 @@ public:
PKG();
~PKG();
bool Open(const std::filesystem::path& filepath);
bool Open(const std::filesystem::path& filepath, std::string& failreason);
void ExtractFiles(const int index);
bool Extract(const std::filesystem::path& filepath, const std::filesystem::path& extract,
std::string& failreason);

View file

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "common/path_util.h"
#include "trp.h"
@ -13,7 +14,10 @@ void TRP::GetNPcommID(const std::filesystem::path& trophyPath, int index) {
if (!npbindFile.IsOpen()) {
return;
}
npbindFile.Seek(0x84 + (index * 0x180));
if (!npbindFile.Seek(0x84 + (index * 0x180))) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to NPbind offset");
return;
}
npbindFile.ReadRaw<u8>(np_comm_id.data(), 12);
std::fill(np_comm_id.begin() + 12, np_comm_id.end(), 0); // fill with 0, we need 16 bytes.
}
@ -56,26 +60,38 @@ bool TRP::Extract(const std::filesystem::path& trophyPath) {
std::filesystem::create_directory(trpFilesPath / "Xml");
for (int i = 0; i < header.entry_num; i++) {
file.Seek(seekPos);
if (!file.Seek(seekPos)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry offset");
return false;
}
seekPos += (s64)header.entry_size;
TrpEntry entry;
file.Read(entry);
std::string_view name(entry.entry_name);
if (entry.flag == 0 && name.find("TROP") != std::string::npos) { // PNG
file.Seek(entry.entry_pos);
if (file.Seek(entry.entry_pos)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry offset");
return false;
}
std::vector<u8> icon(entry.entry_len);
file.Read(icon);
Common::FS::IOFile::WriteBytes(trpFilesPath / "Icons" / name, icon);
}
if (entry.flag == 3 && np_comm_id[0] == 'N' &&
np_comm_id[1] == 'P') { // ESFM, encrypted.
file.Seek(entry.entry_pos);
if (file.Seek(entry.entry_pos)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry offset");
return false;
}
file.Read(esfmIv); // get iv key.
// Skip the first 16 bytes which are the iv key on every entry as we want a
// clean xml file.
std::vector<u8> ESFM(entry.entry_len - iv_len);
std::vector<u8> XML(entry.entry_len - iv_len);
file.Seek(entry.entry_pos + iv_len);
if (file.Seek(entry.entry_pos + iv_len)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry + iv offset");
return false;
}
file.Read(ESFM);
crypto.decryptEFSM(np_comm_id, esfmIv, ESFM, XML); // decrypt
removePadding(XML);

View file

@ -229,7 +229,10 @@ s64 PS4_SYSV_ABI sceKernelLseek(int d, s64 offset, int whence) {
}
std::scoped_lock lk{file->m_mutex};
file->f.Seek(offset, origin);
if (!file->f.Seek(offset, origin)) {
LOG_CRITICAL(Kernel_Fs, "sceKernelLseek: failed to seek");
return SCE_KERNEL_ERROR_EINVAL;
}
return file->f.Tell();
}
@ -311,6 +314,58 @@ int PS4_SYSV_ABI posix_mkdir(const char* path, u16 mode) {
return result;
}
int PS4_SYSV_ABI sceKernelRmdir(const char* path) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
bool ro = false;
const std::filesystem::path dir_name = mnt->GetHostPath(path, &ro);
if (dir_name.empty()) {
LOG_INFO(Kernel_Fs, "Failed to remove directory: {}, permission denied",
fmt::UTF(dir_name.u8string()));
return SCE_KERNEL_ERROR_EACCES;
}
if (ro) {
LOG_INFO(Kernel_Fs, "Failed to remove directory: {}, directory is read only",
fmt::UTF(dir_name.u8string()));
return SCE_KERNEL_ERROR_EROFS;
}
if (!std::filesystem::is_directory(dir_name)) {
LOG_INFO(Kernel_Fs, "Failed to remove directory: {}, path is not a directory",
fmt::UTF(dir_name.u8string()));
return ORBIS_KERNEL_ERROR_ENOTDIR;
}
if (!std::filesystem::exists(dir_name)) {
LOG_INFO(Kernel_Fs, "Failed to remove directory: {}, no such file or directory",
fmt::UTF(dir_name.u8string()));
return ORBIS_KERNEL_ERROR_ENOENT;
}
std::error_code ec;
int result = std::filesystem::remove_all(dir_name, ec);
if (!ec) {
LOG_DEBUG(Kernel_Fs, "Removed directory: {}", fmt::UTF(dir_name.u8string()));
return ORBIS_OK;
}
LOG_ERROR(Kernel_Fs, "Failed to remove directory: {}, error_code={}",
fmt::UTF(dir_name.u8string()), ec.message());
return ErrnoToSceKernelError(ec.value());
}
int PS4_SYSV_ABI posix_rmdir(const char* path) {
int result = sceKernelRmdir(path);
if (result < 0) {
LOG_ERROR(Kernel_Pthread, "posix_rmdir: error = {}", result);
ErrSceToPosix(result);
return -1;
}
return result;
}
int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) {
LOG_INFO(Kernel_Fs, "(PARTIAL) path = {}", path);
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
@ -380,7 +435,10 @@ s64 PS4_SYSV_ABI sceKernelPread(int d, void* buf, size_t nbytes, s64 offset) {
SCOPE_EXIT {
file->f.Seek(pos);
};
file->f.Seek(offset);
if (!file->f.Seek(offset)) {
LOG_CRITICAL(Kernel_Fs, "sceKernelPread: failed to seek");
return ORBIS_KERNEL_ERROR_EINVAL;
}
return file->f.ReadRaw<u8>(buf, nbytes);
}
@ -514,7 +572,10 @@ s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) {
SCOPE_EXIT {
file->f.Seek(pos);
};
file->f.Seek(offset);
if (!file->f.Seek(offset)) {
LOG_CRITICAL(Kernel_Fs, "sceKernelPwrite: failed to seek");
return ORBIS_KERNEL_ERROR_EINVAL;
}
return file->f.WriteRaw<u8>(buf, nbytes);
}
@ -565,6 +626,8 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("AqBioC2vF3I", "libScePosix", 1, "libkernel", 1, 1, posix_read);
LIB_FUNCTION("1-LFLmRFxxM", "libkernel", 1, "libkernel", 1, 1, sceKernelMkdir);
LIB_FUNCTION("JGMio+21L4c", "libScePosix", 1, "libkernel", 1, 1, posix_mkdir);
LIB_FUNCTION("naInUjYt3so", "libkernel", 1, "libkernel", 1, 1, sceKernelRmdir);
LIB_FUNCTION("c7ZnT7V1B98", "libScePosix", 1, "libkernel", 1, 1, posix_rmdir);
LIB_FUNCTION("eV9wAD2riIA", "libkernel", 1, "libkernel", 1, 1, sceKernelStat);
LIB_FUNCTION("kBwCPsYX-m4", "libkernel", 1, "libkernel", 1, 1, sceKernelFStat);
LIB_FUNCTION("mqQMh1zPPT8", "libScePosix", 1, "libkernel", 1, 1, posix_fstat);

View file

@ -204,7 +204,10 @@ void Elf::Open(const std::filesystem::path& file_name) {
}
out.resize(num);
m_f.Seek(offset, SeekOrigin::SetOrigin);
if (!m_f.Seek(offset, SeekOrigin::SetOrigin)) {
LOG_CRITICAL(Loader, "Failed to seek to header tables");
return;
}
m_f.Read(out);
};
@ -465,7 +468,10 @@ std::string Elf::ElfPHeaderStr(u16 no) {
void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) {
if (!is_self) {
// It's elf file
m_f.Seek(file_offset, SeekOrigin::SetOrigin);
if (!m_f.Seek(file_offset, SeekOrigin::SetOrigin)) {
LOG_CRITICAL(Loader, "Failed to seek to ELF header");
return;
}
m_f.ReadRaw<u8>(reinterpret_cast<u8*>(virtual_addr), size);
return;
}
@ -479,7 +485,10 @@ void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) {
if (file_offset >= phdr.p_offset && file_offset < phdr.p_offset + phdr.p_filesz) {
auto offset = file_offset - phdr.p_offset;
m_f.Seek(offset + seg.file_offset, SeekOrigin::SetOrigin);
if (!m_f.Seek(offset + seg.file_offset, SeekOrigin::SetOrigin)) {
LOG_CRITICAL(Loader, "Failed to seek to segment");
return;
}
m_f.ReadRaw<u8>(reinterpret_cast<u8*>(virtual_addr), size);
return;
}

View file

@ -127,7 +127,7 @@ void GameController::SetLightBarRGB(u8 r, u8 g, u8 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) == 0;
(largeMotor / 255.0f) * 0xFFFF, -1);
}
return true;
}

View file

@ -312,10 +312,7 @@ public:
if (selected == &installPackage) {
QStringList pkg_app_ = m_pkg_app_list[itemIndex].split(";;");
std::filesystem::path path(pkg_app_[9].toStdString());
#ifdef _WIN32
path = std::filesystem::path(pkg_app_[9].toStdWString());
#endif
std::filesystem::path path = Common::FS::PathFromQString(pkg_app_[9]);
InstallDragDropPkg(path, 1, 1);
}
}

View file

@ -625,10 +625,7 @@ void MainWindow::InstallPkg() {
int pkgNum = 0;
for (const QString& file : fileNames) {
++pkgNum;
std::filesystem::path path(file.toStdString());
#ifdef _WIN64
path = std::filesystem::path(file.toStdWString());
#endif
std::filesystem::path path = Common::FS::PathFromQString(file);
MainWindow::InstallDragDropPkg(path, pkgNum, nPkg);
}
}
@ -646,10 +643,7 @@ void MainWindow::BootGame() {
QMessageBox::critical(nullptr, tr("Game Boot"),
QString(tr("Only one file can be selected!")));
} else {
std::filesystem::path path(fileNames[0].toStdString());
#ifdef _WIN64
path = std::filesystem::path(fileNames[0].toStdWString());
#endif
std::filesystem::path path = Common::FS::PathFromQString(fileNames[0]);
Core::Emulator emulator;
if (!std::filesystem::exists(path)) {
QMessageBox::critical(nullptr, tr("Run Game"),
@ -663,9 +657,12 @@ void MainWindow::BootGame() {
void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int nPkg) {
if (Loader::DetectFileType(file) == Loader::FileTypes::Pkg) {
pkg = PKG();
pkg.Open(file);
std::string failreason;
pkg = PKG();
if (!pkg.Open(file, failreason)) {
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
return;
}
auto extract_path = Config::getGameInstallDir() / pkg.GetTitleID();
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
QString gameDirPath;

View file

@ -110,10 +110,7 @@ protected:
int nPkg = urlList.size();
for (const QUrl& url : urlList) {
pkgNum++;
std::filesystem::path path(url.toLocalFile().toStdString());
#ifdef _WIN64
path = std::filesystem::path(url.toLocalFile().toStdWString());
#endif
std::filesystem::path path = Common::FS::PathFromQString(url.toLocalFile());
InstallDragDropPkg(path, pkgNum, nPkg);
}
}

View file

@ -104,11 +104,12 @@ void PKGViewer::ProcessPKGInfo() {
m_pkg_patch_list.clear();
m_full_pkg_list.clear();
for (int i = 0; i < m_pkg_list.size(); i++) {
std::filesystem::path path(m_pkg_list[i].toStdString());
#ifdef _WIN32
path = std::filesystem::path(m_pkg_list[i].toStdWString());
#endif
package.Open(path);
std::filesystem::path path = Common::FS::PathFromQString(m_pkg_list[i]);
std::string failreason;
if (!package.Open(path, failreason)) {
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
return;
}
psf.Open(package.sfo);
QString title_name =
QString::fromStdString(std::string{psf.GetString("TITLE").value_or("Unknown")});

View file

@ -70,7 +70,7 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
InitializeEmulatorLanguages();
LoadValuesFromConfig();
defaultTextEdit = tr("Point your mouse at an option to display it's description.");
defaultTextEdit = tr("Point your mouse at an option to display its description.");
ui->descriptionText->setText(defaultTextEdit);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close);

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>وجّه الماوس نحو خيار لعرض وصفه.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Peg musen over et valg for at vise dets beskrivelse.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Bewege die Maus über eine Option, um deren Beschreibung anzuzeigen.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Τοποθετήστε το ποντίκι σας πάνω σε μια επιλογή για να εμφανίσετε την περιγραφή της.</translation>
</message>
<message>

View file

@ -975,8 +975,8 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<translation>Point your mouse at an option to display it's description.</translation>
<source>Point your mouse at an option to display its description.</source>
<translation>Point your mouse at an option to display its description.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="289"/>
@ -1066,7 +1066,7 @@
<message>
<location filename="../settings_dialog.cpp" line="331"/>
<source>vkValidationCheckBox</source>
<translation>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about it's internal state.\nThis will reduce performance and likely change the behavior of emulation.</translation>
<translation>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about its internal state.\nThis will reduce performance and likely change the behavior of emulation.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="333"/>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Coloque el mouse sobre una opción para mostrar su descripción.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>ماوس خود را بر روی یک گزینه قرار دهید تا توضیحات آن نمایش داده شود.</translation>
</message>
<message>
@ -1066,7 +1066,7 @@
<message>
<location filename="../settings_dialog.cpp" line="331"/>
<source>vkValidationCheckBox</source>
<translation>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about it's internal state. This will reduce performance and likely change the behavior of emulation.</translation>
<translation>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about its internal state. This will reduce performance and likely change the behavior of emulation.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="333"/>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Siirrä hiiri vaihtoehdon päälle näyttämään sen kuvaus.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Pointez votre souris sur une option pour afficher sa description.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Helyezze az egérmutatót egy lehetőség fölé, hogy megjelenítse annak leírását.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Arahkan mouse Anda pada opsi untuk menampilkan deskripsinya.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Sposta il mouse su un'opzione per visualizzarne la descrizione.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation></translation>
</message>
<message>

View file

@ -975,8 +975,8 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<translation>Point your mouse at an option to display it's description.</translation>
<source>Point your mouse at an option to display its description.</source>
<translation>Point your mouse at an option to display its description.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="289"/>
@ -1066,7 +1066,7 @@
<message>
<location filename="../settings_dialog.cpp" line="331"/>
<source>vkValidationCheckBox</source>
<translation>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about it's internal state. This will reduce performance and likely change the behavior of emulation.</translation>
<translation>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about its internal state. This will reduce performance and likely change the behavior of emulation.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="333"/>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Žymeklį nukreipkite ant pasirinkimo, kad pamatytumėte jo aprašymą.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Hold musen over et valg for at vise beskrivelsen.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Wijzig de muisaanwijzer naar een optie om de beschrijving weer te geven.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Najedź kursorem na opcję, aby wyświetlić jej opis.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Passe o mouse sobre uma opção para exibir sua descrição.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Indicați mouse-ul asupra unei opțiuni pentru a afișa descrierea acesteia.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Наведите указатель мыши на опцию, чтобы отобразить ее описание.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Hidhni mouse-in mbi një opsion për shfaqur përshkrimin e tij.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Seçenek üzerinde farenizi tutarak ıklamasını görüntüleyin.</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation>Di chuyển chuột đến tùy chọn đ hiển thị tả của .</translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation></translation>
</message>
<message>

View file

@ -975,7 +975,7 @@
</message>
<message>
<location filename="../settings_dialog.cpp" line="72"/>
<source>Point your mouse at an option to display it's description.</source>
<source>Point your mouse at an option to display its description.</source>
<translation></translation>
</message>
<message>

View file

@ -28,10 +28,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
QDir dir(trophyDirQt);
if (!dir.exists()) {
std::filesystem::path path(gameTrpPath_.toStdString());
#ifdef _WIN64
path = std::filesystem::path(gameTrpPath_.toStdWString());
#endif
std::filesystem::path path = Common::FS::PathFromQString(gameTrpPath_);
if (!trp.Extract(path))
return;
}

View file

@ -23,7 +23,7 @@ namespace Frontend {
WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_,
std::string_view window_title)
: width{width_}, height{height_}, controller{controller_} {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
UNREACHABLE_MSG("Failed to initialize SDL video subsystem: {}", SDL_GetError());
}
SDL_InitSubSystem(SDL_INIT_AUDIO);

View file

@ -909,6 +909,8 @@ void Translator::V_CMP_CLASS_F32(const GcnInst& inst) {
switch (inst.dst[1].field) {
case OperandField::VccLo:
return ir.SetVcc(value);
case OperandField::ScalarGPR:
return ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[1].code), value);
default:
UNREACHABLE();
}