mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
Merge branch 'shadps4-emu:main' into fix-bb-lighting
This commit is contained in:
commit
de4eb75cf0
44 changed files with 213 additions and 95 deletions
5
.github/linux-appimage-qt.sh
vendored
5
.github/linux-appimage-qt.sh
vendored
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 të shfaqur përshkrimin e tij.</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -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 açıklamasını görüntüleyin.</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -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ị mô tả của nó.</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue