Merge branch 'main' into main
8
.gitmodules
vendored
|
@ -1,11 +1,3 @@
|
|||
[submodule "externals/cryptopp-cmake"]
|
||||
path = externals/cryptopp-cmake
|
||||
url = https://github.com/shadps4-emu/ext-cryptopp-cmake.git
|
||||
shallow = true
|
||||
[submodule "externals/cryptopp"]
|
||||
path = externals/cryptopp
|
||||
url = https://github.com/shadps4-emu/ext-cryptopp.git
|
||||
shallow = true
|
||||
[submodule "externals/zlib-ng"]
|
||||
path = externals/zlib-ng
|
||||
url = https://github.com/shadps4-emu/ext-zlib-ng.git
|
||||
|
|
|
@ -113,28 +113,39 @@ git_describe(GIT_DESC --always --long --dirty)
|
|||
git_branch_name(GIT_BRANCH)
|
||||
string(TIMESTAMP BUILD_DATE "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
message("start git things")
|
||||
# Try to get the upstream remote and branch
|
||||
message("check for remote and branch")
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref --symbolic-full-name @{u}
|
||||
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
||||
RESULT_VARIABLE GIT_BRANCH_RESULT
|
||||
RESULT_VARIABLE GIT_REMOTE_RESULT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# If there's no upstream set or the command failed, check remote.pushDefault
|
||||
if (GIT_BRANCH_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||
if (GIT_REMOTE_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||
message("check default push")
|
||||
execute_process(
|
||||
COMMAND git config --get remote.pushDefault
|
||||
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
||||
RESULT_VARIABLE GIT_PUSH_DEFAULT_RESULT
|
||||
RESULT_VARIABLE GIT_REMOTE_RESULT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# If remote.pushDefault is not set or fails, default to origin
|
||||
if (GIT_PUSH_DEFAULT_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||
set(GIT_REMOTE_NAME "origin")
|
||||
endif()
|
||||
# If running in GitHub Actions and the above fails
|
||||
if (GIT_REMOTE_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||
message("check github")
|
||||
set(GIT_REMOTE_NAME "origin")
|
||||
|
||||
if (DEFINED ENV{GITHUB_HEAD_REF}) # PR branch name
|
||||
set(GIT_BRANCH "pr-$ENV{GITHUB_HEAD_REF}")
|
||||
elseif (DEFINED ENV{GITHUB_REF}) # Normal branch name
|
||||
string(REGEX REPLACE "^refs/[^/]*/" "" GIT_BRANCH "$ENV{GITHUB_REF}")
|
||||
else()
|
||||
message("couldn't find branch")
|
||||
set(GIT_BRANCH "detached-head")
|
||||
endif()
|
||||
else()
|
||||
# Extract remote name if the output contains a remote/branch format
|
||||
|
@ -148,6 +159,7 @@ else()
|
|||
endif()
|
||||
|
||||
# Get remote link
|
||||
message("getting remote link")
|
||||
execute_process(
|
||||
COMMAND git config --get remote.${GIT_REMOTE_NAME}.url
|
||||
OUTPUT_VARIABLE GIT_REMOTE_URL
|
||||
|
@ -156,6 +168,8 @@ execute_process(
|
|||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY)
|
||||
|
||||
message("end git things, remote: ${GIT_REMOTE_NAME}, branch: ${GIT_BRANCH}")
|
||||
|
||||
find_package(Boost 1.84.0 CONFIG)
|
||||
find_package(FFmpeg 5.1.2 MODULE)
|
||||
find_package(fmt 10.2.0 CONFIG)
|
||||
|
@ -378,6 +392,24 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
|||
src/core/libraries/ngs2/ngs2_error.h
|
||||
src/core/libraries/ngs2/ngs2_impl.cpp
|
||||
src/core/libraries/ngs2/ngs2_impl.h
|
||||
src/core/libraries/ngs2/ngs2_custom.cpp
|
||||
src/core/libraries/ngs2/ngs2_custom.h
|
||||
src/core/libraries/ngs2/ngs2_reverb.cpp
|
||||
src/core/libraries/ngs2/ngs2_reverb.h
|
||||
src/core/libraries/ngs2/ngs2_geom.cpp
|
||||
src/core/libraries/ngs2/ngs2_geom.h
|
||||
src/core/libraries/ngs2/ngs2_pan.cpp
|
||||
src/core/libraries/ngs2/ngs2_pan.h
|
||||
src/core/libraries/ngs2/ngs2_report.cpp
|
||||
src/core/libraries/ngs2/ngs2_report.h
|
||||
src/core/libraries/ngs2/ngs2_eq.cpp
|
||||
src/core/libraries/ngs2/ngs2_eq.h
|
||||
src/core/libraries/ngs2/ngs2_mastering.cpp
|
||||
src/core/libraries/ngs2/ngs2_mastering.h
|
||||
src/core/libraries/ngs2/ngs2_sampler.cpp
|
||||
src/core/libraries/ngs2/ngs2_sampler.h
|
||||
src/core/libraries/ngs2/ngs2_submixer.cpp
|
||||
src/core/libraries/ngs2/ngs2_submixer.h
|
||||
src/core/libraries/ajm/ajm_error.h
|
||||
src/core/libraries/audio3d/audio3d.cpp
|
||||
src/core/libraries/audio3d/audio3d.h
|
||||
|
@ -551,6 +583,7 @@ set(COMMON src/common/logging/backend.cpp
|
|||
src/common/logging/text_formatter.cpp
|
||||
src/common/logging/text_formatter.h
|
||||
src/common/logging/types.h
|
||||
src/common/aes.h
|
||||
src/common/alignment.h
|
||||
src/common/arch.h
|
||||
src/common/assert.cpp
|
||||
|
@ -582,6 +615,7 @@ set(COMMON src/common/logging/backend.cpp
|
|||
src/common/polyfill_thread.h
|
||||
src/common/rdtsc.cpp
|
||||
src/common/rdtsc.h
|
||||
src/common/sha1.h
|
||||
src/common/signal_context.h
|
||||
src/common/signal_context.cpp
|
||||
src/common/singleton.h
|
||||
|
@ -621,9 +655,6 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||
src/core/aerolib/aerolib.h
|
||||
src/core/address_space.cpp
|
||||
src/core/address_space.h
|
||||
src/core/crypto/crypto.cpp
|
||||
src/core/crypto/crypto.h
|
||||
src/core/crypto/keys.h
|
||||
src/core/devices/base_device.cpp
|
||||
src/core/devices/base_device.h
|
||||
src/core/devices/ioccom.h
|
||||
|
@ -641,10 +672,6 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||
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
|
||||
src/core/file_format/pkg_type.cpp
|
||||
src/core/file_format/pkg_type.h
|
||||
src/core/file_format/psf.cpp
|
||||
src/core/file_format/psf.h
|
||||
src/core/file_format/playgo_chunk.cpp
|
||||
|
@ -653,8 +680,6 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||
src/core/file_format/trp.h
|
||||
src/core/file_sys/fs.cpp
|
||||
src/core/file_sys/fs.h
|
||||
src/core/loader.cpp
|
||||
src/core/loader.h
|
||||
src/core/loader/dwarf.cpp
|
||||
src/core/loader/dwarf.h
|
||||
src/core/loader/elf.cpp
|
||||
|
@ -944,10 +969,6 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
|||
src/qt_gui/game_grid_frame.h
|
||||
src/qt_gui/game_install_dialog.cpp
|
||||
src/qt_gui/game_install_dialog.h
|
||||
src/qt_gui/install_dir_select.cpp
|
||||
src/qt_gui/install_dir_select.h
|
||||
src/qt_gui/pkg_viewer.cpp
|
||||
src/qt_gui/pkg_viewer.h
|
||||
src/qt_gui/trophy_viewer.cpp
|
||||
src/qt_gui/trophy_viewer.h
|
||||
src/qt_gui/elf_viewer.cpp
|
||||
|
@ -1003,7 +1024,7 @@ endif()
|
|||
create_target_directory_groups(shadps4)
|
||||
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers cryptopp::cryptopp)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers)
|
||||
|
||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
||||
|
|
|
@ -49,8 +49,10 @@ path = [
|
|||
"src/images/pause_icon.png",
|
||||
"src/images/play_icon.png",
|
||||
"src/images/ps4_controller.png",
|
||||
"src/images/refresh_icon.png",
|
||||
"src/images/restart_game_icon.png",
|
||||
"src/images/refreshlist_icon.png",
|
||||
"src/images/settings_icon.png",
|
||||
"src/images/fullscreen_icon.png",
|
||||
"src/images/stop_icon.png",
|
||||
"src/images/utils_icon.png",
|
||||
"src/images/shadPS4.icns",
|
||||
|
|
Before Width: | Height: | Size: 658 KiB |
|
@ -13,7 +13,6 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
- [**RAM**](#ram)
|
||||
- [**OS**](#os)
|
||||
- [**Have the latest WIP version**](#how-to-run-the-latest-work-in-progress-builds-of-shadps4)
|
||||
- [**Install PKG files (Games and Updates)**](#install-pkg-files)
|
||||
- [**Configure the emulator**](#configure-the-emulator)
|
||||
|
||||
## Minimum PC requirements
|
||||
|
@ -48,13 +47,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
||||
2. Once downloaded, extract to its own folder, and run shadPS4's executable from the extracted folder.
|
||||
|
||||
3. Upon first launch, shadPS4 will prompt you to select a folder to store your installed games in. Select "Browse" and then select a folder that shadPS4 can use to install your PKG files to.
|
||||
|
||||
## Install PKG files
|
||||
|
||||
To install PKG files (game and updates), you will need the Qt application (with UI). You will have to go to "File" then to "Install Packages (PKG)", a window will open then you will have to select the files. You can install multiple PKG files at once. Once finished, the game should appear in the application.
|
||||
|
||||
<img src="https://github.com/shadps4-emu/shadPS4/blob/main/documents/Quickstart/2.png" width="800">
|
||||
3. Upon first launch, shadPS4 will prompt you to select a folder to store your installed games in. Select "Browse" and then select a folder that contains your dumped games.
|
||||
|
||||
## Configure the emulator
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ Now run the emulator. If Qt was enabled at configure time:
|
|||
./build/shadps4
|
||||
```
|
||||
|
||||
Otherwise, specify the path to your PKG's boot file:
|
||||
Otherwise, specify the path to your game's boot file:
|
||||
|
||||
```bash
|
||||
./build/shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
|
||||
|
|
16
externals/CMakeLists.txt
vendored
|
@ -26,21 +26,7 @@ if (NOT TARGET fmt::fmt)
|
|||
add_subdirectory(fmt)
|
||||
endif()
|
||||
|
||||
# CryptoPP
|
||||
if (NOT TARGET cryptopp::cryptopp)
|
||||
set(CRYPTOPP_INSTALL OFF)
|
||||
set(CRYPTOPP_BUILD_TESTING OFF)
|
||||
set(CRYPTOPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp)
|
||||
# cryptopp instruction set checks do not account for added compile options,
|
||||
# so disable extensions in the library config to match our chosen target CPU.
|
||||
set(CRYPTOPP_DISABLE_AESNI ON)
|
||||
set(CRYPTOPP_DISABLE_AVX2 ON)
|
||||
add_subdirectory(cryptopp-cmake)
|
||||
file(COPY cryptopp DESTINATION cryptopp FILES_MATCHING PATTERN "*.h")
|
||||
# remove externals/cryptopp from include directories because it contains a conflicting zlib.h file
|
||||
set_target_properties(cryptopp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/cryptopp")
|
||||
endif()
|
||||
|
||||
# FFmpeg
|
||||
if (NOT TARGET FFmpeg::ffmpeg)
|
||||
add_subdirectory(ffmpeg-core)
|
||||
add_library(FFmpeg::ffmpeg ALIAS ffmpeg)
|
||||
|
|
1
externals/cryptopp
vendored
|
@ -1 +0,0 @@
|
|||
Subproject commit effed0d0b865afc23ed67e0916f83734e4b9b3b7
|
1
externals/cryptopp-cmake
vendored
|
@ -1 +0,0 @@
|
|||
Subproject commit 2c384c28265a93358a2455e610e76393358794df
|
1195
src/common/aes.h
Normal file
|
@ -32,6 +32,7 @@ std::filesystem::path find_fs_path_or(const basic_value<TC>& v, const K& ky,
|
|||
namespace Config {
|
||||
|
||||
static bool isNeo = false;
|
||||
static bool isDevKit = false;
|
||||
static bool playBGM = false;
|
||||
static bool isTrophyPopupDisabled = false;
|
||||
static int BGMvolume = 50;
|
||||
|
@ -40,7 +41,7 @@ static u32 screenWidth = 1280;
|
|||
static u32 screenHeight = 720;
|
||||
static s32 gpuId = -1; // Vulkan physical device index. Set to negative for auto select
|
||||
static std::string logFilter;
|
||||
static std::string logType = "async";
|
||||
static std::string logType = "sync";
|
||||
static std::string userName = "shadPS4";
|
||||
static std::string updateChannel;
|
||||
static std::string chooseHomeTab;
|
||||
|
@ -97,7 +98,6 @@ u32 m_slider_pos_grid = 0;
|
|||
u32 m_table_mode = 0;
|
||||
u32 m_window_size_W = 1280;
|
||||
u32 m_window_size_H = 720;
|
||||
std::vector<std::string> m_pkg_viewer;
|
||||
std::vector<std::string> m_elf_viewer;
|
||||
std::vector<std::string> m_recent_files;
|
||||
std::string emulator_language = "en_US";
|
||||
|
@ -106,6 +106,7 @@ static bool showBackgroundImage = true;
|
|||
static bool isFullscreen = false;
|
||||
static std::string fullscreenMode = "Windowed";
|
||||
static bool isHDRAllowed = false;
|
||||
static bool showLabelsUnderIcons = true;
|
||||
|
||||
// Language
|
||||
u32 m_language = 1; // english
|
||||
|
@ -167,10 +168,22 @@ bool isNeoModeConsole() {
|
|||
return isNeo;
|
||||
}
|
||||
|
||||
bool isDevKitConsole() {
|
||||
return isDevKit;
|
||||
}
|
||||
|
||||
bool getIsFullscreen() {
|
||||
return isFullscreen;
|
||||
}
|
||||
|
||||
bool getShowLabelsUnderIcons() {
|
||||
return showLabelsUnderIcons;
|
||||
}
|
||||
|
||||
bool setShowLabelsUnderIcons() {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string getFullscreenMode() {
|
||||
return fullscreenMode;
|
||||
}
|
||||
|
@ -422,6 +435,9 @@ void setVblankDiv(u32 value) {
|
|||
void setIsFullscreen(bool enable) {
|
||||
isFullscreen = enable;
|
||||
}
|
||||
static void setShowLabelsUnderIcons(bool enable) {
|
||||
showLabelsUnderIcons = enable;
|
||||
}
|
||||
|
||||
void setFullscreenMode(std::string mode) {
|
||||
fullscreenMode = mode;
|
||||
|
@ -584,11 +600,6 @@ void setMainWindowHeight(u32 height) {
|
|||
m_window_size_H = height;
|
||||
}
|
||||
|
||||
void setPkgViewer(const std::vector<std::string>& pkgList) {
|
||||
m_pkg_viewer.resize(pkgList.size());
|
||||
m_pkg_viewer = pkgList;
|
||||
}
|
||||
|
||||
void setElfViewer(const std::vector<std::string>& elfList) {
|
||||
m_elf_viewer.resize(elfList.size());
|
||||
m_elf_viewer = elfList;
|
||||
|
@ -692,10 +703,6 @@ u32 getMainWindowHeight() {
|
|||
return m_window_size_H;
|
||||
}
|
||||
|
||||
std::vector<std::string> getPkgViewer() {
|
||||
return m_pkg_viewer;
|
||||
}
|
||||
|
||||
std::vector<std::string> getElfViewer() {
|
||||
return m_elf_viewer;
|
||||
}
|
||||
|
@ -755,6 +762,7 @@ void load(const std::filesystem::path& path) {
|
|||
const toml::value& general = data.at("General");
|
||||
|
||||
isNeo = toml::find_or<bool>(general, "isPS4Pro", false);
|
||||
isDevKit = toml::find_or<bool>(general, "isDevKit", false);
|
||||
playBGM = toml::find_or<bool>(general, "playBGM", false);
|
||||
isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false);
|
||||
trophyNotificationDuration =
|
||||
|
@ -842,7 +850,7 @@ void load(const std::filesystem::path& path) {
|
|||
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
||||
|
||||
const auto install_dir_array =
|
||||
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||
toml::find_or<std::vector<std::u8string>>(gui, "installDirs", {});
|
||||
|
||||
try {
|
||||
install_dirs_enabled = toml::find<std::vector<bool>>(gui, "installDirsEnabled");
|
||||
|
@ -868,7 +876,6 @@ void load(const std::filesystem::path& path) {
|
|||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||
main_window_geometry_w = toml::find_or<int>(gui, "geometry_w", 0);
|
||||
main_window_geometry_h = toml::find_or<int>(gui, "geometry_h", 0);
|
||||
m_pkg_viewer = toml::find_or<std::vector<std::string>>(gui, "pkgDirs", {});
|
||||
m_elf_viewer = toml::find_or<std::vector<std::string>>(gui, "elfDirs", {});
|
||||
m_recent_files = toml::find_or<std::vector<std::string>>(gui, "recentFiles", {});
|
||||
m_table_mode = toml::find_or<int>(gui, "gameTableMode", 0);
|
||||
|
@ -955,6 +962,7 @@ void save(const std::filesystem::path& path) {
|
|||
}
|
||||
|
||||
data["General"]["isPS4Pro"] = isNeo;
|
||||
data["General"]["isDevKit"] = isDevKit;
|
||||
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled;
|
||||
data["General"]["trophyNotificationDuration"] = trophyNotificationDuration;
|
||||
data["General"]["playBGM"] = playBGM;
|
||||
|
@ -1086,7 +1094,6 @@ void saveMainWindow(const std::filesystem::path& path) {
|
|||
data["GUI"]["geometry_y"] = main_window_geometry_y;
|
||||
data["GUI"]["geometry_w"] = main_window_geometry_w;
|
||||
data["GUI"]["geometry_h"] = main_window_geometry_h;
|
||||
data["GUI"]["pkgDirs"] = m_pkg_viewer;
|
||||
data["GUI"]["elfDirs"] = m_elf_viewer;
|
||||
data["GUI"]["recentFiles"] = m_recent_files;
|
||||
|
||||
|
@ -1101,6 +1108,7 @@ void saveMainWindow(const std::filesystem::path& path) {
|
|||
void setDefaultValues() {
|
||||
isHDRAllowed = false;
|
||||
isNeo = false;
|
||||
isDevKit = false;
|
||||
isFullscreen = false;
|
||||
isTrophyPopupDisabled = false;
|
||||
playBGM = false;
|
||||
|
@ -1109,7 +1117,7 @@ void setDefaultValues() {
|
|||
screenWidth = 1280;
|
||||
screenHeight = 720;
|
||||
logFilter = "";
|
||||
logType = "async";
|
||||
logType = "sync";
|
||||
userName = "shadPS4";
|
||||
if (Common::isRelease) {
|
||||
updateChannel = "Release";
|
||||
|
|
|
@ -26,8 +26,11 @@ bool GetLoadGameSizeEnabled();
|
|||
std::filesystem::path GetSaveDataPath();
|
||||
void setLoadGameSizeEnabled(bool enable);
|
||||
bool getIsFullscreen();
|
||||
bool getShowLabelsUnderIcons();
|
||||
bool setShowLabelsUnderIcons();
|
||||
std::string getFullscreenMode();
|
||||
bool isNeoModeConsole();
|
||||
bool isDevKitConsole();
|
||||
bool getPlayBGM();
|
||||
int getBGMvolume();
|
||||
bool getisTrophyPopupDisabled();
|
||||
|
@ -151,7 +154,6 @@ void setSliderPositionGrid(u32 pos);
|
|||
void setTableMode(u32 mode);
|
||||
void setMainWindowWidth(u32 width);
|
||||
void setMainWindowHeight(u32 height);
|
||||
void setPkgViewer(const std::vector<std::string>& pkgList);
|
||||
void setElfViewer(const std::vector<std::string>& elfList);
|
||||
void setRecentFiles(const std::vector<std::string>& recentFiles);
|
||||
void setEmulatorLanguage(std::string language);
|
||||
|
@ -171,7 +173,6 @@ u32 getSliderPositionGrid();
|
|||
u32 getTableMode();
|
||||
u32 getMainWindowWidth();
|
||||
u32 getMainWindowHeight();
|
||||
std::vector<std::string> getPkgViewer();
|
||||
std::vector<std::string> getElfViewer();
|
||||
std::vector<std::string> getRecentFiles();
|
||||
std::string getEmulatorLanguage();
|
||||
|
|
|
@ -125,12 +125,15 @@ namespace {
|
|||
[[nodiscard]] constexpr int ToSeekOrigin(SeekOrigin origin) {
|
||||
switch (origin) {
|
||||
case SeekOrigin::SetOrigin:
|
||||
default:
|
||||
return SEEK_SET;
|
||||
case SeekOrigin::CurrentPosition:
|
||||
return SEEK_CUR;
|
||||
case SeekOrigin::End:
|
||||
return SEEK_END;
|
||||
default:
|
||||
LOG_ERROR(Common_Filesystem, "Unsupported origin {}, defaulting to SEEK_SET",
|
||||
static_cast<u32>(origin));
|
||||
return SEEK_SET;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ enum class SeekOrigin : u32 {
|
|||
SetOrigin, // Seeks from the start of the file.
|
||||
CurrentPosition, // Seeks from the current file pointer position.
|
||||
End, // Seeks from the end of the file.
|
||||
SeekHole, // Seeks from the start of the next hole in the file.
|
||||
SeekData, // Seeks from the start of the next non-hole region in the file.
|
||||
};
|
||||
|
||||
class IOFile final {
|
||||
|
|
180
src/common/sha1.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
// SPDX-FileCopyrightText: 2012 SAURAV MOHAPATRA <mohaps@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace sha1 {
|
||||
class SHA1 {
|
||||
public:
|
||||
typedef uint32_t digest32_t[5];
|
||||
typedef uint8_t digest8_t[20];
|
||||
inline static uint32_t LeftRotate(uint32_t value, size_t count) {
|
||||
return (value << count) ^ (value >> (32 - count));
|
||||
}
|
||||
SHA1() {
|
||||
reset();
|
||||
}
|
||||
virtual ~SHA1() {}
|
||||
SHA1(const SHA1& s) {
|
||||
*this = s;
|
||||
}
|
||||
const SHA1& operator=(const SHA1& s) {
|
||||
memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
|
||||
memcpy(m_block, s.m_block, 64);
|
||||
m_blockByteIndex = s.m_blockByteIndex;
|
||||
m_byteCount = s.m_byteCount;
|
||||
return *this;
|
||||
}
|
||||
SHA1& reset() {
|
||||
m_digest[0] = 0x67452301;
|
||||
m_digest[1] = 0xEFCDAB89;
|
||||
m_digest[2] = 0x98BADCFE;
|
||||
m_digest[3] = 0x10325476;
|
||||
m_digest[4] = 0xC3D2E1F0;
|
||||
m_blockByteIndex = 0;
|
||||
m_byteCount = 0;
|
||||
return *this;
|
||||
}
|
||||
SHA1& processByte(uint8_t octet) {
|
||||
this->m_block[this->m_blockByteIndex++] = octet;
|
||||
++this->m_byteCount;
|
||||
if (m_blockByteIndex == 64) {
|
||||
this->m_blockByteIndex = 0;
|
||||
processBlock();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
SHA1& processBlock(const void* const start, const void* const end) {
|
||||
const uint8_t* begin = static_cast<const uint8_t*>(start);
|
||||
const uint8_t* finish = static_cast<const uint8_t*>(end);
|
||||
while (begin != finish) {
|
||||
processByte(*begin);
|
||||
begin++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
SHA1& processBytes(const void* const data, size_t len) {
|
||||
const uint8_t* block = static_cast<const uint8_t*>(data);
|
||||
processBlock(block, block + len);
|
||||
return *this;
|
||||
}
|
||||
const uint32_t* getDigest(digest32_t digest) {
|
||||
size_t bitCount = this->m_byteCount * 8;
|
||||
processByte(0x80);
|
||||
if (this->m_blockByteIndex > 56) {
|
||||
while (m_blockByteIndex != 0) {
|
||||
processByte(0);
|
||||
}
|
||||
while (m_blockByteIndex < 56) {
|
||||
processByte(0);
|
||||
}
|
||||
} else {
|
||||
while (m_blockByteIndex < 56) {
|
||||
processByte(0);
|
||||
}
|
||||
}
|
||||
processByte(0);
|
||||
processByte(0);
|
||||
processByte(0);
|
||||
processByte(0);
|
||||
processByte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
|
||||
processByte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
|
||||
processByte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
|
||||
processByte(static_cast<unsigned char>((bitCount) & 0xFF));
|
||||
|
||||
memcpy(digest, m_digest, 5 * sizeof(uint32_t));
|
||||
return digest;
|
||||
}
|
||||
const uint8_t* getDigestBytes(digest8_t digest) {
|
||||
digest32_t d32;
|
||||
getDigest(d32);
|
||||
size_t di = 0;
|
||||
digest[di++] = ((d32[0] >> 24) & 0xFF);
|
||||
digest[di++] = ((d32[0] >> 16) & 0xFF);
|
||||
digest[di++] = ((d32[0] >> 8) & 0xFF);
|
||||
digest[di++] = ((d32[0]) & 0xFF);
|
||||
|
||||
digest[di++] = ((d32[1] >> 24) & 0xFF);
|
||||
digest[di++] = ((d32[1] >> 16) & 0xFF);
|
||||
digest[di++] = ((d32[1] >> 8) & 0xFF);
|
||||
digest[di++] = ((d32[1]) & 0xFF);
|
||||
|
||||
digest[di++] = ((d32[2] >> 24) & 0xFF);
|
||||
digest[di++] = ((d32[2] >> 16) & 0xFF);
|
||||
digest[di++] = ((d32[2] >> 8) & 0xFF);
|
||||
digest[di++] = ((d32[2]) & 0xFF);
|
||||
|
||||
digest[di++] = ((d32[3] >> 24) & 0xFF);
|
||||
digest[di++] = ((d32[3] >> 16) & 0xFF);
|
||||
digest[di++] = ((d32[3] >> 8) & 0xFF);
|
||||
digest[di++] = ((d32[3]) & 0xFF);
|
||||
|
||||
digest[di++] = ((d32[4] >> 24) & 0xFF);
|
||||
digest[di++] = ((d32[4] >> 16) & 0xFF);
|
||||
digest[di++] = ((d32[4] >> 8) & 0xFF);
|
||||
digest[di++] = ((d32[4]) & 0xFF);
|
||||
return digest;
|
||||
}
|
||||
|
||||
protected:
|
||||
void processBlock() {
|
||||
uint32_t w[80];
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
w[i] = (m_block[i * 4 + 0] << 24);
|
||||
w[i] |= (m_block[i * 4 + 1] << 16);
|
||||
w[i] |= (m_block[i * 4 + 2] << 8);
|
||||
w[i] |= (m_block[i * 4 + 3]);
|
||||
}
|
||||
for (size_t i = 16; i < 80; i++) {
|
||||
w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
||||
}
|
||||
|
||||
uint32_t a = m_digest[0];
|
||||
uint32_t b = m_digest[1];
|
||||
uint32_t c = m_digest[2];
|
||||
uint32_t d = m_digest[3];
|
||||
uint32_t e = m_digest[4];
|
||||
|
||||
for (std::size_t i = 0; i < 80; ++i) {
|
||||
uint32_t f = 0;
|
||||
uint32_t k = 0;
|
||||
|
||||
if (i < 20) {
|
||||
f = (b & c) | (~b & d);
|
||||
k = 0x5A827999;
|
||||
} else if (i < 40) {
|
||||
f = b ^ c ^ d;
|
||||
k = 0x6ED9EBA1;
|
||||
} else if (i < 60) {
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = 0x8F1BBCDC;
|
||||
} else {
|
||||
f = b ^ c ^ d;
|
||||
k = 0xCA62C1D6;
|
||||
}
|
||||
uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
|
||||
e = d;
|
||||
d = c;
|
||||
c = LeftRotate(b, 30);
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
|
||||
m_digest[0] += a;
|
||||
m_digest[1] += b;
|
||||
m_digest[2] += c;
|
||||
m_digest[3] += d;
|
||||
m_digest[4] += e;
|
||||
}
|
||||
|
||||
private:
|
||||
digest32_t m_digest;
|
||||
uint8_t m_block[64];
|
||||
size_t m_blockByteIndex;
|
||||
size_t m_byteCount;
|
||||
};
|
||||
} // namespace sha1
|
|
@ -1,215 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
|
||||
CryptoPP::InvertibleRSAFunction params;
|
||||
params.SetPrime1(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime1, 0x80));
|
||||
params.SetPrime2(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime2, 0x80));
|
||||
|
||||
params.SetPublicExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PublicExponent, 4));
|
||||
params.SetPrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PrivateExponent, 0x100));
|
||||
|
||||
params.SetModPrime1PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent1, 0x80));
|
||||
params.SetModPrime2PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent2, 0x80));
|
||||
|
||||
params.SetModulus(CryptoPP::Integer(PkgDerivedKey3Keyset::Modulus, 0x100));
|
||||
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||
CryptoPP::Integer(PkgDerivedKey3Keyset::Coefficient, 0x80));
|
||||
|
||||
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
CryptoPP::RSA::PrivateKey Crypto::FakeKeyset_keyset_init() {
|
||||
CryptoPP::InvertibleRSAFunction params;
|
||||
params.SetPrime1(CryptoPP::Integer(FakeKeyset::Prime1, 0x80));
|
||||
params.SetPrime2(CryptoPP::Integer(FakeKeyset::Prime2, 0x80));
|
||||
|
||||
params.SetPublicExponent(CryptoPP::Integer(FakeKeyset::PublicExponent, 4));
|
||||
params.SetPrivateExponent(CryptoPP::Integer(FakeKeyset::PrivateExponent, 0x100));
|
||||
|
||||
params.SetModPrime1PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent1, 0x80));
|
||||
params.SetModPrime2PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent2, 0x80));
|
||||
|
||||
params.SetModulus(CryptoPP::Integer(FakeKeyset::Modulus, 0x100));
|
||||
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||
CryptoPP::Integer(FakeKeyset::Coefficient, 0x80));
|
||||
|
||||
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
CryptoPP::RSA::PrivateKey Crypto::DebugRifKeyset_init() {
|
||||
CryptoPP::InvertibleRSAFunction params;
|
||||
params.SetPrime1(CryptoPP::Integer(DebugRifKeyset::Prime1, sizeof(DebugRifKeyset::Prime1)));
|
||||
params.SetPrime2(CryptoPP::Integer(DebugRifKeyset::Prime2, sizeof(DebugRifKeyset::Prime2)));
|
||||
|
||||
params.SetPublicExponent(
|
||||
CryptoPP::Integer(DebugRifKeyset::PublicExponent, sizeof(DebugRifKeyset::PublicExponent)));
|
||||
params.SetPrivateExponent(CryptoPP::Integer(DebugRifKeyset::PrivateExponent,
|
||||
sizeof(DebugRifKeyset::PrivateExponent)));
|
||||
|
||||
params.SetModPrime1PrivateExponent(
|
||||
CryptoPP::Integer(DebugRifKeyset::Exponent1, sizeof(DebugRifKeyset::Exponent1)));
|
||||
params.SetModPrime2PrivateExponent(
|
||||
CryptoPP::Integer(DebugRifKeyset::Exponent2, sizeof(DebugRifKeyset::Exponent2)));
|
||||
|
||||
params.SetModulus(CryptoPP::Integer(DebugRifKeyset::Modulus, sizeof(DebugRifKeyset::Modulus)));
|
||||
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||
CryptoPP::Integer(DebugRifKeyset::Coefficient, sizeof(DebugRifKeyset::Coefficient)));
|
||||
|
||||
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
void Crypto::RSA2048Decrypt(std::span<CryptoPP::byte, 32> dec_key,
|
||||
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||
bool is_dk3) { // RSAES_PKCS1v15_
|
||||
// Create an RSA decryptor
|
||||
CryptoPP::RSA::PrivateKey privateKey;
|
||||
if (is_dk3) {
|
||||
privateKey = key_pkg_derived_key3_keyset_init();
|
||||
} else {
|
||||
privateKey = FakeKeyset_keyset_init();
|
||||
}
|
||||
|
||||
CryptoPP::RSAES_PKCS1v15_Decryptor rsaDecryptor(privateKey);
|
||||
|
||||
// Allocate memory for the decrypted data
|
||||
std::array<CryptoPP::byte, 256> decrypted;
|
||||
|
||||
// Perform the decryption
|
||||
CryptoPP::AutoSeededRandomPool rng;
|
||||
CryptoPP::DecodingResult result =
|
||||
rsaDecryptor.Decrypt(rng, ciphertext.data(), decrypted.size(), decrypted.data());
|
||||
std::copy(decrypted.begin(), decrypted.begin() + dec_key.size(), dec_key.begin());
|
||||
}
|
||||
|
||||
void Crypto::ivKeyHASH256(std::span<const CryptoPP::byte, 64> cipher_input,
|
||||
std::span<CryptoPP::byte, 32> ivkey_result) {
|
||||
CryptoPP::SHA256 sha256;
|
||||
std::array<CryptoPP::byte, CryptoPP::SHA256::DIGESTSIZE> hashResult;
|
||||
auto array_sink = new CryptoPP::ArraySink(hashResult.data(), CryptoPP::SHA256::DIGESTSIZE);
|
||||
auto filter = new CryptoPP::HashFilter(sha256, array_sink);
|
||||
CryptoPP::ArraySource r(cipher_input.data(), cipher_input.size(), true, filter);
|
||||
std::copy(hashResult.begin(), hashResult.begin() + ivkey_result.size(), ivkey_result.begin());
|
||||
}
|
||||
|
||||
void Crypto::aesCbcCfb128Decrypt(std::span<const CryptoPP::byte, 32> ivkey,
|
||||
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||
std::span<CryptoPP::byte, 256> decrypted) {
|
||||
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> key;
|
||||
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> iv;
|
||||
|
||||
std::copy(ivkey.begin() + 16, ivkey.begin() + 16 + key.size(), key.begin());
|
||||
std::copy(ivkey.begin(), ivkey.begin() + iv.size(), iv.begin());
|
||||
|
||||
CryptoPP::AES::Decryption aesDecryption(key.data(), CryptoPP::AES::DEFAULT_KEYLENGTH);
|
||||
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data());
|
||||
|
||||
for (size_t i = 0; i < decrypted.size(); i += CryptoPP::AES::BLOCKSIZE) {
|
||||
cbcDecryption.ProcessData(decrypted.data() + i, ciphertext.data() + i,
|
||||
CryptoPP::AES::BLOCKSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> ivkey,
|
||||
std::span<CryptoPP::byte> ciphertext,
|
||||
std::span<CryptoPP::byte> decrypted) {
|
||||
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> key;
|
||||
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> iv;
|
||||
|
||||
std::copy(ivkey.begin() + 16, ivkey.begin() + 16 + key.size(), key.begin());
|
||||
std::copy(ivkey.begin(), ivkey.begin() + iv.size(), iv.begin());
|
||||
|
||||
CryptoPP::AES::Decryption aesDecryption(key.data(), CryptoPP::AES::DEFAULT_KEYLENGTH);
|
||||
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data());
|
||||
|
||||
for (size_t i = 0; i < decrypted.size(); i += CryptoPP::AES::BLOCKSIZE) {
|
||||
cbcDecryption.ProcessData(decrypted.data() + i, ciphertext.data() + i,
|
||||
CryptoPP::AES::BLOCKSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::decryptEFSM(std::span<CryptoPP::byte, 16> trophyKey,
|
||||
std::span<CryptoPP::byte, 16> NPcommID,
|
||||
std::span<CryptoPP::byte, 16> efsmIv, std::span<CryptoPP::byte> ciphertext,
|
||||
std::span<CryptoPP::byte> decrypted) {
|
||||
|
||||
// step 1: Encrypt NPcommID
|
||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt;
|
||||
|
||||
std::vector<CryptoPP::byte> trophyIv(16, 0);
|
||||
std::vector<CryptoPP::byte> trpKey(16);
|
||||
|
||||
encrypt.SetKeyWithIV(trophyKey.data(), trophyKey.size(), trophyIv.data());
|
||||
encrypt.ProcessData(trpKey.data(), NPcommID.data(), 16);
|
||||
|
||||
// step 2: decrypt efsm.
|
||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decrypt;
|
||||
decrypt.SetKeyWithIV(trpKey.data(), trpKey.size(), efsmIv.data());
|
||||
|
||||
for (size_t i = 0; i < decrypted.size(); i += CryptoPP::AES::BLOCKSIZE) {
|
||||
decrypt.ProcessData(decrypted.data() + i, ciphertext.data() + i, CryptoPP::AES::BLOCKSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::PfsGenCryptoKey(std::span<const CryptoPP::byte, 32> ekpfs,
|
||||
std::span<const CryptoPP::byte, 16> seed,
|
||||
std::span<CryptoPP::byte, 16> dataKey,
|
||||
std::span<CryptoPP::byte, 16> tweakKey) {
|
||||
CryptoPP::HMAC<CryptoPP::SHA256> hmac(ekpfs.data(), ekpfs.size());
|
||||
|
||||
CryptoPP::SecByteBlock d(20); // Use Crypto++ SecByteBlock for better memory management
|
||||
|
||||
// Copy the bytes of 'index' to the 'd' array
|
||||
uint32_t index = 1;
|
||||
std::memcpy(d, &index, sizeof(uint32_t));
|
||||
|
||||
// Copy the bytes of 'seed' to the 'd' array starting from index 4
|
||||
std::memcpy(d + sizeof(uint32_t), seed.data(), seed.size());
|
||||
|
||||
// Allocate memory for 'u64' using new
|
||||
std::vector<CryptoPP::byte> data_tweak_key(hmac.DigestSize());
|
||||
|
||||
// Calculate the HMAC
|
||||
hmac.CalculateDigest(data_tweak_key.data(), d, d.size());
|
||||
std::copy(data_tweak_key.begin(), data_tweak_key.begin() + dataKey.size(), tweakKey.begin());
|
||||
std::copy(data_tweak_key.begin() + tweakKey.size(),
|
||||
data_tweak_key.begin() + tweakKey.size() + dataKey.size(), dataKey.begin());
|
||||
}
|
||||
|
||||
void Crypto::decryptPFS(std::span<const CryptoPP::byte, 16> dataKey,
|
||||
std::span<const CryptoPP::byte, 16> tweakKey, std::span<const u8> src_image,
|
||||
std::span<CryptoPP::byte> dst_image, u64 sector) {
|
||||
// Start at 0x10000 to keep the header when decrypting the whole pfs_image.
|
||||
for (int i = 0; i < src_image.size(); i += 0x1000) {
|
||||
const u64 current_sector = sector + (i / 0x1000);
|
||||
CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption encrypt(tweakKey.data(), tweakKey.size());
|
||||
CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption decrypt(dataKey.data(), dataKey.size());
|
||||
|
||||
std::array<CryptoPP::byte, 16> tweak{};
|
||||
std::array<CryptoPP::byte, 16> encryptedTweak;
|
||||
std::array<CryptoPP::byte, 16> xorBuffer;
|
||||
std::memcpy(tweak.data(), ¤t_sector, sizeof(u64));
|
||||
|
||||
// Encrypt the tweak for each sector.
|
||||
encrypt.ProcessData(encryptedTweak.data(), tweak.data(), 16);
|
||||
|
||||
for (int plaintextOffset = 0; plaintextOffset < 0x1000; plaintextOffset += 16) {
|
||||
xtsXorBlock(xorBuffer.data(), src_image.data() + i + plaintextOffset,
|
||||
encryptedTweak.data()); // x, c, t
|
||||
decrypt.ProcessData(xorBuffer.data(), xorBuffer.data(), 16); // x, x
|
||||
xtsXorBlock(dst_image.data() + i + plaintextOffset, xorBuffer.data(),
|
||||
encryptedTweak.data()); //(p) c, x , t
|
||||
xtsMult(encryptedTweak);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <cryptopp/aes.h>
|
||||
#include <cryptopp/filters.h>
|
||||
#include <cryptopp/modes.h>
|
||||
#include <cryptopp/oaep.h>
|
||||
#include <cryptopp/osrng.h>
|
||||
#include <cryptopp/rsa.h>
|
||||
#include <cryptopp/sha.h>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "keys.h"
|
||||
|
||||
class Crypto {
|
||||
public:
|
||||
CryptoPP::RSA::PrivateKey key_pkg_derived_key3_keyset_init();
|
||||
CryptoPP::RSA::PrivateKey FakeKeyset_keyset_init();
|
||||
CryptoPP::RSA::PrivateKey DebugRifKeyset_init();
|
||||
|
||||
void RSA2048Decrypt(std::span<CryptoPP::byte, 32> dk3,
|
||||
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||
bool is_dk3); // RSAES_PKCS1v15_
|
||||
void ivKeyHASH256(std::span<const CryptoPP::byte, 64> cipher_input,
|
||||
std::span<CryptoPP::byte, 32> ivkey_result);
|
||||
void aesCbcCfb128Decrypt(std::span<const CryptoPP::byte, 32> ivkey,
|
||||
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||
std::span<CryptoPP::byte, 256> decrypted);
|
||||
void aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> ivkey,
|
||||
std::span<CryptoPP::byte> ciphertext,
|
||||
std::span<CryptoPP::byte> decrypted);
|
||||
void decryptEFSM(std::span<CryptoPP::byte, 16> trophyKey,
|
||||
std::span<CryptoPP::byte, 16> NPcommID, std::span<CryptoPP::byte, 16> efsmIv,
|
||||
std::span<CryptoPP::byte> ciphertext, std::span<CryptoPP::byte> decrypted);
|
||||
void PfsGenCryptoKey(std::span<const CryptoPP::byte, 32> ekpfs,
|
||||
std::span<const CryptoPP::byte, 16> seed,
|
||||
std::span<CryptoPP::byte, 16> dataKey,
|
||||
std::span<CryptoPP::byte, 16> tweakKey);
|
||||
void decryptPFS(std::span<const CryptoPP::byte, 16> dataKey,
|
||||
std::span<const CryptoPP::byte, 16> tweakKey, std::span<const u8> src_image,
|
||||
std::span<CryptoPP::byte> dst_image, u64 sector);
|
||||
|
||||
void xtsXorBlock(CryptoPP::byte* x, const CryptoPP::byte* a, const CryptoPP::byte* b) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
x[i] = a[i] ^ b[i];
|
||||
}
|
||||
}
|
||||
|
||||
void xtsMult(std::span<CryptoPP::byte, 16> encryptedTweak) {
|
||||
int feedback = 0;
|
||||
for (int k = 0; k < encryptedTweak.size(); k++) {
|
||||
const auto tmp = (encryptedTweak[k] >> 7) & 1;
|
||||
encryptedTweak[k] = ((encryptedTweak[k] << 1) + feedback) & 0xFF;
|
||||
feedback = tmp;
|
||||
}
|
||||
if (feedback != 0) {
|
||||
encryptedTweak[0] ^= 0x87;
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,305 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
#include <cryptopp/rsa.h>
|
||||
|
||||
class FakeKeyset {
|
||||
public:
|
||||
// Constructor
|
||||
static constexpr CryptoPP::byte Exponent1[] = {
|
||||
0x6D, 0x48, 0xE0, 0x54, 0x40, 0x25, 0xC8, 0x41, 0x29, 0x52, 0x42, 0x27, 0xEB, 0xD2, 0xC7,
|
||||
0xAB, 0x6B, 0x9C, 0x27, 0x0A, 0xB4, 0x1F, 0x94, 0x4E, 0xFA, 0x42, 0x1D, 0xB7, 0xBC, 0xB9,
|
||||
0xAE, 0xBC, 0x04, 0x6F, 0x75, 0x8F, 0x10, 0x5F, 0x89, 0xAC, 0xAB, 0x9C, 0xD2, 0xFA, 0xE6,
|
||||
0xA4, 0x13, 0x83, 0x68, 0xD4, 0x56, 0x38, 0xFE, 0xE5, 0x2B, 0x78, 0x44, 0x9C, 0x34, 0xE6,
|
||||
0x5A, 0xA0, 0xBE, 0x05, 0x70, 0xAD, 0x15, 0xC3, 0x2D, 0x31, 0xAC, 0x97, 0x5D, 0x88, 0xFC,
|
||||
0xC1, 0x62, 0x3D, 0xE2, 0xED, 0x11, 0xDB, 0xB6, 0x9E, 0xFC, 0x5A, 0x5A, 0x03, 0xF6, 0xCF,
|
||||
0x08, 0xD4, 0x5D, 0x90, 0xC9, 0x2A, 0xB9, 0x9B, 0xCF, 0xC8, 0x1A, 0x65, 0xF3, 0x5B, 0xE8,
|
||||
0x7F, 0xCF, 0xA5, 0xA6, 0x4C, 0x5C, 0x2A, 0x12, 0x0F, 0x92, 0xA5, 0xE3, 0xF0, 0x17, 0x1E,
|
||||
0x9A, 0x97, 0x45, 0x86, 0xFD, 0xDB, 0x54, 0x25};
|
||||
// exponent2 = d mod (q - 1)
|
||||
static constexpr CryptoPP::byte Exponent2[] = {
|
||||
0x2A, 0x51, 0xCE, 0x02, 0x44, 0x28, 0x50, 0xE8, 0x30, 0x20, 0x7C, 0x9C, 0x55, 0xBF, 0x60,
|
||||
0x39, 0xBC, 0xD1, 0xF0, 0xE7, 0x68, 0xF8, 0x08, 0x5B, 0x61, 0x1F, 0xA7, 0xBF, 0xD0, 0xE8,
|
||||
0x8B, 0xB5, 0xB1, 0xD5, 0xD9, 0x16, 0xAC, 0x75, 0x0C, 0x6D, 0xF2, 0xE0, 0xB5, 0x97, 0x75,
|
||||
0xD2, 0x68, 0x16, 0x1F, 0x00, 0x7D, 0x8B, 0x17, 0xE8, 0x78, 0x48, 0x41, 0x71, 0x2B, 0x18,
|
||||
0x96, 0x80, 0x11, 0xDB, 0x68, 0x39, 0x9C, 0xD6, 0xE0, 0x72, 0x42, 0x86, 0xF0, 0x1B, 0x16,
|
||||
0x0D, 0x3E, 0x12, 0x94, 0x3D, 0x25, 0xA8, 0xA9, 0x30, 0x9E, 0x54, 0x5A, 0xD6, 0x36, 0x6C,
|
||||
0xD6, 0x8C, 0x20, 0x62, 0x8F, 0xA1, 0x6B, 0x1F, 0x7C, 0x6D, 0xB2, 0xB1, 0xC1, 0x2E, 0xAD,
|
||||
0x36, 0x02, 0x9C, 0x3A, 0xCA, 0x2F, 0x09, 0xD2, 0x45, 0x9E, 0xEB, 0xF2, 0xBC, 0x6C, 0xAA,
|
||||
0x3B, 0x3E, 0x90, 0xBC, 0x38, 0x67, 0x35, 0x4D};
|
||||
// e
|
||||
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1};
|
||||
// (InverseQ)(q) = 1 mod p
|
||||
static constexpr CryptoPP::byte Coefficient[] = {
|
||||
0x0B, 0x67, 0x1C, 0x0D, 0x6C, 0x57, 0xD3, 0xE7, 0x05, 0x65, 0x94, 0x31, 0x56, 0x55, 0xFD,
|
||||
0x28, 0x08, 0xFA, 0x05, 0x8A, 0xCC, 0x55, 0x39, 0x61, 0x97, 0x63, 0xA0, 0x16, 0x27, 0x3D,
|
||||
0xED, 0xC1, 0x16, 0x40, 0x2A, 0x12, 0xEA, 0x6F, 0xD9, 0xD8, 0x58, 0x56, 0xA8, 0x56, 0x8B,
|
||||
0x0D, 0x38, 0x5E, 0x1E, 0x80, 0x3B, 0x5F, 0x40, 0x80, 0x6F, 0x62, 0x4F, 0x28, 0xA2, 0x69,
|
||||
0xF3, 0xD3, 0xF7, 0xFD, 0xB2, 0xC3, 0x52, 0x43, 0x20, 0x92, 0x9D, 0x97, 0x8D, 0xA0, 0x15,
|
||||
0x07, 0x15, 0x6E, 0xA4, 0x0D, 0x56, 0xD3, 0x37, 0x1A, 0xC4, 0x9E, 0xDF, 0x02, 0x49, 0xB8,
|
||||
0x0A, 0x84, 0x62, 0xF5, 0xFA, 0xB9, 0x3F, 0xA4, 0x09, 0x76, 0xCC, 0xAA, 0xB9, 0x9B, 0xA6,
|
||||
0x4F, 0xC1, 0x6A, 0x64, 0xCE, 0xD8, 0x77, 0xAB, 0x4B, 0xF9, 0xA0, 0xAE, 0xDA, 0xF1, 0x67,
|
||||
0x87, 0x7C, 0x98, 0x5C, 0x7E, 0xB8, 0x73, 0xF5};
|
||||
// n = p * q
|
||||
static constexpr CryptoPP::byte Modulus[] = {
|
||||
0xC6, 0xCF, 0x71, 0xE7, 0xE5, 0x9A, 0xF0, 0xD1, 0x2A, 0x2C, 0x45, 0x8B, 0xF9, 0x2A, 0x0E,
|
||||
0xC1, 0x43, 0x05, 0x8B, 0xC3, 0x71, 0x17, 0x80, 0x1D, 0xCD, 0x49, 0x7D, 0xDE, 0x35, 0x9D,
|
||||
0x25, 0x9B, 0xA0, 0xD7, 0xA0, 0xF2, 0x7D, 0x6C, 0x08, 0x7E, 0xAA, 0x55, 0x02, 0x68, 0x2B,
|
||||
0x23, 0xC6, 0x44, 0xB8, 0x44, 0x18, 0xEB, 0x56, 0xCF, 0x16, 0xA2, 0x48, 0x03, 0xC9, 0xE7,
|
||||
0x4F, 0x87, 0xEB, 0x3D, 0x30, 0xC3, 0x15, 0x88, 0xBF, 0x20, 0xE7, 0x9D, 0xFF, 0x77, 0x0C,
|
||||
0xDE, 0x1D, 0x24, 0x1E, 0x63, 0xA9, 0x4F, 0x8A, 0xBF, 0x5B, 0xBE, 0x60, 0x19, 0x68, 0x33,
|
||||
0x3B, 0xFC, 0xED, 0x9F, 0x47, 0x4E, 0x5F, 0xF8, 0xEA, 0xCB, 0x3D, 0x00, 0xBD, 0x67, 0x01,
|
||||
0xF9, 0x2C, 0x6D, 0xC6, 0xAC, 0x13, 0x64, 0xE7, 0x67, 0x14, 0xF3, 0xDC, 0x52, 0x69, 0x6A,
|
||||
0xB9, 0x83, 0x2C, 0x42, 0x30, 0x13, 0x1B, 0xB2, 0xD8, 0xA5, 0x02, 0x0D, 0x79, 0xED, 0x96,
|
||||
0xB1, 0x0D, 0xF8, 0xCC, 0x0C, 0xDF, 0x81, 0x95, 0x4F, 0x03, 0x58, 0x09, 0x57, 0x0E, 0x80,
|
||||
0x69, 0x2E, 0xFE, 0xFF, 0x52, 0x77, 0xEA, 0x75, 0x28, 0xA8, 0xFB, 0xC9, 0xBE, 0xBF, 0x9F,
|
||||
0xBB, 0xB7, 0x79, 0x8E, 0x18, 0x05, 0xE1, 0x80, 0xBD, 0x50, 0x34, 0x94, 0x81, 0xD3, 0x53,
|
||||
0xC2, 0x69, 0xA2, 0xD2, 0x4C, 0xCF, 0x6C, 0xF4, 0x57, 0x2C, 0x10, 0x4A, 0x3F, 0xFB, 0x22,
|
||||
0xFD, 0x8B, 0x97, 0xE2, 0xC9, 0x5B, 0xA6, 0x2B, 0xCD, 0xD6, 0x1B, 0x6B, 0xDB, 0x68, 0x7F,
|
||||
0x4B, 0xC2, 0xA0, 0x50, 0x34, 0xC0, 0x05, 0xE5, 0x8D, 0xEF, 0x24, 0x67, 0xFF, 0x93, 0x40,
|
||||
0xCF, 0x2D, 0x62, 0xA2, 0xA0, 0x50, 0xB1, 0xF1, 0x3A, 0xA8, 0x3D, 0xFD, 0x80, 0xD1, 0xF9,
|
||||
0xB8, 0x05, 0x22, 0xAF, 0xC8, 0x35, 0x45, 0x90, 0x58, 0x8E, 0xE3, 0x3A, 0x7C, 0xBD, 0x3E,
|
||||
0x27};
|
||||
// p
|
||||
static constexpr CryptoPP::byte Prime1[] = {
|
||||
0xFE, 0xF6, 0xBF, 0x1D, 0x69, 0xAB, 0x16, 0x25, 0x08, 0x47, 0x55, 0x6B, 0x86, 0xE4, 0x35,
|
||||
0x88, 0x72, 0x2A, 0xB1, 0x3D, 0xF8, 0xB6, 0x44, 0xCA, 0xB3, 0xAB, 0x19, 0xD1, 0x04, 0x24,
|
||||
0x28, 0x0A, 0x74, 0x55, 0xB8, 0x15, 0x45, 0x09, 0xCC, 0x13, 0x1C, 0xF2, 0xBA, 0x37, 0xA9,
|
||||
0x03, 0x90, 0x8F, 0x02, 0x10, 0xFF, 0x25, 0x79, 0x86, 0xCC, 0x18, 0x50, 0x9A, 0x10, 0x5F,
|
||||
0x5B, 0x4C, 0x1C, 0x4E, 0xB0, 0xA7, 0xE3, 0x59, 0xB1, 0x2D, 0xA0, 0xC6, 0xB0, 0x20, 0x2C,
|
||||
0x21, 0x33, 0x12, 0xB3, 0xAF, 0x72, 0x34, 0x83, 0xCD, 0x52, 0x2F, 0xAF, 0x0F, 0x20, 0x5A,
|
||||
0x1B, 0xC0, 0xE2, 0xA3, 0x76, 0x34, 0x0F, 0xD7, 0xFC, 0xC1, 0x41, 0xC9, 0xF9, 0x79, 0x40,
|
||||
0x17, 0x42, 0x21, 0x3E, 0x9D, 0xFD, 0xC7, 0xC1, 0x50, 0xDE, 0x44, 0x5A, 0xC9, 0x31, 0x89,
|
||||
0x6A, 0x78, 0x05, 0xBE, 0x65, 0xB4, 0xE8, 0x2D};
|
||||
// q
|
||||
static constexpr CryptoPP::byte Prime2[] = {
|
||||
0xC7, 0x9E, 0x47, 0x58, 0x00, 0x7D, 0x62, 0x82, 0xB0, 0xD2, 0x22, 0x81, 0xD4, 0xA8, 0x97,
|
||||
0x1B, 0x79, 0x0C, 0x3A, 0xB0, 0xD7, 0xC9, 0x30, 0xE3, 0xC3, 0x53, 0x8E, 0x57, 0xEF, 0xF0,
|
||||
0x9B, 0x9F, 0xB3, 0x90, 0x52, 0xC6, 0x94, 0x22, 0x36, 0xAA, 0xE6, 0x4A, 0x5F, 0x72, 0x1D,
|
||||
0x70, 0xE8, 0x76, 0x58, 0xC8, 0xB2, 0x91, 0xCE, 0x9C, 0xC3, 0xE9, 0x09, 0x7F, 0x2E, 0x47,
|
||||
0x97, 0xCC, 0x90, 0x39, 0x15, 0x35, 0x31, 0xDE, 0x1F, 0x0C, 0x8C, 0x0D, 0xC1, 0xC2, 0x92,
|
||||
0xBE, 0x97, 0xBF, 0x2F, 0x91, 0xA1, 0x8C, 0x7D, 0x50, 0xA8, 0x21, 0x2F, 0xD7, 0xA2, 0x9A,
|
||||
0x7E, 0xB5, 0xA7, 0x2A, 0x90, 0x02, 0xD9, 0xF3, 0x3D, 0xD1, 0xEB, 0xB8, 0xE0, 0x5A, 0x79,
|
||||
0x9E, 0x7D, 0x8D, 0xCA, 0x18, 0x6D, 0xBD, 0x9E, 0xA1, 0x80, 0x28, 0x6B, 0x2A, 0xFE, 0x51,
|
||||
0x24, 0x9B, 0x6F, 0x4D, 0x84, 0x77, 0x80, 0x23};
|
||||
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||
0x7F, 0x76, 0xCD, 0x0E, 0xE2, 0xD4, 0xDE, 0x05, 0x1C, 0xC6, 0xD9, 0xA8, 0x0E, 0x8D, 0xFA,
|
||||
0x7B, 0xCA, 0x1E, 0xAA, 0x27, 0x1A, 0x40, 0xF8, 0xF1, 0x22, 0x87, 0x35, 0xDD, 0xDB, 0xFD,
|
||||
0xEE, 0xF8, 0xC2, 0xBC, 0xBD, 0x01, 0xFB, 0x8B, 0xE2, 0x3E, 0x63, 0xB2, 0xB1, 0x22, 0x5C,
|
||||
0x56, 0x49, 0x6E, 0x11, 0xBE, 0x07, 0x44, 0x0B, 0x9A, 0x26, 0x66, 0xD1, 0x49, 0x2C, 0x8F,
|
||||
0xD3, 0x1B, 0xCF, 0xA4, 0xA1, 0xB8, 0xD1, 0xFB, 0xA4, 0x9E, 0xD2, 0x21, 0x28, 0x83, 0x09,
|
||||
0x8A, 0xF6, 0xA0, 0x0B, 0xA3, 0xD6, 0x0F, 0x9B, 0x63, 0x68, 0xCC, 0xBC, 0x0C, 0x4E, 0x14,
|
||||
0x5B, 0x27, 0xA4, 0xA9, 0xF4, 0x2B, 0xB9, 0xB8, 0x7B, 0xC0, 0xE6, 0x51, 0xAD, 0x1D, 0x77,
|
||||
0xD4, 0x6B, 0xB9, 0xCE, 0x20, 0xD1, 0x26, 0x66, 0x7E, 0x5E, 0x9E, 0xA2, 0xE9, 0x6B, 0x90,
|
||||
0xF3, 0x73, 0xB8, 0x52, 0x8F, 0x44, 0x11, 0x03, 0x0C, 0x13, 0x97, 0x39, 0x3D, 0x13, 0x22,
|
||||
0x58, 0xD5, 0x43, 0x82, 0x49, 0xDA, 0x6E, 0x7C, 0xA1, 0xC5, 0x8C, 0xA5, 0xB0, 0x09, 0xE0,
|
||||
0xCE, 0x3D, 0xDF, 0xF4, 0x9D, 0x3C, 0x97, 0x15, 0xE2, 0x6A, 0xC7, 0x2B, 0x3C, 0x50, 0x93,
|
||||
0x23, 0xDB, 0xBA, 0x4A, 0x22, 0x66, 0x44, 0xAC, 0x78, 0xBB, 0x0E, 0x1A, 0x27, 0x43, 0xB5,
|
||||
0x71, 0x67, 0xAF, 0xF4, 0xAB, 0x48, 0x46, 0x93, 0x73, 0xD0, 0x42, 0xAB, 0x93, 0x63, 0xE5,
|
||||
0x6C, 0x9A, 0xDE, 0x50, 0x24, 0xC0, 0x23, 0x7D, 0x99, 0x79, 0x3F, 0x22, 0x07, 0xE0, 0xC1,
|
||||
0x48, 0x56, 0x1B, 0xDF, 0x83, 0x09, 0x12, 0xB4, 0x2D, 0x45, 0x6B, 0xC9, 0xC0, 0x68, 0x85,
|
||||
0x99, 0x90, 0x79, 0x96, 0x1A, 0xD7, 0xF5, 0x4D, 0x1F, 0x37, 0x83, 0x40, 0x4A, 0xEC, 0x39,
|
||||
0x37, 0xA6, 0x80, 0x92, 0x7D, 0xC5, 0x80, 0xC7, 0xD6, 0x6F, 0xFE, 0x8A, 0x79, 0x89, 0xC6,
|
||||
0xB1};
|
||||
};
|
||||
|
||||
class DebugRifKeyset {
|
||||
public:
|
||||
// std::uint8_t* PrivateExponent;
|
||||
static constexpr CryptoPP::byte Exponent1[] = {
|
||||
0xCD, 0x9A, 0x61, 0xB0, 0xB8, 0xD5, 0xB4, 0xE4, 0xE4, 0xF6, 0xAB, 0xF7, 0x27, 0xB7, 0x56,
|
||||
0x59, 0x6B, 0xB9, 0x11, 0xE7, 0xF4, 0x83, 0xAF, 0xB9, 0x73, 0x99, 0x7F, 0x49, 0xA2, 0x9C,
|
||||
0xF0, 0xB5, 0x6D, 0x37, 0x82, 0x14, 0x15, 0xF1, 0x04, 0x8A, 0xD4, 0x8E, 0xEB, 0x2E, 0x1F,
|
||||
0xE2, 0x81, 0xA9, 0x62, 0x6E, 0xB1, 0x68, 0x75, 0x62, 0xF3, 0x0F, 0xFE, 0xD4, 0x91, 0x87,
|
||||
0x98, 0x78, 0xBF, 0x26, 0xB5, 0x07, 0x58, 0xD0, 0xEE, 0x3F, 0x21, 0xE8, 0xC8, 0x0F, 0x5F,
|
||||
0xFA, 0x1C, 0x64, 0x74, 0x49, 0x52, 0xEB, 0xE7, 0xEE, 0xDE, 0xBA, 0x23, 0x26, 0x4A, 0xF6,
|
||||
0x9C, 0x1A, 0x09, 0x3F, 0xB9, 0x0B, 0x36, 0x26, 0x1A, 0xBE, 0xA9, 0x76, 0xE6, 0xF2, 0x69,
|
||||
0xDE, 0xFF, 0xAF, 0xCC, 0x0C, 0x9A, 0x66, 0x03, 0x86, 0x0A, 0x1F, 0x49, 0xA4, 0x10, 0xB6,
|
||||
0xBC, 0xC3, 0x7C, 0x88, 0xE8, 0xCE, 0x4B, 0xD9};
|
||||
// exponent2 = d mod (q - 1)
|
||||
static constexpr CryptoPP::byte Exponent2[] = {
|
||||
0xB3, 0x73, 0xA3, 0x59, 0xE6, 0x97, 0xC0, 0xAB, 0x3B, 0x68, 0xFC, 0x39, 0xAC, 0xDB, 0x44,
|
||||
0xB1, 0xB4, 0x9E, 0x35, 0x4D, 0xBE, 0xC5, 0x36, 0x69, 0x6C, 0x3D, 0xC5, 0xFC, 0xFE, 0x4B,
|
||||
0x2F, 0xDC, 0x86, 0x80, 0x46, 0x96, 0x40, 0x1A, 0x0D, 0x6E, 0xFA, 0x8C, 0xE0, 0x47, 0x91,
|
||||
0xAC, 0xAD, 0x95, 0x2B, 0x8E, 0x1F, 0xF2, 0x0A, 0x45, 0xF8, 0x29, 0x95, 0x70, 0xC6, 0x88,
|
||||
0x5F, 0x71, 0x03, 0x99, 0x79, 0xBC, 0x84, 0x71, 0xBD, 0xE8, 0x84, 0x8C, 0x0E, 0xD4, 0x7B,
|
||||
0x30, 0x74, 0x57, 0x1A, 0x95, 0xE7, 0x90, 0x19, 0x8D, 0xAD, 0x8B, 0x4C, 0x4E, 0xC3, 0xE7,
|
||||
0x6B, 0x23, 0x86, 0x01, 0xEE, 0x9B, 0xE0, 0x2F, 0x15, 0xA2, 0x2C, 0x4C, 0x39, 0xD3, 0xDF,
|
||||
0x9C, 0x39, 0x01, 0xF1, 0x8C, 0x44, 0x4A, 0x15, 0x44, 0xDC, 0x51, 0xF7, 0x22, 0xD7, 0x7F,
|
||||
0x41, 0x7F, 0x68, 0xFA, 0xEE, 0x56, 0xE8, 0x05};
|
||||
// e
|
||||
static constexpr CryptoPP::byte PublicExponent[] = {0x00, 0x01, 0x00, 0x01};
|
||||
// (InverseQ)(q) = 1 mod p
|
||||
static constexpr CryptoPP::byte Coefficient[] = {
|
||||
0xC0, 0x32, 0x43, 0xD3, 0x8C, 0x3D, 0xB4, 0xD2, 0x48, 0x8C, 0x42, 0x41, 0x24, 0x94, 0x6C,
|
||||
0x80, 0xC9, 0xC1, 0x79, 0x36, 0x7F, 0xAC, 0xC3, 0xFF, 0x6A, 0x25, 0xEB, 0x2C, 0xFB, 0xD4,
|
||||
0x2B, 0xA0, 0xEB, 0xFE, 0x25, 0xE9, 0xC6, 0x77, 0xCE, 0xFE, 0x2D, 0x23, 0xFE, 0xD0, 0xF4,
|
||||
0x0F, 0xD9, 0x7E, 0xD5, 0xA5, 0x7D, 0x1F, 0xC0, 0xE8, 0xE8, 0xEC, 0x80, 0x5B, 0xC7, 0xFD,
|
||||
0xE2, 0xBD, 0x94, 0xA6, 0x2B, 0xDD, 0x6A, 0x60, 0x45, 0x54, 0xAB, 0xCA, 0x42, 0x9C, 0x6A,
|
||||
0x6C, 0xBF, 0x3C, 0x84, 0xF9, 0xA5, 0x0E, 0x63, 0x0C, 0x51, 0x58, 0x62, 0x6D, 0x5A, 0xB7,
|
||||
0x3C, 0x3F, 0x49, 0x1A, 0xD0, 0x93, 0xB8, 0x4F, 0x1A, 0x6C, 0x5F, 0xC5, 0xE5, 0xA9, 0x75,
|
||||
0xD4, 0x86, 0x9E, 0xDF, 0x87, 0x0F, 0x27, 0xB0, 0x26, 0x78, 0x4E, 0xFB, 0xC1, 0x8A, 0x4A,
|
||||
0x24, 0x3F, 0x7F, 0x8F, 0x9A, 0x12, 0x51, 0xCB};
|
||||
// n = p * q
|
||||
static constexpr CryptoPP::byte Modulus[] = {
|
||||
0xC2, 0xD2, 0x44, 0xBC, 0xDD, 0x84, 0x3F, 0xD9, 0xC5, 0x22, 0xAF, 0xF7, 0xFC, 0x88, 0x8A,
|
||||
0x33, 0x80, 0xED, 0x8E, 0xE2, 0xCC, 0x81, 0xF7, 0xEC, 0xF8, 0x1C, 0x79, 0xBF, 0x02, 0xBB,
|
||||
0x12, 0x8E, 0x61, 0x68, 0x29, 0x1B, 0x15, 0xB6, 0x5E, 0xC6, 0xF8, 0xBF, 0x5A, 0xE0, 0x3B,
|
||||
0x6A, 0x6C, 0xD9, 0xD6, 0xF5, 0x75, 0xAB, 0xA0, 0x6F, 0x34, 0x81, 0x34, 0x9A, 0x5B, 0xAD,
|
||||
0xED, 0x31, 0xE3, 0xC6, 0xEA, 0x1A, 0xD1, 0x13, 0x22, 0xBB, 0xB3, 0xDA, 0xB3, 0xB2, 0x53,
|
||||
0xBD, 0x45, 0x79, 0x87, 0xAD, 0x0A, 0x01, 0x72, 0x18, 0x10, 0x29, 0x49, 0xF4, 0x41, 0x7F,
|
||||
0xD6, 0x47, 0x0C, 0x72, 0x92, 0x9E, 0xE9, 0xBB, 0x95, 0xA9, 0x5D, 0x79, 0xEB, 0xE4, 0x30,
|
||||
0x76, 0x90, 0x45, 0x4B, 0x9D, 0x9C, 0xCF, 0x92, 0x03, 0x60, 0x8C, 0x4B, 0x6C, 0xB3, 0x7A,
|
||||
0x3A, 0x05, 0x39, 0xA0, 0x66, 0xA9, 0x35, 0xCF, 0xB9, 0xFA, 0xAD, 0x9C, 0xAB, 0xEB, 0xE4,
|
||||
0x6A, 0x8C, 0xE9, 0x3B, 0xCC, 0x72, 0x12, 0x62, 0x63, 0xBD, 0x80, 0xC4, 0xEE, 0x37, 0x2B,
|
||||
0x32, 0x03, 0xA3, 0x09, 0xF7, 0xA0, 0x61, 0x57, 0xAD, 0x0D, 0xCF, 0x15, 0x98, 0x9E, 0x4E,
|
||||
0x49, 0xF8, 0xB5, 0xA3, 0x5C, 0x27, 0xEE, 0x45, 0x04, 0xEA, 0xE4, 0x4B, 0xBC, 0x8F, 0x87,
|
||||
0xED, 0x19, 0x1E, 0x46, 0x75, 0x63, 0xC4, 0x5B, 0xD5, 0xBC, 0x09, 0x2F, 0x02, 0x73, 0x19,
|
||||
0x3C, 0x58, 0x55, 0x49, 0x66, 0x4C, 0x11, 0xEC, 0x0F, 0x09, 0xFA, 0xA5, 0x56, 0x0A, 0x5A,
|
||||
0x63, 0x56, 0xAD, 0xA0, 0x0D, 0x86, 0x08, 0xC1, 0xE6, 0xB6, 0x13, 0x22, 0x49, 0x2F, 0x7C,
|
||||
0xDB, 0x4C, 0x56, 0x97, 0x0E, 0xC2, 0xD9, 0x2E, 0x87, 0xBC, 0x0E, 0x67, 0xC0, 0x1B, 0x58,
|
||||
0xBC, 0x64, 0x2B, 0xC2, 0x6E, 0xE2, 0x93, 0x2E, 0xB5, 0x6B, 0x70, 0xA4, 0x42, 0x9F, 0x64,
|
||||
0xC1};
|
||||
// p
|
||||
static constexpr CryptoPP::byte Prime1[] = {
|
||||
0xE5, 0x62, 0xE1, 0x7F, 0x9F, 0x86, 0x08, 0xE2, 0x61, 0xD3, 0xD0, 0x42, 0xE2, 0xC4, 0xB6,
|
||||
0xA8, 0x51, 0x09, 0x19, 0x14, 0xA4, 0x3A, 0x11, 0x4C, 0x33, 0xA5, 0x9C, 0x01, 0x5E, 0x34,
|
||||
0xB6, 0x3F, 0x02, 0x1A, 0xCA, 0x47, 0xF1, 0x4F, 0x3B, 0x35, 0x2A, 0x07, 0x20, 0xEC, 0xD8,
|
||||
0xC1, 0x15, 0xD9, 0xCA, 0x03, 0x4F, 0xB8, 0xE8, 0x09, 0x73, 0x3F, 0x85, 0xB7, 0x41, 0xD5,
|
||||
0x51, 0x3E, 0x7B, 0xE3, 0x53, 0x2B, 0x48, 0x8B, 0x8E, 0xCB, 0xBA, 0xF7, 0xE0, 0x60, 0xF5,
|
||||
0x35, 0x0E, 0x6F, 0xB0, 0xD9, 0x2A, 0x99, 0xD0, 0xFF, 0x60, 0x14, 0xED, 0x40, 0xEA, 0xF8,
|
||||
0xD7, 0x0B, 0xC3, 0x8D, 0x8C, 0xE8, 0x81, 0xB3, 0x75, 0x93, 0x15, 0xB3, 0x7D, 0xF6, 0x39,
|
||||
0x60, 0x1A, 0x00, 0xE7, 0xC3, 0x27, 0xAD, 0xA4, 0x33, 0xD5, 0x3E, 0xA4, 0x35, 0x48, 0x6F,
|
||||
0x22, 0xEF, 0x5D, 0xDD, 0x7D, 0x7B, 0x61, 0x05};
|
||||
// q
|
||||
static constexpr CryptoPP::byte Prime2[] = {
|
||||
0xD9, 0x6C, 0xC2, 0x0C, 0xF7, 0xAE, 0xD1, 0xF3, 0x3B, 0x3B, 0x49, 0x1E, 0x9F, 0x12, 0x9C,
|
||||
0xA1, 0x78, 0x1F, 0x35, 0x1D, 0x98, 0x26, 0x13, 0x71, 0xF9, 0x09, 0xFD, 0xF0, 0xAD, 0x38,
|
||||
0x55, 0xB7, 0xEE, 0x61, 0x04, 0x72, 0x51, 0x87, 0x2E, 0x05, 0x84, 0xB1, 0x1D, 0x0C, 0x0D,
|
||||
0xDB, 0xD4, 0x25, 0x3E, 0x26, 0xED, 0xEA, 0xB8, 0xF7, 0x49, 0xFE, 0xA2, 0x94, 0xE6, 0xF2,
|
||||
0x08, 0x92, 0xA7, 0x85, 0xF5, 0x30, 0xB9, 0x84, 0x22, 0xBF, 0xCA, 0xF0, 0x5F, 0xCB, 0x31,
|
||||
0x20, 0x34, 0x49, 0x16, 0x76, 0x34, 0xCC, 0x7A, 0xCB, 0x96, 0xFE, 0x78, 0x7A, 0x41, 0xFE,
|
||||
0x9A, 0xA2, 0x23, 0xF7, 0x68, 0x80, 0xD6, 0xCE, 0x4A, 0x78, 0xA5, 0xB7, 0x05, 0x77, 0x81,
|
||||
0x1F, 0xDE, 0x5E, 0xA8, 0x6E, 0x3E, 0x87, 0xEC, 0x44, 0xD2, 0x69, 0xC6, 0x54, 0x91, 0x6B,
|
||||
0x5E, 0x13, 0x8A, 0x03, 0x87, 0x05, 0x31, 0x8D};
|
||||
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||
0x01, 0x61, 0xAD, 0xD8, 0x9C, 0x06, 0x89, 0xD0, 0x60, 0xC8, 0x41, 0xF0, 0xB3, 0x83, 0x01,
|
||||
0x5D, 0xE3, 0xA2, 0x6B, 0xA2, 0xBA, 0x9A, 0x0A, 0x58, 0xCD, 0x1A, 0xA0, 0x97, 0x64, 0xEC,
|
||||
0xD0, 0x31, 0x1F, 0xCA, 0x36, 0x0E, 0x69, 0xDD, 0x40, 0xF7, 0x4E, 0xC0, 0xC6, 0xA3, 0x73,
|
||||
0xF0, 0x69, 0x84, 0xB2, 0xF4, 0x4B, 0x29, 0x14, 0x2A, 0x6D, 0xB8, 0x23, 0xD8, 0x1B, 0x61,
|
||||
0xD4, 0x9E, 0x87, 0xB3, 0xBB, 0xA9, 0xC4, 0x85, 0x4A, 0xF8, 0x03, 0x4A, 0xBF, 0xFE, 0xF9,
|
||||
0xFE, 0x8B, 0xDD, 0x54, 0x83, 0xBA, 0xE0, 0x2F, 0x3F, 0xB1, 0xEF, 0xA5, 0x05, 0x5D, 0x28,
|
||||
0x8B, 0xAB, 0xB5, 0xD0, 0x23, 0x2F, 0x8A, 0xCF, 0x48, 0x7C, 0xAA, 0xBB, 0xC8, 0x5B, 0x36,
|
||||
0x27, 0xC5, 0x16, 0xA4, 0xB6, 0x61, 0xAC, 0x0C, 0x28, 0x47, 0x79, 0x3F, 0x38, 0xAE, 0x5E,
|
||||
0x25, 0xC6, 0xAF, 0x35, 0xAE, 0xBC, 0xB0, 0xF3, 0xBC, 0xBD, 0xFD, 0xA4, 0x87, 0x0D, 0x14,
|
||||
0x3D, 0x90, 0xE4, 0xDE, 0x5D, 0x1D, 0x46, 0x81, 0xF1, 0x28, 0x6D, 0x2F, 0x2C, 0x5E, 0x97,
|
||||
0x2D, 0x89, 0x2A, 0x51, 0x72, 0x3C, 0x20, 0x02, 0x59, 0xB1, 0x98, 0x93, 0x05, 0x1E, 0x3F,
|
||||
0xA1, 0x8A, 0x69, 0x30, 0x0E, 0x70, 0x84, 0x8B, 0xAE, 0x97, 0xA1, 0x08, 0x95, 0x63, 0x4C,
|
||||
0xC7, 0xE8, 0x5D, 0x59, 0xCA, 0x78, 0x2A, 0x23, 0x87, 0xAC, 0x6F, 0x04, 0x33, 0xB1, 0x61,
|
||||
0xB9, 0xF0, 0x95, 0xDA, 0x33, 0xCC, 0xE0, 0x4C, 0x82, 0x68, 0x82, 0x14, 0x51, 0xBE, 0x49,
|
||||
0x1C, 0x58, 0xA2, 0x8B, 0x05, 0x4E, 0x98, 0x37, 0xEB, 0x94, 0x0B, 0x01, 0x22, 0xDC, 0xB3,
|
||||
0x19, 0xCA, 0x77, 0xA6, 0x6E, 0x97, 0xFF, 0x8A, 0x53, 0x5A, 0xC5, 0x24, 0xE4, 0xAF, 0x6E,
|
||||
0xA8, 0x2B, 0x53, 0xA4, 0xBE, 0x96, 0xA5, 0x7B, 0xCE, 0x22, 0x56, 0xA3, 0xF1, 0xCF, 0x14,
|
||||
0xA5};
|
||||
};
|
||||
|
||||
class PkgDerivedKey3Keyset {
|
||||
public:
|
||||
// std::uint8_t* PrivateExponent;
|
||||
static constexpr CryptoPP::byte Exponent1[] = {
|
||||
0x52, 0xCC, 0x2D, 0xA0, 0x9C, 0x9E, 0x75, 0xE7, 0x28, 0xEE, 0x3D, 0xDE, 0xE3, 0x45, 0xD1,
|
||||
0x4F, 0x94, 0x1C, 0xCC, 0xC8, 0x87, 0x29, 0x45, 0x3B, 0x8D, 0x6E, 0xAB, 0x6E, 0x2A, 0xA7,
|
||||
0xC7, 0x15, 0x43, 0xA3, 0x04, 0x8F, 0x90, 0x5F, 0xEB, 0xF3, 0x38, 0x4A, 0x77, 0xFA, 0x36,
|
||||
0xB7, 0x15, 0x76, 0xB6, 0x01, 0x1A, 0x8E, 0x25, 0x87, 0x82, 0xF1, 0x55, 0xD8, 0xC6, 0x43,
|
||||
0x2A, 0xC0, 0xE5, 0x98, 0xC9, 0x32, 0xD1, 0x94, 0x6F, 0xD9, 0x01, 0xBA, 0x06, 0x81, 0xE0,
|
||||
0x6D, 0x88, 0xF2, 0x24, 0x2A, 0x25, 0x01, 0x64, 0x5C, 0xBF, 0xF2, 0xD9, 0x99, 0x67, 0x3E,
|
||||
0xF6, 0x72, 0xEE, 0xE4, 0xE2, 0x33, 0x5C, 0xF8, 0x00, 0x40, 0xE3, 0x2A, 0x9A, 0xF4, 0x3D,
|
||||
0x22, 0x86, 0x44, 0x3C, 0xFB, 0x0A, 0xA5, 0x7C, 0x3F, 0xCC, 0xF5, 0xF1, 0x16, 0xC4, 0xAC,
|
||||
0x88, 0xB4, 0xDE, 0x62, 0x94, 0x92, 0x6A, 0x13};
|
||||
// exponent2 = d mod (q - 1)
|
||||
static constexpr CryptoPP::byte Exponent2[] = {
|
||||
0x7C, 0x9D, 0xAD, 0x39, 0xE0, 0xD5, 0x60, 0x14, 0x94, 0x48, 0x19, 0x7F, 0x88, 0x95, 0xD5,
|
||||
0x8B, 0x80, 0xAD, 0x85, 0x8A, 0x4B, 0x77, 0x37, 0x85, 0xD0, 0x77, 0xBB, 0xBF, 0x89, 0x71,
|
||||
0x4A, 0x72, 0xCB, 0x72, 0x68, 0x38, 0xEC, 0x02, 0xC6, 0x7D, 0xC6, 0x44, 0x06, 0x33, 0x51,
|
||||
0x1C, 0xC0, 0xFF, 0x95, 0x8F, 0x0D, 0x75, 0xDC, 0x25, 0xBB, 0x0B, 0x73, 0x91, 0xA9, 0x6D,
|
||||
0x42, 0xD8, 0x03, 0xB7, 0x68, 0xD4, 0x1E, 0x75, 0x62, 0xA3, 0x70, 0x35, 0x79, 0x78, 0x00,
|
||||
0xC8, 0xF5, 0xEF, 0x15, 0xB9, 0xFC, 0x4E, 0x47, 0x5A, 0xC8, 0x70, 0x70, 0x5B, 0x52, 0x98,
|
||||
0xC0, 0xC2, 0x58, 0x4A, 0x70, 0x96, 0xCC, 0xB8, 0x10, 0xE1, 0x2F, 0x78, 0x8B, 0x2B, 0xA1,
|
||||
0x7F, 0xF9, 0xAC, 0xDE, 0xF0, 0xBB, 0x2B, 0xE2, 0x66, 0xE3, 0x22, 0x92, 0x31, 0x21, 0x57,
|
||||
0x92, 0xC4, 0xB8, 0xF2, 0x3E, 0x76, 0x20, 0x37};
|
||||
// e
|
||||
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1};
|
||||
// (InverseQ)(q) = 1 mod p
|
||||
static constexpr CryptoPP::byte Coefficient[] = {
|
||||
0x45, 0x97, 0x55, 0xD4, 0x22, 0x08, 0x5E, 0xF3, 0x5C, 0xB4, 0x05, 0x7A, 0xFD, 0xAA, 0x42,
|
||||
0x42, 0xAD, 0x9A, 0x8C, 0xA0, 0x6C, 0xBB, 0x1D, 0x68, 0x54, 0x54, 0x6E, 0x3E, 0x32, 0xE3,
|
||||
0x53, 0x73, 0x76, 0xF1, 0x3E, 0x01, 0xEA, 0xD3, 0xCF, 0xEB, 0xEB, 0x23, 0x3E, 0xC0, 0xBE,
|
||||
0xCE, 0xEC, 0x2C, 0x89, 0x5F, 0xA8, 0x27, 0x3A, 0x4C, 0xB7, 0xE6, 0x74, 0xBC, 0x45, 0x4C,
|
||||
0x26, 0xC8, 0x25, 0xFF, 0x34, 0x63, 0x25, 0x37, 0xE1, 0x48, 0x10, 0xC1, 0x93, 0xA6, 0xAF,
|
||||
0xEB, 0xBA, 0xE3, 0xA2, 0xF1, 0x3D, 0xEF, 0x63, 0xD8, 0xF4, 0xFD, 0xD3, 0xEE, 0xE2, 0x5D,
|
||||
0xE9, 0x33, 0xCC, 0xAD, 0xBA, 0x75, 0x5C, 0x85, 0xAF, 0xCE, 0xA9, 0x3D, 0xD1, 0xA2, 0x17,
|
||||
0xF3, 0xF6, 0x98, 0xB3, 0x50, 0x8E, 0x5E, 0xF6, 0xEB, 0x02, 0x8E, 0xA1, 0x62, 0xA7, 0xD6,
|
||||
0x2C, 0xEC, 0x91, 0xFF, 0x15, 0x40, 0xD2, 0xE3};
|
||||
// n = p * q
|
||||
static constexpr CryptoPP::byte Modulus[] = {
|
||||
0xd2, 0x12, 0xfc, 0x33, 0x5f, 0x6d, 0xdb, 0x83, 0x16, 0x09, 0x62, 0x8b, 0x03, 0x56, 0x27,
|
||||
0x37, 0x82, 0xd4, 0x77, 0x85, 0x35, 0x29, 0x39, 0x2d, 0x52, 0x6b, 0x8c, 0x4c, 0x8c, 0xfb,
|
||||
0x06, 0xc1, 0x84, 0x5b, 0xe7, 0xd4, 0xf7, 0xbc, 0xd2, 0x4e, 0x62, 0x45, 0xcd, 0x2a, 0xbb,
|
||||
0xd7, 0x77, 0x76, 0x45, 0x36, 0x55, 0x27, 0x3f, 0xb3, 0xf5, 0xf9, 0x8e, 0xda, 0x4b, 0xef,
|
||||
0xaa, 0x59, 0xae, 0xb3, 0x9b, 0xea, 0x54, 0x98, 0xd2, 0x06, 0x32, 0x6a, 0x58, 0x31, 0x2a,
|
||||
0xe0, 0xd4, 0x4f, 0x90, 0xb5, 0x0a, 0x7d, 0xec, 0xf4, 0x3a, 0x9c, 0x52, 0x67, 0x2d, 0x99,
|
||||
0x31, 0x8e, 0x0c, 0x43, 0xe6, 0x82, 0xfe, 0x07, 0x46, 0xe1, 0x2e, 0x50, 0xd4, 0x1f, 0x2d,
|
||||
0x2f, 0x7e, 0xd9, 0x08, 0xba, 0x06, 0xb3, 0xbf, 0x2e, 0x20, 0x3f, 0x4e, 0x3f, 0xfe, 0x44,
|
||||
0xff, 0xaa, 0x50, 0x43, 0x57, 0x91, 0x69, 0x94, 0x49, 0x15, 0x82, 0x82, 0xe4, 0x0f, 0x4c,
|
||||
0x8d, 0x9d, 0x2c, 0xc9, 0x5b, 0x1d, 0x64, 0xbf, 0x88, 0x8b, 0xd4, 0xc5, 0x94, 0xe7, 0x65,
|
||||
0x47, 0x84, 0x1e, 0xe5, 0x79, 0x10, 0xfb, 0x98, 0x93, 0x47, 0xb9, 0x7d, 0x85, 0x12, 0xa6,
|
||||
0x40, 0x98, 0x2c, 0xf7, 0x92, 0xbc, 0x95, 0x19, 0x32, 0xed, 0xe8, 0x90, 0x56, 0x0d, 0x65,
|
||||
0xc1, 0xaa, 0x78, 0xc6, 0x2e, 0x54, 0xfd, 0x5f, 0x54, 0xa1, 0xf6, 0x7e, 0xe5, 0xe0, 0x5f,
|
||||
0x61, 0xc1, 0x20, 0xb4, 0xb9, 0xb4, 0x33, 0x08, 0x70, 0xe4, 0xdf, 0x89, 0x56, 0xed, 0x01,
|
||||
0x29, 0x46, 0x77, 0x5f, 0x8c, 0xb8, 0xa9, 0xf5, 0x1e, 0x2e, 0xb3, 0xb9, 0xbf, 0xe0, 0x09,
|
||||
0xb7, 0x8d, 0x28, 0xd4, 0xa6, 0xc3, 0xb8, 0x1e, 0x1f, 0x07, 0xeb, 0xb4, 0x12, 0x0b, 0x95,
|
||||
0xb8, 0x85, 0x30, 0xfd, 0xdc, 0x39, 0x13, 0xd0, 0x7c, 0xdc, 0x8f, 0xed, 0xf9, 0xc9, 0xa3,
|
||||
0xc1};
|
||||
// p
|
||||
static constexpr CryptoPP::byte Prime1[] = {
|
||||
0xF9, 0x67, 0xAD, 0x99, 0x12, 0x31, 0x0C, 0x56, 0xA2, 0x2E, 0x16, 0x1C, 0x46, 0xB3, 0x4D,
|
||||
0x5B, 0x43, 0xBE, 0x42, 0xA2, 0xF6, 0x86, 0x96, 0x80, 0x42, 0xC3, 0xC7, 0x3F, 0xC3, 0x42,
|
||||
0xF5, 0x87, 0x49, 0x33, 0x9F, 0x07, 0x5D, 0x6E, 0x2C, 0x04, 0xFD, 0xE3, 0xE1, 0xB2, 0xAE,
|
||||
0x0A, 0x0C, 0xF0, 0xC7, 0xA6, 0x1C, 0xA1, 0x63, 0x50, 0xC8, 0x09, 0x9C, 0x51, 0x24, 0x52,
|
||||
0x6C, 0x5E, 0x5E, 0xBD, 0x1E, 0x27, 0x06, 0xBB, 0xBC, 0x9E, 0x94, 0xE1, 0x35, 0xD4, 0x6D,
|
||||
0xB3, 0xCB, 0x3C, 0x68, 0xDD, 0x68, 0xB3, 0xFE, 0x6C, 0xCB, 0x8D, 0x82, 0x20, 0x76, 0x23,
|
||||
0x63, 0xB7, 0xE9, 0x68, 0x10, 0x01, 0x4E, 0xDC, 0xBA, 0x27, 0x5D, 0x01, 0xC1, 0x2D, 0x80,
|
||||
0x5E, 0x2B, 0xAF, 0x82, 0x6B, 0xD8, 0x84, 0xB6, 0x10, 0x52, 0x86, 0xA7, 0x89, 0x8E, 0xAE,
|
||||
0x9A, 0xE2, 0x89, 0xC6, 0xF7, 0xD5, 0x87, 0xFB};
|
||||
// q
|
||||
static constexpr CryptoPP::byte Prime2[] = {
|
||||
0xD7, 0xA1, 0x0F, 0x9A, 0x8B, 0xF2, 0xC9, 0x11, 0x95, 0x32, 0x9A, 0x8C, 0xF0, 0xD9, 0x40,
|
||||
0x47, 0xF5, 0x68, 0xA0, 0x0D, 0xBD, 0xC1, 0xFC, 0x43, 0x2F, 0x65, 0xF9, 0xC3, 0x61, 0x0F,
|
||||
0x25, 0x77, 0x54, 0xAD, 0xD7, 0x58, 0xAC, 0x84, 0x40, 0x60, 0x8D, 0x3F, 0xF3, 0x65, 0x89,
|
||||
0x75, 0xB5, 0xC6, 0x2C, 0x51, 0x1A, 0x2F, 0x1F, 0x22, 0xE4, 0x43, 0x11, 0x54, 0xBE, 0xC9,
|
||||
0xB4, 0xC7, 0xB5, 0x1B, 0x05, 0x0B, 0xBC, 0x56, 0x9A, 0xCD, 0x4A, 0xD9, 0x73, 0x68, 0x5E,
|
||||
0x5C, 0xFB, 0x92, 0xB7, 0x8B, 0x0D, 0xFF, 0xF5, 0x07, 0xCA, 0xB4, 0xC8, 0x9B, 0x96, 0x3C,
|
||||
0x07, 0x9E, 0x3E, 0x6B, 0x2A, 0x11, 0xF2, 0x8A, 0xB1, 0x8A, 0xD7, 0x2E, 0x1B, 0xA5, 0x53,
|
||||
0x24, 0x06, 0xED, 0x50, 0xB8, 0x90, 0x67, 0xB1, 0xE2, 0x41, 0xC6, 0x92, 0x01, 0xEE, 0x10,
|
||||
0xF0, 0x61, 0xBB, 0xFB, 0xB2, 0x7D, 0x4A, 0x73};
|
||||
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||
0x32, 0xD9, 0x03, 0x90, 0x8F, 0xBD, 0xB0, 0x8F, 0x57, 0x2B, 0x28, 0x5E, 0x0B, 0x8D, 0xB3,
|
||||
0xEA, 0x5C, 0xD1, 0x7E, 0xA8, 0x90, 0x88, 0x8C, 0xDD, 0x6A, 0x80, 0xBB, 0xB1, 0xDF, 0xC1,
|
||||
0xF7, 0x0D, 0xAA, 0x32, 0xF0, 0xB7, 0x7C, 0xCB, 0x88, 0x80, 0x0E, 0x8B, 0x64, 0xB0, 0xBE,
|
||||
0x4C, 0xD6, 0x0E, 0x9B, 0x8C, 0x1E, 0x2A, 0x64, 0xE1, 0xF3, 0x5C, 0xD7, 0x76, 0x01, 0x41,
|
||||
0x5E, 0x93, 0x5C, 0x94, 0xFE, 0xDD, 0x46, 0x62, 0xC3, 0x1B, 0x5A, 0xE2, 0xA0, 0xBC, 0x2D,
|
||||
0xEB, 0xC3, 0x98, 0x0A, 0xA7, 0xB7, 0x85, 0x69, 0x70, 0x68, 0x2B, 0x64, 0x4A, 0xB3, 0x1F,
|
||||
0xCC, 0x7D, 0xDC, 0x7C, 0x26, 0xF4, 0x77, 0xF6, 0x5C, 0xF2, 0xAE, 0x5A, 0x44, 0x2D, 0xD3,
|
||||
0xAB, 0x16, 0x62, 0x04, 0x19, 0xBA, 0xFB, 0x90, 0xFF, 0xE2, 0x30, 0x50, 0x89, 0x6E, 0xCB,
|
||||
0x56, 0xB2, 0xEB, 0xC0, 0x91, 0x16, 0x92, 0x5E, 0x30, 0x8E, 0xAE, 0xC7, 0x94, 0x5D, 0xFD,
|
||||
0x35, 0xE1, 0x20, 0xF8, 0xAD, 0x3E, 0xBC, 0x08, 0xBF, 0xC0, 0x36, 0x74, 0x9F, 0xD5, 0xBB,
|
||||
0x52, 0x08, 0xFD, 0x06, 0x66, 0xF3, 0x7A, 0xB3, 0x04, 0xF4, 0x75, 0x29, 0x5D, 0xE9, 0x5F,
|
||||
0xAA, 0x10, 0x30, 0xB2, 0x0F, 0x5A, 0x1A, 0xC1, 0x2A, 0xB3, 0xFE, 0xCB, 0x21, 0xAD, 0x80,
|
||||
0xEC, 0x8F, 0x20, 0x09, 0x1C, 0xDB, 0xC5, 0x58, 0x94, 0xC2, 0x9C, 0xC6, 0xCE, 0x82, 0x65,
|
||||
0x3E, 0x57, 0x90, 0xBC, 0xA9, 0x8B, 0x06, 0xB4, 0xF0, 0x72, 0xF6, 0x77, 0xDF, 0x98, 0x64,
|
||||
0xF1, 0xEC, 0xFE, 0x37, 0x2D, 0xBC, 0xAE, 0x8C, 0x08, 0x81, 0x1F, 0xC3, 0xC9, 0x89, 0x1A,
|
||||
0xC7, 0x42, 0x82, 0x4B, 0x2E, 0xDC, 0x8E, 0x8D, 0x73, 0xCE, 0xB1, 0xCC, 0x01, 0xD9, 0x08,
|
||||
0x70, 0x87, 0x3C, 0x44, 0x08, 0xEC, 0x49, 0x8F, 0x81, 0x5A, 0xE2, 0x40, 0xFF, 0x77, 0xFC,
|
||||
0x0D};
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "SDL3/SDL_log.h"
|
||||
#include "layer.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
@ -117,22 +118,6 @@ void L::DrawMenuBar() {
|
|||
|
||||
EndMainMenuBar();
|
||||
}
|
||||
|
||||
if (IsKeyPressed(ImGuiKey_F9, false)) {
|
||||
if (io.KeyCtrl && io.KeyAlt) {
|
||||
if (!DebugState.ShouldPauseInSubmit()) {
|
||||
DebugState.RequestFrameDump(dump_frame_count);
|
||||
}
|
||||
}
|
||||
if (!io.KeyCtrl && !io.KeyAlt) {
|
||||
if (isSystemPaused) {
|
||||
DebugState.ResumeGuestThreads();
|
||||
} else {
|
||||
DebugState.PauseGuestThreads();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (open_popup_options) {
|
||||
OpenPopup("GPU Tools Options");
|
||||
just_opened_options = true;
|
||||
|
@ -381,6 +366,32 @@ void L::Draw() {
|
|||
visibility_toggled = true;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(ImGuiKey_F9, false)) {
|
||||
if (io.KeyCtrl && io.KeyAlt) {
|
||||
if (!DebugState.ShouldPauseInSubmit()) {
|
||||
DebugState.RequestFrameDump(dump_frame_count);
|
||||
}
|
||||
} else {
|
||||
if (DebugState.IsGuestThreadsPaused()) {
|
||||
DebugState.ResumeGuestThreads();
|
||||
SDL_Log("Game resumed from Keyboard");
|
||||
show_pause_status = false;
|
||||
} else {
|
||||
DebugState.PauseGuestThreads();
|
||||
SDL_Log("Game paused from Keyboard");
|
||||
show_pause_status = true;
|
||||
}
|
||||
visibility_toggled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (show_pause_status) {
|
||||
ImVec2 pos = ImVec2(10, 10);
|
||||
ImU32 color = IM_COL32(255, 255, 255, 255);
|
||||
|
||||
ImGui::GetForegroundDrawList()->AddText(pos, color, "Game Paused Press F9 to Resume");
|
||||
}
|
||||
|
||||
if (show_simple_fps) {
|
||||
if (Begin("Video Info", nullptr,
|
||||
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration |
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
static void SetupSettings();
|
||||
|
||||
void Draw() override;
|
||||
bool show_pause_status = false;
|
||||
};
|
||||
|
||||
} // namespace Core::Devtools
|
||||
|
|
|
@ -1,473 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <zlib.h>
|
||||
#include "common/io_file.h"
|
||||
#include "common/logging/formatter.h"
|
||||
#include "core/file_format/pkg.h"
|
||||
#include "core/file_format/pkg_type.h"
|
||||
|
||||
static void DecompressPFSC(std::span<char> compressed_data, std::span<char> decompressed_data) {
|
||||
z_stream decompressStream;
|
||||
decompressStream.zalloc = Z_NULL;
|
||||
decompressStream.zfree = Z_NULL;
|
||||
decompressStream.opaque = Z_NULL;
|
||||
|
||||
if (inflateInit(&decompressStream) != Z_OK) {
|
||||
// std::cerr << "Error initializing zlib for deflation." << std::endl;
|
||||
}
|
||||
|
||||
decompressStream.avail_in = compressed_data.size();
|
||||
decompressStream.next_in = reinterpret_cast<unsigned char*>(compressed_data.data());
|
||||
decompressStream.avail_out = decompressed_data.size();
|
||||
decompressStream.next_out = reinterpret_cast<unsigned char*>(decompressed_data.data());
|
||||
|
||||
if (inflate(&decompressStream, Z_FINISH)) {
|
||||
}
|
||||
if (inflateEnd(&decompressStream) != Z_OK) {
|
||||
// std::cerr << "Error ending zlib inflate" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetPFSCOffset(std::span<const u8> pfs_image) {
|
||||
static constexpr u32 PfscMagic = 0x43534650;
|
||||
u32 value;
|
||||
for (u32 i = 0x20000; i < pfs_image.size(); i += 0x10000) {
|
||||
std::memcpy(&value, &pfs_image[i], sizeof(u32));
|
||||
if (value == PfscMagic)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
PKG::PKG() = default;
|
||||
|
||||
PKG::~PKG() = default;
|
||||
|
||||
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;
|
||||
}
|
||||
pkgSize = file.GetSize();
|
||||
|
||||
file.Read(pkgheader);
|
||||
if (pkgheader.magic != 0x7F434E54)
|
||||
return false;
|
||||
|
||||
for (const auto& flag : flagNames) {
|
||||
if (isFlagSet(pkgheader.pkg_content_flags, flag.first)) {
|
||||
if (!pkgFlags.empty())
|
||||
pkgFlags += (", ");
|
||||
pkgFlags += (flag.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Find title id it is part of pkg_content_id starting at offset 0x40
|
||||
file.Seek(0x47); // skip first 7 characters of content_id
|
||||
file.Read(pkgTitleID);
|
||||
|
||||
u32 offset = pkgheader.pkg_table_entry_offset;
|
||||
u32 n_files = pkgheader.pkg_table_entry_count;
|
||||
|
||||
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);
|
||||
file.Read(entry.filename_offset);
|
||||
file.Read(entry.flags1);
|
||||
file.Read(entry.flags2);
|
||||
file.Read(entry.offset);
|
||||
file.Read(entry.size);
|
||||
file.Seek(8, Common::FS::SeekOrigin::CurrentPosition);
|
||||
|
||||
// Try to figure out the name
|
||||
const auto name = GetEntryNameByType(entry.id);
|
||||
if (name == "param.sfo") {
|
||||
sfo.clear();
|
||||
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);
|
||||
}
|
||||
}
|
||||
file.Close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::path& extract,
|
||||
std::string& failreason) {
|
||||
extract_path = extract;
|
||||
pkgpath = filepath;
|
||||
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
||||
if (!file.IsOpen()) {
|
||||
return false;
|
||||
}
|
||||
pkgSize = file.GetSize();
|
||||
file.ReadRaw<u8>(&pkgheader, sizeof(PKGHeader));
|
||||
|
||||
if (pkgheader.magic != 0x7F434E54)
|
||||
return false;
|
||||
|
||||
if (pkgheader.pkg_size > pkgSize) {
|
||||
failreason = "PKG file size is different";
|
||||
return false;
|
||||
}
|
||||
if ((pkgheader.pkg_content_size + pkgheader.pkg_content_offset) > pkgheader.pkg_size) {
|
||||
failreason = "Content size is bigger than pkg size";
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 offset = pkgheader.pkg_table_entry_offset;
|
||||
u32 n_files = pkgheader.pkg_table_entry_count;
|
||||
|
||||
std::array<u8, 64> concatenated_ivkey_dk3;
|
||||
std::array<u8, 32> seed_digest;
|
||||
std::array<std::array<u8, 32>, 7> digest1;
|
||||
std::array<std::array<u8, 256>, 7> key1;
|
||||
std::array<u8, 256> imgkeydata;
|
||||
|
||||
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);
|
||||
file.Read(entry.filename_offset);
|
||||
file.Read(entry.flags1);
|
||||
file.Read(entry.flags2);
|
||||
file.Read(entry.offset);
|
||||
file.Read(entry.size);
|
||||
file.Seek(8, Common::FS::SeekOrigin::CurrentPosition);
|
||||
|
||||
auto currentPos = file.Tell();
|
||||
|
||||
// Try to figure out the name
|
||||
const auto name = GetEntryNameByType(entry.id);
|
||||
const auto filepath = extract_path / "sce_sys" / name;
|
||||
std::filesystem::create_directories(filepath.parent_path());
|
||||
|
||||
if (name.empty()) {
|
||||
// Just print with id
|
||||
Common::FS::IOFile out(extract_path / "sce_sys" / std::to_string(entry.id),
|
||||
Common::FS::FileAccessMode::Write);
|
||||
if (!file.Seek(entry.offset)) {
|
||||
failreason = "Failed to seek to PKG entry offset";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<u8> data;
|
||||
data.resize(entry.size);
|
||||
file.ReadRaw<u8>(data.data(), entry.size);
|
||||
out.WriteRaw<u8>(data.data(), entry.size);
|
||||
out.Close();
|
||||
|
||||
file.Seek(currentPos);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.id == 0x1) { // DIGESTS, seek;
|
||||
// file.Seek(entry.offset, fsSeekSet);
|
||||
} else if (entry.id == 0x10) { // ENTRY_KEYS, seek;
|
||||
file.Seek(entry.offset);
|
||||
file.Read(seed_digest);
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
file.Read(digest1[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
file.Read(key1[i]);
|
||||
}
|
||||
|
||||
PKG::crypto.RSA2048Decrypt(dk3_, key1[3], true); // decrypt DK3
|
||||
} else if (entry.id == 0x20) { // IMAGE_KEY, seek; IV_KEY
|
||||
file.Seek(entry.offset);
|
||||
file.Read(imgkeydata);
|
||||
|
||||
// The Concatenated iv + dk3 imagekey for HASH256
|
||||
std::memcpy(concatenated_ivkey_dk3.data(), &entry, sizeof(entry));
|
||||
std::memcpy(concatenated_ivkey_dk3.data() + sizeof(entry), dk3_.data(), sizeof(dk3_));
|
||||
|
||||
PKG::crypto.ivKeyHASH256(concatenated_ivkey_dk3, ivKey); // ivkey_
|
||||
// imgkey_ to use for last step to get ekpfs
|
||||
PKG::crypto.aesCbcCfb128Decrypt(ivKey, imgkeydata, imgKey);
|
||||
// ekpfs key to get data and tweak keys.
|
||||
PKG::crypto.RSA2048Decrypt(ekpfsKey, imgKey, false);
|
||||
} else if (entry.id == 0x80) {
|
||||
// GENERAL_DIGESTS, seek;
|
||||
// file.Seek(entry.offset, fsSeekSet);
|
||||
}
|
||||
|
||||
Common::FS::IOFile out(extract_path / "sce_sys" / name, Common::FS::FileAccessMode::Write);
|
||||
if (!file.Seek(entry.offset)) {
|
||||
failreason = "Failed to seek to PKG entry offset";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<u8> data;
|
||||
data.resize(entry.size);
|
||||
file.ReadRaw<u8>(data.data(), entry.size);
|
||||
out.WriteRaw<u8>(data.data(), entry.size);
|
||||
out.Close();
|
||||
|
||||
// Decrypt Np stuff and overwrite.
|
||||
if (entry.id == 0x400 || entry.id == 0x401 || entry.id == 0x402 ||
|
||||
entry.id == 0x403) { // somehow 0x401 is not decrypting
|
||||
decNp.resize(entry.size);
|
||||
if (!file.Seek(entry.offset)) {
|
||||
failreason = "Failed to seek to PKG entry offset";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<u8> data;
|
||||
data.resize(entry.size);
|
||||
file.ReadRaw<u8>(data.data(), entry.size);
|
||||
|
||||
std::span<u8> cipherNp(data.data(), entry.size);
|
||||
std::array<u8, 64> concatenated_ivkey_dk3_;
|
||||
std::memcpy(concatenated_ivkey_dk3_.data(), &entry, sizeof(entry));
|
||||
std::memcpy(concatenated_ivkey_dk3_.data() + sizeof(entry), dk3_.data(), sizeof(dk3_));
|
||||
PKG::crypto.ivKeyHASH256(concatenated_ivkey_dk3_, ivKey);
|
||||
PKG::crypto.aesCbcCfb128DecryptEntry(ivKey, cipherNp, decNp);
|
||||
|
||||
Common::FS::IOFile out(extract_path / "sce_sys" / name,
|
||||
Common::FS::FileAccessMode::Write);
|
||||
out.Write(decNp);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
file.Seek(currentPos);
|
||||
}
|
||||
|
||||
// Read the seed
|
||||
std::array<u8, 16> seed;
|
||||
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.
|
||||
PKG::crypto.PfsGenCryptoKey(ekpfsKey, seed, dataKey, tweakKey);
|
||||
const u32 length = pkgheader.pfs_cache_size * 0x2; // Seems to be ok.
|
||||
|
||||
int num_blocks = 0;
|
||||
std::vector<u8> pfsc(length);
|
||||
if (length != 0) {
|
||||
// Read encrypted pfs_image
|
||||
std::vector<u8> pfs_encrypted(length);
|
||||
file.Seek(pkgheader.pfs_image_offset);
|
||||
file.Read(pfs_encrypted);
|
||||
file.Close();
|
||||
// Decrypt the pfs_image.
|
||||
std::vector<u8> pfs_decrypted(length);
|
||||
PKG::crypto.decryptPFS(dataKey, tweakKey, pfs_encrypted, pfs_decrypted, 0);
|
||||
|
||||
// Retrieve PFSC from decrypted pfs_image.
|
||||
pfsc_offset = GetPFSCOffset(pfs_decrypted);
|
||||
std::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset);
|
||||
|
||||
PFSCHdr pfsChdr;
|
||||
std::memcpy(&pfsChdr, pfsc.data(), sizeof(pfsChdr));
|
||||
|
||||
num_blocks = (int)(pfsChdr.data_length / pfsChdr.block_sz2);
|
||||
sectorMap.resize(num_blocks + 1); // 8 bytes, need extra 1 to get the last offset.
|
||||
|
||||
for (int i = 0; i < num_blocks + 1; i++) {
|
||||
std::memcpy(§orMap[i], pfsc.data() + pfsChdr.block_offsets + i * 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
u32 ent_size = 0;
|
||||
u32 ndinode = 0;
|
||||
int ndinode_counter = 0;
|
||||
bool dinode_reached = false;
|
||||
bool uroot_reached = false;
|
||||
std::vector<char> compressedData;
|
||||
std::vector<char> decompressedData(0x10000);
|
||||
|
||||
// Get iNdoes and Dirents.
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
const u64 sectorOffset = sectorMap[i];
|
||||
const u64 sectorSize = sectorMap[i + 1] - sectorOffset;
|
||||
|
||||
compressedData.resize(sectorSize);
|
||||
std::memcpy(compressedData.data(), pfsc.data() + sectorOffset, sectorSize);
|
||||
|
||||
if (sectorSize == 0x10000) // Uncompressed data
|
||||
std::memcpy(decompressedData.data(), compressedData.data(), 0x10000);
|
||||
else if (sectorSize < 0x10000) // Compressed data
|
||||
DecompressPFSC(compressedData, decompressedData);
|
||||
|
||||
if (i == 0) {
|
||||
std::memcpy(&ndinode, decompressedData.data() + 0x30, 4); // number of folders and files
|
||||
}
|
||||
|
||||
int occupied_blocks =
|
||||
(ndinode * 0xA8) / 0x10000; // how many blocks(0x10000) are taken by iNodes.
|
||||
if (((ndinode * 0xA8) % 0x10000) != 0)
|
||||
occupied_blocks += 1;
|
||||
|
||||
if (i >= 1 && i <= occupied_blocks) { // Get all iNodes, gives type, file size and location.
|
||||
for (int p = 0; p < 0x10000; p += 0xA8) {
|
||||
Inode node;
|
||||
std::memcpy(&node, &decompressedData[p], sizeof(node));
|
||||
if (node.Mode == 0) {
|
||||
break;
|
||||
}
|
||||
iNodeBuf.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
// let's deal with the root/uroot entries here.
|
||||
// Sometimes it's more than 2 entries (Tomb Raider Remastered)
|
||||
const std::string_view flat_path_table(&decompressedData[0x10], 15);
|
||||
if (flat_path_table == "flat_path_table") {
|
||||
uroot_reached = true;
|
||||
}
|
||||
|
||||
if (uroot_reached) {
|
||||
for (int i = 0; i < 0x10000; i += ent_size) {
|
||||
Dirent dirent;
|
||||
std::memcpy(&dirent, &decompressedData[i], sizeof(dirent));
|
||||
ent_size = dirent.entsize;
|
||||
if (dirent.ino != 0) {
|
||||
ndinode_counter++;
|
||||
} else {
|
||||
// Set the the folder according to the current inode.
|
||||
// Can be 2 or more (rarely)
|
||||
auto parent_path = extract_path.parent_path();
|
||||
auto title_id = GetTitleID();
|
||||
|
||||
if (parent_path.filename() != title_id &&
|
||||
!fmt::UTF(extract_path.u8string()).data.ends_with("-patch")) {
|
||||
extractPaths[ndinode_counter] = parent_path / title_id;
|
||||
} else {
|
||||
// DLCs path has different structure
|
||||
extractPaths[ndinode_counter] = extract_path;
|
||||
}
|
||||
uroot_reached = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char dot = decompressedData[0x10];
|
||||
const std::string_view dotdot(&decompressedData[0x28], 2);
|
||||
if (dot == '.' && dotdot == "..") {
|
||||
dinode_reached = true;
|
||||
}
|
||||
|
||||
// Get folder and file names.
|
||||
bool end_reached = false;
|
||||
if (dinode_reached) {
|
||||
for (int j = 0; j < 0x10000; j += ent_size) { // Skip the first parent and child.
|
||||
Dirent dirent;
|
||||
std::memcpy(&dirent, &decompressedData[j], sizeof(dirent));
|
||||
|
||||
// Stop here and continue the main loop
|
||||
if (dirent.ino == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ent_size = dirent.entsize;
|
||||
auto& table = fsTable.emplace_back();
|
||||
table.name = std::string(dirent.name, dirent.namelen);
|
||||
table.inode = dirent.ino;
|
||||
table.type = dirent.type;
|
||||
|
||||
if (table.type == PFS_CURRENT_DIR) {
|
||||
current_dir = extractPaths[table.inode];
|
||||
}
|
||||
extractPaths[table.inode] = current_dir / std::filesystem::path(table.name);
|
||||
|
||||
if (table.type == PFS_FILE || table.type == PFS_DIR) {
|
||||
if (table.type == PFS_DIR) { // Create dirs.
|
||||
std::filesystem::create_directory(extractPaths[table.inode]);
|
||||
}
|
||||
ndinode_counter++;
|
||||
if ((ndinode_counter + 1) == ndinode) // 1 for the image itself (root).
|
||||
end_reached = true;
|
||||
}
|
||||
}
|
||||
if (end_reached) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PKG::ExtractFiles(const int index) {
|
||||
int inode_number = fsTable[index].inode;
|
||||
int inode_type = fsTable[index].type;
|
||||
std::string inode_name = fsTable[index].name;
|
||||
|
||||
if (inode_type == PFS_FILE) {
|
||||
int sector_loc = iNodeBuf[inode_number].loc;
|
||||
int nblocks = iNodeBuf[inode_number].Blocks;
|
||||
int bsize = iNodeBuf[inode_number].Size;
|
||||
|
||||
Common::FS::IOFile inflated;
|
||||
inflated.Open(extractPaths[inode_number], Common::FS::FileAccessMode::Write);
|
||||
|
||||
Common::FS::IOFile pkgFile; // Open the file for each iteration to avoid conflict.
|
||||
pkgFile.Open(pkgpath, Common::FS::FileAccessMode::Read);
|
||||
|
||||
int size_decompressed = 0;
|
||||
std::vector<char> compressedData;
|
||||
std::vector<char> decompressedData(0x10000);
|
||||
|
||||
u64 pfsc_buf_size = 0x11000; // extra 0x1000
|
||||
std::vector<u8> pfsc(pfsc_buf_size);
|
||||
std::vector<u8> pfs_decrypted(pfsc_buf_size);
|
||||
|
||||
for (int j = 0; j < nblocks; j++) {
|
||||
u64 sectorOffset =
|
||||
sectorMap[sector_loc + j]; // offset into PFSC_image and not pfs_image.
|
||||
u64 sectorSize = sectorMap[sector_loc + j + 1] -
|
||||
sectorOffset; // indicates if data is compressed or not.
|
||||
u64 fileOffset = (pkgheader.pfs_image_offset + pfsc_offset + sectorOffset);
|
||||
u64 currentSector1 =
|
||||
(pfsc_offset + sectorOffset) / 0x1000; // block size is 0x1000 for xts decryption.
|
||||
|
||||
int sectorOffsetMask = (sectorOffset + pfsc_offset) & 0xFFFFF000;
|
||||
int previousData = (sectorOffset + pfsc_offset) - sectorOffsetMask;
|
||||
|
||||
pkgFile.Seek(fileOffset - previousData);
|
||||
pkgFile.Read(pfsc);
|
||||
|
||||
PKG::crypto.decryptPFS(dataKey, tweakKey, pfsc, pfs_decrypted, currentSector1);
|
||||
|
||||
compressedData.resize(sectorSize);
|
||||
std::memcpy(compressedData.data(), pfs_decrypted.data() + previousData, sectorSize);
|
||||
|
||||
if (sectorSize == 0x10000) // Uncompressed data
|
||||
std::memcpy(decompressedData.data(), compressedData.data(), 0x10000);
|
||||
else if (sectorSize < 0x10000) // Compressed data
|
||||
DecompressPFSC(compressedData, decompressedData);
|
||||
|
||||
size_decompressed += 0x10000;
|
||||
|
||||
if (j < nblocks - 1) {
|
||||
inflated.WriteRaw<u8>(decompressedData.data(), decompressedData.size());
|
||||
} else {
|
||||
// This is to remove the zeros at the end of the file.
|
||||
const u32 write_size = decompressedData.size() - (size_decompressed - bsize);
|
||||
inflated.WriteRaw<u8>(decompressedData.data(), write_size);
|
||||
}
|
||||
}
|
||||
pkgFile.Close();
|
||||
inflated.Close();
|
||||
}
|
||||
}
|
|
@ -1,174 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "common/endian.h"
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "pfs.h"
|
||||
#include "trp.h"
|
||||
|
||||
struct PKGHeader {
|
||||
u32_be magic; // Magic
|
||||
u32_be pkg_type;
|
||||
u32_be pkg_0x8; // unknown field
|
||||
u32_be pkg_file_count;
|
||||
u32_be pkg_table_entry_count;
|
||||
u16_be pkg_sc_entry_count;
|
||||
u16_be pkg_table_entry_count_2; // same as pkg_entry_count
|
||||
u32_be pkg_table_entry_offset; // file table offset
|
||||
u32_be pkg_sc_entry_data_size;
|
||||
u64_be pkg_body_offset; // offset of PKG entries
|
||||
u64_be pkg_body_size; // length of all PKG entries
|
||||
u64_be pkg_content_offset;
|
||||
u64_be pkg_content_size;
|
||||
u8 pkg_content_id[0x24]; // packages' content ID as a 36-byte string
|
||||
u8 pkg_padding[0xC]; // padding
|
||||
u32_be pkg_drm_type; // DRM type
|
||||
u32_be pkg_content_type; // Content type
|
||||
u32_be pkg_content_flags; // Content flags
|
||||
u32_be pkg_promote_size;
|
||||
u32_be pkg_version_date;
|
||||
u32_be pkg_version_hash;
|
||||
u32_be pkg_0x088;
|
||||
u32_be pkg_0x08C;
|
||||
u32_be pkg_0x090;
|
||||
u32_be pkg_0x094;
|
||||
u32_be pkg_iro_tag;
|
||||
u32_be pkg_drm_type_version;
|
||||
|
||||
u8 pkg_zeroes_1[0x60];
|
||||
|
||||
/* Digest table */
|
||||
u8 digest_entries1[0x20]; // sha256 digest for main entry 1
|
||||
u8 digest_entries2[0x20]; // sha256 digest for main entry 2
|
||||
u8 digest_table_digest[0x20]; // sha256 digest for digest table
|
||||
u8 digest_body_digest[0x20]; // sha256 digest for main table
|
||||
|
||||
u8 pkg_zeroes_2[0x280];
|
||||
|
||||
u32_be pkg_0x400;
|
||||
|
||||
u32_be pfs_image_count; // count of PFS images
|
||||
u64_be pfs_image_flags; // PFS flags
|
||||
u64_be pfs_image_offset; // offset to start of external PFS image
|
||||
u64_be pfs_image_size; // size of external PFS image
|
||||
u64_be mount_image_offset;
|
||||
u64_be mount_image_size;
|
||||
u64_be pkg_size;
|
||||
u32_be pfs_signed_size;
|
||||
u32_be pfs_cache_size;
|
||||
u8 pfs_image_digest[0x20];
|
||||
u8 pfs_signed_digest[0x20];
|
||||
u64_be pfs_split_size_nth_0;
|
||||
u64_be pfs_split_size_nth_1;
|
||||
|
||||
u8 pkg_zeroes_3[0xB50];
|
||||
|
||||
u8 pkg_digest[0x20];
|
||||
};
|
||||
|
||||
enum class PKGContentFlag {
|
||||
FIRST_PATCH = 0x100000,
|
||||
PATCHGO = 0x200000,
|
||||
REMASTER = 0x400000,
|
||||
PS_CLOUD = 0x800000,
|
||||
GD_AC = 0x2000000,
|
||||
NON_GAME = 0x4000000,
|
||||
UNKNOWN_0x8000000 = 0x8000000,
|
||||
SUBSEQUENT_PATCH = 0x40000000,
|
||||
DELTA_PATCH = 0x41000000,
|
||||
CUMULATIVE_PATCH = 0x60000000
|
||||
};
|
||||
|
||||
struct PKGEntry {
|
||||
u32_be id; // File ID, useful for files without a filename entry
|
||||
u32_be filename_offset; // Offset into the filenames table (ID 0x200) where this file's name is
|
||||
// located
|
||||
u32_be flags1; // Flags including encrypted flag, etc
|
||||
u32_be flags2; // Flags including encryption key index, etc
|
||||
u32_be offset; // Offset into PKG to find the file
|
||||
u32_be size; // Size of the file
|
||||
u64_be padding; // blank padding
|
||||
};
|
||||
static_assert(sizeof(PKGEntry) == 32);
|
||||
|
||||
class PKG {
|
||||
public:
|
||||
PKG();
|
||||
~PKG();
|
||||
|
||||
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);
|
||||
|
||||
std::vector<u8> sfo;
|
||||
|
||||
u32 GetNumberOfFiles() {
|
||||
return fsTable.size();
|
||||
}
|
||||
|
||||
u64 GetPkgSize() {
|
||||
return pkgSize;
|
||||
}
|
||||
|
||||
std::string GetPkgFlags() {
|
||||
return pkgFlags;
|
||||
}
|
||||
|
||||
std::string_view GetTitleID() {
|
||||
return std::string_view(pkgTitleID, 9);
|
||||
}
|
||||
|
||||
PKGHeader GetPkgHeader() {
|
||||
return pkgheader;
|
||||
}
|
||||
|
||||
static bool isFlagSet(u32_be variable, PKGContentFlag flag) {
|
||||
return (variable) & static_cast<u32>(flag);
|
||||
}
|
||||
|
||||
static constexpr std::array<std::pair<PKGContentFlag, std::string_view>, 10> flagNames = {
|
||||
{{PKGContentFlag::FIRST_PATCH, "FIRST_PATCH"},
|
||||
{PKGContentFlag::PATCHGO, "PATCHGO"},
|
||||
{PKGContentFlag::REMASTER, "REMASTER"},
|
||||
{PKGContentFlag::PS_CLOUD, "PS_CLOUD"},
|
||||
{PKGContentFlag::GD_AC, "GD_AC"},
|
||||
{PKGContentFlag::NON_GAME, "NON_GAME"},
|
||||
{PKGContentFlag::UNKNOWN_0x8000000, "UNKNOWN_0x8000000"},
|
||||
{PKGContentFlag::SUBSEQUENT_PATCH, "SUBSEQUENT_PATCH"},
|
||||
{PKGContentFlag::DELTA_PATCH, "DELTA_PATCH"},
|
||||
{PKGContentFlag::CUMULATIVE_PATCH, "CUMULATIVE_PATCH"}}};
|
||||
|
||||
private:
|
||||
Crypto crypto;
|
||||
TRP trp;
|
||||
u64 pkgSize = 0;
|
||||
char pkgTitleID[9];
|
||||
PKGHeader pkgheader;
|
||||
std::string pkgFlags;
|
||||
|
||||
std::unordered_map<int, std::filesystem::path> extractPaths;
|
||||
std::vector<pfs_fs_table> fsTable;
|
||||
std::vector<Inode> iNodeBuf;
|
||||
std::vector<u64> sectorMap;
|
||||
u64 pfsc_offset;
|
||||
|
||||
std::array<u8, 32> dk3_;
|
||||
std::array<u8, 32> ivKey;
|
||||
std::array<u8, 256> imgKey;
|
||||
std::array<u8, 32> ekpfsKey;
|
||||
std::array<u8, 16> dataKey;
|
||||
std::array<u8, 16> tweakKey;
|
||||
std::vector<u8> decNp;
|
||||
|
||||
std::filesystem::path pkgpath;
|
||||
std::filesystem::path current_dir;
|
||||
std::filesystem::path extract_path;
|
||||
};
|
|
@ -1,638 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include "pkg_type.h"
|
||||
|
||||
struct PkgEntryValue {
|
||||
u32 type;
|
||||
std::string_view name;
|
||||
|
||||
operator u32() const noexcept {
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr static std::array<PkgEntryValue, 611> PkgEntries = {{
|
||||
{0x0001, "digests"},
|
||||
{0x0010, "entry_keys"},
|
||||
{0x0020, "image_key"},
|
||||
{0x0080, "general_digests"},
|
||||
{0x0100, "metas"},
|
||||
{0x0200, "entry_names"},
|
||||
{0x0400, "license.dat"},
|
||||
{0x0401, "license.info"},
|
||||
{0x0402, "nptitle.dat"},
|
||||
{0x0403, "npbind.dat"},
|
||||
{0x0404, "selfinfo.dat"},
|
||||
{0x0406, "imageinfo.dat"},
|
||||
{0x0407, "target-deltainfo.dat"},
|
||||
{0x0408, "origin-deltainfo.dat"},
|
||||
{0x0409, "psreserved.dat"},
|
||||
{0x1000, "param.sfo"},
|
||||
{0x1001, "playgo-chunk.dat"},
|
||||
{0x1002, "playgo-chunk.sha"},
|
||||
{0x1003, "playgo-manifest.xml"},
|
||||
{0x1004, "pronunciation.xml"},
|
||||
{0x1005, "pronunciation.sig"},
|
||||
{0x1006, "pic1.png"},
|
||||
{0x1007, "pubtoolinfo.dat"},
|
||||
{0x1008, "app/playgo-chunk.dat"},
|
||||
{0x1009, "app/playgo-chunk.sha"},
|
||||
{0x100A, "app/playgo-manifest.xml"},
|
||||
{0x100B, "shareparam.json"},
|
||||
{0x100C, "shareoverlayimage.png"},
|
||||
{0x100D, "save_data.png"},
|
||||
{0x100E, "shareprivacyguardimage.png"},
|
||||
{0x1200, "icon0.png"},
|
||||
{0x1201, "icon0_00.png"},
|
||||
{0x1202, "icon0_01.png"},
|
||||
{0x1203, "icon0_02.png"},
|
||||
{0x1204, "icon0_03.png"},
|
||||
{0x1205, "icon0_04.png"},
|
||||
{0x1206, "icon0_05.png"},
|
||||
{0x1207, "icon0_06.png"},
|
||||
{0x1208, "icon0_07.png"},
|
||||
{0x1209, "icon0_08.png"},
|
||||
{0x120A, "icon0_09.png"},
|
||||
{0x120B, "icon0_10.png"},
|
||||
{0x120C, "icon0_11.png"},
|
||||
{0x120D, "icon0_12.png"},
|
||||
{0x120E, "icon0_13.png"},
|
||||
{0x120F, "icon0_14.png"},
|
||||
{0x1210, "icon0_15.png"},
|
||||
{0x1211, "icon0_16.png"},
|
||||
{0x1212, "icon0_17.png"},
|
||||
{0x1213, "icon0_18.png"},
|
||||
{0x1214, "icon0_19.png"},
|
||||
{0x1215, "icon0_20.png"},
|
||||
{0x1216, "icon0_21.png"},
|
||||
{0x1217, "icon0_22.png"},
|
||||
{0x1218, "icon0_23.png"},
|
||||
{0x1219, "icon0_24.png"},
|
||||
{0x121A, "icon0_25.png"},
|
||||
{0x121B, "icon0_26.png"},
|
||||
{0x121C, "icon0_27.png"},
|
||||
{0x121D, "icon0_28.png"},
|
||||
{0x121E, "icon0_29.png"},
|
||||
{0x121F, "icon0_30.png"},
|
||||
{0x1220, "pic0.png"},
|
||||
{0x1240, "snd0.at9"},
|
||||
{0x1241, "pic1_00.png"},
|
||||
{0x1242, "pic1_01.png"},
|
||||
{0x1243, "pic1_02.png"},
|
||||
{0x1244, "pic1_03.png"},
|
||||
{0x1245, "pic1_04.png"},
|
||||
{0x1246, "pic1_05.png"},
|
||||
{0x1247, "pic1_06.png"},
|
||||
{0x1248, "pic1_07.png"},
|
||||
{0x1249, "pic1_08.png"},
|
||||
{0x124A, "pic1_09.png"},
|
||||
{0x124B, "pic1_10.png"},
|
||||
{0x124C, "pic1_11.png"},
|
||||
{0x124D, "pic1_12.png"},
|
||||
{0x124E, "pic1_13.png"},
|
||||
{0x124F, "pic1_14.png"},
|
||||
{0x1250, "pic1_15.png"},
|
||||
{0x1251, "pic1_16.png"},
|
||||
{0x1252, "pic1_17.png"},
|
||||
{0x1253, "pic1_18.png"},
|
||||
{0x1254, "pic1_19.png"},
|
||||
{0x1255, "pic1_20.png"},
|
||||
{0x1256, "pic1_21.png"},
|
||||
{0x1257, "pic1_22.png"},
|
||||
{0x1258, "pic1_23.png"},
|
||||
{0x1259, "pic1_24.png"},
|
||||
{0x125A, "pic1_25.png"},
|
||||
{0x125B, "pic1_26.png"},
|
||||
{0x125C, "pic1_27.png"},
|
||||
{0x125D, "pic1_28.png"},
|
||||
{0x125E, "pic1_29.png"},
|
||||
{0x125F, "pic1_30.png"},
|
||||
{0x1260, "changeinfo/changeinfo.xml"},
|
||||
{0x1261, "changeinfo/changeinfo_00.xml"},
|
||||
{0x1262, "changeinfo/changeinfo_01.xml"},
|
||||
{0x1263, "changeinfo/changeinfo_02.xml"},
|
||||
{0x1264, "changeinfo/changeinfo_03.xml"},
|
||||
{0x1265, "changeinfo/changeinfo_04.xml"},
|
||||
{0x1266, "changeinfo/changeinfo_05.xml"},
|
||||
{0x1267, "changeinfo/changeinfo_06.xml"},
|
||||
{0x1268, "changeinfo/changeinfo_07.xml"},
|
||||
{0x1269, "changeinfo/changeinfo_08.xml"},
|
||||
{0x126A, "changeinfo/changeinfo_09.xml"},
|
||||
{0x126B, "changeinfo/changeinfo_10.xml"},
|
||||
{0x126C, "changeinfo/changeinfo_11.xml"},
|
||||
{0x126D, "changeinfo/changeinfo_12.xml"},
|
||||
{0x126E, "changeinfo/changeinfo_13.xml"},
|
||||
{0x126F, "changeinfo/changeinfo_14.xml"},
|
||||
{0x1270, "changeinfo/changeinfo_15.xml"},
|
||||
{0x1271, "changeinfo/changeinfo_16.xml"},
|
||||
{0x1272, "changeinfo/changeinfo_17.xml"},
|
||||
{0x1273, "changeinfo/changeinfo_18.xml"},
|
||||
{0x1274, "changeinfo/changeinfo_19.xml"},
|
||||
{0x1275, "changeinfo/changeinfo_20.xml"},
|
||||
{0x1276, "changeinfo/changeinfo_21.xml"},
|
||||
{0x1277, "changeinfo/changeinfo_22.xml"},
|
||||
{0x1278, "changeinfo/changeinfo_23.xml"},
|
||||
{0x1279, "changeinfo/changeinfo_24.xml"},
|
||||
{0x127A, "changeinfo/changeinfo_25.xml"},
|
||||
{0x127B, "changeinfo/changeinfo_26.xml"},
|
||||
{0x127C, "changeinfo/changeinfo_27.xml"},
|
||||
{0x127D, "changeinfo/changeinfo_28.xml"},
|
||||
{0x127E, "changeinfo/changeinfo_29.xml"},
|
||||
{0x127F, "changeinfo/changeinfo_30.xml"},
|
||||
{0x1280, "icon0.dds"},
|
||||
{0x1281, "icon0_00.dds"},
|
||||
{0x1282, "icon0_01.dds"},
|
||||
{0x1283, "icon0_02.dds"},
|
||||
{0x1284, "icon0_03.dds"},
|
||||
{0x1285, "icon0_04.dds"},
|
||||
{0x1286, "icon0_05.dds"},
|
||||
{0x1287, "icon0_06.dds"},
|
||||
{0x1288, "icon0_07.dds"},
|
||||
{0x1289, "icon0_08.dds"},
|
||||
{0x128A, "icon0_09.dds"},
|
||||
{0x128B, "icon0_10.dds"},
|
||||
{0x128C, "icon0_11.dds"},
|
||||
{0x128D, "icon0_12.dds"},
|
||||
{0x128E, "icon0_13.dds"},
|
||||
{0x128F, "icon0_14.dds"},
|
||||
{0x1290, "icon0_15.dds"},
|
||||
{0x1291, "icon0_16.dds"},
|
||||
{0x1292, "icon0_17.dds"},
|
||||
{0x1293, "icon0_18.dds"},
|
||||
{0x1294, "icon0_19.dds"},
|
||||
{0x1295, "icon0_20.dds"},
|
||||
{0x1296, "icon0_21.dds"},
|
||||
{0x1297, "icon0_22.dds"},
|
||||
{0x1298, "icon0_23.dds"},
|
||||
{0x1299, "icon0_24.dds"},
|
||||
{0x129A, "icon0_25.dds"},
|
||||
{0x129B, "icon0_26.dds"},
|
||||
{0x129C, "icon0_27.dds"},
|
||||
{0x129D, "icon0_28.dds"},
|
||||
{0x129E, "icon0_29.dds"},
|
||||
{0x129F, "icon0_30.dds"},
|
||||
{0x12A0, "pic0.dds"},
|
||||
{0x12C0, "pic1.dds"},
|
||||
{0x12C1, "pic1_00.dds"},
|
||||
{0x12C2, "pic1_01.dds"},
|
||||
{0x12C3, "pic1_02.dds"},
|
||||
{0x12C4, "pic1_03.dds"},
|
||||
{0x12C5, "pic1_04.dds"},
|
||||
{0x12C6, "pic1_05.dds"},
|
||||
{0x12C7, "pic1_06.dds"},
|
||||
{0x12C8, "pic1_07.dds"},
|
||||
{0x12C9, "pic1_08.dds"},
|
||||
{0x12CA, "pic1_09.dds"},
|
||||
{0x12CB, "pic1_10.dds"},
|
||||
{0x12CC, "pic1_11.dds"},
|
||||
{0x12CD, "pic1_12.dds"},
|
||||
{0x12CE, "pic1_13.dds"},
|
||||
{0x12CF, "pic1_14.dds"},
|
||||
{0x12D0, "pic1_15.dds"},
|
||||
{0x12D1, "pic1_16.dds"},
|
||||
{0x12D2, "pic1_17.dds"},
|
||||
{0x12D3, "pic1_18.dds"},
|
||||
{0x12D4, "pic1_19.dds"},
|
||||
{0x12D5, "pic1_20.dds"},
|
||||
{0x12D6, "pic1_21.dds"},
|
||||
{0x12D7, "pic1_22.dds"},
|
||||
{0x12D8, "pic1_23.dds"},
|
||||
{0x12D9, "pic1_24.dds"},
|
||||
{0x12DA, "pic1_25.dds"},
|
||||
{0x12DB, "pic1_26.dds"},
|
||||
{0x12DC, "pic1_27.dds"},
|
||||
{0x12DD, "pic1_28.dds"},
|
||||
{0x12DE, "pic1_29.dds"},
|
||||
{0x12DF, "pic1_30.dds"},
|
||||
{0x1400, "trophy/trophy00.trp"},
|
||||
{0x1401, "trophy/trophy01.trp"},
|
||||
{0x1402, "trophy/trophy02.trp"},
|
||||
{0x1403, "trophy/trophy03.trp"},
|
||||
{0x1404, "trophy/trophy04.trp"},
|
||||
{0x1405, "trophy/trophy05.trp"},
|
||||
{0x1406, "trophy/trophy06.trp"},
|
||||
{0x1407, "trophy/trophy07.trp"},
|
||||
{0x1408, "trophy/trophy08.trp"},
|
||||
{0x1409, "trophy/trophy09.trp"},
|
||||
{0x140A, "trophy/trophy10.trp"},
|
||||
{0x140B, "trophy/trophy11.trp"},
|
||||
{0x140C, "trophy/trophy12.trp"},
|
||||
{0x140D, "trophy/trophy13.trp"},
|
||||
{0x140E, "trophy/trophy14.trp"},
|
||||
{0x140F, "trophy/trophy15.trp"},
|
||||
{0x1410, "trophy/trophy16.trp"},
|
||||
{0x1411, "trophy/trophy17.trp"},
|
||||
{0x1412, "trophy/trophy18.trp"},
|
||||
{0x1413, "trophy/trophy19.trp"},
|
||||
{0x1414, "trophy/trophy20.trp"},
|
||||
{0x1415, "trophy/trophy21.trp"},
|
||||
{0x1416, "trophy/trophy22.trp"},
|
||||
{0x1417, "trophy/trophy23.trp"},
|
||||
{0x1418, "trophy/trophy24.trp"},
|
||||
{0x1419, "trophy/trophy25.trp"},
|
||||
{0x141A, "trophy/trophy26.trp"},
|
||||
{0x141B, "trophy/trophy27.trp"},
|
||||
{0x141C, "trophy/trophy28.trp"},
|
||||
{0x141D, "trophy/trophy29.trp"},
|
||||
{0x141E, "trophy/trophy30.trp"},
|
||||
{0x141F, "trophy/trophy31.trp"},
|
||||
{0x1420, "trophy/trophy32.trp"},
|
||||
{0x1421, "trophy/trophy33.trp"},
|
||||
{0x1422, "trophy/trophy34.trp"},
|
||||
{0x1423, "trophy/trophy35.trp"},
|
||||
{0x1424, "trophy/trophy36.trp"},
|
||||
{0x1425, "trophy/trophy37.trp"},
|
||||
{0x1426, "trophy/trophy38.trp"},
|
||||
{0x1427, "trophy/trophy39.trp"},
|
||||
{0x1428, "trophy/trophy40.trp"},
|
||||
{0x1429, "trophy/trophy41.trp"},
|
||||
{0x142A, "trophy/trophy42.trp"},
|
||||
{0x142B, "trophy/trophy43.trp"},
|
||||
{0x142C, "trophy/trophy44.trp"},
|
||||
{0x142D, "trophy/trophy45.trp"},
|
||||
{0x142E, "trophy/trophy46.trp"},
|
||||
{0x142F, "trophy/trophy47.trp"},
|
||||
{0x1430, "trophy/trophy48.trp"},
|
||||
{0x1431, "trophy/trophy49.trp"},
|
||||
{0x1432, "trophy/trophy50.trp"},
|
||||
{0x1433, "trophy/trophy51.trp"},
|
||||
{0x1434, "trophy/trophy52.trp"},
|
||||
{0x1435, "trophy/trophy53.trp"},
|
||||
{0x1436, "trophy/trophy54.trp"},
|
||||
{0x1437, "trophy/trophy55.trp"},
|
||||
{0x1438, "trophy/trophy56.trp"},
|
||||
{0x1439, "trophy/trophy57.trp"},
|
||||
{0x143A, "trophy/trophy58.trp"},
|
||||
{0x143B, "trophy/trophy59.trp"},
|
||||
{0x143C, "trophy/trophy60.trp"},
|
||||
{0x143D, "trophy/trophy61.trp"},
|
||||
{0x143E, "trophy/trophy62.trp"},
|
||||
{0x143F, "trophy/trophy63.trp"},
|
||||
{0x1440, "trophy/trophy64.trp"},
|
||||
{0x1441, "trophy/trophy65.trp"},
|
||||
{0x1442, "trophy/trophy66.trp"},
|
||||
{0x1443, "trophy/trophy67.trp"},
|
||||
{0x1444, "trophy/trophy68.trp"},
|
||||
{0x1445, "trophy/trophy69.trp"},
|
||||
{0x1446, "trophy/trophy70.trp"},
|
||||
{0x1447, "trophy/trophy71.trp"},
|
||||
{0x1448, "trophy/trophy72.trp"},
|
||||
{0x1449, "trophy/trophy73.trp"},
|
||||
{0x144A, "trophy/trophy74.trp"},
|
||||
{0x144B, "trophy/trophy75.trp"},
|
||||
{0x144C, "trophy/trophy76.trp"},
|
||||
{0x144D, "trophy/trophy77.trp"},
|
||||
{0x144E, "trophy/trophy78.trp"},
|
||||
{0x144F, "trophy/trophy79.trp"},
|
||||
{0x1450, "trophy/trophy80.trp"},
|
||||
{0x1451, "trophy/trophy81.trp"},
|
||||
{0x1452, "trophy/trophy82.trp"},
|
||||
{0x1453, "trophy/trophy83.trp"},
|
||||
{0x1454, "trophy/trophy84.trp"},
|
||||
{0x1455, "trophy/trophy85.trp"},
|
||||
{0x1456, "trophy/trophy86.trp"},
|
||||
{0x1457, "trophy/trophy87.trp"},
|
||||
{0x1458, "trophy/trophy88.trp"},
|
||||
{0x1459, "trophy/trophy89.trp"},
|
||||
{0x145A, "trophy/trophy90.trp"},
|
||||
{0x145B, "trophy/trophy91.trp"},
|
||||
{0x145C, "trophy/trophy92.trp"},
|
||||
{0x145D, "trophy/trophy93.trp"},
|
||||
{0x145E, "trophy/trophy94.trp"},
|
||||
{0x145F, "trophy/trophy95.trp"},
|
||||
{0x1460, "trophy/trophy96.trp"},
|
||||
{0x1461, "trophy/trophy97.trp"},
|
||||
{0x1462, "trophy/trophy98.trp"},
|
||||
{0x1463, "trophy/trophy99.trp"},
|
||||
{0x1600, "keymap_rp/001.png"},
|
||||
{0x1601, "keymap_rp/002.png"},
|
||||
{0x1602, "keymap_rp/003.png"},
|
||||
{0x1603, "keymap_rp/004.png"},
|
||||
{0x1604, "keymap_rp/005.png"},
|
||||
{0x1605, "keymap_rp/006.png"},
|
||||
{0x1606, "keymap_rp/007.png"},
|
||||
{0x1607, "keymap_rp/008.png"},
|
||||
{0x1608, "keymap_rp/009.png"},
|
||||
{0x1609, "keymap_rp/010.png"},
|
||||
{0x1610, "keymap_rp/00/001.png"},
|
||||
{0x1611, "keymap_rp/00/002.png"},
|
||||
{0x1612, "keymap_rp/00/003.png"},
|
||||
{0x1613, "keymap_rp/00/004.png"},
|
||||
{0x1614, "keymap_rp/00/005.png"},
|
||||
{0x1615, "keymap_rp/00/006.png"},
|
||||
{0x1616, "keymap_rp/00/007.png"},
|
||||
{0x1617, "keymap_rp/00/008.png"},
|
||||
{0x1618, "keymap_rp/00/009.png"},
|
||||
{0x1619, "keymap_rp/00/010.png"},
|
||||
{0x1620, "keymap_rp/01/001.png"},
|
||||
{0x1621, "keymap_rp/01/002.png"},
|
||||
{0x1622, "keymap_rp/01/003.png"},
|
||||
{0x1623, "keymap_rp/01/004.png"},
|
||||
{0x1624, "keymap_rp/01/005.png"},
|
||||
{0x1625, "keymap_rp/01/006.png"},
|
||||
{0x1626, "keymap_rp/01/007.png"},
|
||||
{0x1627, "keymap_rp/01/008.png"},
|
||||
{0x1628, "keymap_rp/01/009.png"},
|
||||
{0x1629, "keymap_rp/01/010.png"},
|
||||
{0x1630, "keymap_rp/02/001.png"},
|
||||
{0x1631, "keymap_rp/02/002.png"},
|
||||
{0x1632, "keymap_rp/02/003.png"},
|
||||
{0x1633, "keymap_rp/02/004.png"},
|
||||
{0x1634, "keymap_rp/02/005.png"},
|
||||
{0x1635, "keymap_rp/02/006.png"},
|
||||
{0x1636, "keymap_rp/02/007.png"},
|
||||
{0x1637, "keymap_rp/02/008.png"},
|
||||
{0x1638, "keymap_rp/02/009.png"},
|
||||
{0x1639, "keymap_rp/02/010.png"},
|
||||
{0x1640, "keymap_rp/03/001.png"},
|
||||
{0x1641, "keymap_rp/03/002.png"},
|
||||
{0x1642, "keymap_rp/03/003.png"},
|
||||
{0x1643, "keymap_rp/03/004.png"},
|
||||
{0x1644, "keymap_rp/03/005.png"},
|
||||
{0x1645, "keymap_rp/03/006.png"},
|
||||
{0x1646, "keymap_rp/03/007.png"},
|
||||
{0x1647, "keymap_rp/03/008.png"},
|
||||
{0x1648, "keymap_rp/03/0010.png"},
|
||||
{0x1650, "keymap_rp/04/001.png"},
|
||||
{0x1651, "keymap_rp/04/002.png"},
|
||||
{0x1652, "keymap_rp/04/003.png"},
|
||||
{0x1653, "keymap_rp/04/004.png"},
|
||||
{0x1654, "keymap_rp/04/005.png"},
|
||||
{0x1655, "keymap_rp/04/006.png"},
|
||||
{0x1656, "keymap_rp/04/007.png"},
|
||||
{0x1657, "keymap_rp/04/008.png"},
|
||||
{0x1658, "keymap_rp/04/009.png"},
|
||||
{0x1659, "keymap_rp/04/010.png"},
|
||||
{0x1660, "keymap_rp/05/001.png"},
|
||||
{0x1661, "keymap_rp/05/002.png"},
|
||||
{0x1662, "keymap_rp/05/003.png"},
|
||||
{0x1663, "keymap_rp/05/004.png"},
|
||||
{0x1664, "keymap_rp/05/005.png"},
|
||||
{0x1665, "keymap_rp/05/006.png"},
|
||||
{0x1666, "keymap_rp/05/007.png"},
|
||||
{0x1667, "keymap_rp/05/008.png"},
|
||||
{0x1668, "keymap_rp/05/009.png"},
|
||||
{0x1669, "keymap_rp/05/010.png"},
|
||||
{0x1670, "keymap_rp/06/001.png"},
|
||||
{0x1671, "keymap_rp/06/002.png"},
|
||||
{0x1672, "keymap_rp/06/003.png"},
|
||||
{0x1673, "keymap_rp/06/004.png"},
|
||||
{0x1674, "keymap_rp/06/005.png"},
|
||||
{0x1675, "keymap_rp/06/006.png"},
|
||||
{0x1676, "keymap_rp/06/007.png"},
|
||||
{0x1677, "keymap_rp/06/008.png"},
|
||||
{0x1678, "keymap_rp/06/009.png"},
|
||||
{0x1679, "keymap_rp/06/010.png"},
|
||||
{0x1680, "keymap_rp/07/001.png"},
|
||||
{0x1681, "keymap_rp/07/002.png"},
|
||||
{0x1682, "keymap_rp/07/003.png"},
|
||||
{0x1683, "keymap_rp/07/004.png"},
|
||||
{0x1684, "keymap_rp/07/005.png"},
|
||||
{0x1685, "keymap_rp/07/006.png"},
|
||||
{0x1686, "keymap_rp/07/007.png"},
|
||||
{0x1687, "keymap_rp/07/008.png"},
|
||||
{0x1688, "keymap_rp/07/009.png"},
|
||||
{0x1689, "keymap_rp/07/010.png"},
|
||||
{0x1690, "keymap_rp/08/001.png"},
|
||||
{0x1691, "keymap_rp/08/002.png"},
|
||||
{0x1692, "keymap_rp/08/003.png"},
|
||||
{0x1693, "keymap_rp/08/004.png"},
|
||||
{0x1694, "keymap_rp/08/005.png"},
|
||||
{0x1695, "keymap_rp/08/006.png"},
|
||||
{0x1696, "keymap_rp/08/007.png"},
|
||||
{0x1697, "keymap_rp/08/008.png"},
|
||||
{0x1698, "keymap_rp/08/009.png"},
|
||||
{0x1699, "keymap_rp/08/010.png"},
|
||||
{0x16A0, "keymap_rp/09/001.png"},
|
||||
{0x16A1, "keymap_rp/09/002.png"},
|
||||
{0x16A2, "keymap_rp/09/003.png"},
|
||||
{0x16A3, "keymap_rp/09/004.png"},
|
||||
{0x16A4, "keymap_rp/09/005.png"},
|
||||
{0x16A5, "keymap_rp/09/006.png"},
|
||||
{0x16A6, "keymap_rp/09/007.png"},
|
||||
{0x16A7, "keymap_rp/09/008.png"},
|
||||
{0x16A8, "keymap_rp/09/009.png"},
|
||||
{0x16A9, "keymap_rp/09/010.png"},
|
||||
{0x16B0, "keymap_rp/10/001.png"},
|
||||
{0x16B1, "keymap_rp/10/002.png"},
|
||||
{0x16B2, "keymap_rp/10/003.png"},
|
||||
{0x16B3, "keymap_rp/10/004.png"},
|
||||
{0x16B4, "keymap_rp/10/005.png"},
|
||||
{0x16B5, "keymap_rp/10/006.png"},
|
||||
{0x16B6, "keymap_rp/10/007.png"},
|
||||
{0x16B7, "keymap_rp/10/008.png"},
|
||||
{0x16B8, "keymap_rp/10/009.png"},
|
||||
{0x16B9, "keymap_rp/10/010.png"},
|
||||
{0x16C0, "keymap_rp/11/001.png"},
|
||||
{0x16C1, "keymap_rp/11/002.png"},
|
||||
{0x16C2, "keymap_rp/11/003.png"},
|
||||
{0x16C3, "keymap_rp/11/004.png"},
|
||||
{0x16C4, "keymap_rp/11/005.png"},
|
||||
{0x16C5, "keymap_rp/11/006.png"},
|
||||
{0x16C6, "keymap_rp/11/007.png"},
|
||||
{0x16C7, "keymap_rp/11/008.png"},
|
||||
{0x16C8, "keymap_rp/11/009.png"},
|
||||
{0x16C9, "keymap_rp/11/010.png"},
|
||||
{0x16D0, "keymap_rp/12/001.png"},
|
||||
{0x16D1, "keymap_rp/12/002.png"},
|
||||
{0x16D2, "keymap_rp/12/003.png"},
|
||||
{0x16D3, "keymap_rp/12/004.png"},
|
||||
{0x16D4, "keymap_rp/12/005.png"},
|
||||
{0x16D5, "keymap_rp/12/006.png"},
|
||||
{0x16D6, "keymap_rp/12/007.png"},
|
||||
{0x16D7, "keymap_rp/12/008.png"},
|
||||
{0x16D8, "keymap_rp/12/009.png"},
|
||||
{0x16D9, "keymap_rp/12/010.png"},
|
||||
{0x16E0, "keymap_rp/13/001.png"},
|
||||
{0x16E1, "keymap_rp/13/002.png"},
|
||||
{0x16E2, "keymap_rp/13/003.png"},
|
||||
{0x16E3, "keymap_rp/13/004.png"},
|
||||
{0x16E4, "keymap_rp/13/005.png"},
|
||||
{0x16E5, "keymap_rp/13/006.png"},
|
||||
{0x16E6, "keymap_rp/13/007.png"},
|
||||
{0x16E7, "keymap_rp/13/008.png"},
|
||||
{0x16E8, "keymap_rp/13/009.png"},
|
||||
{0x16E9, "keymap_rp/13/010.png"},
|
||||
{0x16F0, "keymap_rp/14/001.png"},
|
||||
{0x16F1, "keymap_rp/14/002.png"},
|
||||
{0x16F2, "keymap_rp/14/003.png"},
|
||||
{0x16F3, "keymap_rp/14/004.png"},
|
||||
{0x16F4, "keymap_rp/14/005.png"},
|
||||
{0x16F5, "keymap_rp/14/006.png"},
|
||||
{0x16F6, "keymap_rp/14/007.png"},
|
||||
{0x16F7, "keymap_rp/14/008.png"},
|
||||
{0x16F8, "keymap_rp/14/009.png"},
|
||||
{0x16F9, "keymap_rp/14/010.png"},
|
||||
{0x1700, "keymap_rp/15/001.png"},
|
||||
{0x1701, "keymap_rp/15/002.png"},
|
||||
{0x1702, "keymap_rp/15/003.png"},
|
||||
{0x1703, "keymap_rp/15/004.png"},
|
||||
{0x1704, "keymap_rp/15/005.png"},
|
||||
{0x1705, "keymap_rp/15/006.png"},
|
||||
{0x1706, "keymap_rp/15/007.png"},
|
||||
{0x1707, "keymap_rp/15/008.png"},
|
||||
{0x1708, "keymap_rp/15/009.png"},
|
||||
{0x1709, "keymap_rp/15/010.png"},
|
||||
{0x1710, "keymap_rp/16/001.png"},
|
||||
{0x1711, "keymap_rp/16/002.png"},
|
||||
{0x1712, "keymap_rp/16/003.png"},
|
||||
{0x1713, "keymap_rp/16/004.png"},
|
||||
{0x1714, "keymap_rp/16/005.png"},
|
||||
{0x1715, "keymap_rp/16/006.png"},
|
||||
{0x1716, "keymap_rp/16/007.png"},
|
||||
{0x1717, "keymap_rp/16/008.png"},
|
||||
{0x1718, "keymap_rp/16/009.png"},
|
||||
{0x1719, "keymap_rp/16/010.png"},
|
||||
{0x1720, "keymap_rp/17/001.png"},
|
||||
{0x1721, "keymap_rp/17/002.png"},
|
||||
{0x1722, "keymap_rp/17/003.png"},
|
||||
{0x1723, "keymap_rp/17/004.png"},
|
||||
{0x1724, "keymap_rp/17/005.png"},
|
||||
{0x1725, "keymap_rp/17/006.png"},
|
||||
{0x1726, "keymap_rp/17/007.png"},
|
||||
{0x1727, "keymap_rp/17/008.png"},
|
||||
{0x1728, "keymap_rp/17/009.png"},
|
||||
{0x1729, "keymap_rp/17/010.png"},
|
||||
{0x1730, "keymap_rp/18/001.png"},
|
||||
{0x1731, "keymap_rp/18/002.png"},
|
||||
{0x1732, "keymap_rp/18/003.png"},
|
||||
{0x1733, "keymap_rp/18/004.png"},
|
||||
{0x1734, "keymap_rp/18/005.png"},
|
||||
{0x1735, "keymap_rp/18/006.png"},
|
||||
{0x1736, "keymap_rp/18/007.png"},
|
||||
{0x1737, "keymap_rp/18/008.png"},
|
||||
{0x1738, "keymap_rp/18/009.png"},
|
||||
{0x1739, "keymap_rp/18/010.png"},
|
||||
{0x1740, "keymap_rp/19/001.png"},
|
||||
{0x1741, "keymap_rp/19/002.png"},
|
||||
{0x1742, "keymap_rp/19/003.png"},
|
||||
{0x1743, "keymap_rp/19/004.png"},
|
||||
{0x1744, "keymap_rp/19/005.png"},
|
||||
{0x1745, "keymap_rp/19/006.png"},
|
||||
{0x1746, "keymap_rp/19/007.png"},
|
||||
{0x1747, "keymap_rp/19/008.png"},
|
||||
{0x1748, "keymap_rp/19/009.png"},
|
||||
{0x1749, "keymap_rp/19/010.png"},
|
||||
{0x1750, "keymap_rp/20/001.png"},
|
||||
{0x1751, "keymap_rp/20/002.png"},
|
||||
{0x1752, "keymap_rp/20/003.png"},
|
||||
{0x1753, "keymap_rp/20/004.png"},
|
||||
{0x1754, "keymap_rp/20/005.png"},
|
||||
{0x1755, "keymap_rp/20/006.png"},
|
||||
{0x1756, "keymap_rp/20/007.png"},
|
||||
{0x1757, "keymap_rp/20/008.png"},
|
||||
{0x1758, "keymap_rp/20/009.png"},
|
||||
{0x1759, "keymap_rp/20/010.png"},
|
||||
{0x1760, "keymap_rp/21/001.png"},
|
||||
{0x1761, "keymap_rp/21/002.png"},
|
||||
{0x1762, "keymap_rp/21/003.png"},
|
||||
{0x1763, "keymap_rp/21/004.png"},
|
||||
{0x1764, "keymap_rp/21/005.png"},
|
||||
{0x1765, "keymap_rp/21/006.png"},
|
||||
{0x1766, "keymap_rp/21/007.png"},
|
||||
{0x1767, "keymap_rp/21/008.png"},
|
||||
{0x1768, "keymap_rp/21/009.png"},
|
||||
{0x1769, "keymap_rp/21/010.png"},
|
||||
{0x1770, "keymap_rp/22/001.png"},
|
||||
{0x1771, "keymap_rp/22/002.png"},
|
||||
{0x1772, "keymap_rp/22/003.png"},
|
||||
{0x1773, "keymap_rp/22/004.png"},
|
||||
{0x1774, "keymap_rp/22/005.png"},
|
||||
{0x1775, "keymap_rp/22/006.png"},
|
||||
{0x1776, "keymap_rp/22/007.png"},
|
||||
{0x1777, "keymap_rp/22/008.png"},
|
||||
{0x1778, "keymap_rp/22/009.png"},
|
||||
{0x1779, "keymap_rp/22/010.png"},
|
||||
{0x1780, "keymap_rp/23/001.png"},
|
||||
{0x1781, "keymap_rp/23/002.png"},
|
||||
{0x1782, "keymap_rp/23/003.png"},
|
||||
{0x1783, "keymap_rp/23/004.png"},
|
||||
{0x1784, "keymap_rp/23/005.png"},
|
||||
{0x1785, "keymap_rp/23/006.png"},
|
||||
{0x1786, "keymap_rp/23/007.png"},
|
||||
{0x1787, "keymap_rp/23/008.png"},
|
||||
{0x1788, "keymap_rp/23/009.png"},
|
||||
{0x1789, "keymap_rp/23/010.png"},
|
||||
{0x1790, "keymap_rp/24/001.png"},
|
||||
{0x1791, "keymap_rp/24/002.png"},
|
||||
{0x1792, "keymap_rp/24/003.png"},
|
||||
{0x1793, "keymap_rp/24/004.png"},
|
||||
{0x1794, "keymap_rp/24/005.png"},
|
||||
{0x1795, "keymap_rp/24/006.png"},
|
||||
{0x1796, "keymap_rp/24/007.png"},
|
||||
{0x1797, "keymap_rp/24/008.png"},
|
||||
{0x1798, "keymap_rp/24/009.png"},
|
||||
{0x1799, "keymap_rp/24/010.png"},
|
||||
{0x17A0, "keymap_rp/25/001.png"},
|
||||
{0x17A1, "keymap_rp/25/002.png"},
|
||||
{0x17A2, "keymap_rp/25/003.png"},
|
||||
{0x17A3, "keymap_rp/25/004.png"},
|
||||
{0x17A4, "keymap_rp/25/005.png"},
|
||||
{0x17A5, "keymap_rp/25/006.png"},
|
||||
{0x17A6, "keymap_rp/25/007.png"},
|
||||
{0x17A7, "keymap_rp/25/008.png"},
|
||||
{0x17A8, "keymap_rp/25/009.png"},
|
||||
{0x17A9, "keymap_rp/25/010.png"},
|
||||
{0x17B0, "keymap_rp/26/001.png"},
|
||||
{0x17B1, "keymap_rp/26/002.png"},
|
||||
{0x17B2, "keymap_rp/26/003.png"},
|
||||
{0x17B3, "keymap_rp/26/004.png"},
|
||||
{0x17B4, "keymap_rp/26/005.png"},
|
||||
{0x17B5, "keymap_rp/26/006.png"},
|
||||
{0x17B6, "keymap_rp/26/007.png"},
|
||||
{0x17B7, "keymap_rp/26/008.png"},
|
||||
{0x17B8, "keymap_rp/26/009.png"},
|
||||
{0x17B9, "keymap_rp/26/010.png"},
|
||||
{0x17C0, "keymap_rp/27/001.png"},
|
||||
{0x17C1, "keymap_rp/27/002.png"},
|
||||
{0x17C2, "keymap_rp/27/003.png"},
|
||||
{0x17C3, "keymap_rp/27/004.png"},
|
||||
{0x17C4, "keymap_rp/27/005.png"},
|
||||
{0x17C5, "keymap_rp/27/006.png"},
|
||||
{0x17C6, "keymap_rp/27/007.png"},
|
||||
{0x17C7, "keymap_rp/27/008.png"},
|
||||
{0x17C8, "keymap_rp/27/009.png"},
|
||||
{0x17C9, "keymap_rp/27/010.png"},
|
||||
{0x17D0, "keymap_rp/28/001.png"},
|
||||
{0x17D1, "keymap_rp/28/002.png"},
|
||||
{0x17D2, "keymap_rp/28/003.png"},
|
||||
{0x17D3, "keymap_rp/28/004.png"},
|
||||
{0x17D4, "keymap_rp/28/005.png"},
|
||||
{0x17D5, "keymap_rp/28/006.png"},
|
||||
{0x17D6, "keymap_rp/28/007.png"},
|
||||
{0x17D7, "keymap_rp/28/008.png"},
|
||||
{0x17D8, "keymap_rp/28/009.png"},
|
||||
{0x17D9, "keymap_rp/28/010.png"},
|
||||
{0x17E0, "keymap_rp/29/001.png"},
|
||||
{0x17E1, "keymap_rp/29/002.png"},
|
||||
{0x17E2, "keymap_rp/29/003.png"},
|
||||
{0x17E3, "keymap_rp/29/004.png"},
|
||||
{0x17E4, "keymap_rp/29/005.png"},
|
||||
{0x17E5, "keymap_rp/29/006.png"},
|
||||
{0x17E6, "keymap_rp/29/007.png"},
|
||||
{0x17E7, "keymap_rp/29/008.png"},
|
||||
{0x17E8, "keymap_rp/29/009.png"},
|
||||
{0x17E9, "keymap_rp/29/010.png"},
|
||||
{0x17F0, "keymap_rp/30/001.png"},
|
||||
{0x17F1, "keymap_rp/30/002.png"},
|
||||
{0x17F2, "keymap_rp/30/003.png"},
|
||||
{0x17F3, "keymap_rp/30/004.png"},
|
||||
{0x17F4, "keymap_rp/30/005.png"},
|
||||
{0x17F5, "keymap_rp/30/006.png"},
|
||||
{0x17F6, "keymap_rp/30/007.png"},
|
||||
{0x17F7, "keymap_rp/30/008.png"},
|
||||
{0x17F8, "keymap_rp/30/009.png"},
|
||||
{0x17F9, "keymap_rp/30/010.png"},
|
||||
}};
|
||||
|
||||
std::string_view GetEntryNameByType(u32 type) {
|
||||
const auto key = PkgEntryValue{type};
|
||||
const auto it = std::ranges::lower_bound(PkgEntries, key);
|
||||
if (it != PkgEntries.end() && it->type == type) {
|
||||
return it->name;
|
||||
}
|
||||
return "";
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include "common/types.h"
|
||||
|
||||
/// Retrieves the PKG entry name from its type identifier.
|
||||
std::string_view GetEntryNameByType(u32 type);
|
|
@ -1,10 +1,25 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/aes.h"
|
||||
#include "common/config.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/path_util.h"
|
||||
#include "trp.h"
|
||||
#include "core/file_format/trp.h"
|
||||
|
||||
static void DecryptEFSM(std::span<u8, 16> trophyKey, std::span<u8, 16> NPcommID,
|
||||
std::span<u8, 16> efsmIv, std::span<u8> ciphertext,
|
||||
std::span<u8> decrypted) {
|
||||
// Step 1: Encrypt NPcommID
|
||||
std::array<u8, 16> trophyIv{};
|
||||
std::array<u8, 16> trpKey;
|
||||
aes::encrypt_cbc(NPcommID.data(), NPcommID.size(), trophyKey.data(), trophyKey.size(),
|
||||
trophyIv.data(), trpKey.data(), trpKey.size(), false);
|
||||
|
||||
// Step 2: Decrypt EFSM
|
||||
aes::decrypt_cbc(ciphertext.data(), ciphertext.size(), trpKey.data(), trpKey.size(),
|
||||
efsmIv.data(), decrypted.data(), decrypted.size(), nullptr);
|
||||
}
|
||||
|
||||
TRP::TRP() = default;
|
||||
TRP::~TRP() = default;
|
||||
|
@ -54,7 +69,7 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string tit
|
|||
return false;
|
||||
}
|
||||
|
||||
std::array<CryptoPP::byte, 16> user_key{};
|
||||
std::array<u8, 16> user_key{};
|
||||
hexToBytes(user_key_str.c_str(), user_key.data());
|
||||
|
||||
for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) {
|
||||
|
@ -115,7 +130,7 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string tit
|
|||
return false;
|
||||
}
|
||||
file.Read(ESFM);
|
||||
crypto.decryptEFSM(user_key, np_comm_id, esfmIv, ESFM, XML); // decrypt
|
||||
DecryptEFSM(user_key, np_comm_id, esfmIv, ESFM, XML); // decrypt
|
||||
removePadding(XML);
|
||||
std::string xml_name = entry.entry_name;
|
||||
size_t pos = xml_name.find("ESFM");
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "common/endian.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/types.h"
|
||||
#include "core/crypto/crypto.h"
|
||||
|
||||
struct TrpHeader {
|
||||
u32_be magic; // (0xDCA24D00)
|
||||
|
@ -37,10 +36,9 @@ public:
|
|||
void GetNPcommID(const std::filesystem::path& trophyPath, int index);
|
||||
|
||||
private:
|
||||
Crypto crypto;
|
||||
std::vector<u8> NPcommID = std::vector<u8>(12);
|
||||
std::array<u8, 16> np_comm_id{};
|
||||
std::array<u8, 16> esfmIv{};
|
||||
std::filesystem::path trpFilesPath;
|
||||
static constexpr int iv_len = 16;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,29 +9,29 @@
|
|||
|
||||
namespace Libraries::DiscMap {
|
||||
|
||||
int PS4_SYSV_ABI sceDiscMapGetPackageSize() {
|
||||
LOG_WARNING(Lib_DiscMap, "(DUMMY) called");
|
||||
int PS4_SYSV_ABI sceDiscMapGetPackageSize(s64 fflags, int* ret1, int* ret2) {
|
||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD() {
|
||||
LOG_WARNING(Lib_DiscMap, "(DUMMY) called");
|
||||
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD(char* path, s64 offset, s64 nbytes, int* ret) {
|
||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A() {
|
||||
LOG_ERROR(Lib_DiscMap, "(STUBBED) called");
|
||||
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
||||
int* ret2) {
|
||||
*flags = 0;
|
||||
*ret1 = 0;
|
||||
*ret2 = 0;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9() {
|
||||
LOG_ERROR(Lib_DiscMap, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
||||
int* ret2) {
|
||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI Func_E7EBCE96E92F91F8() {
|
||||
LOG_ERROR(Lib_DiscMap, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
||||
}
|
||||
|
||||
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym) {
|
||||
|
|
|
@ -10,10 +10,12 @@ class SymbolsResolver;
|
|||
}
|
||||
namespace Libraries::DiscMap {
|
||||
|
||||
int PS4_SYSV_ABI sceDiscMapGetPackageSize();
|
||||
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD();
|
||||
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A();
|
||||
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9();
|
||||
int PS4_SYSV_ABI sceDiscMapGetPackageSize(s64 fflags, int* ret1, int* ret2);
|
||||
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD(char* path, s64 offset, s64 nbytes, int* ret);
|
||||
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
||||
int* ret2);
|
||||
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
||||
int* ret2);
|
||||
int PS4_SYSV_ABI Func_E7EBCE96E92F91F8();
|
||||
|
||||
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym);
|
||||
|
|
|
@ -65,10 +65,10 @@ constexpr int ORBIS_KERNEL_O_DSYNC = 0x1000;
|
|||
constexpr int ORBIS_KERNEL_O_DIRECT = 0x00010000;
|
||||
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);
|
||||
s64 PS4_SYSV_ABI sceKernelWrite(s32 fd, const void* buf, size_t nbytes);
|
||||
s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, size_t nbytes);
|
||||
s64 PS4_SYSV_ABI sceKernelPread(s32 fd, void* buf, size_t nbytes, s64 offset);
|
||||
s64 PS4_SYSV_ABI sceKernelPwrite(s32 fd, void* buf, size_t nbytes, s64 offset);
|
||||
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -85,17 +85,23 @@ int ErrnoToSceKernelError(int error) {
|
|||
}
|
||||
|
||||
void SetPosixErrno(int e) {
|
||||
// Some error numbers are different between supported OSes or the PS4
|
||||
// Some error numbers are different between supported OSes
|
||||
switch (e) {
|
||||
case EPERM:
|
||||
g_posix_errno = POSIX_EPERM;
|
||||
break;
|
||||
case EAGAIN:
|
||||
g_posix_errno = POSIX_EAGAIN;
|
||||
case ENOENT:
|
||||
g_posix_errno = POSIX_ENOENT;
|
||||
break;
|
||||
case EDEADLK:
|
||||
g_posix_errno = POSIX_EDEADLK;
|
||||
break;
|
||||
case ENOMEM:
|
||||
g_posix_errno = POSIX_ENOMEM;
|
||||
break;
|
||||
case EACCES:
|
||||
g_posix_errno = POSIX_EACCES;
|
||||
break;
|
||||
case EINVAL:
|
||||
g_posix_errno = POSIX_EINVAL;
|
||||
break;
|
||||
|
@ -105,13 +111,14 @@ void SetPosixErrno(int e) {
|
|||
case ERANGE:
|
||||
g_posix_errno = POSIX_ERANGE;
|
||||
break;
|
||||
case EDEADLK:
|
||||
g_posix_errno = POSIX_EDEADLK;
|
||||
case EAGAIN:
|
||||
g_posix_errno = POSIX_EAGAIN;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
g_posix_errno = POSIX_ETIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
LOG_WARNING(Kernel, "Unhandled errno {}", e);
|
||||
g_posix_errno = e;
|
||||
}
|
||||
}
|
||||
|
@ -133,14 +140,6 @@ void PS4_SYSV_ABI sceLibcHeapGetTraceInfo(HeapInfoInfo* info) {
|
|||
info->getSegmentInfo = 0;
|
||||
}
|
||||
|
||||
s64 PS4_SYSV_ABI ps4__write(int d, const char* buf, std::size_t nbytes) {
|
||||
return sceKernelWrite(d, buf, nbytes);
|
||||
}
|
||||
|
||||
s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {
|
||||
return sceKernelRead(d, buf, nbytes);
|
||||
}
|
||||
|
||||
struct OrbisKernelUuid {
|
||||
u32 timeLow;
|
||||
u16 timeMid;
|
||||
|
@ -229,13 +228,10 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("Xjoosiw+XPI", "libkernel", 1, "libkernel", 1, 1, sceKernelUuidCreate);
|
||||
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
|
||||
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
||||
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
||||
LIB_FUNCTION("k+AXqu2-eBc", "libkernel", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
|
||||
sceLibcHeapGetTraceInfo);
|
||||
LIB_FUNCTION("FxVZqBAA7ks", "libkernel", 1, "libkernel", 1, 1, ps4__write);
|
||||
LIB_FUNCTION("FN4gaPmuFV8", "libScePosix", 1, "libkernel", 1, 1, ps4__write);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -115,6 +115,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
|||
Libraries::NpParty::RegisterlibSceNpParty(sym);
|
||||
Libraries::Zlib::RegisterlibSceZlib(sym);
|
||||
Libraries::Hmd::RegisterlibSceHmd(sym);
|
||||
Libraries::DiscMap::RegisterlibSceDiscMap(sym);
|
||||
}
|
||||
|
||||
} // namespace Libraries
|
||||
|
|
|
@ -5,21 +5,480 @@
|
|||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/ngs2/ngs2.h"
|
||||
#include "core/libraries/ngs2/ngs2_custom.h"
|
||||
#include "core/libraries/ngs2/ngs2_error.h"
|
||||
#include "core/libraries/ngs2/ngs2_geom.h"
|
||||
#include "core/libraries/ngs2/ngs2_impl.h"
|
||||
#include "core/libraries/ngs2/ngs2_pan.h"
|
||||
#include "core/libraries/ngs2/ngs2_report.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2CalcWaveformBlock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
// Ngs2
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2CalcWaveformBlock(const OrbisNgs2WaveformFormat* format, u32 samplePos,
|
||||
u32 numSamples, OrbisNgs2WaveformBlock* outBlock) {
|
||||
LOG_INFO(Lib_Ngs2, "samplePos = {}, numSamples = {}", samplePos, numSamples);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
s32 PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo(const OrbisNgs2WaveformFormat* format,
|
||||
u32* outFrameSize, u32* outNumFrameSamples,
|
||||
u32* outUnitsPerFrame, u32* outNumDelaySamples) {
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ParseWaveformData(const void* data, size_t dataSize,
|
||||
OrbisNgs2WaveformInfo* outInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "dataSize = {}", dataSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ParseWaveformFile(const char* path, u64 offset,
|
||||
OrbisNgs2WaveformInfo* outInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "path = {}, offset = {}", path, offset);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ParseWaveformUser(OrbisNgs2ParseReadHandler handler, uintptr_t userData,
|
||||
OrbisNgs2WaveformInfo* outInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "userData = {}", userData);
|
||||
if (!handler) {
|
||||
LOG_ERROR(Lib_Ngs2, "handler is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackCreate(OrbisNgs2Handle systemHandle, u32 rackId,
|
||||
const OrbisNgs2RackOption* option,
|
||||
const OrbisNgs2ContextBufferInfo* bufferInfo,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "rackId = {}", rackId);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackCreateWithAllocator(OrbisNgs2Handle systemHandle, u32 rackId,
|
||||
const OrbisNgs2RackOption* option,
|
||||
const OrbisNgs2BufferAllocator* allocator,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "rackId = {}", rackId);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackDestroy(OrbisNgs2Handle rackHandle,
|
||||
OrbisNgs2ContextBufferInfo* outBufferInfo) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2RackInfo* outInfo,
|
||||
size_t infoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "infoSize = {}", infoSize);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackGetUserData(OrbisNgs2Handle rackHandle, uintptr_t* outUserData) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackGetVoiceHandle(OrbisNgs2Handle rackHandle, u32 voiceIndex,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "voiceIndex = {}", voiceIndex);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackLock(OrbisNgs2Handle rackHandle) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackQueryBufferSize(u32 rackId, const OrbisNgs2RackOption* option,
|
||||
OrbisNgs2ContextBufferInfo* outBufferInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "rackId = {}", rackId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackSetUserData(OrbisNgs2Handle rackHandle, uintptr_t userData) {
|
||||
LOG_INFO(Lib_Ngs2, "userData = {}", userData);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackUnlock(OrbisNgs2Handle rackHandle) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemCreate(const OrbisNgs2SystemOption* option,
|
||||
const OrbisNgs2ContextBufferInfo* bufferInfo,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
s32 result;
|
||||
OrbisNgs2ContextBufferInfo localInfo;
|
||||
if (!bufferInfo || !outHandle) {
|
||||
if (!bufferInfo) {
|
||||
result = ORBIS_NGS2_ERROR_INVALID_BUFFER_INFO;
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system buffer info {}", (void*)bufferInfo);
|
||||
} else {
|
||||
result = ORBIS_NGS2_ERROR_INVALID_OUT_ADDRESS;
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system handle address {}", (void*)outHandle);
|
||||
}
|
||||
|
||||
// TODO: Report errors?
|
||||
} else {
|
||||
// Make bufferInfo copy
|
||||
localInfo.hostBuffer = bufferInfo->hostBuffer;
|
||||
localInfo.hostBufferSize = bufferInfo->hostBufferSize;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
localInfo.reserved[i] = bufferInfo->reserved[i];
|
||||
}
|
||||
localInfo.userData = bufferInfo->userData;
|
||||
|
||||
result = SystemSetup(option, &localInfo, 0, outHandle);
|
||||
}
|
||||
|
||||
// TODO: API reporting?
|
||||
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator(const OrbisNgs2SystemOption* option,
|
||||
const OrbisNgs2BufferAllocator* allocator,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
s32 result;
|
||||
if (allocator && allocator->allocHandler != 0) {
|
||||
OrbisNgs2BufferAllocHandler hostAlloc = allocator->allocHandler;
|
||||
if (outHandle) {
|
||||
OrbisNgs2BufferFreeHandler hostFree = allocator->freeHandler;
|
||||
OrbisNgs2ContextBufferInfo* bufferInfo = 0;
|
||||
result = SystemSetup(option, bufferInfo, 0, 0);
|
||||
if (result >= 0) {
|
||||
uintptr_t sysUserData = allocator->userData;
|
||||
result = hostAlloc(bufferInfo);
|
||||
if (result >= 0) {
|
||||
OrbisNgs2Handle* handleCopy = outHandle;
|
||||
result = SystemSetup(option, bufferInfo, hostFree, handleCopy);
|
||||
if (result < 0) {
|
||||
if (hostFree) {
|
||||
hostFree(bufferInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = ORBIS_NGS2_ERROR_INVALID_OUT_ADDRESS;
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system handle address {}", (void*)outHandle);
|
||||
}
|
||||
} else {
|
||||
result = ORBIS_NGS2_ERROR_INVALID_BUFFER_ALLOCATOR;
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system buffer allocator {}", (void*)allocator);
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemDestroy(OrbisNgs2Handle systemHandle,
|
||||
OrbisNgs2ContextBufferInfo* outBufferInfo) {
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemEnumHandles(OrbisNgs2Handle* aOutHandle, u32 maxHandles) {
|
||||
LOG_INFO(Lib_Ngs2, "maxHandles = {}", maxHandles);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemEnumRackHandles(OrbisNgs2Handle systemHandle,
|
||||
OrbisNgs2Handle* aOutHandle, u32 maxHandles) {
|
||||
LOG_INFO(Lib_Ngs2, "maxHandles = {}", maxHandles);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2SystemInfo* outInfo,
|
||||
size_t infoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "infoSize = {}", infoSize);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemGetUserData(OrbisNgs2Handle systemHandle, uintptr_t* outUserData) {
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemLock(OrbisNgs2Handle systemHandle) {
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemQueryBufferSize(const OrbisNgs2SystemOption* option,
|
||||
OrbisNgs2ContextBufferInfo* outBufferInfo) {
|
||||
s32 result;
|
||||
if (outBufferInfo) {
|
||||
result = SystemSetup(option, outBufferInfo, 0, 0);
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
} else {
|
||||
result = ORBIS_NGS2_ERROR_INVALID_OUT_ADDRESS;
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system buffer info {}", (void*)outBufferInfo);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemRender(OrbisNgs2Handle systemHandle,
|
||||
const OrbisNgs2RenderBufferInfo* aBufferInfo,
|
||||
u32 numBufferInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "numBufferInfo = {}", numBufferInfo);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
static s32 PS4_SYSV_ABI sceNgs2SystemResetOption(OrbisNgs2SystemOption* outOption) {
|
||||
static const OrbisNgs2SystemOption option = {
|
||||
sizeof(OrbisNgs2SystemOption), "", 0, 512, 256, 48000, {0}};
|
||||
|
||||
if (!outOption) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option address {}", (void*)outOption);
|
||||
return ORBIS_NGS2_ERROR_INVALID_OPTION_ADDRESS;
|
||||
}
|
||||
*outOption = option;
|
||||
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemSetGrainSamples(OrbisNgs2Handle systemHandle, u32 numSamples) {
|
||||
LOG_INFO(Lib_Ngs2, "numSamples = {}", numSamples);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemSetSampleRate(OrbisNgs2Handle systemHandle, u32 sampleRate) {
|
||||
LOG_INFO(Lib_Ngs2, "sampleRate = {}", sampleRate);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemSetUserData(OrbisNgs2Handle systemHandle, uintptr_t userData) {
|
||||
LOG_INFO(Lib_Ngs2, "userData = {}", userData);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemUnlock(OrbisNgs2Handle systemHandle) {
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceControl(OrbisNgs2Handle voiceHandle,
|
||||
const OrbisNgs2VoiceParamHeader* paramList) {
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo(OrbisNgs2Handle voiceHandle, u32 matrixId,
|
||||
OrbisNgs2VoiceMatrixInfo* outInfo, size_t outInfoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "matrixId = {}, outInfoSize = {}", matrixId, outInfoSize);
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetOwner(OrbisNgs2Handle voiceHandle, OrbisNgs2Handle* outRackHandle,
|
||||
u32* outVoiceId) {
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetPortInfo(OrbisNgs2Handle voiceHandle, u32 port,
|
||||
OrbisNgs2VoicePortInfo* outInfo, size_t outInfoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "port = {}, outInfoSize = {}", port, outInfoSize);
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetState(OrbisNgs2Handle voiceHandle, OrbisNgs2VoiceState* outState,
|
||||
size_t stateSize) {
|
||||
LOG_INFO(Lib_Ngs2, "stateSize = {}", stateSize);
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetStateFlags(OrbisNgs2Handle voiceHandle, u32* outStateFlags) {
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Ngs2Custom
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo(OrbisNgs2Handle rackHandle, u32 moduleIndex,
|
||||
OrbisNgs2CustomModuleInfo* outInfo,
|
||||
size_t infoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "moduleIndex = {}, infoSize = {}", moduleIndex, infoSize);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Ngs2Geom
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomResetListenerParam(OrbisNgs2GeomListenerParam* outListenerParam) {
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomResetSourceParam(OrbisNgs2GeomSourceParam* outSourceParam) {
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomCalcListener(const OrbisNgs2GeomListenerParam* param,
|
||||
OrbisNgs2GeomListenerWork* outWork, u32 flags) {
|
||||
LOG_INFO(Lib_Ngs2, "flags = {}", flags);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomApply(const OrbisNgs2GeomListenerWork* listener,
|
||||
const OrbisNgs2GeomSourceParam* source,
|
||||
OrbisNgs2GeomAttribute* outAttrib, u32 flags) {
|
||||
LOG_INFO(Lib_Ngs2, "flags = {}", flags);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Ngs2Pan
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2PanInit(OrbisNgs2PanWork* work, const float* aSpeakerAngle, float unitAngle,
|
||||
u32 numSpeakers) {
|
||||
LOG_INFO(Lib_Ngs2, "aSpeakerAngle = {}, unitAngle = {}, numSpeakers = {}", *aSpeakerAngle,
|
||||
unitAngle, numSpeakers);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix(OrbisNgs2PanWork* work, const OrbisNgs2PanParam* aParam,
|
||||
u32 numParams, u32 matrixFormat,
|
||||
float* outVolumeMatrix) {
|
||||
LOG_INFO(Lib_Ngs2, "numParams = {}, matrixFormat = {}", numParams, matrixFormat);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Ngs2Report
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ReportRegisterHandler(u32 reportType, OrbisNgs2ReportHandler handler,
|
||||
uintptr_t userData, OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "reportType = {}, userData = {}", reportType, userData);
|
||||
if (!handler) {
|
||||
LOG_ERROR(Lib_Ngs2, "handler is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ReportUnregisterHandler(OrbisNgs2Handle reportHandle) {
|
||||
if (!reportHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "reportHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2FftInit() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
@ -35,31 +494,6 @@ int PS4_SYSV_ABI sceNgs2FftQuerySize() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomApply() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomCalcListener() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomResetListenerParam() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomResetSourceParam() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2JobSchedulerResetOption() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
@ -80,71 +514,6 @@ int PS4_SYSV_ABI sceNgs2ModuleQueueEnumItems() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2PanInit() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ParseWaveformData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ParseWaveformFile() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ParseWaveformUser() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackCreate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackCreateWithAllocator() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackDestroy() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackGetInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackGetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackGetVoiceHandle() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackLock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackQueryBufferSize() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
@ -155,116 +524,21 @@ int PS4_SYSV_ABI sceNgs2RackRunCommands() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackSetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackUnlock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ReportRegisterHandler() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ReportUnregisterHandler() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemCreate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemDestroy() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemEnumHandles() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemEnumRackHandles() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemGetInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemGetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemLock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemQueryBufferSize() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemRender() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemResetOption() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemRunCommands() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetGrainSamples() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetLoudThreshold() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetSampleRate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemUnlock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamCreate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
@ -300,36 +574,6 @@ int PS4_SYSV_ABI sceNgs2StreamRunCommands() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceControl() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetOwner() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetPortInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetState() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetStateFlags() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/libraries/ngs2/ngs2_impl.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
@ -12,60 +16,253 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2;
|
||||
typedef s32 (*OrbisNgs2ParseReadHandler)(uintptr_t userData, u32 offset, void* data, size_t size);
|
||||
|
||||
using SceNgs2Handle = Ngs2*;
|
||||
|
||||
enum class SceNgs2HandleType : u32 {
|
||||
System = 0,
|
||||
enum class OrbisNgs2HandleType : u32 {
|
||||
Invalid = 0,
|
||||
System = 1,
|
||||
Rack = 2,
|
||||
Voice = 3,
|
||||
VoiceControl = 6
|
||||
};
|
||||
|
||||
struct Ngs2Handle {
|
||||
void* selfPointer;
|
||||
void* dataPointer;
|
||||
std::atomic<u32>* atomicPtr;
|
||||
u32 handleType;
|
||||
u32 flags_unk;
|
||||
static const int ORBIS_NGS2_MAX_VOICE_CHANNELS = 8;
|
||||
static const int ORBIS_NGS2_WAVEFORM_INFO_MAX_BLOCKS = 4;
|
||||
static const int ORBIS_NGS2_MAX_MATRIX_LEVELS =
|
||||
(ORBIS_NGS2_MAX_VOICE_CHANNELS * ORBIS_NGS2_MAX_VOICE_CHANNELS);
|
||||
|
||||
u32 uid;
|
||||
u16 maxGrainSamples;
|
||||
u16 minGrainSamples;
|
||||
u16 currentGrainSamples;
|
||||
u16 numGrainSamples;
|
||||
u16 unknown2;
|
||||
struct OrbisNgs2WaveformFormat {
|
||||
u32 waveformType;
|
||||
u32 numChannels;
|
||||
u32 sampleRate;
|
||||
u32 unknown3;
|
||||
|
||||
void* flushMutex;
|
||||
u32 flushMutexInitialized;
|
||||
void* processMutex;
|
||||
u32 processMutexInitialized;
|
||||
|
||||
// Linked list pointers for system list
|
||||
Ngs2Handle* prev;
|
||||
Ngs2Handle* next;
|
||||
u32 configData;
|
||||
u32 frameOffset;
|
||||
u32 frameMargin;
|
||||
};
|
||||
|
||||
struct SystemOptions {
|
||||
char padding[6];
|
||||
s32 maxGrainSamples;
|
||||
s32 numGrainSamples;
|
||||
s32 sampleRate;
|
||||
struct OrbisNgs2WaveformBlock {
|
||||
u32 dataOffset;
|
||||
u32 dataSize;
|
||||
u32 numRepeats;
|
||||
u32 numSkipSamples;
|
||||
u32 numSamples;
|
||||
u32 reserved;
|
||||
uintptr_t userData;
|
||||
};
|
||||
|
||||
struct SystemState {
|
||||
// TODO
|
||||
struct OrbisNgs2WaveformInfo {
|
||||
OrbisNgs2WaveformFormat format;
|
||||
|
||||
u32 dataOffset;
|
||||
u32 dataSize;
|
||||
|
||||
u32 loopBeginPosition;
|
||||
u32 loopEndPosition;
|
||||
u32 numSamples;
|
||||
|
||||
u32 audioUnitSize;
|
||||
u32 numAudioUnitSamples;
|
||||
u32 numAudioUnitPerFrame;
|
||||
|
||||
u32 audioFrameSize;
|
||||
u32 numAudioFrameSamples;
|
||||
|
||||
u32 numDelaySamples;
|
||||
|
||||
u32 numBlocks;
|
||||
OrbisNgs2WaveformBlock aBlock[ORBIS_NGS2_WAVEFORM_INFO_MAX_BLOCKS];
|
||||
};
|
||||
|
||||
struct StackBuffer {
|
||||
void** top;
|
||||
void* base;
|
||||
void* curr;
|
||||
size_t usedSize;
|
||||
size_t totalSize;
|
||||
size_t alignment;
|
||||
char isVerifyEnabled;
|
||||
char padding[7];
|
||||
struct OrbisNgs2EnvelopePoint {
|
||||
u32 curve;
|
||||
u32 duration;
|
||||
float height;
|
||||
};
|
||||
|
||||
struct OrbisNgs2UserFxProcessContext {
|
||||
float** aChannelData;
|
||||
uintptr_t userData0;
|
||||
uintptr_t userData1;
|
||||
uintptr_t userData2;
|
||||
u32 flags;
|
||||
u32 numChannels;
|
||||
u32 numGrainSamples;
|
||||
u32 sampleRate;
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFxProcessHandler)(OrbisNgs2UserFxProcessContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2SetupContext {
|
||||
void* common;
|
||||
void* param;
|
||||
void* work;
|
||||
uintptr_t userData;
|
||||
u32 maxVoices;
|
||||
u32 voiceIndex;
|
||||
u64 reserved[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2SetupHandler)(OrbisNgs2UserFx2SetupContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2CleanupContext {
|
||||
void* common;
|
||||
void* param;
|
||||
void* work;
|
||||
uintptr_t userData;
|
||||
u32 maxVoices;
|
||||
u32 voiceIndex;
|
||||
u64 reserved[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2CleanupHandler)(OrbisNgs2UserFx2CleanupContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2ControlContext {
|
||||
const void* data;
|
||||
size_t dataSize;
|
||||
void* common;
|
||||
void* param;
|
||||
uintptr_t userData;
|
||||
u64 reserved[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2ControlHandler)(OrbisNgs2UserFx2ControlContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2ProcessContext {
|
||||
float** aChannelData;
|
||||
void* common;
|
||||
const void* param;
|
||||
void* work;
|
||||
void* state;
|
||||
uintptr_t userData;
|
||||
u32 flags;
|
||||
u32 numInputChannels;
|
||||
u32 numOutputChannels;
|
||||
u32 numGrainSamples;
|
||||
u32 sampleRate;
|
||||
u32 reserved;
|
||||
u64 reserved2[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2ProcessHandler)(OrbisNgs2UserFx2ProcessContext* context);
|
||||
|
||||
struct OrbisNgs2BufferAllocator {
|
||||
OrbisNgs2BufferAllocHandler allocHandler;
|
||||
OrbisNgs2BufferFreeHandler freeHandler;
|
||||
uintptr_t userData;
|
||||
};
|
||||
|
||||
struct OrbisNgs2RenderBufferInfo {
|
||||
void* buffer;
|
||||
size_t bufferSize;
|
||||
u32 waveformType;
|
||||
u32 numChannels;
|
||||
};
|
||||
|
||||
struct OrbisNgs2RackOption {
|
||||
size_t size;
|
||||
char name[ORBIS_NGS2_RACK_NAME_LENGTH];
|
||||
|
||||
u32 flags;
|
||||
u32 maxGrainSamples;
|
||||
u32 maxVoices;
|
||||
u32 maxInputDelayBlocks;
|
||||
u32 maxMatrices;
|
||||
u32 maxPorts;
|
||||
u32 aReserved[20];
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoiceParamHeader {
|
||||
u16 size;
|
||||
s16 next;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoiceMatrixLevelsParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 matrixId;
|
||||
u32 numLevels;
|
||||
const float* aLevel;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoicePortMatrixParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 port;
|
||||
s32 matrixId;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoicePortVolumeParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 port;
|
||||
float level;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoicePortDelayParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 port;
|
||||
u32 numSamples;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoicePatchParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 port;
|
||||
u32 destInputId;
|
||||
OrbisNgs2Handle destHandle;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoiceEventParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 eventId;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoiceCallbackInfo {
|
||||
uintptr_t callbackData;
|
||||
OrbisNgs2Handle voiceHandle;
|
||||
u32 flag;
|
||||
u32 reserved;
|
||||
union {
|
||||
struct {
|
||||
uintptr_t userData;
|
||||
const void* data;
|
||||
u32 dataSize;
|
||||
u32 repeatedCount;
|
||||
u32 attributeFlags;
|
||||
u32 reserved2;
|
||||
} waveformBlock;
|
||||
} param;
|
||||
};
|
||||
|
||||
typedef void (*OrbisNgs2VoiceCallbackHandler)(const OrbisNgs2VoiceCallbackInfo* info);
|
||||
|
||||
struct OrbisNgs2VoiceCallbackParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
OrbisNgs2VoiceCallbackHandler callbackHandler;
|
||||
|
||||
uintptr_t callbackData;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoicePortInfo {
|
||||
s32 matrixId;
|
||||
float volume;
|
||||
u32 numDelaySamples;
|
||||
u32 destInputId;
|
||||
OrbisNgs2Handle destHandle;
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoiceMatrixInfo {
|
||||
u32 numLevels;
|
||||
float aLevel[ORBIS_NGS2_MAX_MATRIX_LEVELS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2VoiceState {
|
||||
u32 stateFlags;
|
||||
};
|
||||
|
||||
void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym);
|
||||
|
|
12
src/core/libraries/ngs2/ngs2_custom.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
444
src/core/libraries/ngs2/ngs2_custom.h
Normal file
|
@ -0,0 +1,444 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
#include "ngs2_reverb.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Custom;
|
||||
|
||||
static const int ORBIS_NGS2_CUSTOM_MAX_MODULES = 24;
|
||||
static const int ORBIS_NGS2_CUSTOM_MAX_PORTS = 16;
|
||||
static const int ORBIS_NGS2_CUSTOM_DELAY_MAX_TAPS = 8;
|
||||
|
||||
struct OrbisNgs2CustomModuleOption {
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomEnvelopeModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
|
||||
u32 maxPoints;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomReverbModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
|
||||
u32 reverbSize;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomChorusModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
|
||||
u32 maxPhases;
|
||||
u32 reserved;
|
||||
} OrbisNgs2CustomChorusModuleOption;
|
||||
|
||||
struct OrbisNgs2CustomPeakMeterModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
u32 numBlocks;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomDelayModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
|
||||
u32 type;
|
||||
u32 maxTaps;
|
||||
float maxLength;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomPitchShiftModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
|
||||
u32 quality;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomUserFx2ModuleOption {
|
||||
OrbisNgs2CustomModuleOption customModuleOption;
|
||||
|
||||
OrbisNgs2UserFx2SetupHandler setupHandler;
|
||||
OrbisNgs2UserFx2CleanupHandler cleanupHandler;
|
||||
OrbisNgs2UserFx2ControlHandler controlHandler;
|
||||
OrbisNgs2UserFx2ProcessHandler processHandler;
|
||||
|
||||
size_t commonSize;
|
||||
size_t paramSize;
|
||||
size_t workSize;
|
||||
uintptr_t userData;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomRackModuleInfo {
|
||||
const OrbisNgs2CustomModuleOption* option;
|
||||
|
||||
u32 moduleId;
|
||||
u32 sourceBufferId;
|
||||
u32 extraBufferId;
|
||||
u32 destBufferId;
|
||||
u32 stateOffset;
|
||||
u32 stateSize;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomRackPortInfo {
|
||||
u32 sourceBufferId;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomRackOption {
|
||||
OrbisNgs2RackOption rackOption;
|
||||
u32 stateSize;
|
||||
u32 numBuffers;
|
||||
u32 numModules;
|
||||
u32 reserved;
|
||||
OrbisNgs2CustomRackModuleInfo aModule[ORBIS_NGS2_CUSTOM_MAX_MODULES];
|
||||
OrbisNgs2CustomRackPortInfo aPort[ORBIS_NGS2_CUSTOM_MAX_PORTS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerRackOption {
|
||||
OrbisNgs2CustomRackOption customRackOption;
|
||||
|
||||
u32 maxChannelWorks;
|
||||
u32 maxWaveformBlocks;
|
||||
u32 maxAtrac9Decoders;
|
||||
u32 maxAtrac9ChannelWorks;
|
||||
u32 maxAjmAtrac9Decoders;
|
||||
u32 maxCodecCaches;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSubmixerRackOption {
|
||||
OrbisNgs2CustomRackOption customRackOption;
|
||||
|
||||
u32 maxChannels;
|
||||
u32 maxInputs;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomMasteringRackOption {
|
||||
OrbisNgs2CustomRackOption customRackOption;
|
||||
|
||||
u32 maxChannels;
|
||||
u32 maxInputs;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
OrbisNgs2WaveformFormat format;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoiceWaveformBlocksParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
const void* data;
|
||||
u32 flags;
|
||||
u32 numBlocks;
|
||||
const OrbisNgs2WaveformBlock* aBlock;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoiceWaveformAddressParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
const void* from;
|
||||
const void* to;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoiceWaveformFrameOffsetParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 frameOffset;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoiceExitLoopParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoicePitchParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
float ratio;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerVoiceState {
|
||||
OrbisNgs2VoiceState voiceState;
|
||||
char padding[32];
|
||||
const void* waveformData;
|
||||
u64 numDecodedSamples;
|
||||
u64 decodedDataSize;
|
||||
u64 userData;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSubmixerVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 numInputChannels;
|
||||
u32 numOutputChannels;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSubmixerVoiceState {
|
||||
OrbisNgs2VoiceState voiceState; // Voice state
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomMasteringVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 numInputChannels;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomMasteringVoiceOutputParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 outputId;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomMasteringVoiceState {
|
||||
OrbisNgs2VoiceState voiceState;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceEnvelopeParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 numForwardPoints;
|
||||
u32 numReleasePoints;
|
||||
const OrbisNgs2EnvelopePoint* aPoint;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceDistortionParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 flags;
|
||||
float a;
|
||||
float b;
|
||||
float clip;
|
||||
float gate;
|
||||
float wetLevel;
|
||||
float dryLevel;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceCompressorParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 flags;
|
||||
float threshold;
|
||||
float ratio;
|
||||
float knee;
|
||||
float attackTime;
|
||||
float releaseTime;
|
||||
float level;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceFilterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 type;
|
||||
u32 channelMask;
|
||||
union {
|
||||
struct {
|
||||
float i0;
|
||||
float i1;
|
||||
float i2;
|
||||
float o1;
|
||||
float o2;
|
||||
} direct;
|
||||
struct {
|
||||
float fc;
|
||||
float q;
|
||||
float level;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
} fcq;
|
||||
} param;
|
||||
u32 reserved3;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceLfeFilterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 enableFlag;
|
||||
u32 fc;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceGainParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
float aLevel[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceMixerParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
float aSourceLevel[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
float aDestLevel[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceChannelMixerParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
float aLevel[ORBIS_NGS2_MAX_VOICE_CHANNELS][ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceUserFxParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
OrbisNgs2UserFxProcessHandler handler;
|
||||
|
||||
uintptr_t userData0;
|
||||
uintptr_t userData1;
|
||||
uintptr_t userData2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceUserFx2Param {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
const void* data;
|
||||
size_t dataSize;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceOutputParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 outputId;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoicePeakMeterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 enableFlag;
|
||||
u32 reserved;
|
||||
} OrbisNgs2CustomVoicePeakMeterParam;
|
||||
|
||||
struct OrbisNgs2CustomVoiceReverbParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
OrbisNgs2ReverbI3DL2Param i3dl2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceChorusParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 flags;
|
||||
u32 numPhases;
|
||||
u32 channelMask;
|
||||
float inputLevel;
|
||||
float delayTime;
|
||||
float modulationRatio;
|
||||
float modulationDepth;
|
||||
float feedbackLevel;
|
||||
float wetLevel;
|
||||
float dryLevel;
|
||||
};
|
||||
|
||||
struct OrbisNgs2DelayTapInfo {
|
||||
float tapLevel;
|
||||
float delayTime;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceDelayParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
float dryLevel;
|
||||
float wetLevel;
|
||||
float inputLevel;
|
||||
float feedbackLevel;
|
||||
float lowpassFc;
|
||||
u32 numTaps;
|
||||
OrbisNgs2DelayTapInfo aTap[ORBIS_NGS2_CUSTOM_DELAY_MAX_TAPS];
|
||||
float aInputMixLevel[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
u32 channelMask;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoiceNoiseGateParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 flags;
|
||||
float threshold;
|
||||
float attackTime;
|
||||
float releaseTime;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomVoicePitchShiftParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
s32 cent;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomEnvelopeModuleState {
|
||||
float height;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomCompressorModuleState {
|
||||
float peakHeight;
|
||||
float compressorHeight;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomPeakMeterModuleState {
|
||||
float peak;
|
||||
float aChannelPeak[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomNoiseGateModuleState {
|
||||
float gateHeight;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomRackInfo {
|
||||
OrbisNgs2RackInfo rackInfo;
|
||||
u32 stateSize;
|
||||
u32 numBuffers;
|
||||
u32 numModules;
|
||||
u32 reserved;
|
||||
OrbisNgs2CustomRackModuleInfo aModule[ORBIS_NGS2_CUSTOM_MAX_MODULES];
|
||||
OrbisNgs2CustomRackPortInfo aPort[ORBIS_NGS2_CUSTOM_MAX_PORTS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSamplerRackInfo {
|
||||
OrbisNgs2CustomRackInfo customRackInfo;
|
||||
|
||||
u32 maxChannelWorks;
|
||||
u32 maxWaveformBlocks;
|
||||
u32 maxAtrac9Decoders;
|
||||
u32 maxAtrac9ChannelWorks;
|
||||
u32 maxAjmAtrac9Decoders;
|
||||
u32 maxCodecCaches;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomSubmixerRackInfo {
|
||||
OrbisNgs2CustomRackInfo customRackInfo;
|
||||
|
||||
u32 maxChannels;
|
||||
u32 maxInputs;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomMasteringRackInfo {
|
||||
OrbisNgs2CustomRackInfo customRackInfo;
|
||||
|
||||
u32 maxChannels;
|
||||
u32 maxInputs;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomModuleInfo {
|
||||
u32 moduleId;
|
||||
u32 sourceBufferId;
|
||||
u32 extraBufferId;
|
||||
u32 destBufferId;
|
||||
u32 stateOffset;
|
||||
u32 stateSize;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomEnvelopeModuleInfo {
|
||||
OrbisNgs2CustomModuleInfo moduleInfo;
|
||||
|
||||
u32 maxPoints;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2CustomReverbModuleInfo {
|
||||
OrbisNgs2CustomModuleInfo moduleInfo;
|
||||
|
||||
u32 reverbSize;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_eq.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
41
src/core/libraries/ngs2/ngs2_eq.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Eq;
|
||||
|
||||
struct OrbisNgs2EqVoiceSetupParam {
|
||||
u32 numChannels;
|
||||
};
|
||||
|
||||
struct OrbisNgs2EqVoiceFilterParam {
|
||||
u32 type;
|
||||
u32 channelMask;
|
||||
union {
|
||||
struct {
|
||||
float i0;
|
||||
float i1;
|
||||
float i2;
|
||||
float o1;
|
||||
float o2;
|
||||
} direct;
|
||||
struct {
|
||||
float fc;
|
||||
float q;
|
||||
float level;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
} fcq;
|
||||
} param;
|
||||
};
|
||||
|
||||
struct OrbisNgs2EqVoiceState {
|
||||
u32 stateFlags;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_geom.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
80
src/core/libraries/ngs2/ngs2_geom.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Geom;
|
||||
|
||||
struct OrbisNgs2GeomVector {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomCone {
|
||||
float innerLevel;
|
||||
float innerAngle;
|
||||
float outerLevel;
|
||||
float outerAngle;
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomRolloff {
|
||||
u32 model;
|
||||
float maxDistance;
|
||||
float rolloffFactor;
|
||||
float referenceDistance;
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomListenerParam {
|
||||
OrbisNgs2GeomVector position;
|
||||
OrbisNgs2GeomVector orientFront;
|
||||
OrbisNgs2GeomVector orientUp;
|
||||
OrbisNgs2GeomVector velocity;
|
||||
float soundSpeed;
|
||||
u32 reserved[2];
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomListenerWork {
|
||||
float matrix[4][4];
|
||||
OrbisNgs2GeomVector velocity;
|
||||
float soundSpeed;
|
||||
u32 coordinate;
|
||||
u32 reserved[3];
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomSourceParam {
|
||||
OrbisNgs2GeomVector position;
|
||||
OrbisNgs2GeomVector velocity;
|
||||
OrbisNgs2GeomVector direction;
|
||||
OrbisNgs2GeomCone cone;
|
||||
OrbisNgs2GeomRolloff rolloff;
|
||||
float dopplerFactor;
|
||||
float fbwLevel;
|
||||
float lfeLevel;
|
||||
float maxLevel;
|
||||
float minLevel;
|
||||
float radius;
|
||||
u32 numSpeakers;
|
||||
u32 matrixFormat;
|
||||
u32 reserved[2];
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomA3dAttribute {
|
||||
OrbisNgs2GeomVector position;
|
||||
float volume;
|
||||
u32 reserved[4];
|
||||
};
|
||||
|
||||
struct OrbisNgs2GeomAttribute {
|
||||
float pitchRatio;
|
||||
float aLevel[ORBIS_NGS2_MAX_VOICE_CHANNELS * ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
|
||||
OrbisNgs2GeomA3dAttribute a3dAttrib;
|
||||
u32 reserved[4];
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
|
@ -12,153 +12,171 @@ using namespace Libraries::Kernel;
|
|||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
s32 Ngs2::ReportInvalid(Ngs2Handle* handle, u32 handle_type) const {
|
||||
uintptr_t hAddress = reinterpret_cast<uintptr_t>(handle);
|
||||
switch (handle_type) {
|
||||
s32 HandleReportInvalid(OrbisNgs2Handle handle, u32 handleType) {
|
||||
switch (handleType) {
|
||||
case 1:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", hAddress);
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", handle);
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
case 2:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", hAddress);
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", handle);
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
case 4:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", hAddress);
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", handle);
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
case 8:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", hAddress);
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", handle);
|
||||
return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE;
|
||||
default:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid handle {}", hAddress);
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid handle {}", handle);
|
||||
return ORBIS_NGS2_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleSetup(Ngs2Handle* handle, void* data, std::atomic<u32>* atomic, u32 type,
|
||||
u32 flags) {
|
||||
handle->dataPointer = data;
|
||||
handle->atomicPtr = atomic;
|
||||
handle->handleType = type;
|
||||
handle->flags_unk = flags;
|
||||
return ORBIS_OK;
|
||||
void* MemoryClear(void* buffer, size_t size) {
|
||||
return memset(buffer, 0, size);
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut) {
|
||||
if (handle && handle->selfPointer == handle) {
|
||||
std::atomic<u32>* tmp_atomic = handle->atomicPtr;
|
||||
if (tmp_atomic && handle->handleType == hType) {
|
||||
while (tmp_atomic->load() != 0) {
|
||||
u32 expected = 1;
|
||||
if (tmp_atomic->compare_exchange_strong(expected, 0)) {
|
||||
if (dataOut) {
|
||||
dataOut = handle->dataPointer;
|
||||
}
|
||||
// sceNgs2MemoryClear(handle, 32);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
tmp_atomic = handle->atomicPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this->ReportInvalid(handle, hType);
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut) {
|
||||
if (!handle) {
|
||||
return this->ReportInvalid(handle, 0);
|
||||
}
|
||||
|
||||
if (handle->selfPointer != handle || !handle->atomicPtr || !handle->dataPointer ||
|
||||
(~hType & handle->handleType)) {
|
||||
return this->ReportInvalid(handle, handle->handleType);
|
||||
}
|
||||
|
||||
std::atomic<u32>* atomic = handle->atomicPtr;
|
||||
while (true) {
|
||||
u32 i = atomic->load();
|
||||
if (i == 0) {
|
||||
return this->ReportInvalid(handle, handle->handleType);
|
||||
}
|
||||
if (atomic->compare_exchange_strong(i, i + 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (handleOut) {
|
||||
handleOut = handle;
|
||||
s32 StackBufferClose(StackBuffer* stackBuffer, size_t* outTotalSize) {
|
||||
if (outTotalSize) {
|
||||
*outTotalSize = stackBuffer->usedSize + stackBuffer->alignment;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleLeave(Ngs2Handle* handle) {
|
||||
std::atomic<u32>* tmp_atomic;
|
||||
u32 i;
|
||||
do {
|
||||
tmp_atomic = handle->atomicPtr;
|
||||
i = tmp_atomic->load();
|
||||
} while (!tmp_atomic->compare_exchange_strong(i, i - 1));
|
||||
return ORBIS_OK;
|
||||
}
|
||||
s32 StackBufferOpen(StackBuffer* stackBuffer, void* bufferStart, size_t bufferSize,
|
||||
void** outBuffer, u8 flags) {
|
||||
stackBuffer->top = outBuffer;
|
||||
stackBuffer->base = bufferStart;
|
||||
stackBuffer->size = (size_t)bufferStart;
|
||||
stackBuffer->currentOffset = (size_t)bufferStart;
|
||||
stackBuffer->usedSize = 0;
|
||||
stackBuffer->totalSize = bufferSize;
|
||||
stackBuffer->alignment = 8; // this is a fixed value
|
||||
stackBuffer->flags = flags;
|
||||
|
||||
s32 Ngs2::StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop,
|
||||
bool verify) {
|
||||
buf->top = stackTop;
|
||||
buf->base = base_addr;
|
||||
buf->curr = base_addr;
|
||||
buf->usedSize = 0;
|
||||
buf->totalSize = size;
|
||||
buf->alignment = 8;
|
||||
buf->isVerifyEnabled = verify;
|
||||
|
||||
if (stackTop) {
|
||||
*stackTop = nullptr;
|
||||
if (outBuffer != NULL) {
|
||||
*outBuffer = NULL;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::StackBufferClose(StackBuffer* buf, size_t* usedSize) {
|
||||
if (usedSize) {
|
||||
*usedSize = buf->usedSize + buf->alignment;
|
||||
s32 SystemCleanup(OrbisNgs2Handle systemHandle, OrbisNgs2ContextBufferInfo* outInfo) {
|
||||
if (!systemHandle) {
|
||||
return ORBIS_NGS2_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut) {
|
||||
s32 SystemSetupCore(StackBuffer* stackBuffer, const OrbisNgs2SystemOption* option,
|
||||
SystemInternal* outSystem) {
|
||||
u32 maxGrainSamples = 512;
|
||||
u32 numGrainSamples = 256;
|
||||
u32 sampleRate = 48000;
|
||||
|
||||
if (options) {
|
||||
maxGrainSamples = options->maxGrainSamples;
|
||||
numGrainSamples = options->numGrainSamples;
|
||||
sampleRate = options->sampleRate;
|
||||
if (option) {
|
||||
sampleRate = option->sampleRate;
|
||||
maxGrainSamples = option->maxGrainSamples;
|
||||
numGrainSamples = option->numGrainSamples;
|
||||
}
|
||||
|
||||
// Validate maxGrainSamples
|
||||
if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 0x3F) != 0) {
|
||||
if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 63) != 0) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option (maxGrainSamples={},x64)", maxGrainSamples);
|
||||
return ORBIS_NGS2_ERROR_INVALID_MAX_GRAIN_SAMPLES;
|
||||
}
|
||||
|
||||
// Validate numGrainSamples
|
||||
if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 0x3F) != 0) {
|
||||
if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 63) != 0) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option (numGrainSamples={},x64)", numGrainSamples);
|
||||
return ORBIS_NGS2_ERROR_INVALID_NUM_GRAIN_SAMPLES;
|
||||
}
|
||||
|
||||
// Validate sampleRate
|
||||
if (sampleRate != 11025 && sampleRate != 12000 && sampleRate != 22050 && sampleRate != 24000 &&
|
||||
sampleRate != 44100 && sampleRate != 48000 && sampleRate != 88200 && sampleRate != 96000) {
|
||||
sampleRate != 44100 && sampleRate != 48000 && sampleRate != 88200 && sampleRate != 96000 &&
|
||||
sampleRate != 176400 && sampleRate != 192000) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option(sampleRate={}:44.1/48kHz series)", sampleRate);
|
||||
return ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
int result = ORBIS_OK;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 SystemSetup(const OrbisNgs2SystemOption* option, OrbisNgs2ContextBufferInfo* hostBufferInfo,
|
||||
OrbisNgs2BufferFreeHandler hostFree, OrbisNgs2Handle* outHandle) {
|
||||
u8 optionFlags = 0;
|
||||
StackBuffer stackBuffer;
|
||||
SystemInternal setupResult;
|
||||
void* systemList = NULL;
|
||||
size_t requiredBufferSize = 0;
|
||||
u32 result = ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE;
|
||||
|
||||
if (option) {
|
||||
if (option->size != 64) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option size ({})", option->size);
|
||||
return ORBIS_NGS2_ERROR_INVALID_OPTION_SIZE;
|
||||
}
|
||||
optionFlags = option->flags >> 31;
|
||||
}
|
||||
|
||||
// Init
|
||||
StackBufferOpen(&stackBuffer, NULL, 0, NULL, optionFlags);
|
||||
result = SystemSetupCore(&stackBuffer, option, 0);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
StackBufferClose(&stackBuffer, &requiredBufferSize);
|
||||
|
||||
// outHandle unprovided
|
||||
if (!outHandle) {
|
||||
hostBufferInfo->hostBuffer = NULL;
|
||||
hostBufferInfo->hostBufferSize = requiredBufferSize;
|
||||
MemoryClear(&hostBufferInfo->reserved, sizeof(hostBufferInfo->reserved));
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
if (!hostBufferInfo->hostBuffer) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system buffer address ({})", hostBufferInfo->hostBuffer);
|
||||
return ORBIS_NGS2_ERROR_INVALID_BUFFER_ADDRESS;
|
||||
}
|
||||
|
||||
if (hostBufferInfo->hostBufferSize < requiredBufferSize) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system buffer size ({}<{}[byte])",
|
||||
hostBufferInfo->hostBufferSize, requiredBufferSize);
|
||||
return ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// Setup
|
||||
StackBufferOpen(&stackBuffer, hostBufferInfo->hostBuffer, hostBufferInfo->hostBufferSize,
|
||||
&systemList, optionFlags);
|
||||
result = SystemSetupCore(&stackBuffer, option, &setupResult);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
StackBufferClose(&stackBuffer, &requiredBufferSize);
|
||||
|
||||
// Copy buffer results
|
||||
setupResult.bufferInfo = *hostBufferInfo;
|
||||
setupResult.hostFree = hostFree;
|
||||
// TODO
|
||||
// setupResult.systemList = systemList;
|
||||
|
||||
return result; // Success
|
||||
OrbisNgs2Handle systemHandle = setupResult.systemHandle;
|
||||
if (hostBufferInfo->hostBufferSize >= requiredBufferSize) {
|
||||
*outHandle = systemHandle;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
SystemCleanup(systemHandle, 0);
|
||||
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system buffer size ({}<{}[byte])", hostBufferInfo->hostBufferSize,
|
||||
requiredBufferSize);
|
||||
return ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
} // namespace Libraries::Ngs2
|
||||
|
|
|
@ -3,23 +3,176 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
#include "core/libraries/kernel/threads/pthread.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2 {
|
||||
public:
|
||||
s32 ReportInvalid(Ngs2Handle* handle, u32 handle_type) const;
|
||||
s32 HandleSetup(Ngs2Handle* handle, void* data, std::atomic<u32>* atomic, u32 type, u32 flags);
|
||||
s32 HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut);
|
||||
s32 HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut);
|
||||
s32 HandleLeave(Ngs2Handle* handle);
|
||||
s32 StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop,
|
||||
bool verify);
|
||||
s32 StackBufferClose(StackBuffer* buf, size_t* usedSize);
|
||||
s32 SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut);
|
||||
static const int ORBIS_NGS2_SYSTEM_NAME_LENGTH = 16;
|
||||
static const int ORBIS_NGS2_RACK_NAME_LENGTH = 16;
|
||||
|
||||
private:
|
||||
typedef uintptr_t OrbisNgs2Handle;
|
||||
|
||||
struct OrbisNgs2ContextBufferInfo {
|
||||
void* hostBuffer;
|
||||
size_t hostBufferSize;
|
||||
uintptr_t reserved[5];
|
||||
uintptr_t userData;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SystemOption {
|
||||
size_t size;
|
||||
char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH];
|
||||
|
||||
u32 flags;
|
||||
u32 maxGrainSamples;
|
||||
u32 numGrainSamples;
|
||||
u32 sampleRate;
|
||||
u32 aReserved[6];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2BufferAllocHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo);
|
||||
typedef s32 (*OrbisNgs2BufferFreeHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo);
|
||||
|
||||
struct OrbisNgs2SystemInfo {
|
||||
char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; // 0
|
||||
|
||||
OrbisNgs2Handle systemHandle; // 16
|
||||
OrbisNgs2ContextBufferInfo bufferInfo; // 24
|
||||
|
||||
u32 uid; // 88
|
||||
u32 minGrainSamples; // 92
|
||||
u32 maxGrainSamples; // 96
|
||||
|
||||
u32 stateFlags; // 100
|
||||
u32 rackCount; // 104
|
||||
float lastRenderRatio; // 108
|
||||
s64 lastRenderTick; // 112
|
||||
s64 renderCount; // 120
|
||||
u32 sampleRate; // 128
|
||||
u32 numGrainSamples; // 132
|
||||
};
|
||||
|
||||
struct OrbisNgs2RackInfo {
|
||||
char name[ORBIS_NGS2_RACK_NAME_LENGTH]; // 0
|
||||
|
||||
OrbisNgs2Handle rackHandle; // 16
|
||||
OrbisNgs2ContextBufferInfo bufferInfo; // 24
|
||||
|
||||
OrbisNgs2Handle ownerSystemHandle; // 88
|
||||
|
||||
u32 type; // 96
|
||||
u32 rackId; // 100
|
||||
u32 uid; // 104
|
||||
u32 minGrainSamples; // 108
|
||||
u32 maxGrainSamples; // 112
|
||||
u32 maxVoices; // 116
|
||||
u32 maxChannelWorks; // 120
|
||||
u32 maxInputs; // 124
|
||||
u32 maxMatrices; // 128
|
||||
u32 maxPorts; // 132
|
||||
|
||||
u32 stateFlags; // 136
|
||||
float lastProcessRatio; // 140
|
||||
u64 lastProcessTick; // 144
|
||||
u64 renderCount; // 152
|
||||
u32 activeVoiceCount; // 160
|
||||
u32 activeChannelWorkCount; // 164
|
||||
};
|
||||
|
||||
struct StackBuffer {
|
||||
void** top;
|
||||
void* base;
|
||||
size_t size;
|
||||
size_t currentOffset;
|
||||
size_t usedSize;
|
||||
size_t totalSize;
|
||||
size_t alignment;
|
||||
u8 flags;
|
||||
char padding[7];
|
||||
};
|
||||
|
||||
struct SystemInternal {
|
||||
// setup init
|
||||
char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; // 0
|
||||
OrbisNgs2ContextBufferInfo bufferInfo; // 16
|
||||
OrbisNgs2BufferFreeHandler hostFree; // 80
|
||||
OrbisNgs2Handle systemHandle; // 88
|
||||
void* unknown1; // 96
|
||||
void* unknown2; // 104
|
||||
OrbisNgs2Handle rackHandle; // 112
|
||||
uintptr_t* userData; // 120
|
||||
SystemInternal* systemList; // 128
|
||||
StackBuffer* stackBuffer; // 136
|
||||
OrbisNgs2SystemInfo ownerSystemInfo; // 144
|
||||
|
||||
struct rackList {
|
||||
void* prev;
|
||||
void* next;
|
||||
void* unknown;
|
||||
};
|
||||
|
||||
rackList rackListPreset; // 152
|
||||
rackList rackListNormal; // 176
|
||||
rackList rackListMaster; // 200
|
||||
|
||||
void* unknown3; // 208
|
||||
void* systemListPrev; // 216
|
||||
void* unknown4; // 224
|
||||
void* systemListNext; // 232
|
||||
void* rackFunction; // 240
|
||||
|
||||
Kernel::PthreadMutex processLock; // 248
|
||||
u32 hasProcessMutex; // 256
|
||||
u32 unknown5; // 260
|
||||
Kernel::PthreadMutex flushLock; // 264
|
||||
u32 hasFlushMutex; // 272
|
||||
u32 unknown6; // 276
|
||||
|
||||
// info
|
||||
u64 lastRenderTick; // 280
|
||||
u64 renderCount; // 288
|
||||
u32 isActive; // 296
|
||||
std::atomic<int> lockCount; // 300
|
||||
u32 uid; // 304
|
||||
u32 systemType; // 308
|
||||
|
||||
struct {
|
||||
u8 isBufferValid : 1;
|
||||
u8 isRendering : 1;
|
||||
u8 isSorted : 1;
|
||||
u8 isFlushReady : 1;
|
||||
} flags; // 312
|
||||
|
||||
u16 currentMaxGrainSamples; // 316
|
||||
u16 minGrainSamples; // 318
|
||||
u16 maxGrainSamples; // 320
|
||||
u16 numGrainSamples; // 322
|
||||
u32 currentNumGrainSamples; // 324
|
||||
u32 sampleRate; // 328
|
||||
u32 currentSampleRate; // 332
|
||||
u32 rackCount; // 336
|
||||
float lastRenderRatio; // 340
|
||||
float cpuLoad; // 344
|
||||
};
|
||||
|
||||
struct HandleInternal {
|
||||
HandleInternal* selfPtr; // 0
|
||||
SystemInternal* systemData; // 8
|
||||
std::atomic<int> refCount; // 16
|
||||
u32 handleType; // 24
|
||||
u32 handleID; // 28
|
||||
};
|
||||
|
||||
s32 StackBufferClose(StackBuffer* stackBuffer, size_t* outTotalSize);
|
||||
s32 StackBufferOpen(StackBuffer* stackBuffer, void* buffer, size_t bufferSize, void** outBuffer,
|
||||
u8 flags);
|
||||
s32 SystemSetupCore(StackBuffer* stackBuffer, const OrbisNgs2SystemOption* option,
|
||||
SystemInternal* outSystem);
|
||||
|
||||
s32 HandleReportInvalid(OrbisNgs2Handle handle, u32 handleType);
|
||||
void* MemoryClear(void* buffer, size_t size);
|
||||
s32 SystemCleanup(OrbisNgs2Handle systemHandle, OrbisNgs2ContextBufferInfo* outInfo);
|
||||
s32 SystemSetup(const OrbisNgs2SystemOption* option, OrbisNgs2ContextBufferInfo* hostBufferInfo,
|
||||
OrbisNgs2BufferFreeHandler hostFree, OrbisNgs2Handle* outHandle);
|
||||
|
||||
} // namespace Libraries::Ngs2
|
||||
|
|
12
src/core/libraries/ngs2/ngs2_mastering.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
81
src/core/libraries/ngs2/ngs2_mastering.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Mastering;
|
||||
|
||||
struct OrbisNgs2MasteringRackOption {
|
||||
OrbisNgs2RackOption rackOption;
|
||||
u32 maxChannels;
|
||||
u32 numPeakMeterBlocks;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 numInputChannels;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceMatrixParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 type;
|
||||
u32 numLevels;
|
||||
const float* aLevel;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceLfeParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 enableFlag;
|
||||
u32 fc;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceLimiterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 enableFlag;
|
||||
float threshold;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceGainParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
float fbwLevel;
|
||||
float lfeLevel;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceOutputParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 outputId;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoicePeakMeterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 enableFlag;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringVoiceState {
|
||||
OrbisNgs2VoiceState voiceState;
|
||||
float limiterPeakLevel;
|
||||
float limiterPressLevel;
|
||||
float aInputPeakHeight[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
float aOutputPeakHeight[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
};
|
||||
|
||||
struct OrbisNgs2MasteringRackInfo {
|
||||
OrbisNgs2RackInfo rackInfo;
|
||||
u32 maxChannels;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_pan.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
25
src/core/libraries/ngs2/ngs2_pan.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Pan;
|
||||
|
||||
struct OrbisNgs2PanParam {
|
||||
float angle;
|
||||
float distance;
|
||||
float fbwLevel;
|
||||
float lfeLevel;
|
||||
};
|
||||
|
||||
struct OrbisNgs2PanWork {
|
||||
float aSpeakerAngle[ORBIS_NGS2_MAX_VOICE_CHANNELS];
|
||||
float unitAngle;
|
||||
u32 numSpeakers;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_report.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
78
src/core/libraries/ngs2/ngs2_report.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
#include <stdarg.h> // va_list
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Report;
|
||||
|
||||
struct OrbisNgs2ReportDataHeader {
|
||||
size_t size;
|
||||
OrbisNgs2Handle handle;
|
||||
u32 type;
|
||||
s32 result;
|
||||
};
|
||||
|
||||
typedef void (*OrbisNgs2ReportHandler)(const OrbisNgs2ReportDataHeader* data, uintptr_t userData);
|
||||
|
||||
struct OrbisNgs2ReportMessageData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
const char* message;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReportApiData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
const char* functionName;
|
||||
const char* format;
|
||||
va_list argument;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReportControlData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
const OrbisNgs2VoiceParamHeader* param;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReportOutputData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
const OrbisNgs2RenderBufferInfo* bufferInfo;
|
||||
|
||||
u32 bufferIndex;
|
||||
u32 sampleRate;
|
||||
u32 numGrainSamples;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReportCpuLoadData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
float totalRatio;
|
||||
float flushRatio;
|
||||
float processRatio;
|
||||
float feedbackRatio;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReportRenderStateData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
u32 state;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReportVoiceWaveformData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
u32 location;
|
||||
u32 waveformType;
|
||||
u32 numChannels;
|
||||
u32 sampleRate;
|
||||
u32 numGrainSamples;
|
||||
u32 reserved;
|
||||
void* const* aData;
|
||||
};
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ReportRegisterHandler(u32 reportType, OrbisNgs2ReportHandler handler,
|
||||
uintptr_t userData, OrbisNgs2Handle* outHandle);
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_reverb.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
61
src/core/libraries/ngs2/ngs2_reverb.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Reverb;
|
||||
|
||||
struct OrbisNgs2ReverbRackOption {
|
||||
OrbisNgs2RackOption rackOption;
|
||||
u32 maxChannels;
|
||||
u32 reverbSize;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReverbI3DL2Param {
|
||||
float wet;
|
||||
float dry;
|
||||
s32 room;
|
||||
s32 roomHF;
|
||||
u32 reflectionPattern;
|
||||
float decayTime;
|
||||
float decayHFRatio;
|
||||
s32 reflections;
|
||||
float reflectionsDelay;
|
||||
s32 reverb;
|
||||
float reverbDelay;
|
||||
float diffusion;
|
||||
float density;
|
||||
float HFReference;
|
||||
u32 reserve[8];
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReverbVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 numInputChannels;
|
||||
u32 numOutputChannels;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReverbVoiceI3DL2Param {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
OrbisNgs2ReverbI3DL2Param i3dl2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReverbVoiceState {
|
||||
OrbisNgs2VoiceState voiceState;
|
||||
};
|
||||
|
||||
struct OrbisNgs2ReverbRackInfo {
|
||||
OrbisNgs2RackInfo rackInfo;
|
||||
u32 maxChannels;
|
||||
u32 reverbSize;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_sampler.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
162
src/core/libraries/ngs2/ngs2_sampler.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Sampler;
|
||||
|
||||
struct OrbisNgs2SamplerRackOption {
|
||||
OrbisNgs2RackOption rackOption;
|
||||
u32 maxChannelWorks;
|
||||
u32 maxCodecCaches;
|
||||
u32 maxWaveformBlocks;
|
||||
u32 maxEnvelopePoints;
|
||||
u32 maxFilters;
|
||||
u32 maxAtrac9Decoders;
|
||||
u32 maxAtrac9ChannelWorks;
|
||||
u32 maxAjmAtrac9Decoders;
|
||||
u32 numPeakMeterBlocks;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
OrbisNgs2WaveformFormat format;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceWaveformBlocksParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
const void* data;
|
||||
u32 flags;
|
||||
u32 numBlocks;
|
||||
const OrbisNgs2WaveformBlock* aBlock;
|
||||
// Blocks
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceWaveformAddressParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
const void* from;
|
||||
const void* to;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceWaveformFrameOffsetParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 frameOffset;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceExitLoopParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoicePitchParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
float ratio;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceEnvelopeParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 numForwardPoints;
|
||||
u32 numReleasePoints;
|
||||
const OrbisNgs2EnvelopePoint* aPoint;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceDistortionParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 flags;
|
||||
float a;
|
||||
float b;
|
||||
float clip;
|
||||
float gate;
|
||||
float wetLevel;
|
||||
float dryLevel;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceUserFxParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
OrbisNgs2UserFxProcessHandler handler;
|
||||
|
||||
uintptr_t userData0;
|
||||
uintptr_t userData1;
|
||||
uintptr_t userData2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoicePeakMeterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 enableFlag;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceFilterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 index;
|
||||
u32 location;
|
||||
u32 type;
|
||||
u32 channelMask;
|
||||
union {
|
||||
struct {
|
||||
float i0;
|
||||
float i1;
|
||||
float i2;
|
||||
float o1;
|
||||
float o2;
|
||||
} direct;
|
||||
struct {
|
||||
float fc;
|
||||
float q;
|
||||
float level;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
} fcq;
|
||||
} param;
|
||||
u32 reserved3;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceNumFilters {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 numFilters;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerVoiceState {
|
||||
OrbisNgs2VoiceState voiceState;
|
||||
float envelopeHeight;
|
||||
float peakHeight;
|
||||
u32 reserved;
|
||||
u64 numDecodedSamples;
|
||||
u64 decodedDataSize;
|
||||
u64 userData;
|
||||
const void* waveformData;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SamplerRackInfo {
|
||||
OrbisNgs2RackInfo rackInfo;
|
||||
u32 maxChannelWorks;
|
||||
u32 maxCodecCaches;
|
||||
u32 maxWaveformBlocks;
|
||||
u32 maxEnvelopePoints;
|
||||
u32 maxFilters;
|
||||
u32 maxAtrac9Decoders;
|
||||
u32 maxAtrac9ChannelWorks;
|
||||
u32 maxAjmAtrac9Decoders;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
12
src/core/libraries/ngs2/ngs2_submixer.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
126
src/core/libraries/ngs2/ngs2_submixer.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2Submixer;
|
||||
|
||||
struct OrbisNgs2SubmixerRackOption {
|
||||
OrbisNgs2RackOption rackOption;
|
||||
u32 maxChannels;
|
||||
u32 maxEnvelopePoints;
|
||||
u32 maxFilters;
|
||||
u32 maxInputs;
|
||||
u32 numPeakMeterBlocks;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceSetupParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
u32 numIoChannels;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceEnvelopeParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 numForwardPoints;
|
||||
u32 numReleasePoints;
|
||||
const OrbisNgs2EnvelopePoint* aPoint;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceCompressorParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 flags;
|
||||
float threshold;
|
||||
float ratio;
|
||||
float knee;
|
||||
float attackTime;
|
||||
float releaseTime;
|
||||
float level;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceDistortionParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 flags;
|
||||
float a;
|
||||
float b;
|
||||
float clip;
|
||||
float gate;
|
||||
float wetLevel;
|
||||
float dryLevel;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceUserFxParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
OrbisNgs2UserFxProcessHandler handler;
|
||||
|
||||
uintptr_t userData0;
|
||||
uintptr_t userData1;
|
||||
uintptr_t userData2;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoicePeakMeterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 enableFlag;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceFilterParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 index;
|
||||
u32 location;
|
||||
u32 type;
|
||||
u32 channelMask;
|
||||
union {
|
||||
struct {
|
||||
float i0;
|
||||
float i1;
|
||||
float i2;
|
||||
float o1;
|
||||
float o2;
|
||||
} direct;
|
||||
struct {
|
||||
float fc;
|
||||
float q;
|
||||
float level;
|
||||
u32 reserved;
|
||||
u32 reserved2;
|
||||
} fcq;
|
||||
} param;
|
||||
u32 reserved3;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceNumFilters {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
||||
u32 numFilters;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerVoiceState {
|
||||
OrbisNgs2VoiceState voiceState;
|
||||
float envelopeHeight;
|
||||
float peakHeight;
|
||||
float compressorHeight;
|
||||
};
|
||||
|
||||
struct OrbisNgs2SubmixerRackInfo {
|
||||
OrbisNgs2RackInfo rackInfo;
|
||||
u32 maxChannels;
|
||||
u32 maxEnvelopePoints;
|
||||
u32 maxFilters;
|
||||
u32 maxInputs;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
|
@ -1,28 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/io_file.h"
|
||||
#include "common/types.h"
|
||||
#include "loader.h"
|
||||
|
||||
namespace Loader {
|
||||
|
||||
FileTypes DetectFileType(const std::filesystem::path& filepath) {
|
||||
// No file loaded
|
||||
if (filepath.empty()) {
|
||||
return FileTypes::Unknown;
|
||||
}
|
||||
Common::FS::IOFile file;
|
||||
file.Open(filepath, Common::FS::FileAccessMode::Read);
|
||||
file.Seek(0);
|
||||
u32 magic;
|
||||
file.Read(magic);
|
||||
file.Close();
|
||||
switch (magic) {
|
||||
case PkgMagic:
|
||||
return FileTypes::Pkg;
|
||||
}
|
||||
return FileTypes::Unknown;
|
||||
}
|
||||
|
||||
} // namespace Loader
|
|
@ -1,18 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Loader {
|
||||
|
||||
constexpr static u32 PkgMagic = 0x544e437f;
|
||||
|
||||
enum class FileTypes {
|
||||
Unknown,
|
||||
Pkg,
|
||||
};
|
||||
|
||||
FileTypes DetectFileType(const std::filesystem::path& filepath);
|
||||
} // namespace Loader
|
|
@ -38,6 +38,16 @@ void MemoryManager::SetupMemoryRegions(u64 flexible_size, bool use_extended_mem1
|
|||
bool use_extended_mem2) {
|
||||
const bool is_neo = ::Libraries::Kernel::sceKernelIsNeoMode();
|
||||
auto total_size = is_neo ? SCE_KERNEL_TOTAL_MEM_PRO : SCE_KERNEL_TOTAL_MEM;
|
||||
if (Config::isDevKitConsole()) {
|
||||
const auto old_size = total_size;
|
||||
// Assuming 2gb is neo for now, will need to link it with sceKernelIsDevKit
|
||||
total_size += is_neo ? 2_GB : 768_MB;
|
||||
LOG_WARNING(Kernel_Vmm,
|
||||
"Config::isDevKitConsole is enabled! Added additional {:s} of direct memory.",
|
||||
is_neo ? "2 GB" : "768 MB");
|
||||
LOG_WARNING(Kernel_Vmm, "Old Direct Size: {:#x} -> New Direct Size: {:#x}", old_size,
|
||||
total_size);
|
||||
}
|
||||
if (!use_extended_mem1 && is_neo) {
|
||||
total_size -= 256_MB;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cryptopp/sha.h>
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/arch.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/memory_patcher.h"
|
||||
#include "common/sha1.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/aerolib/aerolib.h"
|
||||
#include "core/cpu_patches.h"
|
||||
|
@ -65,11 +64,13 @@ static std::string StringToNid(std::string_view symbol) {
|
|||
std::memcpy(input.data(), symbol.data(), symbol.size());
|
||||
std::memcpy(input.data() + symbol.size(), Salt.data(), Salt.size());
|
||||
|
||||
std::array<u8, CryptoPP::SHA1::DIGESTSIZE> hash;
|
||||
CryptoPP::SHA1().CalculateDigest(hash.data(), input.data(), input.size());
|
||||
sha1::SHA1::digest8_t hash;
|
||||
sha1::SHA1 sha;
|
||||
sha.processBytes(input.data(), input.size());
|
||||
sha.getDigestBytes(hash);
|
||||
|
||||
u64 digest;
|
||||
std::memcpy(&digest, hash.data(), sizeof(digest));
|
||||
std::memcpy(&digest, hash, sizeof(digest));
|
||||
|
||||
static constexpr std::string_view codes =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
|
||||
|
|
|
@ -289,13 +289,12 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
|
|||
}
|
||||
|
||||
void Emulator::LoadSystemModules(const std::string& game_serial) {
|
||||
constexpr std::array<SysModules, 11> ModulesToLoad{
|
||||
constexpr std::array<SysModules, 10> ModulesToLoad{
|
||||
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
||||
{"libSceUlt.sprx", nullptr},
|
||||
{"libSceJson.sprx", nullptr},
|
||||
{"libSceJson2.sprx", nullptr},
|
||||
{"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal},
|
||||
{"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap},
|
||||
{"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc},
|
||||
{"libSceCesCs.sprx", nullptr},
|
||||
{"libSceFont.sprx", nullptr},
|
||||
|
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 4 KiB |
BIN
src/images/fullscreen_icon.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 965 B After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.3 KiB |
BIN
src/images/refreshlist_icon.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
src/images/restart_game_icon.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 658 B After Width: | Height: | Size: 1.6 KiB |
|
@ -185,7 +185,8 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
|
|||
|
||||
// Recompute if opacity changed or we switched to a different game
|
||||
if (opacity != m_last_opacity || game.pic_path != m_current_game_path) {
|
||||
QImage original_image(QString::fromStdString(game.pic_path.string()));
|
||||
auto image_path = game.pic_path.u8string();
|
||||
QImage original_image(QString::fromStdString({image_path.begin(), image_path.end()}));
|
||||
if (!original_image.isNull()) {
|
||||
backgroundImage = m_game_list_utils.ChangeImageOpacity(
|
||||
original_image, original_image.rect(), opacity / 100.0f);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <QDesktopServices>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include <qt_gui/background_music_player.h>
|
||||
|
@ -142,14 +141,16 @@ public:
|
|||
Common::FS::PathToQString(open_update_path, m_games[itemID].path);
|
||||
open_update_path += "-UPDATE";
|
||||
if (!std::filesystem::exists(Common::FS::PathFromQString(open_update_path))) {
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(open_update_path));
|
||||
} else {
|
||||
Common::FS::PathToQString(open_update_path, m_games[itemID].path);
|
||||
open_update_path += "-patch";
|
||||
if (!std::filesystem::exists(Common::FS::PathFromQString(open_update_path))) {
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(open_update_path));
|
||||
} else {
|
||||
QMessageBox::critical(nullptr, tr("Error"),
|
||||
QString(tr("This game has no update folder to open!")));
|
||||
}
|
||||
} else {
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(open_update_path));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,30 +600,6 @@ public:
|
|||
return -1;
|
||||
}
|
||||
|
||||
void RequestGameMenuPKGViewer(
|
||||
const QPoint& pos, QStringList m_pkg_app_list, QTreeWidget* treeWidget,
|
||||
std::function<void(std::filesystem::path, int, int)> InstallDragDropPkg) {
|
||||
QPoint global_pos = treeWidget->viewport()->mapToGlobal(pos); // context menu position
|
||||
QTreeWidgetItem* currentItem = treeWidget->currentItem(); // current clicked item
|
||||
int itemIndex = GetRowIndex(treeWidget, currentItem); // row
|
||||
|
||||
QMenu menu(treeWidget);
|
||||
QAction installPackage(tr("Install PKG"), treeWidget);
|
||||
|
||||
menu.addAction(&installPackage);
|
||||
|
||||
auto selected = menu.exec(global_pos);
|
||||
if (!selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected == &installPackage) {
|
||||
QStringList pkg_app_ = m_pkg_app_list[itemIndex].split(";;");
|
||||
std::filesystem::path path = Common::FS::PathFromQString(pkg_app_[9]);
|
||||
InstallDragDropPkg(path, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool convertPngToIco(const QString& pngFilePath, const QString& icoFilePath) {
|
||||
// Load the PNG image
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "install_dir_select.h"
|
||||
|
||||
InstallDirSelect::InstallDirSelect() : selected_dir() {
|
||||
auto install_dirs = Config::getGameInstallDirs();
|
||||
selected_dir = install_dirs.empty() ? "" : install_dirs.front();
|
||||
|
||||
if (!install_dirs.empty() && install_dirs.size() == 1) {
|
||||
accept();
|
||||
}
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
|
||||
layout->addWidget(SetupInstallDirList());
|
||||
layout->addStretch();
|
||||
layout->addWidget(SetupDialogActions());
|
||||
|
||||
setWindowTitle(tr("shadPS4 - Choose directory"));
|
||||
setWindowIcon(QIcon(":images/shadps4.ico"));
|
||||
}
|
||||
|
||||
InstallDirSelect::~InstallDirSelect() {}
|
||||
|
||||
QWidget* InstallDirSelect::SetupInstallDirList() {
|
||||
auto group = new QGroupBox(tr("Select which directory you want to install to."));
|
||||
auto vlayout = new QVBoxLayout();
|
||||
|
||||
auto m_path_list = new QListWidget();
|
||||
QList<QString> qt_list;
|
||||
for (const auto& str : Config::getGameInstallDirs()) {
|
||||
QString installDirPath;
|
||||
Common::FS::PathToQString(installDirPath, str);
|
||||
qt_list.append(installDirPath);
|
||||
}
|
||||
m_path_list->insertItems(0, qt_list);
|
||||
m_path_list->setSpacing(1);
|
||||
|
||||
connect(m_path_list, &QListWidget::itemClicked, this, &InstallDirSelect::setSelectedDirectory);
|
||||
connect(m_path_list, &QListWidget::itemActivated, this,
|
||||
&InstallDirSelect::setSelectedDirectory);
|
||||
|
||||
vlayout->addWidget(m_path_list);
|
||||
|
||||
auto checkbox = new QCheckBox(tr("Install All Queued to Selected Folder"));
|
||||
connect(checkbox, &QCheckBox::toggled, this, &InstallDirSelect::setUseForAllQueued);
|
||||
vlayout->addWidget(checkbox);
|
||||
|
||||
auto checkbox2 = new QCheckBox(tr("Delete PKG File on Install"));
|
||||
connect(checkbox2, &QCheckBox::toggled, this, &InstallDirSelect::setDeleteFileOnInstall);
|
||||
vlayout->addWidget(checkbox2);
|
||||
|
||||
group->setLayout(vlayout);
|
||||
return group;
|
||||
}
|
||||
|
||||
void InstallDirSelect::setSelectedDirectory(QListWidgetItem* item) {
|
||||
if (item) {
|
||||
const auto highlighted_path = Common::FS::PathFromQString(item->text());
|
||||
if (!highlighted_path.empty()) {
|
||||
selected_dir = highlighted_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstallDirSelect::setUseForAllQueued(bool enabled) {
|
||||
use_for_all_queued = enabled;
|
||||
}
|
||||
|
||||
void InstallDirSelect::setDeleteFileOnInstall(bool enabled) {
|
||||
delete_file_on_install = enabled;
|
||||
}
|
||||
|
||||
QWidget* InstallDirSelect::SetupDialogActions() {
|
||||
auto actions = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
|
||||
connect(actions, &QDialogButtonBox::accepted, this, &InstallDirSelect::accept);
|
||||
connect(actions, &QDialogButtonBox::rejected, this, &InstallDirSelect::reject);
|
||||
|
||||
return actions;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidget>
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/path_util.h"
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
class InstallDirSelect final : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InstallDirSelect();
|
||||
~InstallDirSelect();
|
||||
|
||||
std::filesystem::path getSelectedDirectory() {
|
||||
return selected_dir;
|
||||
}
|
||||
|
||||
bool useForAllQueued() {
|
||||
return use_for_all_queued;
|
||||
}
|
||||
|
||||
bool deleteFileOnInstall() {
|
||||
return delete_file_on_install;
|
||||
}
|
||||
|
||||
private:
|
||||
QWidget* SetupInstallDirList();
|
||||
QWidget* SetupDialogActions();
|
||||
void setSelectedDirectory(QListWidgetItem* item);
|
||||
void setDeleteFileOnInstall(bool enabled);
|
||||
void setUseForAllQueued(bool enabled);
|
||||
std::filesystem::path selected_dir;
|
||||
bool delete_file_on_install = false;
|
||||
bool use_for_all_queued = false;
|
||||
};
|
|
@ -157,13 +157,8 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
bool allInstallDirsDisabled =
|
||||
std::all_of(Config::getGameInstallDirsEnabled().begin(),
|
||||
Config::getGameInstallDirsEnabled().end(), [](bool val) { return !val; });
|
||||
|
||||
// If no game directory is set and no command line argument, prompt for it
|
||||
if (Config::getGameInstallDirs().empty() && allInstallDirsDisabled &&
|
||||
!has_command_line_argument) {
|
||||
// If no game directories are set and no command line argument, prompt for it
|
||||
if (Config::getGameInstallDirsEnabled().empty() && !has_command_line_argument) {
|
||||
GameInstallDialog dlg;
|
||||
dlg.exec();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "SDL3/SDL_events.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QKeyEvent>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QProgressDialog>
|
||||
#include <QStatusBar>
|
||||
|
||||
#include "about_dialog.h"
|
||||
#include "cheats_patches.h"
|
||||
|
@ -17,10 +20,7 @@
|
|||
#include "common/string_util.h"
|
||||
#include "common/version.h"
|
||||
#include "control_settings.h"
|
||||
#include "core/file_format/pkg.h"
|
||||
#include "core/loader.h"
|
||||
#include "game_install_dialog.h"
|
||||
#include "install_dir_select.h"
|
||||
#include "kbm_gui.h"
|
||||
#include "main_window.h"
|
||||
#include "settings_dialog.h"
|
||||
|
@ -132,23 +132,160 @@ void MainWindow::CreateActions() {
|
|||
m_theme_act_group->addAction(ui->setThemeOled);
|
||||
}
|
||||
|
||||
void MainWindow::PauseGame() {
|
||||
SDL_Event event;
|
||||
SDL_memset(&event, 0, sizeof(event));
|
||||
event.type = SDL_EVENT_TOGGLE_PAUSE;
|
||||
is_paused = !is_paused;
|
||||
UpdateToolbarButtons();
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void MainWindow::toggleLabelsUnderIcons() {
|
||||
bool showLabels = ui->toggleLabelsAct->isChecked();
|
||||
Config::setShowLabelsUnderIcons();
|
||||
UpdateToolbarLabels();
|
||||
if (isGameRunning) {
|
||||
UpdateToolbarButtons();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::toggleFullscreen() {
|
||||
SDL_Event event;
|
||||
SDL_memset(&event, 0, sizeof(event));
|
||||
event.type = SDL_EVENT_TOGGLE_FULLSCREEN;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
QWidget* MainWindow::createButtonWithLabel(QPushButton* button, const QString& labelText,
|
||||
bool showLabel) {
|
||||
QWidget* container = new QWidget(this);
|
||||
QVBoxLayout* layout = new QVBoxLayout(container);
|
||||
layout->setAlignment(Qt::AlignCenter | Qt::AlignBottom);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(button);
|
||||
|
||||
QLabel* label = nullptr;
|
||||
if (showLabel && ui->toggleLabelsAct->isChecked()) {
|
||||
label = new QLabel(labelText, this);
|
||||
label->setAlignment(Qt::AlignCenter | Qt::AlignBottom);
|
||||
layout->addWidget(label);
|
||||
button->setToolTip("");
|
||||
} else {
|
||||
button->setToolTip(labelText);
|
||||
}
|
||||
|
||||
container->setLayout(layout);
|
||||
container->setProperty("buttonLabel", QVariant::fromValue(label));
|
||||
return container;
|
||||
}
|
||||
|
||||
QWidget* createSpacer(QWidget* parent) {
|
||||
QWidget* spacer = new QWidget(parent);
|
||||
spacer->setFixedWidth(15);
|
||||
spacer->setFixedHeight(15);
|
||||
return spacer;
|
||||
}
|
||||
|
||||
void MainWindow::AddUiWidgets() {
|
||||
// add toolbar widgets
|
||||
QApplication::setStyle("Fusion");
|
||||
ui->toolBar->setObjectName("mw_toolbar");
|
||||
ui->toolBar->addWidget(ui->playButton);
|
||||
ui->toolBar->addWidget(ui->pauseButton);
|
||||
ui->toolBar->addWidget(ui->stopButton);
|
||||
ui->toolBar->addWidget(ui->refreshButton);
|
||||
ui->toolBar->addWidget(ui->settingsButton);
|
||||
ui->toolBar->addWidget(ui->controllerButton);
|
||||
ui->toolBar->addWidget(ui->keyboardButton);
|
||||
|
||||
bool showLabels = ui->toggleLabelsAct->isChecked();
|
||||
ui->toolBar->clear();
|
||||
|
||||
ui->toolBar->addWidget(createSpacer(this));
|
||||
ui->toolBar->addWidget(createButtonWithLabel(ui->playButton, tr("Play"), showLabels));
|
||||
ui->toolBar->addWidget(createButtonWithLabel(ui->pauseButton, tr("Pause"), showLabels));
|
||||
ui->toolBar->addWidget(createButtonWithLabel(ui->stopButton, tr("Stop"), showLabels));
|
||||
ui->toolBar->addWidget(createButtonWithLabel(ui->restartButton, tr("Restart"), showLabels));
|
||||
ui->toolBar->addWidget(createSpacer(this));
|
||||
ui->toolBar->addWidget(createButtonWithLabel(ui->settingsButton, tr("Settings"), showLabels));
|
||||
ui->toolBar->addWidget(
|
||||
createButtonWithLabel(ui->fullscreenButton, tr("Full Screen"), showLabels));
|
||||
ui->toolBar->addWidget(createSpacer(this));
|
||||
ui->toolBar->addWidget(
|
||||
createButtonWithLabel(ui->controllerButton, tr("Controllers"), showLabels));
|
||||
ui->toolBar->addWidget(createButtonWithLabel(ui->keyboardButton, tr("Keyboard"), showLabels));
|
||||
ui->toolBar->addWidget(createSpacer(this));
|
||||
QFrame* line = new QFrame(this);
|
||||
line->setFrameShape(QFrame::StyledPanel);
|
||||
line->setFrameShape(QFrame::VLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
line->setMinimumWidth(2);
|
||||
ui->toolBar->addWidget(line);
|
||||
ui->toolBar->addWidget(ui->sizeSliderContainer);
|
||||
ui->toolBar->addWidget(ui->mw_searchbar);
|
||||
ui->toolBar->addWidget(createSpacer(this));
|
||||
if (showLabels) {
|
||||
QLabel* pauseButtonLabel = ui->pauseButton->parentWidget()->findChild<QLabel*>();
|
||||
if (pauseButtonLabel) {
|
||||
pauseButtonLabel->setVisible(false);
|
||||
}
|
||||
}
|
||||
ui->toolBar->addWidget(
|
||||
createButtonWithLabel(ui->refreshButton, tr("Refresh List"), showLabels));
|
||||
ui->toolBar->addWidget(createSpacer(this));
|
||||
|
||||
QBoxLayout* toolbarLayout = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
toolbarLayout->setSpacing(2);
|
||||
toolbarLayout->setContentsMargins(2, 2, 2, 2);
|
||||
ui->sizeSliderContainer->setFixedWidth(150);
|
||||
|
||||
QWidget* searchSliderContainer = new QWidget(this);
|
||||
QBoxLayout* searchSliderLayout = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
searchSliderLayout->setContentsMargins(0, 0, 6, 6);
|
||||
searchSliderLayout->setSpacing(2);
|
||||
ui->mw_searchbar->setFixedWidth(150);
|
||||
|
||||
searchSliderLayout->addWidget(ui->sizeSliderContainer);
|
||||
searchSliderLayout->addWidget(ui->mw_searchbar);
|
||||
|
||||
searchSliderContainer->setLayout(searchSliderLayout);
|
||||
|
||||
ui->toolBar->addWidget(searchSliderContainer);
|
||||
|
||||
if (!showLabels) {
|
||||
toolbarLayout->addWidget(searchSliderContainer);
|
||||
}
|
||||
|
||||
ui->playButton->setVisible(true);
|
||||
ui->pauseButton->setVisible(false);
|
||||
}
|
||||
|
||||
void MainWindow::UpdateToolbarButtons() {
|
||||
// add toolbar widgets when game is running
|
||||
bool showLabels = ui->toggleLabelsAct->isChecked();
|
||||
|
||||
ui->playButton->setVisible(false);
|
||||
ui->pauseButton->setVisible(true);
|
||||
|
||||
if (showLabels) {
|
||||
QLabel* playButtonLabel = ui->playButton->parentWidget()->findChild<QLabel*>();
|
||||
if (playButtonLabel)
|
||||
playButtonLabel->setVisible(false);
|
||||
}
|
||||
|
||||
if (is_paused) {
|
||||
ui->pauseButton->setIcon(ui->playButton->icon());
|
||||
ui->pauseButton->setToolTip(tr("Resume"));
|
||||
} else {
|
||||
if (isIconBlack) {
|
||||
ui->pauseButton->setIcon(QIcon(":images/pause_icon.png"));
|
||||
} else {
|
||||
ui->pauseButton->setIcon(RecolorIcon(QIcon(":images/pause_icon.png"), isWhite));
|
||||
}
|
||||
ui->pauseButton->setToolTip(tr("Pause"));
|
||||
}
|
||||
|
||||
if (showLabels) {
|
||||
QLabel* pauseButtonLabel = ui->pauseButton->parentWidget()->findChild<QLabel*>();
|
||||
if (pauseButtonLabel) {
|
||||
pauseButtonLabel->setText(is_paused ? tr("Resume") : tr("Pause"));
|
||||
pauseButtonLabel->setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::UpdateToolbarLabels() {
|
||||
AddUiWidgets();
|
||||
}
|
||||
|
||||
void MainWindow::CreateDockWindows() {
|
||||
|
@ -253,6 +390,8 @@ void MainWindow::CreateConnects() {
|
|||
connect(ui->refreshButton, &QPushButton::clicked, this, &MainWindow::RefreshGameTable);
|
||||
connect(ui->showGameListAct, &QAction::triggered, this, &MainWindow::ShowGameList);
|
||||
connect(this, &MainWindow::ExtractionFinished, this, &MainWindow::RefreshGameTable);
|
||||
connect(ui->toggleLabelsAct, &QAction::toggled, this, &MainWindow::toggleLabelsUnderIcons);
|
||||
connect(ui->fullscreenButton, &QPushButton::clicked, this, &MainWindow::toggleFullscreen);
|
||||
|
||||
connect(ui->sizeSlider, &QSlider::valueChanged, this, [this](int value) {
|
||||
if (isTableList) {
|
||||
|
@ -276,6 +415,7 @@ void MainWindow::CreateConnects() {
|
|||
});
|
||||
|
||||
connect(ui->playButton, &QPushButton::clicked, this, &MainWindow::StartGame);
|
||||
connect(ui->pauseButton, &QPushButton::clicked, this, &MainWindow::PauseGame);
|
||||
connect(m_game_grid_frame.get(), &QTableWidget::cellDoubleClicked, this,
|
||||
&MainWindow::StartGame);
|
||||
connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this,
|
||||
|
@ -576,7 +716,6 @@ void MainWindow::CreateConnects() {
|
|||
});
|
||||
|
||||
// Package install.
|
||||
connect(ui->bootInstallPkgAct, &QAction::triggered, this, &MainWindow::InstallPkg);
|
||||
connect(ui->bootGameAct, &QAction::triggered, this, &MainWindow::BootGame);
|
||||
connect(ui->gameInstallPathAct, &QAction::triggered, this, &MainWindow::InstallDirectory);
|
||||
|
||||
|
@ -584,15 +723,6 @@ void MainWindow::CreateConnects() {
|
|||
connect(ui->addElfFolderAct, &QAction::triggered, m_elf_viewer.data(),
|
||||
&ElfViewer::OpenElfFolder);
|
||||
|
||||
// Package Viewer.
|
||||
connect(ui->pkgViewerAct, &QAction::triggered, this, [this]() {
|
||||
PKGViewer* pkgViewer = new PKGViewer(
|
||||
m_game_info, this, [this](std::filesystem::path file, int pkgNum, int nPkg) {
|
||||
this->InstallDragDropPkg(file, pkgNum, nPkg);
|
||||
});
|
||||
pkgViewer->show();
|
||||
});
|
||||
|
||||
// Trophy Viewer
|
||||
connect(ui->trophyViewerAct, &QAction::triggered, this, [this]() {
|
||||
if (m_game_info->m_games.empty()) {
|
||||
|
@ -743,6 +873,8 @@ void MainWindow::StartGame() {
|
|||
return;
|
||||
}
|
||||
StartEmulator(path);
|
||||
|
||||
UpdateToolbarButtons();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,22 +953,6 @@ void MainWindow::SaveWindowState() const {
|
|||
this->geometry().width(), this->geometry().height());
|
||||
}
|
||||
|
||||
void MainWindow::InstallPkg() {
|
||||
QFileDialog dialog;
|
||||
dialog.setFileMode(QFileDialog::ExistingFiles);
|
||||
dialog.setNameFilter(tr("PKG File (*.PKG *.pkg)"));
|
||||
if (dialog.exec()) {
|
||||
QStringList fileNames = dialog.selectedFiles();
|
||||
int nPkg = fileNames.size();
|
||||
int pkgNum = 0;
|
||||
for (const QString& file : fileNames) {
|
||||
++pkgNum;
|
||||
std::filesystem::path path = Common::FS::PathFromQString(file);
|
||||
MainWindow::InstallDragDropPkg(path, pkgNum, nPkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::BootGame() {
|
||||
QFileDialog dialog;
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
|
@ -860,260 +976,6 @@ void MainWindow::BootGame() {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int nPkg) {
|
||||
if (Loader::DetectFileType(file) == Loader::FileTypes::Pkg) {
|
||||
std::string failreason;
|
||||
pkg = PKG();
|
||||
if (!pkg.Open(file, failreason)) {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
|
||||
return;
|
||||
}
|
||||
if (!psf.Open(pkg.sfo)) {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"),
|
||||
"Could not read SFO. Check log for details");
|
||||
return;
|
||||
}
|
||||
auto category = psf.GetString("CATEGORY");
|
||||
|
||||
if (!use_for_all_queued || pkgNum == 1) {
|
||||
InstallDirSelect ids;
|
||||
const auto selected = ids.exec();
|
||||
if (selected == QDialog::Rejected) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_install_dir = ids.getSelectedDirectory();
|
||||
delete_file_on_install = ids.deleteFileOnInstall();
|
||||
use_for_all_queued = ids.useForAllQueued();
|
||||
}
|
||||
std::filesystem::path game_install_dir = last_install_dir;
|
||||
|
||||
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
||||
bool use_game_update = pkgType.contains("PATCH") && Config::getSeparateUpdateEnabled();
|
||||
|
||||
// Default paths
|
||||
auto game_folder_path = game_install_dir / pkg.GetTitleID();
|
||||
auto game_update_path = use_game_update ? game_folder_path.parent_path() /
|
||||
(std::string{pkg.GetTitleID()} + "-patch")
|
||||
: game_folder_path;
|
||||
const int max_depth = 5;
|
||||
|
||||
if (pkgType.contains("PATCH")) {
|
||||
// For patches, try to find the game recursively
|
||||
auto found_game = Common::FS::FindGameByID(game_install_dir,
|
||||
std::string{pkg.GetTitleID()}, max_depth);
|
||||
if (found_game.has_value()) {
|
||||
game_folder_path = found_game.value().parent_path();
|
||||
game_update_path = use_game_update ? game_folder_path.parent_path() /
|
||||
(std::string{pkg.GetTitleID()} + "-patch")
|
||||
: game_folder_path;
|
||||
}
|
||||
} else {
|
||||
// For base games, we check if the game is already installed
|
||||
auto found_game = Common::FS::FindGameByID(game_install_dir,
|
||||
std::string{pkg.GetTitleID()}, max_depth);
|
||||
if (found_game.has_value()) {
|
||||
game_folder_path = found_game.value().parent_path();
|
||||
}
|
||||
// If the game is not found, we install it in the game install directory
|
||||
else {
|
||||
game_folder_path = game_install_dir / pkg.GetTitleID();
|
||||
}
|
||||
game_update_path = use_game_update ? game_folder_path.parent_path() /
|
||||
(std::string{pkg.GetTitleID()} + "-patch")
|
||||
: game_folder_path;
|
||||
}
|
||||
|
||||
QString gameDirPath;
|
||||
Common::FS::PathToQString(gameDirPath, game_folder_path);
|
||||
QDir game_dir(gameDirPath);
|
||||
if (game_dir.exists()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("PKG Extraction"));
|
||||
|
||||
std::string content_id;
|
||||
if (auto value = psf.GetString("CONTENT_ID"); value.has_value()) {
|
||||
content_id = std::string{*value};
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"), "PSF file there is no CONTENT_ID");
|
||||
return;
|
||||
}
|
||||
std::string entitlement_label = Common::SplitString(content_id, '-')[2];
|
||||
|
||||
auto addon_extract_path =
|
||||
Config::getAddonInstallDir() / pkg.GetTitleID() / entitlement_label;
|
||||
QString addonDirPath;
|
||||
Common::FS::PathToQString(addonDirPath, addon_extract_path);
|
||||
QDir addon_dir(addonDirPath);
|
||||
|
||||
if (pkgType.contains("PATCH")) {
|
||||
QString pkg_app_version;
|
||||
if (auto app_ver = psf.GetString("APP_VER"); app_ver.has_value()) {
|
||||
pkg_app_version = QString::fromStdString(std::string{*app_ver});
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"), "PSF file there is no APP_VER");
|
||||
return;
|
||||
}
|
||||
std::filesystem::path sce_folder_path =
|
||||
std::filesystem::exists(game_update_path / "sce_sys" / "param.sfo")
|
||||
? game_update_path / "sce_sys" / "param.sfo"
|
||||
: game_folder_path / "sce_sys" / "param.sfo";
|
||||
psf.Open(sce_folder_path);
|
||||
QString game_app_version;
|
||||
if (auto app_ver = psf.GetString("APP_VER"); app_ver.has_value()) {
|
||||
game_app_version = QString::fromStdString(std::string{*app_ver});
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"), "PSF file there is no APP_VER");
|
||||
return;
|
||||
}
|
||||
double appD = game_app_version.toDouble();
|
||||
double pkgD = pkg_app_version.toDouble();
|
||||
if (pkgD == appD) {
|
||||
msgBox.setText(QString(tr("Patch detected!") + "\n" +
|
||||
tr("PKG and Game versions match: ") + pkg_app_version +
|
||||
"\n" + tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
} else if (pkgD < appD) {
|
||||
msgBox.setText(QString(tr("Patch detected!") + "\n" +
|
||||
tr("PKG Version %1 is older than installed version: ")
|
||||
.arg(pkg_app_version) +
|
||||
game_app_version + "\n" +
|
||||
tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
} else {
|
||||
msgBox.setText(QString(tr("Patch detected!") + "\n" +
|
||||
tr("Game is installed: ") + game_app_version + "\n" +
|
||||
tr("Would you like to install Patch: ") +
|
||||
pkg_app_version + " ?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
}
|
||||
int result = msgBox.exec();
|
||||
if (result == QMessageBox::Yes) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (category == "ac") {
|
||||
if (!addon_dir.exists()) {
|
||||
QMessageBox addonMsgBox;
|
||||
addonMsgBox.setWindowTitle(tr("DLC Installation"));
|
||||
addonMsgBox.setText(QString(tr("Would you like to install DLC: %1?"))
|
||||
.arg(QString::fromStdString(entitlement_label)));
|
||||
|
||||
addonMsgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
addonMsgBox.setDefaultButton(QMessageBox::No);
|
||||
int result = addonMsgBox.exec();
|
||||
if (result == QMessageBox::Yes) {
|
||||
game_update_path = addon_extract_path;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
msgBox.setText(QString(tr("DLC already installed:") + "\n" + addonDirPath +
|
||||
"\n\n" + tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
int result = msgBox.exec();
|
||||
if (result == QMessageBox::Yes) {
|
||||
game_update_path = addon_extract_path;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msgBox.setText(QString(tr("Game already installed") + "\n" + gameDirPath + "\n" +
|
||||
tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
int result = msgBox.exec();
|
||||
if (result == QMessageBox::Yes) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Do nothing;
|
||||
if (pkgType.contains("PATCH") || category == "ac") {
|
||||
QMessageBox::information(
|
||||
this, tr("PKG Extraction"),
|
||||
tr("PKG is a patch or DLC, please install the game first!"));
|
||||
return;
|
||||
}
|
||||
// what else?
|
||||
}
|
||||
if (!pkg.Extract(file, game_update_path, failreason)) {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
|
||||
} else {
|
||||
int nfiles = pkg.GetNumberOfFiles();
|
||||
|
||||
if (nfiles > 0) {
|
||||
QVector<int> indices;
|
||||
for (int i = 0; i < nfiles; i++) {
|
||||
indices.append(i);
|
||||
}
|
||||
|
||||
QProgressDialog dialog;
|
||||
dialog.setWindowTitle(tr("PKG Extraction"));
|
||||
dialog.setWindowModality(Qt::WindowModal);
|
||||
QString extractmsg = QString(tr("Extracting PKG %1/%2")).arg(pkgNum).arg(nPkg);
|
||||
dialog.setLabelText(extractmsg);
|
||||
dialog.setAutoClose(true);
|
||||
dialog.setRange(0, nfiles);
|
||||
|
||||
dialog.setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,
|
||||
dialog.size(), this->geometry()));
|
||||
|
||||
QFutureWatcher<void> futureWatcher;
|
||||
connect(&futureWatcher, &QFutureWatcher<void>::finished, this, [=, this]() {
|
||||
if (pkgNum == nPkg) {
|
||||
QString path;
|
||||
|
||||
// We want to show the parent path instead of the full path
|
||||
Common::FS::PathToQString(path, game_folder_path.parent_path());
|
||||
QIcon windowIcon(
|
||||
Common::FS::PathToUTF8String(game_folder_path / "sce_sys/icon0.png")
|
||||
.c_str());
|
||||
|
||||
QMessageBox extractMsgBox(this);
|
||||
extractMsgBox.setWindowTitle(tr("Extraction Finished"));
|
||||
if (!windowIcon.isNull()) {
|
||||
extractMsgBox.setWindowIcon(windowIcon);
|
||||
}
|
||||
extractMsgBox.setText(
|
||||
QString(tr("Game successfully installed at %1")).arg(path));
|
||||
extractMsgBox.addButton(QMessageBox::Ok);
|
||||
extractMsgBox.setDefaultButton(QMessageBox::Ok);
|
||||
connect(&extractMsgBox, &QMessageBox::buttonClicked, this,
|
||||
[&](QAbstractButton* button) {
|
||||
if (extractMsgBox.button(QMessageBox::Ok) == button) {
|
||||
extractMsgBox.close();
|
||||
emit ExtractionFinished();
|
||||
}
|
||||
});
|
||||
extractMsgBox.exec();
|
||||
}
|
||||
if (delete_file_on_install) {
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
});
|
||||
connect(&dialog, &QProgressDialog::canceled, [&]() { futureWatcher.cancel(); });
|
||||
connect(&futureWatcher, &QFutureWatcher<void>::progressValueChanged, &dialog,
|
||||
&QProgressDialog::setValue);
|
||||
futureWatcher.setFuture(
|
||||
QtConcurrent::map(indices, [&](int index) { pkg.ExtractFiles(index); }));
|
||||
dialog.exec();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("PKG ERROR"),
|
||||
tr("File doesn't appear to be a valid PKG file"));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::InstallDirectory() {
|
||||
GameInstallDialog dlg;
|
||||
dlg.exec();
|
||||
|
@ -1196,7 +1058,6 @@ 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));
|
||||
|
@ -1217,12 +1078,13 @@ void MainWindow::SetUiIcons(bool isWhite) {
|
|||
ui->pauseButton->setIcon(RecolorIcon(ui->pauseButton->icon(), isWhite));
|
||||
ui->stopButton->setIcon(RecolorIcon(ui->stopButton->icon(), isWhite));
|
||||
ui->refreshButton->setIcon(RecolorIcon(ui->refreshButton->icon(), isWhite));
|
||||
ui->restartButton->setIcon(RecolorIcon(ui->restartButton->icon(), isWhite));
|
||||
ui->settingsButton->setIcon(RecolorIcon(ui->settingsButton->icon(), isWhite));
|
||||
ui->fullscreenButton->setIcon(RecolorIcon(ui->fullscreenButton->icon(), isWhite));
|
||||
ui->controllerButton->setIcon(RecolorIcon(ui->controllerButton->icon(), isWhite));
|
||||
ui->keyboardButton->setIcon(RecolorIcon(ui->keyboardButton->icon(), isWhite));
|
||||
ui->refreshGameListAct->setIcon(RecolorIcon(ui->refreshGameListAct->icon(), isWhite));
|
||||
ui->menuGame_List_Mode->setIcon(RecolorIcon(ui->menuGame_List_Mode->icon(), isWhite));
|
||||
ui->pkgViewerAct->setIcon(RecolorIcon(ui->pkgViewerAct->icon(), isWhite));
|
||||
ui->trophyViewerAct->setIcon(RecolorIcon(ui->trophyViewerAct->icon(), isWhite));
|
||||
ui->configureAct->setIcon(RecolorIcon(ui->configureAct->icon(), isWhite));
|
||||
ui->addElfFolderAct->setIcon(RecolorIcon(ui->addElfFolderAct->icon(), isWhite));
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QActionGroup>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QProcess>
|
||||
#include <QTranslator>
|
||||
|
||||
#include "background_music_player.h"
|
||||
|
@ -21,7 +22,6 @@
|
|||
#include "game_list_utils.h"
|
||||
#include "main_window_themes.h"
|
||||
#include "main_window_ui.h"
|
||||
#include "pkg_viewer.h"
|
||||
|
||||
class GameListFrame;
|
||||
|
||||
|
@ -35,9 +35,10 @@ public:
|
|||
explicit MainWindow(QWidget* parent = nullptr);
|
||||
~MainWindow();
|
||||
bool Init();
|
||||
void InstallDragDropPkg(std::filesystem::path file, int pkgNum, int nPkg);
|
||||
void InstallDirectory();
|
||||
void StartGame();
|
||||
void PauseGame();
|
||||
bool showLabels;
|
||||
|
||||
private Q_SLOTS:
|
||||
void ConfigureGuiFromSettings();
|
||||
|
@ -47,15 +48,21 @@ private Q_SLOTS:
|
|||
void RefreshGameTable();
|
||||
void HandleResize(QResizeEvent* event);
|
||||
void OnLanguageChanged(const std::string& locale);
|
||||
void toggleLabelsUnderIcons();
|
||||
|
||||
private:
|
||||
Ui_MainWindow* ui;
|
||||
void AddUiWidgets();
|
||||
void UpdateToolbarLabels();
|
||||
void UpdateToolbarButtons();
|
||||
QWidget* createButtonWithLabel(QPushButton* button, const QString& labelText, bool showLabel);
|
||||
void CreateActions();
|
||||
void toggleFullscreen();
|
||||
void CreateRecentGameActions();
|
||||
void CreateDockWindows();
|
||||
void GetPhysicalDevices();
|
||||
void LoadGameLists();
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
void CheckUpdateMain(bool checkSave);
|
||||
#endif
|
||||
|
@ -63,7 +70,6 @@ private:
|
|||
void SetLastUsedTheme();
|
||||
void SetLastIconSizeBullet();
|
||||
void SetUiIcons(bool isWhite);
|
||||
void InstallPkg();
|
||||
void BootGame();
|
||||
void AddRecentFiles(QString filePath);
|
||||
void LoadTranslation();
|
||||
|
@ -73,11 +79,13 @@ private:
|
|||
bool isIconBlack = false;
|
||||
bool isTableList = true;
|
||||
bool isGameRunning = false;
|
||||
bool isWhite = false;
|
||||
bool is_paused = false;
|
||||
|
||||
QActionGroup* m_icon_size_act_group = nullptr;
|
||||
QActionGroup* m_list_mode_act_group = nullptr;
|
||||
QActionGroup* m_theme_act_group = nullptr;
|
||||
QActionGroup* m_recent_files_group = nullptr;
|
||||
PKG pkg;
|
||||
// Dockable widget frames
|
||||
WindowThemes m_window_themes;
|
||||
GameListUtils m_game_list_utils;
|
||||
|
@ -108,20 +116,6 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void dropEvent(QDropEvent* event1) override {
|
||||
const QMimeData* mimeData = event1->mimeData();
|
||||
if (mimeData->hasUrls()) {
|
||||
QList<QUrl> urlList = mimeData->urls();
|
||||
int pkgNum = 0;
|
||||
int nPkg = urlList.size();
|
||||
for (const QUrl& url : urlList) {
|
||||
pkgNum++;
|
||||
std::filesystem::path path = Common::FS::PathFromQString(url.toLocalFile());
|
||||
InstallDragDropPkg(path, pkgNum, nPkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
std::filesystem::path last_install_dir = "";
|
||||
|
|
|
@ -19,7 +19,7 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
themePalette.setColor(QPalette::WindowText, Qt::white);
|
||||
themePalette.setColor(QPalette::Base, QColor(20, 20, 20));
|
||||
themePalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
|
||||
themePalette.setColor(QPalette::ToolTipBase, Qt::white);
|
||||
themePalette.setColor(QPalette::ToolTipBase, QColor(20, 20, 20));
|
||||
themePalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||
themePalette.setColor(QPalette::Text, Qt::white);
|
||||
themePalette.setColor(QPalette::Button, QColor(53, 53, 53));
|
||||
|
@ -37,18 +37,18 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
themePalette.setColor(QPalette::Window, QColor(240, 240, 240)); // Light gray
|
||||
themePalette.setColor(QPalette::WindowText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Base, QColor(230, 230, 230, 80)); // Grayish
|
||||
themePalette.setColor(QPalette::ToolTipBase, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::ToolTipText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Text, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Button, QColor(240, 240, 240)); // Light gray
|
||||
themePalette.setColor(QPalette::ButtonText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::BrightText, Qt::red); // Red
|
||||
themePalette.setColor(QPalette::Link, QColor(42, 130, 218)); // Blue
|
||||
themePalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); // Blue
|
||||
themePalette.setColor(QPalette::HighlightedText, Qt::white); // White
|
||||
themePalette.setColor(QPalette::Window, QColor(240, 240, 240)); // Light gray
|
||||
themePalette.setColor(QPalette::WindowText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Base, QColor(230, 230, 230, 80)); // Grayish
|
||||
themePalette.setColor(QPalette::ToolTipBase, QColor(230, 230, 230, 80)); // Grayish
|
||||
themePalette.setColor(QPalette::ToolTipText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Text, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Button, QColor(240, 240, 240)); // Light gray
|
||||
themePalette.setColor(QPalette::ButtonText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::BrightText, Qt::red); // Red
|
||||
themePalette.setColor(QPalette::Link, QColor(42, 130, 218)); // Blue
|
||||
themePalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); // Blue
|
||||
themePalette.setColor(QPalette::HighlightedText, Qt::white); // White
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Green:
|
||||
|
@ -62,8 +62,9 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
themePalette.setColor(QPalette::WindowText, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Base, QColor(25, 40, 25)); // Darker green base
|
||||
themePalette.setColor(QPalette::AlternateBase,
|
||||
QColor(53, 69, 53)); // Dark green alternate base
|
||||
themePalette.setColor(QPalette::ToolTipBase, Qt::white); // White tooltip background
|
||||
QColor(53, 69, 53)); // Dark green alternate base
|
||||
themePalette.setColor(QPalette::ToolTipBase,
|
||||
QColor(25, 40, 25)); // White tooltip background
|
||||
themePalette.setColor(QPalette::ToolTipText, Qt::white); // White tooltip text
|
||||
themePalette.setColor(QPalette::Text, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Button, QColor(53, 69, 53)); // Dark green button
|
||||
|
@ -85,8 +86,9 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
themePalette.setColor(QPalette::WindowText, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Base, QColor(20, 40, 60)); // Darker blue base
|
||||
themePalette.setColor(QPalette::AlternateBase,
|
||||
QColor(40, 60, 90)); // Dark blue alternate base
|
||||
themePalette.setColor(QPalette::ToolTipBase, Qt::white); // White tooltip background
|
||||
QColor(40, 60, 90)); // Dark blue alternate base
|
||||
themePalette.setColor(QPalette::ToolTipBase,
|
||||
QColor(20, 40, 60)); // White tooltip background
|
||||
themePalette.setColor(QPalette::ToolTipText, Qt::white); // White tooltip text
|
||||
themePalette.setColor(QPalette::Text, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Button, QColor(40, 60, 90)); // Dark blue button
|
||||
|
@ -109,8 +111,9 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
themePalette.setColor(QPalette::WindowText, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Base, QColor(80, 30, 90)); // Darker violet base
|
||||
themePalette.setColor(QPalette::AlternateBase,
|
||||
QColor(100, 50, 120)); // Violet alternate base
|
||||
themePalette.setColor(QPalette::ToolTipBase, Qt::white); // White tooltip background
|
||||
QColor(100, 50, 120)); // Violet alternate base
|
||||
themePalette.setColor(QPalette::ToolTipBase,
|
||||
QColor(80, 30, 90)); // White tooltip background
|
||||
themePalette.setColor(QPalette::ToolTipText, Qt::white); // White tooltip text
|
||||
themePalette.setColor(QPalette::Text, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Button, QColor(100, 50, 120)); // Violet button
|
||||
|
@ -133,7 +136,7 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
themePalette.setColor(QPalette::WindowText, QColor(249, 245, 215));
|
||||
themePalette.setColor(QPalette::Base, QColor(29, 32, 33));
|
||||
themePalette.setColor(QPalette::AlternateBase, QColor(50, 48, 47));
|
||||
themePalette.setColor(QPalette::ToolTipBase, QColor(249, 245, 215));
|
||||
themePalette.setColor(QPalette::ToolTipBase, QColor(29, 32, 33));
|
||||
themePalette.setColor(QPalette::ToolTipText, QColor(249, 245, 215));
|
||||
themePalette.setColor(QPalette::Text, QColor(249, 245, 215));
|
||||
themePalette.setColor(QPalette::Button, QColor(40, 40, 40));
|
||||
|
@ -155,7 +158,7 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
|||
themePalette.setColor(QPalette::WindowText, QColor(192, 202, 245));
|
||||
themePalette.setColor(QPalette::Base, QColor(25, 28, 39));
|
||||
themePalette.setColor(QPalette::AlternateBase, QColor(36, 40, 59));
|
||||
themePalette.setColor(QPalette::ToolTipBase, QColor(192, 202, 245));
|
||||
themePalette.setColor(QPalette::ToolTipBase, QColor(25, 28, 39));
|
||||
themePalette.setColor(QPalette::ToolTipText, QColor(192, 202, 245));
|
||||
themePalette.setColor(QPalette::Text, QColor(192, 202, 245));
|
||||
themePalette.setColor(QPalette::Button, QColor(30, 30, 41));
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
class Ui_MainWindow {
|
||||
public:
|
||||
QAction* bootInstallPkgAct;
|
||||
QAction* bootGameAct;
|
||||
QAction* addElfFolderAct;
|
||||
QAction* shadFolderAct;
|
||||
|
@ -20,13 +19,13 @@ public:
|
|||
QAction* setIconSizeSmallAct;
|
||||
QAction* setIconSizeMediumAct;
|
||||
QAction* setIconSizeLargeAct;
|
||||
QAction* toggleLabelsAct;
|
||||
QAction* setlistModeListAct;
|
||||
QAction* setlistModeGridAct;
|
||||
QAction* setlistElfAct;
|
||||
QAction* gameInstallPathAct;
|
||||
QAction* downloadCheatsPatchesAct;
|
||||
QAction* dumpGameListAct;
|
||||
QAction* pkgViewerAct;
|
||||
QAction* trophyViewerAct;
|
||||
#ifdef ENABLE_UPDATER
|
||||
QAction* updaterAct;
|
||||
|
@ -50,6 +49,8 @@ public:
|
|||
QPushButton* settingsButton;
|
||||
QPushButton* controllerButton;
|
||||
QPushButton* keyboardButton;
|
||||
QPushButton* fullscreenButton;
|
||||
QPushButton* restartButton;
|
||||
|
||||
QWidget* sizeSliderContainer;
|
||||
QHBoxLayout* sizeSliderContainer_layout;
|
||||
|
@ -84,9 +85,6 @@ public:
|
|||
MainWindow->setDockNestingEnabled(true);
|
||||
MainWindow->setDockOptions(QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks |
|
||||
QMainWindow::AnimatedDocks | QMainWindow::GroupedDragging);
|
||||
bootInstallPkgAct = new QAction(MainWindow);
|
||||
bootInstallPkgAct->setObjectName("bootInstallPkgAct");
|
||||
bootInstallPkgAct->setIcon(QIcon(":images/file_icon.png"));
|
||||
bootGameAct = new QAction(MainWindow);
|
||||
bootGameAct->setObjectName("bootGameAct");
|
||||
bootGameAct->setIcon(QIcon(":images/play_icon.png"));
|
||||
|
@ -104,7 +102,15 @@ public:
|
|||
showGameListAct->setCheckable(true);
|
||||
refreshGameListAct = new QAction(MainWindow);
|
||||
refreshGameListAct->setObjectName("refreshGameListAct");
|
||||
refreshGameListAct->setIcon(QIcon(":images/refresh_icon.png"));
|
||||
refreshGameListAct->setIcon(QIcon(":images/refreshlist_icon.png"));
|
||||
|
||||
toggleLabelsAct = new QAction(MainWindow);
|
||||
toggleLabelsAct->setObjectName("toggleLabelsAct");
|
||||
toggleLabelsAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Show Labels Under Icons"));
|
||||
toggleLabelsAct->setCheckable(true);
|
||||
toggleLabelsAct->setChecked(Config::getShowLabelsUnderIcons());
|
||||
|
||||
setIconSizeTinyAct = new QAction(MainWindow);
|
||||
setIconSizeTinyAct->setObjectName("setIconSizeTinyAct");
|
||||
setIconSizeTinyAct->setCheckable(true);
|
||||
|
@ -137,9 +143,6 @@ public:
|
|||
dumpGameListAct = new QAction(MainWindow);
|
||||
dumpGameListAct->setObjectName("dumpGameList");
|
||||
dumpGameListAct->setIcon(QIcon(":images/dump_icon.png"));
|
||||
pkgViewerAct = new QAction(MainWindow);
|
||||
pkgViewerAct->setObjectName("pkgViewer");
|
||||
pkgViewerAct->setIcon(QIcon(":images/file_icon.png"));
|
||||
trophyViewerAct = new QAction(MainWindow);
|
||||
trophyViewerAct->setObjectName("trophyViewer");
|
||||
trophyViewerAct->setIcon(QIcon(":images/trophy_icon.png"));
|
||||
|
@ -210,20 +213,28 @@ public:
|
|||
stopButton->setIconSize(QSize(40, 40));
|
||||
refreshButton = new QPushButton(centralWidget);
|
||||
refreshButton->setFlat(true);
|
||||
refreshButton->setIcon(QIcon(":images/refresh_icon.png"));
|
||||
refreshButton->setIconSize(QSize(32, 32));
|
||||
refreshButton->setIcon(QIcon(":images/refreshlist_icon.png"));
|
||||
refreshButton->setIconSize(QSize(40, 40));
|
||||
fullscreenButton = new QPushButton(centralWidget);
|
||||
fullscreenButton->setFlat(true);
|
||||
fullscreenButton->setIcon(QIcon(":images/fullscreen_icon.png"));
|
||||
fullscreenButton->setIconSize(QSize(38, 38));
|
||||
settingsButton = new QPushButton(centralWidget);
|
||||
settingsButton->setFlat(true);
|
||||
settingsButton->setIcon(QIcon(":images/settings_icon.png"));
|
||||
settingsButton->setIconSize(QSize(44, 44));
|
||||
settingsButton->setIconSize(QSize(40, 40));
|
||||
controllerButton = new QPushButton(centralWidget);
|
||||
controllerButton->setFlat(true);
|
||||
controllerButton->setIcon(QIcon(":images/controller_icon.png"));
|
||||
controllerButton->setIconSize(QSize(40, 40));
|
||||
controllerButton->setIconSize(QSize(55, 48));
|
||||
keyboardButton = new QPushButton(centralWidget);
|
||||
keyboardButton->setFlat(true);
|
||||
keyboardButton->setIcon(QIcon(":images/keyboard_icon.png"));
|
||||
keyboardButton->setIconSize(QSize(48, 44));
|
||||
keyboardButton->setIconSize(QSize(50, 50));
|
||||
restartButton = new QPushButton(centralWidget);
|
||||
restartButton->setFlat(true);
|
||||
restartButton->setIcon(QIcon(":images/restart_game_icon.png"));
|
||||
restartButton->setIconSize(QSize(40, 40));
|
||||
|
||||
sizeSliderContainer = new QWidget(centralWidget);
|
||||
sizeSliderContainer->setObjectName("sizeSliderContainer");
|
||||
|
@ -290,7 +301,6 @@ public:
|
|||
menuBar->addAction(menuView->menuAction());
|
||||
menuBar->addAction(menuSettings->menuAction());
|
||||
menuBar->addAction(menuHelp->menuAction());
|
||||
menuFile->addAction(bootInstallPkgAct);
|
||||
menuFile->addAction(bootGameAct);
|
||||
menuFile->addSeparator();
|
||||
menuFile->addAction(addElfFolderAct);
|
||||
|
@ -304,6 +314,7 @@ public:
|
|||
menuView->addAction(refreshGameListAct);
|
||||
menuView->addAction(menuGame_List_Mode->menuAction());
|
||||
menuView->addAction(menuGame_List_Icons->menuAction());
|
||||
menuView->addAction(toggleLabelsAct);
|
||||
menuView->addAction(menuThemes->menuAction());
|
||||
menuThemes->addAction(setThemeDark);
|
||||
menuThemes->addAction(setThemeLight);
|
||||
|
@ -325,7 +336,6 @@ public:
|
|||
menuSettings->addAction(menuUtils->menuAction());
|
||||
menuUtils->addAction(downloadCheatsPatchesAct);
|
||||
menuUtils->addAction(dumpGameListAct);
|
||||
menuUtils->addAction(pkgViewerAct);
|
||||
menuUtils->addAction(trophyViewerAct);
|
||||
#ifdef ENABLE_UPDATER
|
||||
menuHelp->addAction(updaterAct);
|
||||
|
@ -341,8 +351,6 @@ public:
|
|||
MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "shadPS4", nullptr));
|
||||
addElfFolderAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Open/Add Elf Folder", nullptr));
|
||||
bootInstallPkgAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Install Packages (PKG)", nullptr));
|
||||
bootGameAct->setText(QCoreApplication::translate("MainWindow", "Boot Game", nullptr));
|
||||
#ifdef ENABLE_UPDATER
|
||||
updaterAct->setText(
|
||||
|
@ -351,8 +359,6 @@ public:
|
|||
aboutAct->setText(QCoreApplication::translate("MainWindow", "About shadPS4", nullptr));
|
||||
configureAct->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
|
||||
#if QT_CONFIG(tooltip)
|
||||
bootInstallPkgAct->setToolTip(QCoreApplication::translate(
|
||||
"MainWindow", "Install application from a .pkg file", nullptr));
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
menuRecent->setTitle(QCoreApplication::translate("MainWindow", "Recent Games", nullptr));
|
||||
shadFolderAct->setText(
|
||||
|
@ -384,7 +390,6 @@ public:
|
|||
QCoreApplication::translate("MainWindow", "Download Cheats/Patches", nullptr));
|
||||
dumpGameListAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Dump Game List", nullptr));
|
||||
pkgViewerAct->setText(QCoreApplication::translate("MainWindow", "PKG Viewer", nullptr));
|
||||
trophyViewerAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Trophy Viewer", nullptr));
|
||||
mw_searchbar->setPlaceholderText(
|
||||
|
@ -413,4 +418,4 @@ public:
|
|||
|
||||
namespace Ui {
|
||||
class MainWindow : public Ui_MainWindow {};
|
||||
} // namespace Ui
|
||||
} // namespace Ui
|
||||
|
|
|
@ -1,217 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "pkg_viewer.h"
|
||||
|
||||
PKGViewer::PKGViewer(std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent,
|
||||
std::function<void(std::filesystem::path, int, int)> InstallDragDropPkg)
|
||||
: QMainWindow(), m_game_info(game_info_get) {
|
||||
this->resize(1280, 720);
|
||||
this->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dir_list_std = Config::getPkgViewer();
|
||||
dir_list.clear();
|
||||
for (const auto& str : dir_list_std) {
|
||||
dir_list.append(QString::fromStdString(str));
|
||||
}
|
||||
statusBar = new QStatusBar(treeWidget);
|
||||
this->setStatusBar(statusBar);
|
||||
treeWidget = new QTreeWidget(this);
|
||||
treeWidget->setColumnCount(9);
|
||||
QStringList headers;
|
||||
headers << tr("Name") << tr("Serial") << tr("Installed") << tr("Size") << tr("Category")
|
||||
<< tr("Type") << tr("App Ver") << tr("FW") << tr("Region") << tr("Flags") << tr("Path");
|
||||
treeWidget->setHeaderLabels(headers);
|
||||
treeWidget->header()->setDefaultAlignment(Qt::AlignCenter);
|
||||
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
treeWidget->setColumnWidth(8, 170);
|
||||
this->setCentralWidget(treeWidget);
|
||||
QMenuBar* menuBar = new QMenuBar(this);
|
||||
menuBar->setContextMenuPolicy(Qt::PreventContextMenu);
|
||||
QMenu* fileMenu = menuBar->addMenu(tr("File"));
|
||||
QAction* openFolderAct = new QAction(tr("Open Folder"), this);
|
||||
fileMenu->addAction(openFolderAct);
|
||||
this->setMenuBar(menuBar);
|
||||
CheckPKGFolders(); // Check for new PKG files in existing folders.
|
||||
ProcessPKGInfo();
|
||||
|
||||
connect(openFolderAct, &QAction::triggered, this, &PKGViewer::OpenPKGFolder);
|
||||
|
||||
connect(treeWidget, &QTreeWidget::customContextMenuRequested, this,
|
||||
[=, this](const QPoint& pos) {
|
||||
if (treeWidget->selectedItems().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_gui_context_menus.RequestGameMenuPKGViewer(pos, m_full_pkg_list, treeWidget,
|
||||
InstallDragDropPkg);
|
||||
});
|
||||
|
||||
connect(parent, &QWidget::destroyed, this, [this]() { this->deleteLater(); });
|
||||
}
|
||||
|
||||
PKGViewer::~PKGViewer() {}
|
||||
|
||||
void PKGViewer::OpenPKGFolder() {
|
||||
QString folderPath =
|
||||
QFileDialog::getExistingDirectory(this, tr("Open Folder"), QDir::homePath());
|
||||
if (!dir_list.contains(folderPath)) {
|
||||
dir_list.append(folderPath);
|
||||
QDir directory(folderPath);
|
||||
QFileInfoList fileInfoList = directory.entryInfoList(QDir::Files);
|
||||
for (const QFileInfo& fileInfo : fileInfoList) {
|
||||
QString file_ext = fileInfo.suffix();
|
||||
if (fileInfo.isFile() && file_ext == "pkg") {
|
||||
m_pkg_list.append(fileInfo.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
std::sort(m_pkg_list.begin(), m_pkg_list.end());
|
||||
ProcessPKGInfo();
|
||||
dir_list_std.clear();
|
||||
for (auto dir : dir_list) {
|
||||
dir_list_std.push_back(dir.toStdString());
|
||||
}
|
||||
Config::setPkgViewer(dir_list_std);
|
||||
} else {
|
||||
// qDebug() << "Folder selection canceled.";
|
||||
}
|
||||
}
|
||||
|
||||
void PKGViewer::CheckPKGFolders() { // Check for new PKG file additions.
|
||||
m_pkg_list.clear();
|
||||
for (const QString& dir : dir_list) {
|
||||
QDir directory(dir);
|
||||
QFileInfoList fileInfoList = directory.entryInfoList(QDir::Files);
|
||||
for (const QFileInfo& fileInfo : fileInfoList) {
|
||||
QString file_ext = fileInfo.suffix();
|
||||
if (fileInfo.isFile() && file_ext == "pkg") {
|
||||
m_pkg_list.append(fileInfo.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(m_pkg_list.begin(), m_pkg_list.end());
|
||||
}
|
||||
|
||||
void PKGViewer::ProcessPKGInfo() {
|
||||
treeWidget->clear();
|
||||
map_strings.clear();
|
||||
map_integers.clear();
|
||||
m_pkg_app_list.clear();
|
||||
m_pkg_patch_list.clear();
|
||||
m_full_pkg_list.clear();
|
||||
for (int i = 0; i < m_pkg_list.size(); i++) {
|
||||
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(std::string{tr("Unknown").toStdString()})});
|
||||
QString title_id = QString::fromStdString(std::string{
|
||||
psf.GetString("TITLE_ID").value_or(std::string{tr("Unknown").toStdString()})});
|
||||
QString app_type = GameListUtils::GetAppType(psf.GetInteger("APP_TYPE").value_or(0));
|
||||
QString app_version = QString::fromStdString(std::string{
|
||||
psf.GetString("APP_VER").value_or(std::string{tr("Unknown").toStdString()})});
|
||||
QString title_category = QString::fromStdString(std::string{
|
||||
psf.GetString("CATEGORY").value_or(std::string{tr("Unknown").toStdString()})});
|
||||
QString pkg_size = GameListUtils::FormatSize(package.GetPkgHeader().pkg_size);
|
||||
pkg_content_flag = package.GetPkgHeader().pkg_content_flags;
|
||||
QString flagss = "";
|
||||
for (const auto& flag : package.flagNames) {
|
||||
if (package.isFlagSet(pkg_content_flag, flag.first)) {
|
||||
if (!flagss.isEmpty())
|
||||
flagss += (", ");
|
||||
flagss += QString::fromStdString(flag.second.data());
|
||||
}
|
||||
}
|
||||
|
||||
QString fw_ = tr("Unknown");
|
||||
if (const auto fw_int_opt = psf.GetInteger("SYSTEM_VER"); fw_int_opt.has_value()) {
|
||||
const u32 fw_int = *fw_int_opt;
|
||||
if (fw_int == 0) {
|
||||
fw_ = "0.00";
|
||||
} else {
|
||||
QString fw = QString::number(fw_int, 16);
|
||||
fw_ = fw.length() > 7 ? QString::number(fw_int, 16).left(3).insert(2, '.')
|
||||
: fw.left(3).insert(1, '.');
|
||||
}
|
||||
}
|
||||
char region = package.GetPkgHeader().pkg_content_id[0];
|
||||
QString pkg_info = "";
|
||||
if (title_category == "gd" && !flagss.contains("PATCH")) {
|
||||
title_category = "App";
|
||||
pkg_info = title_name + ";;" + title_id + ";;" + pkg_size + ";;" + title_category +
|
||||
";;" + app_type + ";;" + app_version + ";;" + fw_ + ";;" +
|
||||
game_list_util.GetRegion(region) + ";;" + flagss + ";;" + m_pkg_list[i];
|
||||
m_pkg_app_list.append(pkg_info);
|
||||
} else {
|
||||
title_category = "Patch";
|
||||
pkg_info = title_name + ";;" + title_id + ";;" + pkg_size + ";;" + title_category +
|
||||
";;" + app_type + ";;" + app_version + ";;" + fw_ + ";;" +
|
||||
game_list_util.GetRegion(region) + ";;" + flagss + ";;" + m_pkg_list[i];
|
||||
m_pkg_patch_list.append(pkg_info);
|
||||
}
|
||||
}
|
||||
std::sort(m_pkg_app_list.begin(), m_pkg_app_list.end());
|
||||
for (int i = 0; i < m_pkg_app_list.size(); i++) {
|
||||
QTreeWidgetItem* treeItem = new QTreeWidgetItem(treeWidget);
|
||||
QStringList pkg_app_ = m_pkg_app_list[i].split(";;");
|
||||
m_full_pkg_list.append(m_pkg_app_list[i]);
|
||||
treeItem->setExpanded(true);
|
||||
treeItem->setText(0, pkg_app_[0]);
|
||||
treeItem->setText(1, pkg_app_[1]);
|
||||
treeItem->setText(3, pkg_app_[2]);
|
||||
treeItem->setTextAlignment(3, Qt::AlignCenter);
|
||||
treeItem->setText(4, pkg_app_[3]);
|
||||
treeItem->setTextAlignment(4, Qt::AlignCenter);
|
||||
treeItem->setText(5, pkg_app_[4]);
|
||||
treeItem->setTextAlignment(5, Qt::AlignCenter);
|
||||
treeItem->setText(6, pkg_app_[5]);
|
||||
treeItem->setTextAlignment(6, Qt::AlignCenter);
|
||||
treeItem->setText(7, pkg_app_[6]);
|
||||
treeItem->setTextAlignment(7, Qt::AlignCenter);
|
||||
treeItem->setText(8, pkg_app_[7]);
|
||||
treeItem->setTextAlignment(8, Qt::AlignCenter);
|
||||
treeItem->setText(9, pkg_app_[8]);
|
||||
treeItem->setText(10, pkg_app_[9]);
|
||||
for (const GameInfo& info : m_game_info->m_games) { // Check if game is installed.
|
||||
if (info.serial == pkg_app_[1].toStdString()) {
|
||||
treeItem->setText(2, QChar(0x2713));
|
||||
treeItem->setTextAlignment(2, Qt::AlignCenter);
|
||||
}
|
||||
}
|
||||
for (const QString& item : m_pkg_patch_list) {
|
||||
QStringList pkg_patch_ = item.split(";;");
|
||||
if (pkg_patch_[1] == pkg_app_[1]) { // check patches with serial.
|
||||
m_full_pkg_list.append(item);
|
||||
QTreeWidgetItem* childItem = new QTreeWidgetItem(treeItem);
|
||||
childItem->setText(0, pkg_patch_[0]);
|
||||
childItem->setText(1, pkg_patch_[1]);
|
||||
childItem->setText(3, pkg_patch_[2]);
|
||||
childItem->setTextAlignment(3, Qt::AlignCenter);
|
||||
childItem->setText(4, pkg_patch_[3]);
|
||||
childItem->setTextAlignment(4, Qt::AlignCenter);
|
||||
childItem->setText(5, pkg_patch_[4]);
|
||||
childItem->setTextAlignment(5, Qt::AlignCenter);
|
||||
childItem->setText(6, pkg_patch_[5]);
|
||||
childItem->setTextAlignment(6, Qt::AlignCenter);
|
||||
childItem->setText(7, pkg_patch_[6]);
|
||||
childItem->setTextAlignment(7, Qt::AlignCenter);
|
||||
childItem->setText(8, pkg_patch_[7]);
|
||||
childItem->setTextAlignment(8, Qt::AlignCenter);
|
||||
childItem->setText(9, pkg_patch_[8]);
|
||||
childItem->setText(10, pkg_patch_[9]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int column = 0; column < treeWidget->columnCount() - 2; ++column) {
|
||||
// Resize the column to fit its contents
|
||||
treeWidget->resizeColumnToContents(column);
|
||||
}
|
||||
// Update status bar.
|
||||
statusBar->clearMessage();
|
||||
int numPkgs = m_pkg_list.size();
|
||||
QString statusMessage = QString::number(numPkgs) + " " + tr("Package");
|
||||
statusBar->showMessage(statusMessage);
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMenuBar>
|
||||
#include <QStatusBar>
|
||||
|
||||
#include "common/io_file.h"
|
||||
#include "core/file_format/pkg.h"
|
||||
#include "core/file_format/pkg_type.h"
|
||||
#include "core/file_format/psf.h"
|
||||
#include "game_info.h"
|
||||
#include "game_list_utils.h"
|
||||
#include "gui_context_menus.h"
|
||||
|
||||
class PKGViewer : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PKGViewer(
|
||||
std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent,
|
||||
std::function<void(std::filesystem::path, int, int)> InstallDragDropPkg = nullptr);
|
||||
~PKGViewer();
|
||||
void OpenPKGFolder();
|
||||
void CheckPKGFolders();
|
||||
void ProcessPKGInfo();
|
||||
|
||||
private:
|
||||
GuiContextMenus m_gui_context_menus;
|
||||
PKG package;
|
||||
PSF psf;
|
||||
PKGHeader pkgheader;
|
||||
PKGEntry entry;
|
||||
PSFHeader header;
|
||||
char pkgTitleID[9];
|
||||
std::vector<u8> pkg;
|
||||
u64 pkgSize = 0;
|
||||
std::unordered_map<std::string, std::string> map_strings;
|
||||
std::unordered_map<std::string, u32> map_integers;
|
||||
|
||||
u32_be pkg_content_flag;
|
||||
std::shared_ptr<GameInfoClass> m_game_info;
|
||||
GameListUtils game_list_util;
|
||||
// Status bar
|
||||
QStatusBar* statusBar;
|
||||
|
||||
std::vector<std::pair<int, QString>> appTypes = {
|
||||
{0, "FULL APP"},
|
||||
{1, "UPGRADABLE"},
|
||||
{2, "DEMO"},
|
||||
{3, "FREEMIUM"},
|
||||
};
|
||||
|
||||
QStringList m_full_pkg_list;
|
||||
QStringList m_pkg_app_list;
|
||||
QStringList m_pkg_patch_list;
|
||||
QStringList m_pkg_list;
|
||||
QStringList dir_list;
|
||||
std::vector<std::string> dir_list_std;
|
||||
QTreeWidget* treeWidget = nullptr;
|
||||
};
|
|
@ -817,7 +817,7 @@ void SettingsDialog::ResetInstallFolders() {
|
|||
if (data.contains("GUI")) {
|
||||
const toml::value& gui = data.at("GUI");
|
||||
const auto install_dir_array =
|
||||
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||
toml::find_or<std::vector<std::u8string>>(gui, "installDirs", {});
|
||||
|
||||
std::vector<bool> install_dirs_enabled;
|
||||
try {
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation type="unfinished">Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation type="unfinished">Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation type="unfinished">Game</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation type="unfinished">shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation type="unfinished">Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation type="unfinished">Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation type="unfinished">Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation type="unfinished">Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation type="unfinished">Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation type="unfinished">Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation type="unfinished">Recent Games</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation type="unfinished">Dump Game List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation type="unfinished">PKG Viewer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Kun én fil kan vælges!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG-udtrækning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Opdatering detekteret!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG og spilversioner matcher: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Vil du overskrive?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG Version %1 er ældre end den installerede version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Spillet er installeret: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Vil du installere opdateringen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation type="unfinished">DLC Installation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Vil du installere DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC allerede installeret:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Spillet er allerede installeret</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG FEJL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Udvinding af PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Udvinding afsluttet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Spillet blev installeret succesfuldt på %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Filen ser ikke ud til at være en gyldig PKG-fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation type="unfinished">Open Folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG FEJL</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Navn</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Seriel</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Størrelse</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation type="unfinished">Region</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Sti</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Ukendt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Fehler beim Erstellen der Verknüpfung!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>PKG installieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Spiel</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation>Tastenbelegung</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Wähle Ordner</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Wählen Sie das Verzeichnis aus, in das Sie installieren möchten.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Installieren Sie alles aus der Warteschlange in den ausgewählten Ordner</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>PKG-Datei beim Installieren löschen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Elf-Ordner öffnen/hinzufügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Pakete installieren (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Spiel starten</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Konfigurieren...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Installiere Anwendung aus .pkg-Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Zuletzt gespielt</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Spielliste ausgeben</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKG-Anschauer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Es kann nur eine Datei ausgewählt werden!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG-Extraktion</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch erkannt!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- und Spielversionen stimmen überein: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Willst du überschreiben?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-Version %1 ist älter als die installierte Version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Spiel ist installiert: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Willst du den Patch installieren: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC-Installation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Willst du das DLC installieren: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC bereits installiert:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Spiel bereits installiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG-FEHLER</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Extrahiere PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extraktion abgeschlossen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Spiel erfolgreich installiert auf %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Die Datei scheint keine gültige PKG-Datei zu sein</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Spiel ausführen</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Eboot.bin Datei nicht gefunden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>PKG-Datei (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>PKG ist ein Patch oder DLC, bitte installieren Sie zuerst das Spiel!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>Spiel läuft bereits!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Ordner öffnen</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG-FEHLER</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Name</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Seriennummer</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Installiert</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Größe</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Kategorie</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Typ</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Region</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Markierungen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Pfad</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Unbekannt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Paket</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Trophäenansicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation type="unfinished">Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation type="unfinished">Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation type="unfinished">Game</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation type="unfinished">shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation type="unfinished">Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation type="unfinished">Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation type="unfinished">Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation type="unfinished">Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation type="unfinished">Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation type="unfinished">Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation type="unfinished">Recent Games</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation type="unfinished">Dump Game List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation type="unfinished">PKG Viewer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Μπορεί να επιλεγεί μόνο ένα αρχείο!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Εξαγωγή PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Αναγνώριση ενημέρωσης!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Οι εκδόσεις PKG και παιχνιδιού ταιριάζουν: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Θέλετε να αντικαταστήσετε;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Η έκδοση PKG %1 είναι παλαιότερη από την εγκατεστημένη έκδοση: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Το παιχνίδι είναι εγκατεστημένο: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Θέλετε να εγκαταστήσετε την ενημέρωση: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Εγκατάσταση DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Θέλετε να εγκαταστήσετε το DLC: %1;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC ήδη εγκατεστημένο:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Παιχνίδι ήδη εγκατεστημένο</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ΣΦΑΛΜΑ PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Εξαγωγή PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Η εξαγωγή ολοκληρώθηκε</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Το παιχνίδι εγκαταστάθηκε επιτυχώς στο %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Η αρχείο δεν φαίνεται να είναι έγκυρο αρχείο PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation type="unfinished">Open Folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ΣΦΑΛΜΑ PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Όνομα</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Σειριακός αριθμός</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Μέγεθος</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Περιοχή</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Διαδρομή</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Άγνωστο</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Recent Games</translation>
|
||||
|
@ -1314,10 +1283,6 @@
|
|||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKG Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
<translation>Search...</translation>
|
||||
|
@ -1426,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Only one file can be selected!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG Extraction</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch detected!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG and Game versions match: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Would you like to overwrite?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG Version %1 is older than installed version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game is installed: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Would you like to install Patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC already installed:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game already installed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG ERROR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Extracting PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extraction Finished</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Game successfully installed at %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>File doesn't appear to be a valid PKG file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -1498,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -1514,71 +1407,44 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Open Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation type="unfinished">PKG ERROR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished">Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation type="unfinished">Serial</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation type="unfinished">Size</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation type="unfinished">Region</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation type="unfinished">Path</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation type="unfinished">Unknown</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>¡Error al crear el acceso directo!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Instalar PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Juego</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation>Asignación de Teclas</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Elegir carpeta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Selecciona el directorio de instalación.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Instalar toda la cola en la carpeta seleccionada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Eliminar archivo PKG tras la instalación</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Abrir/Agregar carpeta Elf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Instalar paquetes (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Iniciar juego</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Configurar...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Instalar aplicación desde un archivo .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Juegos recientes</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Volcar Lista de Juegos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>Vista PKG</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Expositor de Trofeos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>No se encontraron juegos. Por favor, añade tus juegos a tu biblioteca primero.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>¡Solo se puede seleccionar un archivo!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Extracción de PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>¡Actualización detectada!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Las versiones de PKG y del juego coinciden: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>¿Desea sobrescribir?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>La versión de PKG %1 es más antigua que la versión instalada: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>El juego está instalado: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>¿Desea instalar la actualización: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Instalación de DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>¿Desea instalar el DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC ya instalado:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Juego ya instalado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERROR PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Extrayendo PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extracción terminada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Juego instalado exitosamente en %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>El archivo parece no ser un archivo PKG válido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Ejecutar juego</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Archivo Eboot.bin no encontrado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>Archivo PKG (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>El archivo PKG es un parche o DLC, ¡debes instalar el juego primero!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>¡El juego ya se está ejecutando!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Abrir Carpeta</translation>
|
||||
<source>Play</source>
|
||||
<translation>Jugar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERROR PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation>Pausar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nombre</translation>
|
||||
<source>Stop</source>
|
||||
<translation>Detener</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Número de Serie</translation>
|
||||
<source>Restart</source>
|
||||
<translation>Reiniciar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Instalado</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation>Pantalla completa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Tamaño</translation>
|
||||
<source>Controllers</source>
|
||||
<translation>Controles</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Categoría</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation>Teclado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Tipo</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation>Actualizar lista</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>Versión de la Aplicación</translation>
|
||||
<source>Resume</source>
|
||||
<translation>Reanudar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Región</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Etiquetas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Ruta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Archivo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Desconocido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Paquete</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation>Mostrar etiquetas debajo de los iconos</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Expositor de Trofeos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Selecciona un Juego:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Progreso</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>مشکلی در هنگام ساخت میانبر بوجود آمد!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>نصب PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>بازی</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>ShadPS4 - انتخاب محل نصب بازی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>محلی را که میخواهید در آن نصب شود، انتخاب کنید.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>ELF بازکردن/ساختن پوشه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>نصب بسته (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>اجرای بازی</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>...تنظیمات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>.PKG نصب بازی از فایل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>بازی های اخیر</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>استخراج لیست بازی ها</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKG مشاهده گر</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>فقط یک فایل انتخاب کنید!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG استخراج فایل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>پچ شناسایی شد!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>و نسخه بازی همخوانی دارد PKG فایل:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>آیا مایل به جایگزینی فایل هستید؟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>نسخه فایل PKG %1 قدیمی تر از نسخه نصب شده است:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>بازی نصب شد:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>آیا مایل به نصب پچ هستید:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>نصب DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>آیا مایل به نصب DLC هستید: %1 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>قبلا نصب شده DLC این:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>این بازی قبلا نصب شده</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG ارور فایل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>درحال استخراج PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>استخراج به پایان رسید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>بازی با موفقیت در %1 نصب شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation> این فایل یک PKG درست به نظر نمی آید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>ShadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>بازکردن پوشه</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG ارور فایل</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>نام</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>سریال</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>اندازه</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>منطقه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>مسیر</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>فایل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>ناشناخته</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>مشاهده جوایز</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -407,206 +407,206 @@
|
|||
<name>ControlSettings</name>
|
||||
<message>
|
||||
<source>Configure Controls</source>
|
||||
<translation type="unfinished">Configure Controls</translation>
|
||||
<translation>Määritä Kontrollit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>D-Pad</source>
|
||||
<translation type="unfinished">D-Pad</translation>
|
||||
<translation>D-Pad</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Up</source>
|
||||
<translation type="unfinished">Up</translation>
|
||||
<translation>Ylös</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left</source>
|
||||
<translation type="unfinished">Left</translation>
|
||||
<translation>Vasen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right</source>
|
||||
<translation type="unfinished">Right</translation>
|
||||
<translation>Oikea</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Down</source>
|
||||
<translation type="unfinished">Down</translation>
|
||||
<translation>Alas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Stick Deadzone (def:2 max:127)</source>
|
||||
<translation type="unfinished">Left Stick Deadzone (def:2 max:127)</translation>
|
||||
<translation>Vasemman Analogin Deadzone (oletus:2 max:127)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Deadzone</source>
|
||||
<translation type="unfinished">Left Deadzone</translation>
|
||||
<translation>Vasen Deadzone</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Stick</source>
|
||||
<translation type="unfinished">Left Stick</translation>
|
||||
<translation>Vasen Analogi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Config Selection</source>
|
||||
<translation type="unfinished">Config Selection</translation>
|
||||
<translation>Asetusten Valinta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common Config</source>
|
||||
<translation type="unfinished">Common Config</translation>
|
||||
<translation>Yleinen Asetus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use per-game configs</source>
|
||||
<translation type="unfinished">Use per-game configs</translation>
|
||||
<translation>Käytä pelikohtaisia asetuksia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>L1 / LB</source>
|
||||
<translation type="unfinished">L1 / LB</translation>
|
||||
<translation>L1 / LB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>L2 / LT</source>
|
||||
<translation type="unfinished">L2 / LT</translation>
|
||||
<translation>L2 / LT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
<translation type="unfinished">Back</translation>
|
||||
<translation>Back</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R1 / RB</source>
|
||||
<translation type="unfinished">R1 / RB</translation>
|
||||
<translation>R1 / RB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R2 / RT</source>
|
||||
<translation type="unfinished">R2 / RT</translation>
|
||||
<translation>R2 / RT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>L3</source>
|
||||
<translation type="unfinished">L3</translation>
|
||||
<translation>L3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options / Start</source>
|
||||
<translation type="unfinished">Options / Start</translation>
|
||||
<translation>Options / Start</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R3</source>
|
||||
<translation type="unfinished">R3</translation>
|
||||
<translation>R3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face Buttons</source>
|
||||
<translation type="unfinished">Face Buttons</translation>
|
||||
<translation>Etunäppäimet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Triangle / Y</source>
|
||||
<translation type="unfinished">Triangle / Y</translation>
|
||||
<translation>Kolmio / Y</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Square / X</source>
|
||||
<translation type="unfinished">Square / X</translation>
|
||||
<translation>Neliö / X</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Circle / B</source>
|
||||
<translation type="unfinished">Circle / B</translation>
|
||||
<translation>Ympyrä / B</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cross / A</source>
|
||||
<translation type="unfinished">Cross / A</translation>
|
||||
<translation>Rasti / A</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right Stick Deadzone (def:2, max:127)</source>
|
||||
<translation type="unfinished">Right Stick Deadzone (def:2, max:127)</translation>
|
||||
<translation>Oikean Analogin Deadzone (oletus:2 max:127)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right Deadzone</source>
|
||||
<translation type="unfinished">Right Deadzone</translation>
|
||||
<translation>Oikea Deadzone</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right Stick</source>
|
||||
<translation type="unfinished">Right Stick</translation>
|
||||
<translation>Oikea Analogi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Color Adjustment</source>
|
||||
<translation type="unfinished">Color Adjustment</translation>
|
||||
<translation>Värinhallinta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R:</source>
|
||||
<translation type="unfinished">R:</translation>
|
||||
<translation>R:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>G:</source>
|
||||
<translation type="unfinished">G:</translation>
|
||||
<translation>G:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>B:</source>
|
||||
<translation type="unfinished">B:</translation>
|
||||
<translation>B:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Override Lightbar Color</source>
|
||||
<translation type="unfinished">Override Lightbar Color</translation>
|
||||
<translation>Pakota Ohjaimen Valopalkin Väri</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Override Color</source>
|
||||
<translation type="unfinished">Override Color</translation>
|
||||
<translation>Pakotettava Väri</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to Save</source>
|
||||
<translation type="unfinished">Unable to Save</translation>
|
||||
<translation>Tallentaminen Epäonnistui</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot bind axis values more than once</source>
|
||||
<translation type="unfinished">Cannot bind axis values more than once</translation>
|
||||
<translation>Akseliarvoja ei voi määrittää kertaa useammin</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished">Save</translation>
|
||||
<translation>Tallenna</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Apply</source>
|
||||
<translation type="unfinished">Apply</translation>
|
||||
<translation>Ota Käyttöön</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore Defaults</source>
|
||||
<translation type="unfinished">Restore Defaults</translation>
|
||||
<translation>Palauta Oletukset</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">Cancel</translation>
|
||||
<translation>Peruuta</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditorDialog</name>
|
||||
<message>
|
||||
<source>Edit Keyboard + Mouse and Controller input bindings</source>
|
||||
<translation type="unfinished">Edit Keyboard + Mouse and Controller input bindings</translation>
|
||||
<translation>Muokkaa Näppäimistön + Hiiren ja Ohjaimen näppäinasetuksia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Per-Game configs</source>
|
||||
<translation type="unfinished">Use Per-Game configs</translation>
|
||||
<translation>Käytä Pelikohtaisia Asetuksia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished">Error</translation>
|
||||
<translation>Virhe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for reading</source>
|
||||
<translation type="unfinished">Could not open the file for reading</translation>
|
||||
<translation>Tiedostoa ei voitu avata luettavaksi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for writing</source>
|
||||
<translation type="unfinished">Could not open the file for writing</translation>
|
||||
<translation>Tiedostoa ei voitu avata kirjoitettavaksi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Changes</source>
|
||||
<translation type="unfinished">Save Changes</translation>
|
||||
<translation>Tallenna Muutokset</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to save changes?</source>
|
||||
<translation type="unfinished">Do you want to save changes?</translation>
|
||||
<translation>Haluatko tallentaa muutokset?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Help</source>
|
||||
<translation type="unfinished">Help</translation>
|
||||
<translation>Tietoa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset your custom default config to the original default config?</source>
|
||||
<translation type="unfinished">Do you want to reset your custom default config to the original default config?</translation>
|
||||
<translation>Haluatko nollata oletusasetuksiin tekemäsi muutokset?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset this config to your custom default config?</source>
|
||||
<translation type="unfinished">Do you want to reset this config to your custom default config?</translation>
|
||||
<translation>Haluato palauttaa nämä asetukset takaisin määrittämiisi oletuksiin?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reset to Default</source>
|
||||
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Virhe pikakuvakkeen luonnissa!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Asenna PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Peli</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Valitse hakemisto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Valitse, mihin hakemistoon haluat asentaa.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1077,35 +1054,35 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>L3</source>
|
||||
<translation type="unfinished">L3</translation>
|
||||
<translation>L3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Touchpad Click</source>
|
||||
<translation type="unfinished">Touchpad Click</translation>
|
||||
<translation>Kosketuslevyn Klikkaus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mouse to Joystick</source>
|
||||
<translation type="unfinished">Mouse to Joystick</translation>
|
||||
<translation>Hiiri Joystickinä</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>*press F7 ingame to activate</source>
|
||||
<translation type="unfinished">*press F7 ingame to activate</translation>
|
||||
<translation>*paina F7 pelissä aktivoidaksesi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R3</source>
|
||||
<translation type="unfinished">R3</translation>
|
||||
<translation>R3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options</source>
|
||||
<translation type="unfinished">Options</translation>
|
||||
<translation>Options</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mouse Movement Parameters</source>
|
||||
<translation type="unfinished">Mouse Movement Parameters</translation>
|
||||
<translation>Hiiren Liikkeen Parametrit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>note: click Help Button/Special Keybindings for more information</source>
|
||||
<translation type="unfinished">note: click Help Button/Special Keybindings for more information</translation>
|
||||
<translation>huomio: klikkaa apunappia/näppäintä saadaksesi lisää tietoa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face Buttons</source>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Avaa/Lisää Elf Hakemisto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Asenna Paketteja (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Käynnistä Peli</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Asetukset...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Asenna sovellus .pkg tiedostosta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Viimeisimmät Pelit</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Kirjoita Pelilista Tiedostoon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKG Selain</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Vain yksi tiedosto voi olla valittuna!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG:n purku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Päivitys havaittu!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- ja peliversiot vastaavat: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Haluatko korvata?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-versio %1 on vanhempi kuin asennettu versio: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Peli on asennettu: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Haluatko asentaa päivityksen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Lisäsisällön asennus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Haluatko asentaa lisäsisällön: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>Lisäsisältö on jo asennettu:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Peli on jo asennettu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG VIRHE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Purkaminen PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Purku valmis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Peli asennettu onnistuneesti kohtaan %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Tiedosto ei vaikuta olevan kelvollinen PKG-tiedosto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Avaa Hakemisto</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG VIRHE</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nimi</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Sarjanumero</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Koko</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Alue</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Polku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Tiedosto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Tuntematon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Trophy Selain</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Erreur lors de la création du raccourci !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Installer un PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Jeu</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation>Raccourcis</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Choisir un répertoire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Sélectionnez le répertoire où vous souhaitez effectuer l'installation.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Installer toute la file d’attente dans le dossier sélectionné</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Supprimer le fichier PKG à l'installation</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Ouvrir/Ajouter un dossier ELF</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Installer des packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Démarrer un jeu</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Configurer...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Installer une application depuis un fichier .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Jeux récents</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Dumper la liste des jeux</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>Visionneuse PKG</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Visionneuse de trophées</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>Aucun jeu trouvé. Veuillez d'abord ajouter vos jeux à votre bibliothèque.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Un seul fichier peut être sélectionné !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Extraction du PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch détecté !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Les versions PKG et jeu correspondent: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Souhaitez-vous remplacer ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>La version PKG %1 est plus ancienne que la version installée: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Jeu installé: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Souhaitez-vous installer le patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Installation du DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Souhaitez-vous installer le DLC: %1 ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC déjà installé:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Jeu déjà installé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>Erreur PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Extraction PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extraction terminée</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Jeu installé avec succès dans %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Le fichier ne semble pas être un PKG valide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Lancer le jeu</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Fichier Eboot.bin introuvable</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>Fichier PKG (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>PKG est un patch ou DLC, veuillez d'abord installer le jeu !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>Le jeu est déjà en cours !</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Ouvrir un dossier</translation>
|
||||
<source>Play</source>
|
||||
<translation>Jouer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>Erreur PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation>Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nom</translation>
|
||||
<source>Stop</source>
|
||||
<translation>Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Numéro de série</translation>
|
||||
<source>Restart</source>
|
||||
<translation>Redémarrer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Installé</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation>Plein écran</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Taille</translation>
|
||||
<source>Controllers</source>
|
||||
<translation>Contrôleurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Catégorie</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation>Clavier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation>Rafraîchir la liste</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation>Reprendre</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Région</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Les indicateurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Répertoire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Fichier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Inconnu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation>Afficher les libellés sous les icônes</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Visionneuse de trophées</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Sélectionnez un jeu:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Progression</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Hiba a parancsikon létrehozásával!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>PKG telepítése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Játék</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Mappa kiválasztása</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Válassza ki a mappát a játékok telepítésére.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>ELF Mappa Megnyitása/Hozzáadása</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>PKG-k Telepítése (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Játék Indítása</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Konfigurálás...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Program telepítése egy .pkg fájlból</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Legutóbbi Játékok</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Játéklista Dumpolása</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKG Nézegető</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Csak egy fájl választható ki!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG kicsomagolás</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Frissítés észlelve!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>A PKG és a játék verziói egyeznek: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Szeretné felülírni?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>A(z) %1-es PKG verzió régebbi, mint a telepített verzió: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>A játék telepítve van: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Szeretné telepíteni a frissítést: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Telepítés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Szeretné telepíteni a %1 DLC-t?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC már telepítve:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>A játék már telepítve van</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG HIBA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>PKG kicsomagolása %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Kicsomagolás befejezve</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>A játék sikeresen telepítve itt: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>A fájl nem tűnik érvényes PKG fájlnak</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Mappa Megnyitása</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG HIBA</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Név</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Sorozatszám</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Méret</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Régió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Útvonal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Fájl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Ismeretlen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Trófeák Megtekintése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -7,22 +7,22 @@
|
|||
<name>AboutDialog</name>
|
||||
<message>
|
||||
<source>About shadPS4</source>
|
||||
<translation type="unfinished">About shadPS4</translation>
|
||||
<translation>Tentang shadPS4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source>
|
||||
<translation type="unfinished">shadPS4 is an experimental open-source emulator for the PlayStation 4.</translation>
|
||||
<translation>shadPS4 adalah emulator sumber terbuka eksperimental untuk PlayStation 4.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This software should not be used to play games you have not legally obtained.</source>
|
||||
<translation type="unfinished">This software should not be used to play games you have not legally obtained.</translation>
|
||||
<translation>Perangkat lunak ini tidak boleh digunakan untuk memainkan permainan yang tidak Anda peroleh secara legal.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CheatsPatches</name>
|
||||
<message>
|
||||
<source>Cheats / Patches for </source>
|
||||
<translation type="unfinished">Cheats / Patches for </translation>
|
||||
<translation>Kecurangan / Tambalan untuk </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cheats/Patches are experimental.\nUse with caution.\n\nDownload cheats individually by selecting the repository and clicking the download button.\nIn the Patches tab, you can download all patches at once, choose which ones you want to use, and save your selection.\n\nSince we do not develop the Cheats/Patches,\nplease report issues to the cheat author.\n\nCreated a new cheat? Visit:\n</source>
|
||||
|
@ -34,7 +34,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Serial: </source>
|
||||
<translation type="unfinished">Serial: </translation>
|
||||
<translation>Seri: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Version: </source>
|
||||
|
@ -400,38 +400,38 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Playable</source>
|
||||
<translation type="unfinished">Playable</translation>
|
||||
<translation>Dapat dimainkan</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ControlSettings</name>
|
||||
<message>
|
||||
<source>Configure Controls</source>
|
||||
<translation type="unfinished">Configure Controls</translation>
|
||||
<translation>Konfigurasi Kontrol</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>D-Pad</source>
|
||||
<translation type="unfinished">D-Pad</translation>
|
||||
<translation>Tombol arah</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Up</source>
|
||||
<translation type="unfinished">Up</translation>
|
||||
<translation>Atas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left</source>
|
||||
<translation type="unfinished">Left</translation>
|
||||
<translation>Kiri</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right</source>
|
||||
<translation type="unfinished">Right</translation>
|
||||
<translation>Kanan</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Down</source>
|
||||
<translation type="unfinished">Down</translation>
|
||||
<translation>Bawah</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Stick Deadzone (def:2 max:127)</source>
|
||||
<translation type="unfinished">Left Stick Deadzone (def:2 max:127)</translation>
|
||||
<translation>Zona Mati Stik Kiri (standar: 2, maksimum: 127)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Deadzone</source>
|
||||
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation type="unfinished">Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation type="unfinished">Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation type="unfinished">Game</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation type="unfinished">shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation type="unfinished">Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation type="unfinished">Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation type="unfinished">Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation type="unfinished">Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation type="unfinished">Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation type="unfinished">Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation type="unfinished">Recent Games</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation type="unfinished">Dump Game List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation type="unfinished">PKG Viewer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Hanya satu file yang bisa dipilih!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Ekstraksi PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch terdeteksi!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Versi PKG dan Game cocok: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Apakah Anda ingin menimpa?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Versi PKG %1 lebih lama dari versi yang terpasang: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game telah terpasang: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Apakah Anda ingin menginstal patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Instalasi DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Apakah Anda ingin menginstal DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC sudah terpasang:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game sudah terpasang</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>KESALAHAN PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Mengekstrak PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Ekstraksi Selesai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Game berhasil dipasang di %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>File tampaknya bukan file PKG yang valid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation type="unfinished">Open Folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>KESALAHAN PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nama</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation type="unfinished">Serial</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Ukuran</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Wilayah</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Jalur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Tidak Dikenal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Errore nella creazione della scorciatoia!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Installa PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Gioco</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation>Associazioni dei pulsanti</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Scegli cartella</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Seleziona in quale cartella vuoi effettuare l'installazione.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Installa tutto in coda nella Cartella Selezionata</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Elimina file PKG dopo Installazione</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Apri/Aggiungi cartella Elf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Installa Pacchetti (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Avvia Gioco</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Configura...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Installa applicazione da un file .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Giochi Recenti</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Scarica Lista Giochi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>Visualizzatore PKG</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Visualizzatore Trofei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>Nessun gioco trovato. Aggiungi prima i tuoi giochi alla tua libreria.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Si può selezionare solo un file!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Estrazione file PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch rilevata!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Le versioni di PKG e del Gioco corrispondono: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Vuoi sovrascrivere?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>La versione PKG %1 è più vecchia rispetto alla versione installata: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Gioco installato: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Vuoi installare la patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Installazione DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Vuoi installare il DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC già installato:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Gioco già installato</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRORE PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Estrazione file PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Estrazione Completata</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Gioco installato correttamente in %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Il file sembra non essere un file PKG valido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Esegui Gioco</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>File Eboot.bin non trovato</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>File PKG (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>Il file PKG è una patch o DLC, si prega di installare prima il gioco!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>Il gioco è già in esecuzione!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Apri Cartella</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRORE PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nome</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Seriale</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Installato</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Dimensione</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Categoria</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Tipo</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>Vers. App.</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Regione</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Segnalazioni</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Percorso</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Sconosciuto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Pacchetto</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Visualizzatore Trofei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Seleziona Gioco:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Progresso</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>ショートカットの作成に失敗しました!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>PKGをインストール</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>ゲーム</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - ディレクトリを選択</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>インストール先のディレクトリを選択してください。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>インストール時にPKGファイルを削除</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Elfフォルダを開く/追加する</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>パッケージをインストール (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>ゲームを起動</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>設定...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>.pkgファイルからアプリケーションをインストール</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>最近プレイしたゲーム</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>ゲームリストをダンプ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKGビューアー</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>1つのファイルしか選択できません!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKGの抽出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>パッチが検出されました!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKGとゲームのバージョンが一致しています: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>上書きしてもよろしいですか?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKGバージョン %1 はインストールされているバージョンよりも古いです: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>ゲームはインストール済みです: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>パッチをインストールしてもよろしいですか: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLCのインストール</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>DLCをインストールしてもよろしいですか: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLCはすでにインストールされています:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>ゲームはすでにインストールされています</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKGエラー</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>PKGを抽出中 %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>抽出完了</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>ゲームが %1 に正常にインストールされました</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>ファイルが有効なPKGファイルでないようです</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>ゲームを実行</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Eboot.bin ファイルが見つかりません</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>PKGファイル (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>ゲームは既に実行されています!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>フォルダーを開く</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKGエラー</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>名前</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>シリアル</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>サイズ</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>地域</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>パス</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>ファイル</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>不明</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>パッケージ</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>トロフィービューアー</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation type="unfinished">Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation type="unfinished">Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation type="unfinished">Game</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation type="unfinished">shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation type="unfinished">Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation type="unfinished">Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation type="unfinished">Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation type="unfinished">Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation type="unfinished">Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation type="unfinished">Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation type="unfinished">Recent Games</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation type="unfinished">Dump Game List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation type="unfinished">PKG Viewer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation type="unfinished">Only one file can be selected!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation type="unfinished">PKG Extraction</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation type="unfinished">Patch detected!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation type="unfinished">PKG and Game versions match: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation type="unfinished">Would you like to overwrite?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation type="unfinished">PKG Version %1 is older than installed version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation type="unfinished">Game is installed: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation type="unfinished">Would you like to install Patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation type="unfinished">DLC Installation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation type="unfinished">Would you like to install DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation type="unfinished">DLC already installed:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation type="unfinished">Game already installed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation type="unfinished">PKG ERROR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation type="unfinished">Extracting PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation type="unfinished">Extraction Finished</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation type="unfinished">Game successfully installed at %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation type="unfinished">File doesn't appear to be a valid PKG file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation type="unfinished">Open Folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation type="unfinished">PKG ERROR</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished">Name</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation type="unfinished">Serial</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation type="unfinished">Size</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation type="unfinished">Region</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation type="unfinished">Path</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>알 수 없음</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<name>AboutDialog</name>
|
||||
<message>
|
||||
<source>About shadPS4</source>
|
||||
<translation type="unfinished">About shadPS4</translation>
|
||||
<translation>Apie shadPS4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>This software should not be used to play games you have not legally obtained.</source>
|
||||
<translation type="unfinished">This software should not be used to play games you have not legally obtained.</translation>
|
||||
<translation>Ši programa neturėtų būti naudojama žaidimams kurių neturite legaliai įsigiję.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -463,7 +463,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
<translation type="unfinished">Back</translation>
|
||||
<translation>Atgal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R1 / RB</source>
|
||||
|
@ -519,7 +519,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Color Adjustment</source>
|
||||
<translation type="unfinished">Color Adjustment</translation>
|
||||
<translation>Spalvų Reguliavimas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R:</source>
|
||||
|
@ -543,7 +543,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Unable to Save</source>
|
||||
<translation type="unfinished">Unable to Save</translation>
|
||||
<translation>Nepavyko Išsaugoti</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot bind axis values more than once</source>
|
||||
|
@ -563,7 +563,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">Cancel</translation>
|
||||
<translation>Atšaukti</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -590,15 +590,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Save Changes</source>
|
||||
<translation type="unfinished">Save Changes</translation>
|
||||
<translation>Išsaugoti Pakeitimus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to save changes?</source>
|
||||
<translation type="unfinished">Do you want to save changes?</translation>
|
||||
<translation>Ar norite išsaugoti pakeitimus?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Help</source>
|
||||
<translation type="unfinished">Help</translation>
|
||||
<translation>Pagalba</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset your custom default config to the original default config?</source>
|
||||
|
@ -876,19 +876,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished">Error</translation>
|
||||
<translation>Klaida</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error creating shortcut!</source>
|
||||
<translation type="unfinished">Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation type="unfinished">Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation type="unfinished">Game</translation>
|
||||
<translation>Žaidimas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This game has no update to delete!</source>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation type="unfinished">shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation type="unfinished">Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation type="unfinished">Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation type="unfinished">Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation type="unfinished">Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation type="unfinished">Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation type="unfinished">Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation type="unfinished">Recent Games</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation type="unfinished">Dump Game List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation type="unfinished">PKG Viewer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Galite pasirinkti tik vieną failą!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG ištraukimas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Rasta atnaujinimą!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG ir žaidimo versijos sutampa: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Ar norite perrašyti?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG versija %1 yra senesnė nei įdiegta versija: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Žaidimas įdiegtas: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Ar norite įdiegti atnaujinimą: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC diegimas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Ar norite įdiegti DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC jau įdiegtas:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Žaidimas jau įdiegtas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG KLAIDA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Ekstrakcinis PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Ekstrakcija baigta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Žaidimas sėkmingai įdiegtas %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Failas atrodo, kad nėra galiojantis PKG failas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation type="unfinished">Open Folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG KLAIDA</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Vardas</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Serijinis numeris</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Dydis</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Regionas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Kelias</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Nežinoma</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Feil ved opprettelse av snarvei!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Installer PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Spill</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation>Hurtigtast</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Velg mappe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Velg hvilken mappe du vil installere til.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Installer alle i kø til den valgte mappa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Slett PKG-fila ved installering</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Åpne eller legg til Elf-mappe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Installer pakker (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Start spill</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Sett opp …</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Installer fra en .pkg fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Nylige spill</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Dump spilliste</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>PKG-viser</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Troféviser</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>Fant ingen spill. Legg til spillene dine i biblioteket først.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Kun én fil kan velges!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG-utpakking</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Programrettelse oppdaget!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG og spillversjoner stemmer overens: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Ønsker du å overskrive?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-versjon %1 er eldre enn installert versjon: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Spillet er installert: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Ønsker du å installere programrettelsen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC installasjon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Ønsker du å installere DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC allerede installert:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Spillet er allerede installert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG FEIL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Pakker ut PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Utpakking fullført</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Spillet ble installert i %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Fila ser ikke ut til å være en gyldig PKG-fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Kjør spill</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Klarte ikke finne Eboot.bin-fila</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>PKG-fil (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>PKG er en programrettelse eller DLC. Installer spillet først!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>Spillet kjører allerede!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Åpne mappe</translation>
|
||||
<source>Play</source>
|
||||
<translation>Spill</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG FEIL</translation>
|
||||
<source>Pause</source>
|
||||
<translation>Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Navn</translation>
|
||||
<source>Stop</source>
|
||||
<translation>Stopp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Serienummer</translation>
|
||||
<source>Restart</source>
|
||||
<translation>Start på nytt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Installert</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation>Fullskjerm</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Størrelse</translation>
|
||||
<source>Controllers</source>
|
||||
<translation>Kontroller</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Kategori</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation>Tastatur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation>Oppdater lista</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>Programversjon</translation>
|
||||
<source>Resume</source>
|
||||
<translation>Gjenoppta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FV</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Region</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Flagg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Adresse</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Ukjent</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Pakke</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation>Vis merkelapp under ikoner</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Troféviser</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Velg spill:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Fremdrift</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation type="unfinished">Error creating shortcut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation type="unfinished">Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation type="unfinished">Game</translation>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation type="unfinished">shadPS4 - Choose directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation type="unfinished">Select which directory you want to install to.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation type="unfinished">Install All Queued to Selected Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation type="unfinished">Delete PKG File on Install</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation type="unfinished">Open/Add Elf Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation type="unfinished">Install Packages (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation type="unfinished">Boot Game</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation type="unfinished">Configure...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation type="unfinished">Install application from a .pkg file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation type="unfinished">Recent Games</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation type="unfinished">Dump Game List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation type="unfinished">PKG Viewer</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Je kunt slechts één bestand selecteren!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>PKG-extractie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch gedetecteerd!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- en gameversies komen overeen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Wilt u overschrijven?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-versie %1 is ouder dan de geïnstalleerde versie: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game is geïnstalleerd: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Wilt u de patch installeren: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC-installatie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Wilt u DLC installeren: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC al geïnstalleerd:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game al geïnstalleerd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG FOUT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>PKG %1/%2 aan het extraheren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extractie voltooid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Spel succesvol geïnstalleerd op %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Het bestand lijkt geen geldig PKG-bestand te zijn</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation type="unfinished">Run Game</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation type="unfinished">Eboot.bin file not found</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation type="unfinished">Game is already running!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation type="unfinished">shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation type="unfinished">Open Folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>PKG FOUT</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Naam</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Serienummer</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation type="unfinished">Installed</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Grootte</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished">Category</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation type="unfinished">Type</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation type="unfinished">App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation type="unfinished">FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Regio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation type="unfinished">Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Pad</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Onbekend</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation type="unfinished">Package</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
|
|
|
@ -543,38 +543,38 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Unable to Save</source>
|
||||
<translation type="unfinished">Unable to Save</translation>
|
||||
<translation>Zapisywanie nie powiodło się</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot bind axis values more than once</source>
|
||||
<translation type="unfinished">Cannot bind axis values more than once</translation>
|
||||
<translation>Nie można powiązać wartości osi więcej niż raz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished">Save</translation>
|
||||
<translation>Zapisz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Apply</source>
|
||||
<translation type="unfinished">Apply</translation>
|
||||
<translation>Zastosuj</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore Defaults</source>
|
||||
<translation type="unfinished">Restore Defaults</translation>
|
||||
<translation>Przywróć ustawienia domyślne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">Cancel</translation>
|
||||
<translation>Anuluj</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditorDialog</name>
|
||||
<message>
|
||||
<source>Edit Keyboard + Mouse and Controller input bindings</source>
|
||||
<translation type="unfinished">Edit Keyboard + Mouse and Controller input bindings</translation>
|
||||
<translation>Edytuj przypisanie klawiszy klawiatury + myszy oraz kontrolera</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Per-Game configs</source>
|
||||
<translation type="unfinished">Use Per-Game configs</translation>
|
||||
<translation>Użyj osobnej konfiguracji dla każdej gry</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
|
@ -582,11 +582,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for reading</source>
|
||||
<translation type="unfinished">Could not open the file for reading</translation>
|
||||
<translation>Nie można otworzyć pliku do odczytu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for writing</source>
|
||||
<translation type="unfinished">Could not open the file for writing</translation>
|
||||
<translation>Nie można otworzyć pliku do zapisu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Changes</source>
|
||||
|
@ -602,11 +602,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset your custom default config to the original default config?</source>
|
||||
<translation type="unfinished">Do you want to reset your custom default config to the original default config?</translation>
|
||||
<translation>Czy chcesz zresetować Twoją domyślną konfigurację do oryginalnej domyślnej konfiguracji?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset this config to your custom default config?</source>
|
||||
<translation type="unfinished">Do you want to reset this config to your custom default config?</translation>
|
||||
<translation>Czy chcesz zresetować tę konfigurację do Twojej domyślnej konfiguracji?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reset to Default</source>
|
||||
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Utworzenie skrótu zakończone niepowodzeniem!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Zainstaluj PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Gra</translation>
|
||||
|
@ -959,253 +955,234 @@
|
|||
<name>HelpDialog</name>
|
||||
<message>
|
||||
<source>Quickstart</source>
|
||||
<translation type="unfinished">Quickstart</translation>
|
||||
<translation>Szybki start</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FAQ</source>
|
||||
<translation type="unfinished">FAQ</translation>
|
||||
<translation>Najczęściej zadawane pytania</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Syntax</source>
|
||||
<translation type="unfinished">Syntax</translation>
|
||||
<translation>Składnia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Bindings</source>
|
||||
<translation type="unfinished">Special Bindings</translation>
|
||||
<translation>Specjalne wiązania</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keybindings</source>
|
||||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Wybierz katalog</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Wybierz katalog, do którego chcesz zainstalować.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Zainstaluj wszystkie oczekujące do wybranego folderu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Usuń plik PKG po instalacji</translation>
|
||||
<translation>Przypisanie klawiszy</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
<source>Configure Controls</source>
|
||||
<translation type="unfinished">Configure Controls</translation>
|
||||
<translation>Skonfiguruj sterowanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>D-Pad</source>
|
||||
<translation type="unfinished">D-Pad</translation>
|
||||
<translation>Krzyżak</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Up</source>
|
||||
<translation type="unfinished">Up</translation>
|
||||
<translation>Strzałka w górę</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>unmapped</source>
|
||||
<translation type="unfinished">unmapped</translation>
|
||||
<translation>nieprzypisane</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left</source>
|
||||
<translation type="unfinished">Left</translation>
|
||||
<translation>Strzałka w lewo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right</source>
|
||||
<translation type="unfinished">Right</translation>
|
||||
<translation>Strzałka w prawo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Down</source>
|
||||
<translation type="unfinished">Down</translation>
|
||||
<translation>Strzałka w dół</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Analog Halfmode</source>
|
||||
<translation type="unfinished">Left Analog Halfmode</translation>
|
||||
<translation>Połowiczny tryb lewego drążka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>hold to move left stick at half-speed</source>
|
||||
<translation type="unfinished">hold to move left stick at half-speed</translation>
|
||||
<translation>przytrzymaj, aby przesuwać lewy drążek dwa razy wolniej</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Left Stick</source>
|
||||
<translation type="unfinished">Left Stick</translation>
|
||||
<translation>Lewy drążek</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Config Selection</source>
|
||||
<translation type="unfinished">Config Selection</translation>
|
||||
<translation>Wybór konfiguracji</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common Config</source>
|
||||
<translation type="unfinished">Common Config</translation>
|
||||
<translation>Typowa konfiguracja</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use per-game configs</source>
|
||||
<translation type="unfinished">Use per-game configs</translation>
|
||||
<translation>Użyj osobnej konfiguracji dla każdej gry</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>L1</source>
|
||||
<translation type="unfinished">L1</translation>
|
||||
<translation>L1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>L2</source>
|
||||
<translation type="unfinished">L2</translation>
|
||||
<translation>L2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Text Editor</source>
|
||||
<translation type="unfinished">Text Editor</translation>
|
||||
<translation>Edytor tekstu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Help</source>
|
||||
<translation type="unfinished">Help</translation>
|
||||
<translation>Pomoc</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R1</source>
|
||||
<translation type="unfinished">R1</translation>
|
||||
<translation>R1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R2</source>
|
||||
<translation type="unfinished">R2</translation>
|
||||
<translation>R2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>L3</source>
|
||||
<translation type="unfinished">L3</translation>
|
||||
<translation>L3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Touchpad Click</source>
|
||||
<translation type="unfinished">Touchpad Click</translation>
|
||||
<translation>Kliknięcie Touchpada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mouse to Joystick</source>
|
||||
<translation type="unfinished">Mouse to Joystick</translation>
|
||||
<translation>Mysz na Joystick</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>*press F7 ingame to activate</source>
|
||||
<translation type="unfinished">*press F7 ingame to activate</translation>
|
||||
<translation>*naciśnij F7 w grze aby aktywować</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>R3</source>
|
||||
<translation type="unfinished">R3</translation>
|
||||
<translation>R3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options</source>
|
||||
<translation type="unfinished">Options</translation>
|
||||
<translation>Opcje</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mouse Movement Parameters</source>
|
||||
<translation type="unfinished">Mouse Movement Parameters</translation>
|
||||
<translation>Parametry ruchu myszy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>note: click Help Button/Special Keybindings for more information</source>
|
||||
<translation type="unfinished">note: click Help Button/Special Keybindings for more information</translation>
|
||||
<translation>uwaga: kliknij przycisk Pomoc/Specjalne skróty klawiszowe, aby uzyskać więcej informacji</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face Buttons</source>
|
||||
<translation type="unfinished">Face Buttons</translation>
|
||||
<translation>Przednie przyciski</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Triangle</source>
|
||||
<translation type="unfinished">Triangle</translation>
|
||||
<translation>Trójkąt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Square</source>
|
||||
<translation type="unfinished">Square</translation>
|
||||
<translation>Kwadrat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Circle</source>
|
||||
<translation type="unfinished">Circle</translation>
|
||||
<translation>Kółko</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cross</source>
|
||||
<translation type="unfinished">Cross</translation>
|
||||
<translation>Krzyżyk</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right Analog Halfmode</source>
|
||||
<translation type="unfinished">Right Analog Halfmode</translation>
|
||||
<translation>Połowiczny tryb prawego drążka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>hold to move right stick at half-speed</source>
|
||||
<translation type="unfinished">hold to move right stick at half-speed</translation>
|
||||
<translation>przytrzymaj, aby przesuwać prawy drążek dwa razy wolniej</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Right Stick</source>
|
||||
<translation type="unfinished">Right Stick</translation>
|
||||
<translation>Prawy drążek</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Speed Offset (def 0.125):</source>
|
||||
<translation type="unfinished">Speed Offset (def 0.125):</translation>
|
||||
<translation>Offset prędkości (def 0,125):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy from Common Config</source>
|
||||
<translation type="unfinished">Copy from Common Config</translation>
|
||||
<translation>Kopiuj z typowej konfiguracji</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Deadzone Offset (def 0.50):</source>
|
||||
<translation type="unfinished">Deadzone Offset (def 0.50):</translation>
|
||||
<translation>Offset martwych stref (def 0,50):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Speed Multiplier (def 1.0):</source>
|
||||
<translation type="unfinished">Speed Multiplier (def 1.0):</translation>
|
||||
<translation>Mnożnik prędkości (def1.0):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common Config Selected</source>
|
||||
<translation type="unfinished">Common Config Selected</translation>
|
||||
<translation>Wybrano typową konfigurację</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This button copies mappings from the Common Config to the currently selected profile, and cannot be used when the currently selected profile is the Common Config.</source>
|
||||
<translation type="unfinished">This button copies mappings from the Common Config to the currently selected profile, and cannot be used when the currently selected profile is the Common Config.</translation>
|
||||
<translation>Przycisk ten kopiuje mapowanie z typowej konfiguracji do aktualnie wybranego profilu, i nie może być użyty, gdy aktualnie wybranym profilem jest typowa konfiguracja.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy values from Common Config</source>
|
||||
<translation type="unfinished">Copy values from Common Config</translation>
|
||||
<translation>Kopiuj z typowej konfiguracji</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to overwrite existing mappings with the mappings from the Common Config?</source>
|
||||
<translation type="unfinished">Do you want to overwrite existing mappings with the mappings from the Common Config?</translation>
|
||||
<translation>Czy chcesz nadpisać istniejące mapowania mapowaniem z typowej konfiguracji?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to Save</source>
|
||||
<translation type="unfinished">Unable to Save</translation>
|
||||
<translation>Zapisywanie nie powiodło się</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot bind any unique input more than once</source>
|
||||
<translation type="unfinished">Cannot bind any unique input more than once</translation>
|
||||
<translation>Nie można powiązać żadnych unikalnych danych wejściowych więcej niż raz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Press a key</source>
|
||||
<translation type="unfinished">Press a key</translation>
|
||||
<translation>Naciśnij klawisz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot set mapping</source>
|
||||
<translation type="unfinished">Cannot set mapping</translation>
|
||||
<translation>Nie można ustawić mapowania</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mousewheel cannot be mapped to stick outputs</source>
|
||||
<translation type="unfinished">Mousewheel cannot be mapped to stick outputs</translation>
|
||||
<translation>Kółko myszy nie może być przypisane do sterowania drążkiem</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished">Save</translation>
|
||||
<translation>Zapisz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Apply</source>
|
||||
<translation type="unfinished">Apply</translation>
|
||||
<translation>Zastosuj</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore Defaults</source>
|
||||
<translation type="unfinished">Restore Defaults</translation>
|
||||
<translation>Przywróć ustawienia domyślne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">Cancel</translation>
|
||||
<translation>Anuluj</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Otwórz/Dodaj folder Elf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Zainstaluj paczkę (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Uruchom grę</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Konfiguruj...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Zainstaluj aplikacje z pliku .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Ostatnie gry</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Zgraj listę gier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>Menedżer plików PKG</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Menedżer trofeów</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>Nie znaleziono gier. Najpierw dodaj swoje gry do swojej biblioteki.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Można wybrać tylko jeden plik!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Wypakowywanie PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Wykryto łatkę!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Wersje PKG i gry są zgodne: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Czy chcesz nadpisać?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Wersja PKG %1 jest starsza niż zainstalowana wersja: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Gra jest zainstalowana: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Czy chcesz zainstalować łatkę: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Instalacja dodatkowej zawartości (DLC)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Czy chcesz zainstalować dodatkową zawartość (DLC): %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>Dodatkowa zawartość (DLC) już zainstalowana:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>Gra już zainstalowana</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>BŁĄD PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Wypakowywanie PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Wypakowywanie zakończone</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Gra pomyślnie zainstalowana w %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>Plik nie wydaje się być prawidłowym plikiem PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Uruchom grę</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Nie znaleziono pliku EBOOT.BIN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>Plik PKG (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>PKG jest aktualizacją lub dodatkową zawartością (DLC), najpierw zainstaluj grę!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>Gra jest już uruchomiona!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Otwórz folder</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>BŁĄD PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nazwa</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Numer seryjny</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Zainstalowano</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Rozmiar</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Kategoria</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Typ</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>Wersja aplikacji</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>Oprogramowanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Region</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Flagi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Ścieżka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Plik</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Nieznany</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Paczka</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2154,35 +2028,35 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Portable User Folder</source>
|
||||
<translation type="unfinished">Portable User Folder</translation>
|
||||
<translation>Przenośny folder użytkownika</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create Portable User Folder from Common User Folder</source>
|
||||
<translation type="unfinished">Create Portable User Folder from Common User Folder</translation>
|
||||
<translation>Utwórz przenośny folder użytkownika ze zwykłego folderu użytkownika</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Portable user folder:\nStores shadPS4 settings and data that will be applied only to the shadPS4 build located in the current folder. Restart the app after creating the portable user folder to begin using it.</source>
|
||||
<translation type="unfinished">Portable user folder:\nStores shadPS4 settings and data that will be applied only to the shadPS4 build located in the current folder. Restart the app after creating the portable user folder to begin using it.</translation>
|
||||
<translation>Przenośny folder użytkownika:\nPrzechowuje ustawienia shadPS4 i dane, które zostaną zastosowane tylko do kompilacji shadPS4 znajdującej się w bieżącym folderze. Uruchom ponownie aplikację po utworzeniu przenośnego folderu użytkownika, aby zacząć z niego korzystać.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot create portable user folder</source>
|
||||
<translation type="unfinished">Cannot create portable user folder</translation>
|
||||
<translation>Nie można utworzyć przenośnego folderu użytkownika</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 already exists</source>
|
||||
<translation type="unfinished">%1 already exists</translation>
|
||||
<translation>%1 już istnieje</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Portable user folder created</source>
|
||||
<translation type="unfinished">Portable user folder created</translation>
|
||||
<translation>Utworzono przenośny folder użytkownika</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 successfully created.</source>
|
||||
<translation type="unfinished">%1 successfully created.</translation>
|
||||
<translation>%1 prawidłowo utworzony.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</source>
|
||||
<translation type="unfinished">Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</translation>
|
||||
<translation>Otwórz niestandardowy folder obrazów/dźwięków:\nMożesz dodać własne obrazy dla trofeów i ich dźwięki.\nDodaj pliki do custom_trophy o następujących nazwach:\ntrophy.wav LUB trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nUwaga: Dźwięki działają tylko w wersji QT.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Menedżer trofeów</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Wybierz grę:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Postęp</translation>
|
||||
|
|
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Erro ao criar atalho!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Instalar PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Jogo</translation>
|
||||
|
@ -912,7 +908,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Tem certeza de que deseja excluir o diretório %2 de %1?</translation>
|
||||
<translation>Tem certeza de que deseja excluir o diretório do %2 %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open Update Folder</source>
|
||||
|
@ -978,25 +974,6 @@
|
|||
<translation>Teclas de atalho</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Escolha o diretório</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Selecione o diretório em que você deseja instalar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Instalar Tudo da Fila para a Pasta Selecionada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Excluir o PKG após a Instalação</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>KBMSettings</name>
|
||||
<message>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Abrir/Adicionar pasta Elf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Instalar Pacotes (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Iniciar Jogo</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Configurar...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Instalar aplicativo de um arquivo .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Jogos Recentes</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Exportar Lista de Jogos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>Visualizador de PKG</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Visualizador de Troféus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>Nenhum jogo encontrado. Adicione seus jogos à sua biblioteca primeiro.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Apenas um arquivo pode ser selecionado!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Extração de PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Atualização detectada!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>As versões do PKG e do Jogo são iguais: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Você gostaria de sobrescrever?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>A Versão do PKG %1 é mais antiga do que a versão instalada: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Jogo instalado: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Você gostaria de instalar a atualização: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Instalação de DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Você gostaria de instalar o DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC já está instalado:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>O jogo já está instalado:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRO DE PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>Extraindo PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extração Concluída</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Jogo instalado com sucesso em %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>O arquivo não parece ser um arquivo PKG válido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Executar Jogo</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Arquivo Eboot.bin não encontrado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>Arquivo PKG (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>O PKG é um patch ou DLC, por favor instale o jogo primeiro!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>O jogo já está executando!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Abrir Pasta</translation>
|
||||
<source>Play</source>
|
||||
<translation>Jogar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRO DE PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation>Pausar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nome</translation>
|
||||
<source>Stop</source>
|
||||
<translation>Parar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Serial</translation>
|
||||
<source>Restart</source>
|
||||
<translation>Reiniciar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Instalado</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation>Tela Cheia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Tamanho</translation>
|
||||
<source>Controllers</source>
|
||||
<translation>Controles</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Categoria</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation>Teclado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Tipo</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation>Atualizar Lista</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>Versão do App</translation>
|
||||
<source>Resume</source>
|
||||
<translation>Continuar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Região</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Caminho</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Arquivo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Desconhecido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Pacote</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation>Mostrar Rótulos Sob Ícones</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Visualizador de Troféus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Selecionar Jogo:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Progresso</translation>
|
||||
|
|
|
@ -543,74 +543,74 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Unable to Save</source>
|
||||
<translation type="unfinished">Unable to Save</translation>
|
||||
<translation>Não é possível salvar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot bind axis values more than once</source>
|
||||
<translation type="unfinished">Cannot bind axis values more than once</translation>
|
||||
<translation>Não foi possível atribuir os valores do eixo X ou Y mais de uma vez</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished">Save</translation>
|
||||
<translation>Salvar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Apply</source>
|
||||
<translation type="unfinished">Apply</translation>
|
||||
<translation>Aplicar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore Defaults</source>
|
||||
<translation type="unfinished">Restore Defaults</translation>
|
||||
<translation>Restaurar o Padrão</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">Cancel</translation>
|
||||
<translation>Cancelar</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditorDialog</name>
|
||||
<message>
|
||||
<source>Edit Keyboard + Mouse and Controller input bindings</source>
|
||||
<translation type="unfinished">Edit Keyboard + Mouse and Controller input bindings</translation>
|
||||
<translation>Editar comandos do Teclado + Mouse e do Controle</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Per-Game configs</source>
|
||||
<translation type="unfinished">Use Per-Game configs</translation>
|
||||
<translation>Use uma configuração para cada jogo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished">Error</translation>
|
||||
<translation>Erro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for reading</source>
|
||||
<translation type="unfinished">Could not open the file for reading</translation>
|
||||
<translation>Não foi possível abrir o arquivo para ler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for writing</source>
|
||||
<translation type="unfinished">Could not open the file for writing</translation>
|
||||
<translation>Não foi possível abrir o arquivo para escrever</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Changes</source>
|
||||
<translation type="unfinished">Save Changes</translation>
|
||||
<translation>Salvar mudanças</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to save changes?</source>
|
||||
<translation type="unfinished">Do you want to save changes?</translation>
|
||||
<translation>Salvar as mudanças?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Help</source>
|
||||
<translation type="unfinished">Help</translation>
|
||||
<translation>Ajuda</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset your custom default config to the original default config?</source>
|
||||
<translation type="unfinished">Do you want to reset your custom default config to the original default config?</translation>
|
||||
<translation>Restaurar a configuração customizada padrão para a configuração original padrão?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to reset this config to your custom default config?</source>
|
||||
<translation type="unfinished">Do you want to reset this config to your custom default config?</translation>
|
||||
<translation>Deseja redefinir esta configuração para a configuração padrão personalizada?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reset to Default</source>
|
||||
<translation type="unfinished">Reset to Default</translation>
|
||||
<translation>Resetar ao Padrão</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -882,10 +882,6 @@
|
|||
<source>Error creating shortcut!</source>
|
||||
<translation>Erro ao criar atalho!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install PKG</source>
|
||||
<translation>Instalar PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game</source>
|
||||
<translation>Jogo</translation>
|
||||
|
@ -959,42 +955,23 @@
|
|||
<name>HelpDialog</name>
|
||||
<message>
|
||||
<source>Quickstart</source>
|
||||
<translation type="unfinished">Quickstart</translation>
|
||||
<translation>Início Rápido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FAQ</source>
|
||||
<translation type="unfinished">FAQ</translation>
|
||||
<translation>Perguntas Frequentes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Syntax</source>
|
||||
<translation type="unfinished">Syntax</translation>
|
||||
<translation>Sintaxe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Bindings</source>
|
||||
<translation type="unfinished">Special Bindings</translation>
|
||||
<translation>Atalhos Especiais</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keybindings</source>
|
||||
<translation type="unfinished">Keybindings</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallDirSelect</name>
|
||||
<message>
|
||||
<source>shadPS4 - Choose directory</source>
|
||||
<translation>shadPS4 - Escolher diretório</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Selecione o diretório em que deseja instalar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install All Queued to Selected Folder</source>
|
||||
<translation>Instalar Todos os Pendentes para a Pasta Selecionada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete PKG File on Install</source>
|
||||
<translation>Eliminar Ficheiro PKG após Instalação</translation>
|
||||
<translation>Combinações de Teclas</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1145,67 +1122,67 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Copy from Common Config</source>
|
||||
<translation type="unfinished">Copy from Common Config</translation>
|
||||
<translation>Copiar da Configuração Comum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Deadzone Offset (def 0.50):</source>
|
||||
<translation type="unfinished">Deadzone Offset (def 0.50):</translation>
|
||||
<translation>Deslocamento da Zona Morta (def 0,50):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Speed Multiplier (def 1.0):</source>
|
||||
<translation type="unfinished">Speed Multiplier (def 1.0):</translation>
|
||||
<translation>Multiplicador de Velocidade (def 1,0):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common Config Selected</source>
|
||||
<translation type="unfinished">Common Config Selected</translation>
|
||||
<translation>Configuração Comum Selecionada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This button copies mappings from the Common Config to the currently selected profile, and cannot be used when the currently selected profile is the Common Config.</source>
|
||||
<translation type="unfinished">This button copies mappings from the Common Config to the currently selected profile, and cannot be used when the currently selected profile is the Common Config.</translation>
|
||||
<translation>Este botão copia mapeamentos da Configuração Comum para o perfil atualmente selecionado, e não pode ser usado quando o perfil atualmente selecionado é a Configuração Comum.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy values from Common Config</source>
|
||||
<translation type="unfinished">Copy values from Common Config</translation>
|
||||
<translation>Copiar valores da Configuração Comum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to overwrite existing mappings with the mappings from the Common Config?</source>
|
||||
<translation type="unfinished">Do you want to overwrite existing mappings with the mappings from the Common Config?</translation>
|
||||
<translation>Substituir mapeamentos existentes com os mapeamentos da Configuração Comum?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to Save</source>
|
||||
<translation type="unfinished">Unable to Save</translation>
|
||||
<translation>Não é possível salvar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot bind any unique input more than once</source>
|
||||
<translation type="unfinished">Cannot bind any unique input more than once</translation>
|
||||
<translation>Não é possível vincular qualquer entrada única mais de uma vez</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Press a key</source>
|
||||
<translation type="unfinished">Press a key</translation>
|
||||
<translation>Pressione uma tecla</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot set mapping</source>
|
||||
<translation type="unfinished">Cannot set mapping</translation>
|
||||
<translation>Não é possível definir o mapeamento</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mousewheel cannot be mapped to stick outputs</source>
|
||||
<translation type="unfinished">Mousewheel cannot be mapped to stick outputs</translation>
|
||||
<translation>Roda do rato não pode ser mapeada para saídas empates</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished">Save</translation>
|
||||
<translation>Salvar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Apply</source>
|
||||
<translation type="unfinished">Apply</translation>
|
||||
<translation>Aplicar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore Defaults</source>
|
||||
<translation type="unfinished">Restore Defaults</translation>
|
||||
<translation>Restaurar Definições</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">Cancel</translation>
|
||||
<translation>Cancelar</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1214,10 +1191,6 @@
|
|||
<source>Open/Add Elf Folder</source>
|
||||
<translation>Abrir/Adicionar pasta Elf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install Packages (PKG)</source>
|
||||
<translation>Instalar Pacotes (PKG)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boot Game</source>
|
||||
<translation>Iniciar Jogo</translation>
|
||||
|
@ -1234,10 +1207,6 @@
|
|||
<source>Configure...</source>
|
||||
<translation>Configurar...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Instalar aplicação através de um ficheiro .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent Games</source>
|
||||
<translation>Jogos Recentes</translation>
|
||||
|
@ -1307,8 +1276,12 @@
|
|||
<translation>Exportar Lista de Jogos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Viewer</source>
|
||||
<translation>Visualizador PKG</translation>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation>Visualizador de Troféus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation>Nenhum jogo encontrado. Por favor, adicione os seus jogos à sua biblioteca primeiro.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1418,70 +1391,6 @@
|
|||
<source>Only one file can be selected!</source>
|
||||
<translation>Apenas um ficheiro pode ser selecionado!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Extraction</source>
|
||||
<translation>Extração de PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch detetado!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>As versões do PKG e do Jogo coincidem: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Gostaria de substituir?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>A versão do PKG %1 é mais antiga do que a versão instalada: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is installed: </source>
|
||||
<translation>O jogo está instalado: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Gostaria de instalar o Patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Instalação de DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Deseja instalar o DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC já está instalado:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game already installed</source>
|
||||
<translation>O jogo já está instalado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRO PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extracting PKG %1/%2</source>
|
||||
<translation>A extrair PKG %1/%2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Extraction Finished</source>
|
||||
<translation>Extração Finalizada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Jogo instalado com sucesso em %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File doesn't appear to be a valid PKG file</source>
|
||||
<translation>O ficheiro não aparenta ser um ficheiro PKG válido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run Game</source>
|
||||
<translation>Executar Jogo</translation>
|
||||
|
@ -1490,14 +1399,6 @@
|
|||
<source>Eboot.bin file not found</source>
|
||||
<translation>Ficheiro eboot.bin não encontrado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG File (*.PKG *.pkg)</source>
|
||||
<translation>Ficheiro PKG (*.PKG *.pkg)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG is a patch or DLC, please install the game first!</source>
|
||||
<translation>Este PKG é um patch ou DLC, por favor instale o respetivo jogo primeiro!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game is already running!</source>
|
||||
<translation>O jogo já está a ser executado!</translation>
|
||||
|
@ -1506,72 +1407,45 @@
|
|||
<source>shadPS4</source>
|
||||
<translation>shadPS4</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PKGViewer</name>
|
||||
<message>
|
||||
<source>Open Folder</source>
|
||||
<translation>Abrir Pasta</translation>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRO PKG</translation>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
<translation>Nome</translation>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Serial</source>
|
||||
<translation>Número de Série</translation>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installed</source>
|
||||
<translation>Instalado</translation>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Tamanho</translation>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translation>Categoria</translation>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type</source>
|
||||
<translation>Tipo</translation>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>App Ver</source>
|
||||
<translation>App Ver</translation>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FW</source>
|
||||
<translation>FW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Region</source>
|
||||
<translation>Região</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flags</source>
|
||||
<translation>Flags</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Path</source>
|
||||
<translation>Caminho</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File</source>
|
||||
<translation>Ficheiro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Desconhecido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Package</source>
|
||||
<translation>Pacote</translation>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2166,23 +2040,23 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Cannot create portable user folder</source>
|
||||
<translation type="unfinished">Cannot create portable user folder</translation>
|
||||
<translation>Não é possível criar pasta de utilizador portátil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 already exists</source>
|
||||
<translation type="unfinished">%1 already exists</translation>
|
||||
<translation>%1 já existe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Portable user folder created</source>
|
||||
<translation type="unfinished">Portable user folder created</translation>
|
||||
<translation>Pasta de utilizador portátil criada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 successfully created.</source>
|
||||
<translation type="unfinished">%1 successfully created.</translation>
|
||||
<translation>%1 criado com sucesso.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</source>
|
||||
<translation type="unfinished">Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</translation>
|
||||
<translation>Abra a pasta de imagens/sons de troféus personalizados:\nPoderá adicionar imagens personalizadas aos troféus e um áudio.\nAdicione os arquivos na pasta custom_trophy com os seguintes nomes:\ntrophy.mp3 ou trophy.wav, bronze.png, gold.png, platinum.png, silver.png\nObservação: O som funcionará apenas nas versões Qt.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2191,6 +2065,10 @@
|
|||
<source>Trophy Viewer</source>
|
||||
<translation>Visualizador de Troféus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation>Escolha o Jogo:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation>Progresso</translation>
|
||||
|
|