Compare commits

..

6 Commits

Author SHA1 Message Date
Zangetsu38 3f3d08a9d4 hack bleach 2017-10-15 01:04:42 +02:00
Zangetsu38 f614151133 Update LLVM 5.0 2017-10-15 01:03:40 +02:00
Zion Nimchuk 7e7d3e658e Initial LLVM 5 port 2017-10-15 01:03:40 +02:00
Megamouse 7b81d19103 GUI: add some visual studio filters (#3375) 2017-10-15 01:03:40 +02:00
Zangetsu38 9425e22ad0 Update Project to Visual Studio 2017. 2017-10-15 01:03:40 +02:00
kd-11 c8b39fe7dd update vulkan submodules 2017-10-14 16:29:36 +03:00
337 changed files with 9402 additions and 30952 deletions
+1
View File
@@ -59,6 +59,7 @@ rpcs3/git-version.h
# Visual Studio Files
.vs/*
*.ipch
*.vspx
*.psess
*.VC.*
+7 -8
View File
@@ -7,14 +7,14 @@
ignore = dirty
[submodule "llvm"]
path = llvm
url = https://github.com/RPCS3/llvm
branch = release_60
url = https://github.com/llvm-mirror/llvm
branch = release_50
[submodule "GSL"]
path = 3rdparty/GSL
url = https://github.com/Microsoft/GSL.git
[submodule "libpng"]
path = 3rdparty/libpng
url = https://github.com/RPCS3/libpng
url = https://github.com/Zangetsu38/libpng
ignore = dirty
[submodule "Vulkan/glslang"]
path = Vulkan/glslang
@@ -25,6 +25,9 @@
[submodule "Utilities/yaml-cpp"]
path = Utilities/yaml-cpp
url = https://github.com/RPCS3/yaml-cpp
[submodule "3rdparty/pugixml"]
path = 3rdparty/pugixml
url = https://github.com/RPCS3/pugixml
[submodule "3rdparty/cereal"]
path = 3rdparty/cereal
url = https://github.com/USCiLab/cereal.git
@@ -33,12 +36,8 @@
url = https://github.com/madler/zlib
[submodule "3rdparty/hidapi"]
path = 3rdparty/hidapi
url = https://github.com/RPCS3/hidapi
url = https://github.com/Zangetsu38/hidapi
branch = master
ignore = dirty
[submodule "3rdparty/Optional"]
path = 3rdparty/Optional
url = https://github.com/akrzemi1/Optional.git
[submodule "3rdparty/pugixml"]
path = 3rdparty/pugixml
url = https://github.com/zeux/pugixml
+24 -26
View File
@@ -22,10 +22,12 @@ matrix:
compiler: gcc
git:
depth: false # Unshallow clone to obtain proper GIT_VERSION
submodules: false
before_install:
- if [ "$CC" = "clang" ]; then
export CXX="clang++-4.0" CC="clang-4.0";
fi;
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then
export CXX="g++-5" CC="gcc-5" CXXFLAGS="-Wno-format-security";
fi;
@@ -33,16 +35,16 @@ before_install:
wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run ;
chmod a+x ./qt-unified-linux-x64-online.run ;
export QT_QPA_PLATFORM=minimal ;
travis_wait 60 ./qt-unified-linux-x64-online.run --script qt-installer-noninteractive.qs --no-force-installations --verbose ;
./qt-unified-linux-x64-online.run --script qt-installer-noninteractive.qs --no-force-installations ;
fi;
# Install updated libglew-dev since the version provided by trusty is outdated
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
wget https://mirrors.kernel.org/ubuntu/pool/universe/g/glew/libglew-dev_2.0.0-5_amd64.deb;
wget https://mirrors.kernel.org/ubuntu/pool/universe/g/glew/libglew2.0_2.0.0-5_amd64.deb;
wget https://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.61.1+dfsg1-1ubuntu1~16.04.1_amd64.deb;
wget https://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.61.1+dfsg1-1ubuntu1~16.04.1_amd64.deb;
sudo dpkg -i libglew2.0_2.0.0-5_amd64.deb libglew-dev_2.0.0-5_amd64.deb libvulkan1_1.0.61.1+dfsg1-1ubuntu1~16.04.1_amd64.deb libvulkan-dev_1.0.61.1+dfsg1-1ubuntu1~16.04.1_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew-dev_1.13.0-2_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew1.13_1.13.0-2_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
sudo dpkg -i libglew1.13_1.13.0-2_amd64.deb libglew-dev_1.13.0-2_amd64.deb libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
else
brew update;
brew install ccache glew llvm40;
@@ -52,32 +54,30 @@ before_script:
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi 3rdparty/Optional Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
- mkdir build
- cd build
- export CMAKE_PREFIX_PATH=~/Qt/5.10.0/gcc_64/lib/cmake
- export CXXFLAGS="$CXXFLAGS -DTRAVIS=true";
- export CMAKE_PREFIX_PATH=~/Qt/5.9.1/gcc_64/lib/cmake
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
else
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/#$TRAVIS_PULL_REQUEST";
fi;
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr -G Ninja;
- ninja
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
- make -j 3
- # AppImage generation
- if [ -n "$UPLOAD_URL" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
export LD_LIBRARY_PATH=~/Qt/5.10.0/gcc_64/lib;
DESTDIR=appdir ninja install ; find appdir/ ;
- if [ -n "$UPLOAD_URL" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
export LD_LIBRARY_PATH=~/Qt/5.9.1/gcc_64/lib;
make DESTDIR=appdir install ; find appdir/ ;
find ../bin ;
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" ;
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" ;
chmod a+x linuxdeployqt*.AppImage ;
export PATH=~/Qt/5.10.0/gcc_64/bin/:${PATH} ;
export PATH=~/Qt/5.9.1/gcc_64/bin/:${PATH} ;
./linuxdeployqt*.AppImage --appimage-extract ;
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
mkdir ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.10.0/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
cp ~/Qt/5.10.0/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
cp ~/Qt/5.10.0/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.10.0/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
rm ./appdir/usr/lib/libfreetype.so.6 ;
cp ~/Qt/5.9.1/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
@@ -99,7 +99,6 @@ addons:
packages:
- binutils
- cmake
- ninja-build
- libasound2-dev
- libopenal-dev
- freeglut3-dev
@@ -109,15 +108,14 @@ addons:
- libc6-dev
- llvm-4.0
- llvm-4.0-dev
# Clang 5.0 is now bundled in travis, so we no longer need the ppa version.
#- clang-4.0
- clang-4.0
- libedit-dev
- g++-5
- gcc-5
- libstdc++-5-dev
- lib32stdc++6
- zlib1g-dev
# We need to install qt 5.10.0 manually because the version trusty provides is too old.
# We need to install qt 5.9.1 manually because the version trusty provides is too old.
#- qtbase5-dev
- libudev-dev
- libevdev-dev
+1 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.0.2)
option(WITH_GDB "WITH_GDB" OFF)
option(WITHOUT_LLVM "WITHOUT_LLVM" OFF)
+10 -19
View File
@@ -20,20 +20,19 @@ If you want to contribute please take a look at the [Coding Style](https://githu
## Dependencies
### Windows
* [Visual Studio 2015](https://www.visualstudio.com/vs/older-downloads/)
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
* [Visual Studio 2017](https://www.visualstudio.com/en/downloads/)
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
* [Cmake 3.1.0+](https://www.cmake.org/download/) (required; add to PATH)
* [Python 3.3+](https://www.python.org/downloads/) (required; add to PATH)
* [Qt 5.8+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.8\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
* [Qt 5.9+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.9.1\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
### Linux
* [Qt 5.7+](https://www.qt.io/download-open-source/)
* [Qt 5.9+](https://www.qt.io/download-open-source/)
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default`
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default`
* Arch: `sudo pacman -S glew openal cmake llvm qt5-base`
* Fedora: `sudo dnf install cmake glew glew-devel libatomic libudev-devel openal-devel qt5-devel vulkan-devel`
* OpenSUSE: `sudo zypper install git cmake libasound2 libpulse-devel openal-soft-devel glew-devel zlib-devel libedit-devel vulkan-devel libudev-devel libqt5-qtbase-devel libevdev-devel`
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel glew glew-devel`
**If you have a NVIDIA GPU, you may need to install the libglvnd package.**
### MacOS
@@ -48,23 +47,15 @@ To initialize the repository don't forget to execute `git submodule update --ini
### Configuring Qt
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.8\msvc2015_64\` </br>
Open `rpcs3.sln`
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.9.1\msvc2017_64\` </br>
*If you wish to use the Visual Studio plugin for Qt:* </br>
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.8\msvc2015_64`. </br>
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.9.1\msvc2015_64`. </br>
2) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
### Building the projects
You may want to download precompiled [LLVM lib](https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8) and extract to root rpcs3 folder (which contains `rpcs3.sln`), as well as download and extract [additional libs](https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U) to `lib\%CONFIGURATION%-x64\` to speed up compilation time (unoptimised/debug libs are currently not available precompiled).
If you're not using precompiled libs, build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*. </br></br>
`Build > Build Solution`</br>
1) Build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*. </br>
2) Press *BUILD* > *Build Solution* or *Rebuild Solution*. </br>
## Building on Linux & Mac OS:
+1 -1
View File
@@ -470,7 +470,7 @@ struct se_storage<T, 16, 16>
static inline v128 swap(const v128& src)
{
return v128::from64(se_storage<u64>::swap(src._u64[1]), se_storage<u64>::swap(src._u64[0]));
return v128::fromV(_mm_shuffle_epi8(src.vi, _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)));
}
static inline v128 to(const T& src)
+2 -5
View File
@@ -202,12 +202,9 @@ void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs)
out << YAML::EndMap;
return;
}
default:
{
out << rhs.to_string();
return;
}
}
out << rhs.to_string();
}
void cfg::decode(const YAML::Node& data, cfg::_base& rhs)
+3 -13
View File
@@ -118,7 +118,7 @@ namespace cfg
bool m_value;
public:
bool def;
const bool def;
_bool(node* owner, const std::string& name, bool def = false)
: _base(type::_bool, owner, name)
@@ -150,11 +150,6 @@ namespace cfg
return true;
}
void set(const bool& value)
{
m_value = value;
}
};
// Value node with fixed set of possible values, each maps to an enum value of type T.
@@ -222,7 +217,7 @@ namespace cfg
int_type m_value;
public:
int_type def;
const int_type def;
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)))
: _base(type::_int, owner, name)
@@ -258,11 +253,6 @@ namespace cfg
return false;
}
void set(const s64& value)
{
m_value = static_cast<int_type>(value);
}
std::vector<std::string> to_list() const override
{
return make_int_range(Min, Max);
@@ -281,7 +271,7 @@ namespace cfg
std::string m_value;
public:
std::string def;
const std::string def;
string(node* owner, const std::string& name, const std::string& def = {})
: _base(type::string, owner, name)
+6 -36
View File
@@ -75,25 +75,10 @@ static time_t to_time(const FILETIME& ft)
static FILETIME from_time(s64 _time)
{
const ullong wtime = (_time + 11644473600ULL) * 10000000ULL;
FILETIME result;
if (_time <= -11644473600ll)
{
result.dwLowDateTime = 0;
result.dwHighDateTime = 0;
}
else if (_time > INT64_MAX / 10000000ll - 11644473600ll)
{
result.dwLowDateTime = 0xffffffff;
result.dwHighDateTime = 0x7fffffff;
}
else
{
const ullong wtime = (_time + 11644473600ull) * 10000000ull;
result.dwLowDateTime = static_cast<DWORD>(wtime);
result.dwHighDateTime = static_cast<DWORD>(wtime >> 32);
}
result.dwLowDateTime = static_cast<DWORD>(wtime);
result.dwHighDateTime = static_cast<DWORD>(wtime >> 32);
return result;
}
@@ -111,8 +96,6 @@ static fs::error to_error(DWORD e)
case ERROR_INVALID_NAME: return fs::error::inval;
case ERROR_SHARING_VIOLATION: return fs::error::acces;
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
case ERROR_NOT_READY: return fs::error::noent;
//case ERROR_INVALID_PARAMETER: return fs::error::inval;
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
}
}
@@ -123,7 +106,6 @@ static fs::error to_error(DWORD e)
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/statvfs.h>
#include <sys/file.h>
#include <dirent.h>
#include <fcntl.h>
#include <libgen.h>
@@ -955,13 +937,6 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
return;
}
if (test(mode & fs::unshare) && ::flock(fd, LOCK_EX | LOCK_NB) != 0)
{
g_tls_error = errno == EWOULDBLOCK ? fs::error::acces : to_error(errno);
::close(fd);
return;
}
class unix_file final : public file_base, public get_native_handle
{
const int m_fd;
@@ -1034,7 +1009,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
(fmt::throw_exception("Invalid whence (0x%x)" HERE, whence), 0);
const auto result = ::lseek(m_fd, offset, mode);
if (result == -1)
{
g_tls_error = to_error(errno);
@@ -1258,12 +1233,7 @@ bool fs::dir::open(const std::string& path)
}
struct ::stat file_info;
if (::fstatat(::dirfd(m_dd), found->d_name, &file_info, 0) != 0)
{
//failed metadata (broken symlink?), ignore and skip to next file
return read(info);
}
verify("dir::read" HERE), ::fstatat(::dirfd(m_dd), found->d_name, &file_info, 0) == 0;
info.name = found->d_name;
info.is_directory = S_ISDIR(file_info.st_mode);
@@ -1363,7 +1333,7 @@ std::string fs::get_data_dir(const std::string& prefix, const std::string& locat
continue;
}
buf.push_back(c);
}
+7 -7
View File
@@ -422,7 +422,7 @@ namespace fs
class iterator
{
const dir* m_parent;
dir* m_parent;
dir_entry m_entry;
public:
@@ -432,7 +432,7 @@ namespace fs
from_current
};
iterator(const dir* parent, mode mode_ = mode::from_first)
iterator(dir* parent, mode mode_ = mode::from_first)
: m_parent(parent)
{
if (!m_parent)
@@ -458,7 +458,7 @@ namespace fs
iterator& operator++()
{
*this = {m_parent, mode::from_current};
*this = { m_parent, mode::from_current };
return *this;
}
@@ -468,14 +468,14 @@ namespace fs
}
};
iterator begin() const
iterator begin()
{
return {m_dir ? this : nullptr};
return{ m_dir ? this : nullptr };
}
iterator end() const
iterator end()
{
return {nullptr};
return{ nullptr };
}
};
+11 -43
View File
@@ -30,8 +30,6 @@
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/mman.h>
#endif
#include "JIT.h"
@@ -49,11 +47,6 @@ static void* const s_memory = []() -> void*
llvm::InitializeNativeTargetAsmPrinter();
LLVMLinkInMCJIT();
#ifdef MAP_32BIT
auto ptr = ::mmap(nullptr, s_memory_size, PROT_NONE, MAP_ANON | MAP_PRIVATE | MAP_32BIT, -1, 0);
if (ptr != MAP_FAILED)
return ptr;
#else
for (u64 addr = 0x10000000; addr <= 0x80000000 - s_memory_size; addr += 0x1000000)
{
if (auto ptr = utils::memory_reserve(s_memory_size, (void*)addr))
@@ -61,7 +54,6 @@ static void* const s_memory = []() -> void*
return ptr;
}
}
#endif
return utils::memory_reserve(s_memory_size);
}();
@@ -71,8 +63,6 @@ static void* s_next = s_memory;
#ifdef _WIN32
static std::deque<std::vector<RUNTIME_FUNCTION>> s_unwater;
static std::vector<std::vector<RUNTIME_FUNCTION>> s_unwind; // .pdata
#else
static std::deque<std::tuple<u8*, u64, std::size_t>> s_unfire;
#endif
// Reset memory manager
@@ -89,30 +79,7 @@ extern void jit_finalize()
s_unwind.clear();
#else
struct MemoryManager : llvm::RTDyldMemoryManager
{
u8* allocateCodeSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name) override
{
return nullptr;
}
u8* allocateDataSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name, bool is_ro) override
{
return nullptr;
}
bool finalizeMemory(std::string* = nullptr) override
{
return false;
}
} mem;
for (auto&& t : s_unfire)
{
mem.deregisterEHFrames(std::get<0>(t), std::get<1>(t), std::get<2>(t));
}
s_unfire.clear();
// TODO: unregister EH frames if necessary
#endif
utils::memory_decommit(s_memory, s_memory_size);
@@ -196,7 +163,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return {addr, llvm::JITSymbolFlags::Exported};
}
u8* allocateCodeSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name) override
virtual u8* allocateCodeSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name) override
{
// Lock memory manager
writer_lock lock(s_mutex);
@@ -217,7 +184,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return (u8*)std::exchange(s_next, (void*)next);
}
u8* allocateDataSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name, bool is_ro) override
virtual u8* allocateDataSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name, bool is_ro) override
{
// Lock memory manager
writer_lock lock(s_mutex);
@@ -242,7 +209,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return (u8*)std::exchange(s_next, (void*)next);
}
bool finalizeMemory(std::string* = nullptr) override
virtual bool finalizeMemory(std::string* = nullptr) override
{
// Lock memory manager
writer_lock lock(s_mutex);
@@ -259,7 +226,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return false;
}
void registerEHFrames(u8* addr, u64 load_addr, std::size_t size) override
virtual void registerEHFrames(u8* addr, u64 load_addr, std::size_t size) override
{
#ifdef _WIN32
// Lock memory manager
@@ -286,15 +253,16 @@ struct MemoryManager : llvm::RTDyldMemoryManager
{
s_unwind.emplace_back(std::move(pdata));
}
#else
s_unfire.push_front(std::make_tuple(addr, load_addr, size));
#endif
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
}
void deregisterEHFrames(u8* addr, u64 load_addr, std::size_t size) override
virtual void deregisterEHFrames() override
{
LOG_ERROR(GENERAL, "deregisterEHFrames() called"); // Not expected
return RTDyldMemoryManager::deregisterEHFrames();
}
};
@@ -308,7 +276,7 @@ struct EventListener : llvm::JITEventListener
{
}
void NotifyObjectEmitted(const llvm::object::ObjectFile& obj, const llvm::RuntimeDyld::LoadedObjectInfo& inf) override
virtual void NotifyObjectEmitted(const llvm::object::ObjectFile& obj, const llvm::RuntimeDyld::LoadedObjectInfo& inf) override
{
#ifdef _WIN32
for (auto it = obj.section_begin(), end = obj.section_end(); it != end; ++it)
@@ -404,7 +372,7 @@ public:
};
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, std::string _cpu)
: m_link(_link)
: m_link(std::move(_link))
, m_cpu(std::move(_cpu))
{
if (m_cpu.empty())
+48 -221
View File
@@ -4,19 +4,15 @@
#include "sema.h"
#include "Utilities/sysinfo.h"
#include "Utilities/Thread.h"
#include "rpcs3_version.h"
#include <string>
#include <unordered_map>
#include <thread>
#include <chrono>
using namespace std::literals::chrono_literals;
#ifdef _WIN32
#define NOMINMAX
#include <Windows.h>
#else
#include <chrono>
#include <sys/mman.h>
#endif
@@ -45,7 +41,6 @@ void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
case logs::level::warning: return "Warning";
case logs::level::notice: return "Notice";
case logs::level::trace: return "Trace";
case logs::level::_uninit: return unknown;
}
return unknown;
@@ -54,32 +49,23 @@ void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
namespace logs
{
// Memory-mapped buffer size
constexpr u64 s_log_size = 32 * 1024 * 1024;
constexpr std::size_t s_log_size = 128 * 1024 * 1024;
constexpr std::size_t s_log_size_s = s_log_size / 2;
constexpr std::size_t s_log_size_t = s_log_size / 4 + s_log_size_s;
constexpr std::size_t s_log_size_e = s_log_size / 8 + s_log_size_t;
constexpr std::size_t s_log_size_f = s_log_size / 16 + s_log_size_e;
class file_writer
{
fs::file m_file;
std::string m_name;
std::thread m_writer;
fs::file m_fout;
fs::file m_fout2;
u64 m_max_size;
#ifdef _WIN32
::HANDLE m_fmap;
#endif
atomic_t<std::size_t> m_pos{0};
std::size_t m_size{0};
uchar* m_fptr{};
z_stream m_zs{};
semaphore<> m_m;
alignas(128) atomic_t<u64> m_buf{0}; // MSB (40 bit): push begin, LSB (24 bis): push size
alignas(128) atomic_t<u64> m_out{0}; // Amount of bytes written to file
uchar m_zout[65536];
// Write buffered logs immediately
bool flush(u64 bufv);
public:
file_writer(const std::string& name);
@@ -133,7 +119,7 @@ namespace logs
static file_listener* get_logger()
{
// Use magic static
static file_listener logger("RPCS3");
static file_listener logger("RPCS3.log");
return &logger;
}
@@ -305,45 +291,13 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
logs::file_writer::file_writer(const std::string& name)
: m_name(name)
{
const std::string log_name = fs::get_config_dir() + name + ".log";
const std::string buf_name = fs::get_config_dir() + name + ".buf";
try
{
if (!m_file.open(buf_name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
if (!m_file.open(fs::get_config_dir() + name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
{
if (fs::g_tls_error == fs::error::acces)
{
if (fs::exists(buf_name))
{
fmt::throw_exception("Another instance of %s is running. Close it or kill its process, if necessary.", name);
}
else
{
fmt::throw_exception("Cannot create %s.log (access denied)."
#ifdef _WIN32
"\nNote that %s cannot be installed in Program Files or similar directory with limited permissions."
#else
"\nPlease, check %s permissions in '~/.config/'."
#endif
, name, name);
}
}
fmt::throw_exception("Cannot create %s.log (error %s)", name, fs::g_tls_error);
fmt::throw_exception("Can't create file %s (error %s)", name, fs::g_tls_error);
}
// Check free space
fs::device_stat stats{};
if (!fs::statfs(fs::get_config_dir(), stats) || stats.avail_free < s_log_size * 8)
{
fmt::throw_exception("Not enough free space (%f KB)", stats.avail_free / 1000000.);
}
// Limit log size to ~25% of free space
m_max_size = stats.avail_free / 4;
// Initialize memory mapped file
#ifdef _WIN32
m_fmap = CreateFileMappingW(m_file.get_handle(), 0, PAGE_READWRITE, s_log_size >> 32, s_log_size & 0xffffffff, 0);
m_fptr = m_fmap ? (uchar*)MapViewOfFile(m_fmap, FILE_MAP_WRITE, 0, 0, 0) : nullptr;
@@ -353,94 +307,44 @@ logs::file_writer::file_writer(const std::string& name)
#endif
verify(name.c_str()), m_fptr;
std::memset(m_fptr, '\n', s_log_size);
// Rotate backups (TODO)
fs::remove_file(fs::get_config_dir() + name + "1.log.gz");
fs::remove_file(fs::get_config_dir() + name + "1.gz");
fs::create_dir(fs::get_config_dir() + "old_logs");
fs::rename(fs::get_config_dir() + m_name + ".log.gz", fs::get_config_dir() + "old_logs/" + m_name + ".log.gz", true);
// Actual log file (allowed to fail)
m_fout.open(log_name, fs::rewrite);
// Compressed log
if (!m_fout2.open(log_name + ".gz", fs::rewrite) || deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
{
m_fout2.close();
}
}
catch (const std::exception& e)
{
std::thread([text = std::string{e.what()}]{ report_fatal_error(text); }).detach();
return;
fs::rename(fs::get_config_dir() + m_name + ".gz", fs::get_config_dir() + "old_logs/" + m_name + ".gz", true);
}
catch (...)
{
std::thread([]{ report_fatal_error("Unknown error" HERE); }).detach();
return;
catch_all_exceptions();
}
m_writer = std::thread([this]()
{
thread_ctrl::set_native_priority(-1);
while (true)
{
const u64 bufv = m_buf;
if (bufv & 0xffffff)
{
// Wait if threads are writing logs
std::this_thread::yield();
continue;
}
if (!flush(bufv))
{
if (m_out == -1)
{
break;
}
std::this_thread::sleep_for(10ms);
}
}
});
}
logs::file_writer::~file_writer()
{
if (!m_fptr)
if (m_size == 0)
{
return;
m_size = std::min<std::size_t>(+m_pos, s_log_size);
}
// Stop writer thread
while (m_out << 24 < m_buf)
// Compress
z_stream zs{};
if (deflateInit2(&zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) == Z_OK)
{
std::this_thread::yield();
}
auto buf = std::make_unique<uchar[]>(s_log_size);
zs.avail_in = ::narrow<u32>(m_size);
zs.avail_out = s_log_size;
zs.next_in = m_fptr;
zs.next_out = buf.get();
m_out = -1;
m_writer.join();
if (m_fout2)
{
m_zs.avail_in = 0;
m_zs.next_in = nullptr;
do
if (deflate(&zs, Z_FINISH) != Z_STREAM_ERROR)
{
m_zs.avail_out = sizeof(m_zout);
m_zs.next_out = m_zout;
if (deflate(&m_zs, Z_FINISH) == Z_STREAM_ERROR || m_fout2.write(m_zout, sizeof(m_zout) - m_zs.avail_out) != sizeof(m_zout) - m_zs.avail_out)
{
break;
}
fs::file(fs::get_config_dir() + m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
}
while (m_zs.avail_out == 0);
deflateEnd(&m_zs);
if (deflateEnd(&zs) != Z_OK)
{
}
}
#ifdef _WIN32
@@ -449,109 +353,33 @@ logs::file_writer::~file_writer()
#else
::munmap(m_fptr, s_log_size);
#endif
}
bool logs::file_writer::flush(u64 bufv)
{
semaphore_lock lock(m_m);
const u64 st = +m_out;
const u64 end = std::min<u64>((st + s_log_size) & ~(s_log_size - 1), bufv >> 24);
if (end > st)
{
// Avoid writing too big fragments
const u64 size = std::min<u64>(end - st, sizeof(m_zout) / 2);
// Write uncompressed
if (m_fout && st < m_max_size && m_fout.write(m_fptr + st % s_log_size, size) != size)
{
m_fout.close();
}
// Write compressed
if (m_fout2 && st < m_max_size)
{
m_zs.avail_in = size;
m_zs.next_in = m_fptr + st % s_log_size;
do
{
m_zs.avail_out = sizeof(m_zout);
m_zs.next_out = m_zout;
if (deflate(&m_zs, Z_NO_FLUSH) == Z_STREAM_ERROR || m_fout2.write(m_zout, sizeof(m_zout) - m_zs.avail_out) != sizeof(m_zout) - m_zs.avail_out)
{
deflateEnd(&m_zs);
m_fout2.close();
break;
}
}
while (m_zs.avail_out == 0);
}
m_out += size;
return true;
}
return false;
m_file.trunc(m_size);
}
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
{
if (!m_fptr)
// Adaptive log limit
const auto lim =
sev >= logs::level::success ? s_log_size_s :
sev == logs::level::todo ? s_log_size_t :
sev == logs::level::error ? s_log_size_e : s_log_size_f;
if (m_pos >= lim)
{
return;
}
// TODO: write bigger fragment directly in blocking manner
while (size && size <= 0xffffff)
// Acquire memory
const auto pos = m_pos.fetch_add(size);
// Write if possible
if (pos + size <= s_log_size)
{
u64 bufv;
const auto pos = m_buf.atomic_op([&](u64& v) -> uchar*
{
const u64 v1 = v >> 24;
const u64 v2 = v & 0xffffff;
if (UNLIKELY(v2 + size > 0xffffff || v1 + v2 + size >= m_out + s_log_size))
{
bufv = v;
return nullptr;
}
v += size;
return m_fptr + (v1 + v2) % s_log_size;
});
if (UNLIKELY(!pos))
{
if ((bufv & 0xffffff) + size > 0xffffff || bufv & 0xffffff)
{
// Concurrency limit reached
std::this_thread::yield();
}
else
{
// Queue is full, need to write out
flush(bufv);
}
continue;
}
if (pos + size > m_fptr + s_log_size)
{
const auto frag = m_fptr + s_log_size - pos;
std::memcpy(pos, text, frag);
std::memcpy(m_fptr, text + frag, size - frag);
}
else
{
std::memcpy(pos, text, size);
}
m_buf += (u64{size} << 24) - size;
break;
std::memcpy(m_fptr + pos, text, size);
}
else if (pos <= s_log_size)
{
m_size = pos;
}
}
@@ -589,7 +417,6 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
case level::warning: text = u8"·W "; break;
case level::notice: text = u8"·! "; break;
case level::trace: text = u8"·T "; break;
case level::_uninit: text = u8"· "; break;
}
// Print miscosecond timestamp
-6
View File
@@ -24,12 +24,6 @@ inline void strcpy_trunc(char (&dst)[N], const char (&src)[N2])
dst[count] = '\0';
}
template <std::size_t N>
inline bool ends_with(const std::string& src, const char (&end)[N])
{
return src.size() >= N - 1 && src.compare(src.size() - (N - 1), N - 1, end, N - 1) == 0;
}
namespace fmt
{
std::string replace_first(const std::string& src, const std::string& from, const std::string& to);
+47 -144
View File
@@ -6,9 +6,7 @@
#include "Emu/Cell/lv2/sys_mmapper.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Thread.h"
#include "sysinfo.h"
#include <typeinfo>
#include <thread>
#ifdef _WIN32
#include <Windows.h>
@@ -18,12 +16,6 @@
#ifdef __APPLE__
#define _XOPEN_SOURCE
#define __USE_GNU
#include <mach/thread_act.h>
#include <mach/thread_policy.h>
#endif
#if defined(__DragonFly__) || defined(__FreeBSD__)
#include <pthread_np.h>
#define cpu_set_t cpuset_t
#endif
#include <errno.h>
#include <signal.h>
@@ -39,6 +31,32 @@ thread_local u64 g_tls_fault_all = 0;
thread_local u64 g_tls_fault_rsx = 0;
thread_local u64 g_tls_fault_spu = 0;
static void report_fatal_error(const std::string& msg)
{
static semaphore<> g_report_only_once;
g_report_only_once.wait();
std::string _msg = msg + "\n"
"HOW TO REPORT ERRORS: https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support\n"
"Please, don't send incorrect reports. Thanks for understanding.\n";
#ifdef _WIN32
_msg += "\nPress Yes or Enter to visit the URL above immediately.";
const std::size_t buf_size = _msg.size() + 1;
const int size = static_cast<int>(buf_size);
std::unique_ptr<wchar_t[]> buffer(new wchar_t[buf_size]);
MultiByteToWideChar(CP_UTF8, 0, _msg.c_str(), size, buffer.get(), size);
if (MessageBoxW(0, buffer.get(), L"Fatal error", MB_ICONERROR | MB_YESNO) == IDYES)
{
ShellExecuteW(0, L"open", L"https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support", 0, 0, SW_SHOWNORMAL);
}
#else
std::printf("Fatal error: \n%s", _msg.c_str());
#endif
}
[[noreturn]] void catch_all_exceptions()
{
try
@@ -53,6 +71,8 @@ thread_local u64 g_tls_fault_spu = 0;
{
report_fatal_error("Unhandled exception (unknown)");
}
std::abort();
}
enum x64_reg_t : u32
@@ -965,8 +985,8 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v
// save the value into x64 register
switch (d_size)
{
case 1: *X64REG(context, reg - X64R_RAX) = (value & 0xff) | (*X64REG(context, reg - X64R_RAX) & 0xffffff00); return true;
case 2: *X64REG(context, reg - X64R_RAX) = (value & 0xffff) | (*X64REG(context, reg - X64R_RAX) & 0xffff0000); return true;
case 1: *X64REG(context, reg - X64R_RAX) = value & 0xff | *X64REG(context, reg - X64R_RAX) & 0xffffff00; return true;
case 2: *X64REG(context, reg - X64R_RAX) = value & 0xffff | *X64REG(context, reg - X64R_RAX) & 0xffff0000; return true;
case 4: *X64REG(context, reg - X64R_RAX) = value & 0xffffffff; return true;
case 8: *X64REG(context, reg - X64R_RAX) = value; return true;
}
@@ -1471,11 +1491,13 @@ const bool s_exception_handler_set = []() -> bool
if (!AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)exception_handler))
{
report_fatal_error("AddVectoredExceptionHandler() failed.");
std::abort();
}
if (!SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exception_filter))
{
report_fatal_error("SetUnhandledExceptionFilter() failed.");
std::abort();
}
return true;
@@ -1522,6 +1544,7 @@ static void signal_handler(int sig, siginfo_t* info, void* uct)
// TODO (debugger interaction)
report_fatal_error(fmt::format("Segfault %s location %p at %p.", cause, info->si_addr, RIP(context)));
std::abort();
}
const bool s_exception_handler_set = []() -> bool
@@ -1549,8 +1572,6 @@ thread_local DECLARE(thread_ctrl::g_tls_this_thread) = nullptr;
extern thread_local std::string(*g_tls_log_prefix)();
DECLARE(thread_ctrl::g_native_core_layout) { native_core_arrangement::undefined };
void thread_ctrl::start(const std::shared_ptr<thread_ctrl>& ctrl, task_stack task)
{
#ifdef _WIN32
@@ -1747,7 +1768,7 @@ bool thread_ctrl::_wait_for(u64 usec)
}
}
}
while (_this->m_cond.wait(_lock, std::exchange(usec, usec > cond_variable::max_timeout ? -1 : 0)));
while (_this->m_cond.wait(_lock, std::exchange(usec, usec == -1 ? -1 : 0)));
// Timeout
return false;
@@ -1857,156 +1878,38 @@ void thread_ctrl::test()
}
}
void thread_ctrl::detect_cpu_layout()
{
if (!g_native_core_layout.compare_and_swap_test(native_core_arrangement::undefined, native_core_arrangement::generic))
return;
const auto system_id = utils::get_system_info();
if (system_id.find("Ryzen") != std::string::npos)
{
g_native_core_layout.store(native_core_arrangement::amd_ccx);
}
else if (system_id.find("i3") != std::string::npos || system_id.find("i7") != std::string::npos)
{
g_native_core_layout.store(native_core_arrangement::intel_ht);
}
}
u16 thread_ctrl::get_affinity_mask(thread_class group)
{
detect_cpu_layout();
if (const auto thread_count = std::thread::hardware_concurrency())
{
const u16 all_cores_mask = thread_count < 16 ? (u16)(~(UINT16_MAX << thread_count)): UINT16_MAX;
switch (g_native_core_layout)
{
default:
case native_core_arrangement::generic:
{
return all_cores_mask;
}
case native_core_arrangement::amd_ccx:
{
u16 spu_mask, ppu_mask, rsx_mask;
if (thread_count >= 16)
{
// Threadripper, R7
// Assign threads 8-16
// It appears some windows code is bound to lower core addresses, binding 8-16 is alot faster than 0-7
ppu_mask = spu_mask = 0b1111111100000000;
rsx_mask = all_cores_mask;
}
else if (thread_count == 12)
{
// 1600/2600 (x)
ppu_mask = spu_mask = 0b111111000000;
rsx_mask = all_cores_mask;
}
else
{
// R5 & R3 don't seem to improve performance no matter how these are shuffled
ppu_mask = spu_mask = rsx_mask = 0b11111111 & all_cores_mask;
}
switch (group)
{
default:
case thread_class::general:
return all_cores_mask;
case thread_class::rsx:
return rsx_mask;
case thread_class::ppu:
return ppu_mask;
case thread_class::spu:
return spu_mask;
}
}
case native_core_arrangement::intel_ht:
{
if (thread_count <= 4)
{
//i3 or worse
switch (group)
{
case thread_class::rsx:
case thread_class::ppu:
return (0b0101 & all_cores_mask);
case thread_class::spu:
return (0b1010 & all_cores_mask);
case thread_class::general:
return all_cores_mask;
}
}
return all_cores_mask;
}
}
}
return UINT16_MAX;
}
void thread_ctrl::set_native_priority(int priority)
{
#ifdef _WIN32
HANDLE _this_thread = GetCurrentThread();
INT native_priority = THREAD_PRIORITY_NORMAL;
if (priority > 0)
switch (priority)
{
default:
case 0:
break;
case 1:
native_priority = THREAD_PRIORITY_ABOVE_NORMAL;
if (priority < 0)
break;
case -1:
native_priority = THREAD_PRIORITY_BELOW_NORMAL;
if (!SetThreadPriority(_this_thread, native_priority))
{
LOG_ERROR(GENERAL, "SetThreadPriority() failed: 0x%x", GetLastError());
break;
}
#else
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, &param);
if (priority > 0)
param.sched_priority = sched_get_priority_max(policy);
if (priority < 0)
param.sched_priority = sched_get_priority_min(policy);
if (int err = pthread_setschedparam(pthread_self(), policy, &param))
{
LOG_ERROR(GENERAL, "pthraed_setschedparam() failed: %d", err);
}
SetThreadPriority(_this_thread, native_priority);
#endif
}
void thread_ctrl::set_thread_affinity_mask(u16 mask)
void thread_ctrl::set_ideal_processor_core(int core)
{
#ifdef _WIN32
HANDLE _this_thread = GetCurrentThread();
SetThreadAffinityMask(_this_thread, (DWORD_PTR)mask);
#elif __APPLE__
thread_affinity_policy_data_t policy = { static_cast<integer_t>(mask) };
thread_port_t mach_thread = pthread_mach_thread_np(pthread_self());
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1);
#elif defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__)
cpu_set_t cs;
CPU_ZERO(&cs);
for (u32 core = 0; core < 16u; ++core)
{
if ((u32)mask & (1u << core))
{
CPU_SET(core, &cs);
}
}
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs);
SetThreadIdealProcessor(_this_thread, core);
#endif
}
named_thread::named_thread()
{
}
+1 -33
View File
@@ -10,29 +10,9 @@
#include "sema.h"
#include "cond.h"
// Report error and call std::abort(), defined in main.cpp
[[noreturn]] void report_fatal_error(const std::string&);
// Will report exception and call std::abort() if put in catch(...)
[[noreturn]] void catch_all_exceptions();
// Hardware core layout
enum class native_core_arrangement : u32
{
undefined,
generic,
intel_ht,
amd_ccx
};
enum class thread_class : u32
{
general,
rsx,
spu,
ppu
};
// Simple list of void() functors
class task_stack
{
@@ -108,9 +88,6 @@ class thread_ctrl final
// Current thread
static thread_local thread_ctrl* g_tls_this_thread;
// Target cpu core layout
static atomic_t<native_core_arrangement> g_native_core_layout;
// Self pointer
std::shared_ptr<thread_ctrl> m_self;
@@ -254,17 +231,8 @@ public:
thread_ctrl::start(out, std::forward<F>(func));
}
// Detect layout
static void detect_cpu_layout();
// Returns a core affinity mask. Set whether to generate the high priority set or not
static u16 get_affinity_mask(thread_class group);
// Sets the native thread priority
static void set_native_priority(int priority);
// Sets the preferred affinity mask for this thread
static void set_thread_affinity_mask(u16 mask);
static void set_ideal_processor_core(int core);
};
class named_thread
+3 -13
View File
@@ -32,23 +32,13 @@ void patch_engine::append(const std::string& patch)
{
if (fs::file f{patch})
{
YAML::Node root;
try
{
root = YAML::Load(f.to_string());
}
catch (const std::exception& e)
{
LOG_FATAL(GENERAL, "Failed to load patch file %s\n%s thrown: %s", patch, typeid(e).name(), e.what());
return;
}
auto root = YAML::Load(f.to_string());
for (auto pair : root)
{
auto& name = pair.first.Scalar();
auto& data = m_map[name];
for (auto patch : pair.second)
{
u64 type64 = 0;
@@ -101,7 +91,7 @@ void patch_engine::append(const std::string& patch)
break;
}
}
data.emplace_back(info);
}
}
+3 -4
View File
@@ -10,13 +10,12 @@
bool cond_variable::imp_wait(u32 _old, u64 _timeout) noexcept
{
verify(HERE), _old != -1; // Very unlikely: it requires 2^32 distinct threads to wait simultaneously
const bool is_inf = _timeout > max_timeout;
#ifdef _WIN32
LARGE_INTEGER timeout;
timeout.QuadPart = _timeout * -10;
if (HRESULT rc = NtWaitForKeyedEvent(nullptr, &m_value, false, is_inf ? nullptr : &timeout))
if (HRESULT rc = NtWaitForKeyedEvent(nullptr, &m_value, false, _timeout == -1 ? nullptr : &timeout))
{
verify(HERE), rc == WAIT_TIMEOUT;
@@ -38,12 +37,12 @@ bool cond_variable::imp_wait(u32 _old, u64 _timeout) noexcept
for (u32 value = _old + 1;; value = m_value)
{
const int err = futex((int*)&m_value.raw(), FUTEX_WAIT_PRIVATE, value, is_inf ? nullptr : &timeout, nullptr, 0) == 0
const int err = futex((int*)&m_value.raw(), FUTEX_WAIT_PRIVATE, value, _timeout == -1 ? nullptr : &timeout, nullptr, 0) == 0
? 0
: errno;
// Normal or timeout wakeup
if (!err || (!is_inf && err == ETIMEDOUT))
if (!err || (_timeout != -1 && err == ETIMEDOUT))
{
// Cleanup (remove waiter)
verify(HERE), m_value--;
-2
View File
@@ -47,6 +47,4 @@ public:
imp_wake(-1);
}
}
static constexpr u64 max_timeout = u64{UINT32_MAX} / 1000 * 1000000;
};
+5 -30
View File
@@ -13,10 +13,9 @@ rem // A copy of the GPL 2.0 should have been included with the program.
rem // If not, see http://www.gnu.org/licenses/
rem // Official git repository and contact information can be found at
rem // https://github.com/RPCS3/rpcs3 and https://rpcs3.net/.
rem // https://github.com/RPCS3/rpcs3 and http://rpcs3.net/.
setlocal ENABLEDELAYEDEXPANSION
setlocal ENABLEEXTENSIONS
set GIT_VERSION_FILE=%~p0..\rpcs3\git-version.h
if not defined GIT (
@@ -55,33 +54,9 @@ if errorlevel 1 (
goto done
)
rem // Get commit count from (unshallowed) HEAD
for /F %%I IN ('call %GIT% rev-list HEAD --count') do set COMMIT_COUNT=%%I
rem // If we're in AppVeyor, building a non-master, pull request artifact
if defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
if "%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"=="master" (
rem // If pull request comes from a master branch, GIT_BRANCH = username/branch in order to distinguish from upstream/master
for /f "tokens=1* delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set user=%%a
set "GIT_BRANCH=!user!/%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"
) else (
rem // Otherwise, GIT_BRANCH=branch
set GIT_BRANCH=%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%
)
rem // Make GIT_VERSION the last commit (shortened); Don't include commit count on non-master builds
for /F %%I IN ('call %GIT% rev-parse --short HEAD') do set GIT_VERSION=%%I
) else (
rem // Get last commit (shortened) and concat after commit count in GIT_VERSION
for /F %%I IN ('call %GIT% rev-parse --short HEAD') do set GIT_VERSION=%COMMIT_COUNT%-%%I
for /F %%I IN ('call %GIT% rev-parse --abbrev-ref HEAD') do set GIT_BRANCH=%%I
)
rem // Echo obtained GIT_VERSION for debug purposes if needed
echo %GIT_VERSION%
for /F %%I IN ('call %GIT% rev-list HEAD --count') do set GIT_VERSION=%%I
for /F %%I IN ('call %GIT% rev-parse --short HEAD') do set GIT_VERSION=%GIT_VERSION%-%%I
for /F %%I IN ('call %GIT% rev-parse --abbrev-ref HEAD') do set GIT_BRANCH=%%I
rem // Don't modify the file if it already has the current version.
if exist "%GIT_VERSION_FILE%" (
@@ -94,7 +69,7 @@ if exist "%GIT_VERSION_FILE%" (
echo // This is a generated file. > "%GIT_VERSION_FILE%"
echo. >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_VERSION "%GIT_VERSION%" >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_BRANCH ^"%GIT_BRANCH%^" >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_BRANCH "%GIT_BRANCH%" >> "%GIT_VERSION_FILE%"
echo. >> "%GIT_VERSION_FILE%"
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
-53
View File
@@ -7,44 +7,6 @@
#include <unistd.h>
#endif
bool utils::has_ssse3()
{
static const bool g_value = get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x200;
return g_value;
}
bool utils::has_avx()
{
static const bool g_value = get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000;
return g_value;
}
bool utils::has_avx2()
{
static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && get_cpuid(7, 0)[1] & 0x20;
return g_value;
}
bool utils::has_rtm()
{
// Check RTM and MPX extensions in order to filter out TSX on Haswell CPUs
static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0x4800) == 0x4800;
return g_value;
}
bool utils::has_512()
{
// Check AVX512F, AVX512CD, AVX512DQ, AVX512BW, AVX512VL extensions (Skylake-X level support)
static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0xd0030000) == 0xd0030000;
return g_value;
}
bool utils::has_xop()
{
static const bool g_value = has_avx() && get_cpuid(0x80000001, 0)[2] & 0x800;
return g_value;
}
std::string utils::get_system_info()
{
std::string result;
@@ -88,21 +50,6 @@ std::string utils::get_system_info()
if (has_avx())
{
result += " | AVX";
if (has_avx2())
{
result += '+';
}
if (has_512())
{
result += '+';
}
if (has_xop())
{
result += 'x';
}
}
if (has_rtm())
+16 -12
View File
@@ -8,25 +8,29 @@ namespace utils
inline std::array<u32, 4> get_cpuid(u32 func, u32 subfunc)
{
int regs[4];
#ifdef _MSC_VER
#ifdef _MSC_VER
__cpuidex(regs, func, subfunc);
#else
#else
__asm__ volatile("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (func), "c" (subfunc));
#endif
#endif
return {0u+regs[0], 0u+regs[1], 0u+regs[2], 0u+regs[3]};
}
bool has_ssse3();
inline bool has_ssse3()
{
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x200;
}
bool has_avx();
inline bool has_avx()
{
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000;
}
bool has_avx2();
bool has_rtm();
bool has_512();
bool has_xop();
inline bool has_rtm()
{
// Check RTM and MPX extensions in order to filter out TSX on Haswell CPUs
return get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0x4800) == 0x4800;
}
inline bool transaction_enter()
{
+1 -21
View File
@@ -48,7 +48,7 @@
#define CONCATENATE_DETAIL(x, y) x ## y
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
#define STRINGIZE_DETAIL(x) #x ""
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
#define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")"
@@ -534,26 +534,6 @@ inline u64 cntlz64(u64 arg, bool nonzero = false)
#endif
}
inline u32 cnttz32(u32 arg, bool nonzero = false)
{
#ifdef _MSC_VER
ulong res;
return _BitScanForward(&res, arg) || nonzero ? res : 32;
#else
return arg || nonzero ? __builtin_ctzll(arg) : 32;
#endif
}
inline u64 cnttz64(u64 arg, bool nonzero = false)
{
#ifdef _MSC_VER
ulong res;
return _BitScanForward64(&res, arg) || nonzero ? res : 64;
#else
return arg || nonzero ? __builtin_ctzll(arg) : 64;
#endif
}
// Helper function, used by ""_u16, ""_u32, ""_u64
constexpr u8 to_u8(char c)
{
-17
View File
@@ -12,7 +12,6 @@
#include <utility>
#include "recursive_wrapper.hpp"
#include "variant_visitor.hpp"
// clang-format off
// [[deprecated]] is only available in C++14, use this for the time being
@@ -850,22 +849,6 @@ namespace std {
return detail::binary_dispatcher<F, V, R, Types...>::apply(v0, v1, std::forward<F>(f));
}
// match
// unary
template <typename... Fs>
auto VARIANT_INLINE match(Fs&&... fs) const
-> decltype(variant::visit(*this, ::std::make_visitor(std::forward<Fs>(fs)...)))
{
return variant::visit(*this, ::std::make_visitor(std::forward<Fs>(fs)...));
}
// non-const
template <typename... Fs>
auto VARIANT_INLINE match(Fs&&... fs)
-> decltype(variant::visit(*this, ::std::make_visitor(std::forward<Fs>(fs)...)))
{
return variant::visit(*this, ::std::make_visitor(std::forward<Fs>(fs)...));
}
~variant() noexcept // no-throw destructor
{
helper_type::destroy(type_index, &data);
-45
View File
@@ -1,45 +0,0 @@
#ifndef MAPBOX_UTIL_VARIANT_VISITOR_HPP
#define MAPBOX_UTIL_VARIANT_VISITOR_HPP
#include <utility>
//namespace mapbox {
//namespace util {
namespace std {
template <typename... Fns>
struct visitor;
template <typename Fn>
struct visitor<Fn> : Fn
{
using Fn::operator();
template<typename T>
visitor(T&& fn) : Fn(std::forward<T>(fn)) {}
};
template <typename Fn, typename... Fns>
struct visitor<Fn, Fns...> : Fn, visitor<Fns...>
{
using Fn::operator();
using visitor<Fns...>::operator();
template<typename T, typename... Ts>
visitor(T&& fn, Ts&&... fns)
: Fn(std::forward<T>(fn))
, visitor<Fns...>(std::forward<Ts>(fns)...) {}
};
template <typename... Fns>
visitor<typename std::decay<Fns>::type...> make_visitor(Fns&&... fns)
{
return visitor<typename std::decay<Fns>::type...>
(std::forward<Fns>(fns)...);
}
}
//} // namespace util
//} // namespace mapbox
#endif // MAPBOX_UTIL_VARIANT_VISITOR_HPP
+1 -1
View File
@@ -19,7 +19,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+8 -12
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,24 +39,20 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
-13
View File
@@ -1,13 +0,0 @@
@ECHO OFF
REM Setting up dummy git helper
MKDIR ..\Vulkan-LoaderAndValidationLayers\external\glslang\External\spirv-tools
SET header="@ECHO off"
SET content="ECHO unused"
ECHO %header:"=% > git.bat
ECHO %content:"=% >> git.bat
COPY /Y git.bat ..\Vulkan-LoaderAndValidationLayers\external\glslang\External\spirv-tools\git.bat
REM Set up gitignore
SET ignored="*"
ECHO %ignored:"=% > ..\Vulkan-LoaderAndValidationLayers\external\glslang\External\spirv-tools\.gitignore
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,24 +39,24 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
+39 -95
View File
@@ -1,100 +1,44 @@
version: '0.0.3-{build}'
version: '{build}'
image: Visual Studio 2015
environment:
QTDIR: C:\Qt\5.10.0\msvc2015_64
LLVMLIBS: https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8
VULKAN: https://drive.google.com/uc?export=download&id=1A2eOMmCO714i0U7J0qI4aEMKnuWl8l_R
COMPATDB: https://rpcs3.net/compatibility?api=v1&export
cache:
- llvmlibs.7z -> appveyor.yml
- vulkan.7z -> appveyor.yml
- compat_database.dat
install:
- ps: | # set env vars for versioning
$commDate = $env:APPVEYOR_REPO_COMMIT_TIMESTAMP.Substring(0,10)
$commSha = $env:APPVEYOR_REPO_COMMIT.Substring(0,8)
$commTag = $(git describe --tags $(git rev-list --tags --max-count=1))
$env:AVVER = "{0}-{1}" -f $commTag.TrimStart("v"), $env:APPVEYOR_BUILD_NUMBER
$env:BUILD = "rpcs3-{0}-{1}-{2}_win64.7z" -f $commTag, $commDate, $commSha
- ps: | # used for experimental build warnings for pr builds
$env:BRANCH = "{0}/{1}/#{2}" -f $env:APPVEYOR_REPO_NAME, `
$env:APPVEYOR_REPO_BRANCH, $env:APPVEYOR_PULL_REQUEST_NUMBER
$env:BRANCH = $env:BRANCH -replace "/#$"
- ps: | # misc global settings
$env:PATH += $env:QTDIR
[net.servicepointmanager]::securityprotocol = "tls12, tls11, tls"
- ps: | # update and init submodules
git submodule -q update --init `
3rdparty/cereal `
3rdparty/ffmpeg `
3rdparty/GSL `
3rdparty/hidapi `
3rdparty/libpng `
3rdparty/Optional `
3rdparty/pugixml `
3rdparty/zlib `
asmjit `
Utilities/yaml-cpp `
Vulkan/glslang `
Vulkan/Vulkan-LoaderAndValidationLayers
os: Visual Studio 2017
platform: x64
configuration: Release - LLVM
build:
parallel: true
project: rpcs3.sln
verbosity: normal
before_build:
- ps: | # fetch precompiled build dependencies
if (!(test-path llvmlibs.7z)) { irm $env:LLVMLIBS -outfile llvmlibs.7z }
if (!(test-path vulkan.7z)) { irm $env:VULKAN -outfile vulkan.7z }
7z x llvmlibs.7z -aos -o"." | out-null
7z x vulkan.7z -aos -o".\lib\$env:CONFIGURATION-$env:PLATFORM" | out-null
after_build:
- ps: | # remove unnecessary files
rm .\bin\rpcs3.exp, .\bin\rpcs3.lib, .\bin\rpcs3.pdb
- ps: | # prepare compatibility database for packaging
$db = irm $env:COMPATDB -erroraction silentlycontinue
if ($db -and $db.return_code -eq 0) {
$db | convertto-json -compress | out-file compat_database.dat -encoding utf8
}
copy-item compat_database.dat .\bin\GuiConfigs\compat_database.dat
- ps: | # package artifacts
7z a -m0=LZMA2 -mx9 $env:BUILD .\bin\*
7z a -m0=LZMA2 -mx9 openssl_win64.7z C:\OpenSSL-Win64\bin\libeay32.dll `
C:\OpenSSL-Win64\bin\ssleay32.dll
- ps: | # generate sha256 hashes
(Get-FileHash $env:BUILD -Algorithm SHA256).Hash | Out-File -encoding ASCII "$($env:BUILD).sha256"
(Get-FileHash openssl_win64.7z -Algorithm SHA256).Hash | Out-File -encoding ASCII "openssl_win64.7z.sha256"
clone_folder: C:\rpcs3
clone_depth: 3
test: off
artifacts:
- path: $(BUILD)
name: rpcs3
- path: $(BUILD).sha256
name: rpcs3 sha256 hash
- path: openssl_win64.7z
name: openssl
- path: openssl_win64.7z.sha256
name: openssl sha256 hash
configuration:
# Release
- ReleaseLLVM
on_finish:
- ps: | # update appveyor build version, done last to prevent webhook breakage
update-appveyorbuild -version $env:AVVER
before_build:
- ps: $env:Date="$(git show -s --date=short --format='%ad')"
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp 3rdparty/cereal 3rdparty/zlib 3rdparty/hidapi 3rdparty/Optional
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
- set CXXFLAGS=-DBRANCH=%BRANCH%
- if %configuration%==Release (cmake -G "Visual Studio 15 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 15 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
build_script:
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
install:
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B-BE73aaGDNxdG1PM1JPb0hNeHM" -FileName llvmlibs.7z
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
- if not exist zlib.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B-HVE3xvheVFX05lRFdnZlh5aUU" -FileName zlib.7z
- set QTDIR=C:\Qt\5.9.1\msvc2017_64
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
- set PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%QTDIR%;%PATH%
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
artifacts:
- path: bin
name: 'rpcs3-v0.0.3-$(Date)-$(COMMIT_SHA)_win64'
type: zip
cache:
- llvmlibs.7z -> appveyor.yml
- vulkan.7z -> appveyor.yml
- zlib.7z -> appveyor.yml
+1 -1
Submodule asmjit updated: 673dcefaa0...1370fe6a26
+1 -1
View File
@@ -93,7 +93,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -1,332 +0,0 @@
/*
TheMitoSan Dark-Theme for RPCS3
Based on Kuroi (Dark) by Ani
by themitosan @ twitter.com/themitosan
Ani @ https://github.com/AniLeo
(2017.11.14)
*/
/* Every widget */
QWidget {
background-color: #131313;
color: #FFF;
alternate-background-color: #212121;
}
/* Mouse tooltips */
QToolTip {
padding: 0.125em;
border: 0.0625em #444;
background-color: #222;
color: #FFF;
}
/* Table headers */
QHeaderView::section {
background-color: #010101;
color: #ecf0f1;
padding-left: 0.25em;
border: 0.0525em solid #FFF;
}
/* Settings Dialog: Tabs */
QTabBar::tab {
color: #ecf0f1;
border: 0.0625em solid #444;
border-bottom-style: none;
background-color: #353535;
padding-left: 1em;
padding-right: 1em;
padding-top: 0.25em;
padding-bottom: 0.25em;
margin-right: -0.125em;
border-top-left-radius: 0.25em;
border-top-right-radius: 0.25em;
}
QTabBar::tab:last {
margin-right: 0em;
}
QTabBar::tab:!selected {
color: #888;
border-bottom-style: solid;
margin-top: 0.1875em;
background-color: #111;
}
QTabBar::tab:hover {
background-color: #353535;
color: #FFF;
}
/* Checkboxes */
QCheckBox::indicator {
border-radius: 0.125em;
border-top-right-radius: 0em;
border-bottom-left-radius: 0em;
border: 0.0625em solid #FFF;
width: 0.8em;
height: 0.8em;
margin-top: 0.0625em;
}
QCheckBox::indicator:checked {
background-color: #FFF; /* White */
}
QCheckBox::indicator:unchecked {
background-color: #000; /* Black */
}
QCheckBox::indicator::disabled {
background-color: #af4949; /* Red */
}
/* Radio Buttons */
QRadioButton::indicator {
border: 0.0625em solid #FFF;
width: 0.8em;
height: 0.8em;
margin-top: 0.0625em;
border-radius: 0.270em;
}
QRadioButton::indicator:checked {
background-color: #FFF; /* Green */
}
QRadioButton::indicator:unchecked {
background-color: #000; /* Red */
}
QRadioButton::indicator::disabled {
background-color: #af4949; /* Gray */
}
/* Combo Boxes */
QComboBox {
background-color: #404040;
color: #fff;
border: 0.0625em solid #1e1e1e;
border-radius: 0.25em;
padding-bottom: 0.125em;
padding-left: 0.25em;
}
QComboBox::disabled {
background-color: #252525;
color: #fff;
}
/* Group Boxes (Settings Dialog) */
QGroupBox {
margin-top: 1em;
font-size: 8pt;
border: 0.05em solid #bdc3c7;
border-radius: 0.3em;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top;
padding: 0.3em 0.5em 0.3em 0.5em;
color: #fff;
}
/* Buttons */
QPushButton {
background-color: #404040;
color: #fff;
}
QPushButton::disabled {
background-color: #353535;
color: #FFF;
}
QPushButton::pressed {
background-color: #333;
}
/* Log and Debugger borders */
QTextEdit {
border: 0.05em solid #353535;
}
/* For dock buttons to be visible */
QDockWidget::close-button, QDockWidget::float-button {
background-color: #bdc3c7;
border: 0.05em solid #000;
border-radius: 0.25em;
width: auto;
}
/* Disable ugly borders */
QTabWidget::pane {
border: 0em solid #353535;
}
/* Top menu bar */
QMenuBar::item:selected {
background: #454545;
border-radius: 0.25em;
}
QMenu::item {
padding-left: 1.5em;
padding-right: 0.75em;
padding-top: 0.25em;
padding-bottom: 0.25em;
border-radius: 0.25em;
margin-bottom: 0.125em;
}
QMenu::item:selected {
background: #444;
border: 0.05em solid #bdc3c7;
border-radius: 0.25em;
}
QMenu::item:disabled {
background-color: #313131;
color: #888888;
border-radius: 0.25em;
}
/* Libraries list */
QListWidget::item:selected {
background-color: #3d3d3d;
color: #ecf0f1;
border-radius: 0.125em;
}
QListWidget::item:hover {
background-color: #4c4b4b;
color: #ecf0f1;
border-radius: 0.25em;
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
color: #FFF;
}
/* Game Grid Font */
QLabel#gamegrid_font {
font-weight: 600;
font-size: 8pt;
font-family: Lucida Grande;
color: #FFF;
}
/* Slider on toolbar */
QWidget#sizeSliderContainer {
background: transparent;
}
/* Debug UI Settings buttons */
QLabel#color_button {
background: transparent;
}
/* Seachbar on main toolbar */
QLineEdit#mw_searchbar {
margin-left: 0.7em;
color: #ecf0f1;
}
/* Uniform colors in Toolbar */
QToolButton {
background: transparent;
color: transparent;
border-radius: 0.125em;
padding: 0.09375em;
margin-left: 0.125em;
margin-top: 0.125em;
margin-bottom: 0.125em;
min-width: 0.063em;
width: auto;
}
QToolButton::disabled {
background-color: #353535;
}
QToolButton::hover {
background-color: #555;
}
/* Set Theme UI colors */
QLabel#gamelist_icon_background_color {
color: transparent;
}
QLabel#gamelist_toolbar_icon_color {
color: #828790;
}
/* Set Windows Taskbar Thumbnail colors */
QLabel#thumbnail_icon_color {
color: #262626;
}
/* Set Log colors */
QTextEdit#log_frame {
background-color: #000; /* Black */
}
QLabel#log_level_always {
color: #00ffff; /* Cyan */
}
QLabel#log_level_fatal {
color: #ff00ff; /* Fuchsia */
}
QLabel#log_level_error {
color: #ff0000; /* Red */
}
QLabel#log_level_todo {
color: #ff6000; /* Orange */
}
QLabel#log_level_success {
color: #00ff00; /* Green */
}
QLabel#log_level_warning {
color: #ffff00; /* Yellow */
}
QLabel#log_level_notice {
color: #ffffff; /* White */
}
QLabel#log_level_trace {
color: #808080; /* Gray */
}
QLabel#log_stack {
color: #ffffff; /* White */
}
/* Set TTY colors */
QTextEdit#tty_frame {
background-color: #000; /* Black */
}
QLabel#tty_text {
color: #fff; /* White */
}
/* RSX Debugger */
QLabel#rsx_debugger_display_buffer {
background-color: #131313;
}
/* Kernel Explorer */
QDialog#kernel_explorer {
background-color: #131313;
}
/* Memory Viewer */
QDialog#memory_viewer {
background-color: #131313;
color: #FFF;
}
QLabel#memory_viewer_address_panel {
color: #00cbff; /* Font Color: Blue */
background-color: #131313;
}
QLabel#memory_viewer_hex_panel {
color: #FFF; /* Font Color: White */
background-color: #131313;
}
QLabel#memory_viewer_ascii_panel {
color: #FFF; /* Font Color: White */
background-color: #131313;
}
/* Debugger colors */
QLabel#debugger_frame_breakpoint {
color: #000; /* Font Color: Black */
background-color: #ffff00; /* Yellow */
}
QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #00ff00; /* Green */
}
+43 -43
View File
@@ -40,7 +40,7 @@ QWidget {
/* Mouse tooltips */
QToolTip {
border: 0.05em solid #323232;
border: 1px solid #323232;
background-color: #323232;
color: #ecf0f1;
}
@@ -49,29 +49,29 @@ QToolTip {
QHeaderView::section {
background-color: #323232;
color: #ecf0f1;
padding-left: 0.2em;
border: 0.05em solid #323232;
padding-left: 4px;
border: 1px solid #323232;
}
/* Settings Dialog: Tabs */
QTabBar::tab {
color: #ecf0f1;
border: 0.05em solid #444;
border: 1px solid #444;
border-bottom-style: none;
background-color: #333333;
padding-left: 0.9em;
padding-right: 0.9em;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin-right: -0.2em;
padding-left: 16px;
padding-right: 16px;
padding-top: 4px;
padding-bottom: 4px;
margin-right: -2px;
}
QTabBar::tab:last {
margin-right: 0em;
margin-right: 0px;
}
QTabBar::tab:!selected {
color: #b1b1b1;
border-bottom-style: solid;
margin-top: 0.15em;
margin-top: 3px;
background-color: #292929;
}
QTabBar::tab:hover {
@@ -81,11 +81,11 @@ QTabBar::tab:hover {
/* Checkboxes */
QCheckBox::indicator {
border-radius: 0.1em;
border: 0.05em solid #ecf0f1;
margin-top: 0.05em;
width: 0.8em;
height: 0.8em;
border-radius: 2px;
border: 1px solid #ecf0f1;
width: 10px;
height: 10px;
margin-top: 1px;
}
QCheckBox::indicator:checked {
background-color: #2ecc71; /* Green */
@@ -99,11 +99,11 @@ QCheckBox::indicator::disabled {
/* Radio Buttons */
QRadioButton::indicator {
border-radius: 0.4em;
border: 0.05em solid;
border-color: white;
width: 0.8em;
height: 0.8em;
border-radius: 6px;
border: 1px solid #ecf0f1;
width: 10px;
height: 10px;
margin-top: 1px;
}
QRadioButton::indicator:checked {
background-color: #2ecc71; /* Green */
@@ -119,10 +119,10 @@ QRadioButton::indicator::disabled {
QComboBox {
background-color: #404040;
color: #fff;
border: 0.05em solid #1e1e1e;
border-radius: 0.15em;
padding-bottom: 0.2em;
padding-left: 0.4em;
border: 1px solid #1e1e1e;
border-radius: 3px;
padding-bottom: 2px;
padding-left: 4px;
}
QComboBox::disabled {
background-color: #828790;
@@ -131,15 +131,15 @@ QComboBox::disabled {
/* Group Boxes (Settings Dialog) */
QGroupBox {
margin-top: 1em;
font-size: 8pt;
border: 0.05em solid #bdc3c7;
border-radius: 0.3em;
margin-top: 17px;
font-size: 13px;
border: 1px solid #bdc3c7;
border-radius: 4px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top;
padding: 0.3em 0.5em 0.3em 0.5em;
subcontrol-position: top center;
padding: 5px 10px 5px 10px;
color: #fff;
}
@@ -154,19 +154,19 @@ QPushButton::disabled {
/* Log and Debugger borders */
QTextEdit {
border: 0.05em solid #828790;
border: 1px solid #828790;
}
/* For dock buttons to be visible */
QDockWidget::close-button, QDockWidget::float-button {
background-color: #bdc3c7;
border: 0.05em solid #000;
border-radius: 0.3em;
border: 1px solid #000;
border-radius: 4px;
}
/* Disable ugly borders */
QTabWidget::pane {
border: 0em solid #828790;
border: 0px solid #828790;
}
/* Top menu bar */
@@ -174,14 +174,14 @@ QMenuBar::item:selected {
background: #444444;
}
QMenu::item {
padding-left: 1.5em;
padding-right: 0.75em;
padding-top: 0.25em;
padding-bottom: 0.25em;
padding-left: 20px;
padding-right: 15px;
padding-top: 4px;
padding-bottom: 4px;
}
QMenu::item:selected {
background: #444444;
border: 0.05em solid #bdc3c7;
border: 1px solid #bdc3c7;
}
QMenu::item:disabled {
background-color: #444444;
@@ -223,7 +223,7 @@ QLabel#color_button {
/* Seachbar on main toolbar */
QLineEdit#mw_searchbar {
margin-left: 0.7em;
margin-left:14px;
color: #ecf0f1;
}
@@ -241,10 +241,10 @@ QToolButton::hover {
/* Set Theme UI colors */
QLabel#gamelist_icon_background_color {
color: transparent;
background-color: #323232;
}
QLabel#gamelist_toolbar_icon_color {
color: #828790;
background-color: #e3e3e3;
}
/* Set Windows Taskbar Thumbnail colors */
@@ -1,329 +0,0 @@
/*
ModernBlue Theme for RPCS3
by themitosan @ twitter.com/themitosan
(2017.12.12)
*/
/* Every widget */
QWidget {
background-color: #232e3a;
color: #fff;
alternate-background-color: #141e28;
}
/* Mouse tooltips */
QToolTip {
padding: 0.125em;
border: 0.0625em #444;
background-color: #181d24;
color: #fff;
}
/* Table headers */
QHeaderView::section {
background-color: #333b44;
color: #ecf0f1;
padding-left: 0.25em;
border: 0.0425em solid #fff;
}
/* Settings Dialog: Tabs */
QTabBar::tab {
color: #ecf0f1;
border: 0.0625em solid #feffff;
border-bottom-style: none;
background-color: #232e3a;
padding-left: 1em;
padding-right: 1em;
padding-top: 0.25em;
padding-bottom: 0.25em;
margin-right: -0.125em;
border-top-left-radius: 0.25em;
border-top-right-radius: 0.25em;
}
QTabBar::tab:last {
margin-right: 0em;
}
QTabBar::tab:!selected {
color: #666;
border-bottom-style: solid;
margin-top: 0.1875em;
background-color: #1b242f;
}
QTabBar::tab:hover {
background-color: #232e3a;
color: #fff;
}
/* Checkboxes */
QCheckBox::indicator {
border-radius: 0.125em;
border-top-right-radius: 0em;
border-bottom-left-radius: 0em;
border: 0.0625em solid #fff;
width: 0.8em;
height: 0.8em;
margin-top: 0.0625em;
}
QCheckBox::indicator:checked {
background-color: #849ad2; /* Green */
}
QCheckBox::indicator:unchecked {
background-color: #203042; /* Red */
}
QCheckBox::indicator::disabled {
background-color: red; /* Gray */
}
/* Radio Buttons */
QRadioButton::indicator {
border: 0.0625em solid #fff;
width: 0.8em;
height: 0.8em;
margin-top: 0.0625em;
border-radius: 0.270em;
}
QRadioButton::indicator:checked {
background-color: #849ad2; /* Green */
}
QRadioButton::indicator:unchecked {
background-color: #203042; /* Red */
}
QRadioButton::indicator::disabled {
background-color: red; /* Gray */
}
/* Combo Boxes */
QComboBox {
background-color: #323c47;
color: #fff;
border: 0.0625em solid #ddd;
border-radius: 0.25em;
padding-bottom: 0.125em;
padding-left: 0.25em;
}
QComboBox::disabled {
background-color: #11182b;
color: #fff;
}
/* Group Boxes (Settings Dialog) */
QGroupBox {
margin-top: 1em;
font-size: 8pt;
border: 0.05em solid #bdc3c7;
border-radius: 0.3em;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top;
padding: 0.3em 0.5em 0.3em 0.5em;
color: #fff;
}
/* Buttons */
QPushButton {
background-color: #46598b;
color: #fff;
}
QPushButton::disabled {
background-color: #20283c;
color: #fff;
}
QPushButton::pressed {
background-color: #172038;
}
/* Log and Debugger borders */
QTextEdit {
border: 0.05em solid #ddd;
}
/* For dock buttons to be visible */
QDockWidget::close-button, QDockWidget::float-button {
background-color: #bdc3c7;
border: 0.05em solid #777;
border-radius: 0.25em;
}
/* Disable ugly borders */
QTabWidget::pane {
border: 0em solid #333b44;
}
/* Top menu bar */
QMenuBar::item:selected {
background: #353e48;
border-radius: 0.25em;
}
QMenu::item {
padding-left: 1.5em;
padding-right: 0.75em;
padding-top: 0.25em;
padding-bottom: 0.25em;
border-radius: 0.25em;
margin-bottom: 0.125em;
}
QMenu::item:selected {
background: #354454;
border: 0.05em solid #bdc3c7;
border-radius: 0.25em;
}
QMenu::item:disabled {
background-color: #181d24;
color: #fff;
border-radius: 0.25em;
}
/* Libraries list */
QListWidget::item:selected {
background-color: #3d3d3d;
color: #ecf0f1;
border-radius: 0.125em;
}
QListWidget::item:hover {
background-color: #4c4b4b;
color: #ecf0f1;
border-radius: 0.25em;
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
color: #fff;
}
/* Game Grid Font */
QLabel#gamegrid_font {
font-weight: 600;
font-size: 8pt;
font-family: Lucida Grande;
color: #fff;
}
/* Slider on toolbar */
QWidget#sizeSliderContainer {
background: transparent;
}
/* Debug UI Settings buttons */
QLabel#color_button {
background: transparent;
}
/* Seachbar on main toolbar */
QLineEdit#mw_searchbar {
margin-left: 0.7em;
color: #ecf0f1;
}
/* Uniform colors in Toolbar */
QToolButton {
background: transparent;
color: transparent;
border-radius: 0.125em;
padding: 0.09375em;
margin-left: 0.125em;
margin-top: 0.125em;
margin-bottom: 0.125em;
min-width: 0.063em;
width: auto;
}
QToolButton::disabled {
background-color: #11182b;
}
QToolButton::hover {
background-color: #3d475e;
}
/* Set Theme UI colors */
QLabel#gamelist_icon_background_color {
color: transparent;
}
QLabel#gamelist_toolbar_icon_color {
color: #828790;
}
/* Set Windows Taskbar Thumbnail colors */
QLabel#thumbnail_icon_color {
color: #262626;
}
/* Set Log colors */
QTextEdit#log_frame {
background-color: #181d24; /* Black */
}
QLabel#log_level_always {
color: #74ffda; /* Cyan */
}
QLabel#log_level_fatal {
color: #ff35ff; /* Fuchsia */
}
QLabel#log_level_error {
color: #ff2424; /* Red */
}
QLabel#log_level_todo {
color: #ff8c46; /* Orange */
}
QLabel#log_level_success {
color: #7aff7a; /* Green */
}
QLabel#log_level_warning {
color: #f7ff74; /* Yellow */
}
QLabel#log_level_notice {
color: #fff; /* White */
}
QLabel#log_level_trace {
color: #808080; /* Gray */
}
QLabel#log_stack {
color: #fff; /* White */
}
/* Set TTY colors */
QTextEdit#tty_frame {
background-color: #181d24; /* Black */
}
QLabel#tty_text {
color: #fff; /* White */
}
/* RSX Debugger */
QLabel#rsx_debugger_display_buffer {
background-color: #181d24;
}
/* Kernel Explorer */
QDialog#kernel_explorer {
background-color: #333b44;
}
/* Memory Viewer */
QDialog#memory_viewer {
background-color: #333b44;
color: #fff;
}
QLabel#memory_viewer_address_panel {
color: #00cbff; /* Font Color: Blue */
background-color: #333b44;
}
QLabel#memory_viewer_hex_panel {
color: #fff; /* Font Color: Grey */
background-color: #333b44;
}
QLabel#memory_viewer_ascii_panel {
color: #fff; /* Font Color: Grey */
background-color: #333b44;
}
/* Debugger colors */
QLabel#debugger_frame_breakpoint {
color: #000; /* Font Color: Black */
background-color: #333b44; /* Yellow */
}
QLabel#debugger_frame_pc {
color: #000; /* Font Color: Black */
background-color: #333b44; /* Green */
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

+1 -1
Submodule llvm updated: 4423e35117...0779919c44
+8 -8
View File
@@ -18,12 +18,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,30 +39,30 @@
<NMakePreprocessorDefinitions>
</NMakePreprocessorDefinitions>
<NMakeBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakePreprocessorDefinitions />
<NMakeBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
</NMakeCleanCommandLine>
</PropertyGroup>
+2 -3
View File
@@ -9,8 +9,7 @@ function Controller() {
}
Controller.prototype.WelcomePageCallback = function() {
// Wait 10 seconds to load licenses and such.
gui.clickButton(buttons.NextButton, 10000);
gui.clickButton(buttons.NextButton);
}
Controller.prototype.CredentialsPageCallback = function() {
@@ -33,7 +32,7 @@ Controller.prototype.ComponentSelectionPageCallback = function() {
var widget = gui.currentPageWidget();
widget.deselectAll();
widget.selectComponent("qt.qt5.5100.gcc_64");
widget.selectComponent("qt.591.gcc_64");
gui.clickButton(buttons.NextButton);
}
+2 -2
View File
@@ -20,14 +20,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
+2 -2
View File
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26430.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
EndProject
+117 -142
View File
@@ -1,48 +1,50 @@
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.0.2)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(RES_FILES "")
set(CMAKE_CXX_STANDARD 14)
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
# Qt section
find_package(Qt5 5.7 COMPONENTS Widgets Network)
if(WIN32)
find_package(Qt5 5.7 COMPONENTS WinExtras REQUIRED)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras Qt5::Network)
find_package(Qt5 5.9 COMPONENTS Widgets)
if (WIN32)
find_package(Qt5WinExtras REQUIRED)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS})
else()
find_package(Qt5 5.7 COMPONENTS DBus Gui)
if(Qt5DBus_FOUND)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus Qt5::Network)
find_package(Qt5DBus)
if (Qt5DBus_FOUND)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus)
add_definitions(-DHAVE_QTDBUS)
else()
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::Network)
set(RPCS3_QT_LIBS Qt5::Widgets)
endif()
include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
include_directories(${Qt5Widgets_INCLUDE_DIRS})
endif()
# Let's make sure we have Qt before we continue
if(NOT Qt5Widgets_FOUND)
if(Qt5Widgets_VERSION VERSION_LESS 5.7.0)
message("Minimum supported Qt5 version is 5.7! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if("${CMAKE_SYSTEM}" MATCHES "Linux")
if (NOT Qt5Widgets_FOUND)
if (Qt5Widgets_VERSION VERSION_LESS 5.9.0)
message("Minimum supported Qt5 version is 5.9! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if ("${CMAKE_SYSTEM}" MATCHES "Linux")
message(FATAL_ERROR "Most distros do not provide an up-to-date version of Qt.
If you're on Ubuntu or Linux Mint, there are PPAs you can use to install an up-to-date qt5 version.
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt593-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt593-trusty
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt591-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt591-trusty
just make sure to run
source /opt/qt59/bin/qt59-env.sh
before re-running cmake")
elseif(WIN32)
elseif(WIN32)
message(FATAL_ERROR "You can download the latest version of Qt5 here: https://www.qt.io/download-open-source/")
else()
message(FATAL_ERROR "Look online for instructions on installing an up-to-date Qt5 on ${CMAKE_SYSTEM}.")
endif()
endif()
message("CMake was unable to find Qt5!")
if(WIN32)
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.8\\msvc2017_64\\)")
endif()
message("CMake was unable to find Qt5!")
if (WIN32)
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.9\\msvc2017_64\\)")
elseif("${CMAKE_SYSTEM}" MATCHES "Linux")
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
else()
@@ -55,16 +57,14 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# To make UI files on cmake 3.7 or less work
if(CMAKE_VERION VERSION_LESS 3.8)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
if(Qt5_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(UNIX)
# Cotire needs this set for some reason
set(CMAKE_CXX_COMPILE_OPTIONS_PIE -fPIC)
endif()
if (Qt5_POSITION_INDEPENDENT_CODE)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(UNIX)
# Cotire needs this set for some reason
SET(CMAKE_CXX_COMPILE_OPTIONS_PIE -fPIC)
endif()
endif()
include(cotire)
@@ -101,18 +101,14 @@ if(NOT MSVC)
set(CMAKE_RC_COMPILER_INIT windres)
enable_language(RC)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
# Workaround for mingw64 (MSYS2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition")
endif()
add_compile_options(-msse -msse2 -mcx16 -mrtm)
if(NOT DEFINED ENV{TRAVIS})
add_compile_options(-march=native)
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options(-msse -msse2 -mcx16 -mssse3 -mrtm)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# This fixes 'some' of the st11range issues. See issue #2516
if(APPLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-image_base,0x10000 -Wl,-pagezero_size,0x10000")
@@ -120,13 +116,13 @@ if(NOT MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -image-base=0x10000")
endif()
endif()
# Some distros have the compilers set to use PIE by default, but RPCS3 doesn't work with PIE, so we need to disable it.
if(APPLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie")
else()
CHECK_CXX_COMPILER_FLAG("-no-pie" HAS_NO_PIE)
CHECK_CXX_COMPILER_FLAG("-nopie" HAS_NOPIE)
CHECK_C_COMPILER_FLAG("-no-pie" HAS_NO_PIE)
CHECK_C_COMPILER_FLAG("-nopie" HAS_NOPIE)
if(HAS_NO_PIE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
@@ -134,11 +130,12 @@ if(NOT MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nopie")
endif()
endif()
find_package(GLEW REQUIRED)
find_package(ZLIB REQUIRED)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:throwingNew /D _CRT_SECURE_NO_DEPRECATE=1 /D _CRT_NON_CONFORMING_SWPRINTFS=1 /D _SCL_SECURE_NO_WARNINGS=1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /DYNAMICBASE:NO /BASE:0x10000 /FIXED")
endif()
@@ -154,49 +151,44 @@ elseif(NOT MSVC AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
endif()
if(UNIX AND NOT APPLE)
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "X11")
find_package(Wayland)
if (WAYLAND_FOUND)
include_directories(${WAYLAND_INCLUDE_DIR})
add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
endif()
endif()
if(NOT RPCS3_SRC_DIR)
set(RPCS3_SRC_DIR ${CMAKE_CURRENT_LIST_DIR})
message("-- Initializing RPCS3_SRC_DIR=${RPCS3_SRC_DIR}")
SET(RPCS3_SRC_DIR ${CMAKE_CURRENT_LIST_DIR})
Message("-- Initializing RPCS3_SRC_DIR=${RPCS3_SRC_DIR}")
else()
message("-- Using Custom RPCS3_SRC_DIR=${RPCS3_SRC_DIR}")
Message("-- Using Custom RPCS3_SRC_DIR=${RPCS3_SRC_DIR}")
endif()
set(CMAKE_MODULE_PATH "${RPCS3_SRC_DIR}/cmake_modules")
find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
if(NOT WITHOUT_LLVM)
find_package(LLVM 4.0 CONFIG)
if(NOT LLVM_FOUND)
message("System LLVM was not found, LLVM will be built from the submodule.")
if (NOT WITHOUT_LLVM)
find_package(LLVM 5.0 CONFIG)
if (NOT LLVM_FOUND)
message("System LLVM was not found, LLVM will be built from the submodule.")
set(LLVM_TARGETS_TO_BUILD "X86" CACHE INTERNAL "")
option(LLVM_BUILD_RUNTIME OFF)
option(LLVM_BUILD_TOOLS OFF)
option(LLVM_INCLUDE_DOCS OFF)
option(LLVM_INCLUDE_EXAMPLES OFF)
option(LLVM_INCLUDE_TESTS OFF)
option(LLVM_INCLUDE_TOOLS OFF)
option(LLVM_INCLUDE_UTILS OFF)
option(WITH_POLLY OFF)
set(LLVM_TARGETS_TO_BUILD "X86" CACHE INTERNAL "")
option(LLVM_BUILD_RUNTIME OFF)
option(LLVM_BUILD_TOOLS OFF)
option(LLVM_INCLUDE_DOCS OFF)
option(LLVM_INCLUDE_EXAMPLES OFF)
option(LLVM_INCLUDE_TESTS OFF)
option(LLVM_INCLUDE_TOOLS OFF)
option(LLVM_INCLUDE_UTILS OFF)
option(WITH_POLLY OFF)
# LLVM needs to be built out-of-tree
add_subdirectory(../llvm ../llvm_build)
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/")
# LLVM needs to be built out-of-tree
add_subdirectory(../llvm ../llvm_build)
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/")
# now tries to find LLVM again
find_package(LLVM 4.0 CONFIG)
if(NOT LLVM_FOUND)
message(WARNING "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
endif()
endif()
# now tries to find LLVM again
find_package(LLVM 5.0 CONFIG)
if (NOT LLVM_FOUND)
message(WARNING "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
endif()
endif()
endif()
@@ -207,17 +199,18 @@ elseif(WIN32)
else()
set(PLATFORM_ARCH "linux/x86_64")
option(USE_ALSA "ALSA audio backend" ON)
option(USE_PULSE "PulseAudio audio backend" ON)
option(USE_PULSE "PulseAudio audio backend" ON)
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
option(USE_VULKAN "Vulkan render backend" ON)
endif()
if(USE_ALSA)
find_package(ALSA)
find_package(PkgConfig)
pkg_check_modules(ALSA alsa)
if(ALSA_FOUND)
add_definitions(-DHAVE_ALSA)
include_directories(SYSTEM ${ALSA_INCLUDE_DIRS})
list(APPEND ADDITIONAL_LIBS ${ALSA_LIBRARIES})
list(APPEND ADDITIONAL_LIBS ${ALSA_LDFLAGS})
endif()
endif()
if(USE_PULSE)
@@ -243,9 +236,6 @@ if(NOT WIN32 AND USE_VULKAN)
if(VULKAN_FOUND)
add_definitions(-DHAVE_VULKAN)
list(APPEND ADDITIONAL_LIBS ${VULKAN_LIBRARY})
if(VULKAN_PREBUILT)
list(APPEND ADDITIONAL_LIBS glslang HLSL OGLCompiler SPIRV OSDependent)
endif()
else()
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
endif()
@@ -272,6 +262,8 @@ else()
endif()
include_directories(
${GLEW_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}
${LLVM_INCLUDE_DIRS}
"${RPCS3_SRC_DIR}/../3rdparty/pugixml/src"
@@ -300,17 +292,17 @@ if(WIN32)
endif()
if(NOT LLVM_FOUND)
message("LLVM 4.0 not found. RPCS3 will be compiled without LLVM support.")
Message("LLVM 5.0 not found. RPCS3 will be compiled without LLVM support.")
else()
add_definitions(${LLVM_DEFINITIONS})
add_definitions(-DLLVM_AVAILABLE)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
if (CMAKE_BUILD_TYPE STREQUAL "Release")
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler)
else()
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
endif()
if(NOT MSVC)
if (NOT MSVC)
set_source_files_properties(${RPCS3_SRC_DIR}/../Utilities/JIT.cpp PROPERTIES COMPILE_FLAGS -fno-rtti)
set_source_files_properties(${RPCS3_SRC_DIR}/Emu/Cell/PPUTranslator.cpp PROPERTIES COMPILE_FLAGS -fno-rtti)
endif()
@@ -329,7 +321,7 @@ if(NOT USE_SYSTEM_FFMPEG)
endif()
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach (dir ${dirs})
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
@@ -341,7 +333,7 @@ RPCS3_SRC
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit/*.cpp"
)
if(NOT WIN32 AND VULKAN_FOUND)
if (NOT WIN32 AND VULKAN_FOUND)
# Compile glslang and SPIRV modules needed for glsl compilation
file(
GLOB_RECURSE
@@ -352,26 +344,26 @@ if(NOT WIN32 AND VULKAN_FOUND)
"${RPCS3_SRC_DIR}/../Vulkan/glslang/OGLCompilersDLL/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/SPIRV/*.cpp"
)
set(RPCS3_SRC ${RPCS3_SRC} ${UNIX_GLSLANG})
set (RPCS3_SRC ${RPCS3_SRC} ${UNIX_GLSLANG})
endif()
#File exclusion section
if(NOT WIN32 AND NOT VULKAN_FOUND)
set(EXCLUDE_FILES "/RSX/VK/")
set (EXCLUDE_FILES "/RSX/VK/")
endif()
# Ignore autogenerated moc_* files if present
set(EXCLUDE_FILES ${EXCLUDE_FILES} "moc_")
set(EXCLUDE_FILES ${EXCLUDE_FILES} "rpcs3_automoc")
set(EXCLUDE_FILES ${EXCLUDE_FILES} "qrc_resources.cpp")
set (EXCLUDE_FILES ${EXCLUDE_FILES} "moc_")
set (EXCLUDE_FILES ${EXCLUDE_FILES} "rpcs3_automoc")
set (EXCLUDE_FILES ${EXCLUDE_FILES} "qrc_resources.cpp")
foreach (TMP_PATH ${RPCS3_SRC})
foreach (EXCLUDE_PATH ${EXCLUDE_FILES})
string(FIND ${TMP_PATH} ${EXCLUDE_PATH} EXCLUDE_FILE_FOUND)
if(NOT ${EXCLUDE_FILE_FOUND} EQUAL -1)
list(REMOVE_ITEM RPCS3_SRC ${TMP_PATH})
string (FIND ${TMP_PATH} ${EXCLUDE_PATH} EXCLUDE_FILE_FOUND)
if (NOT ${EXCLUDE_FILE_FOUND} EQUAL -1)
list (REMOVE_ITEM RPCS3_SRC ${TMP_PATH})
endif ()
endforeach(EXCLUDE_PATH)
endforeach(TMP_PATH)
@@ -380,29 +372,24 @@ endforeach(TMP_PATH)
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp" "${RPCS3_SRC_DIR}/qrc_resources.cpp")
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${TMP_MOC}")
if(WIN32)
add_executable(rpcs3 WIN32 ${RPCS3_SRC} ${RES_FILES} resources.qrc)
if (WIN32)
add_executable(rpcs3 WIN32 ${RPCS3_SRC} ${RES_FILES} resources.qrc)
else()
add_executable(rpcs3 ${RPCS3_SRC} ${RES_FILES} resources.qrc)
add_executable(rpcs3 ${RPCS3_SRC} ${RES_FILES} resources.qrc)
endif()
add_dependencies(rpcs3 GitVersion)
if(NOT MSVC)
find_package(GLEW 1.13.0 REQUIRED)
target_link_libraries(rpcs3 GLEW::GLEW)
endif()
if(WIN32)
target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib VKstatic.1 glslang OSDependent OGLCompiler SPIRV HLSL setupapi.lib hidapi-hid Shlwapi.lib)
if(NOT MSVC)
target_link_libraries(rpcs3 ${OPENGL_LIBRARIES} opengl32.lib glu32.lib libpthread)
target_link_libraries(rpcs3 ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} opengl32.lib glu32.lib libpthread)
else()
target_link_libraries(rpcs3 dxgi.lib d2d1.lib dwrite.lib)
target_link_libraries(rpcs3 dxgi.lib d2d1.lib dwrite.lib)
endif()
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
else()
target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${OPENGL_LIBRARIES})
target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
if(APPLE)
target_link_libraries(rpcs3 hidapi-mac "-framework CoreFoundation" "-framework IOKit")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
@@ -413,57 +400,50 @@ else()
if(VULKAN_FOUND)
target_link_libraries(rpcs3 ${VULKAN_LIBRARIES})
endif()
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ZLIB::ZLIB ${ADDITIONAL_LIBS})
if(USE_SYSTEM_FFMPEG)
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
if (USE_SYSTEM_FFMPEG)
link_libraries(${FFMPEG_LIBRARY_DIR})
target_link_libraries(rpcs3 libavformat.so libavcodec.so libavutil.so libswscale.so)
target_link_libraries(rpcs3 libavformat.so libavcodec.so libavutil.so libswresample.so libswscale.so)
else()
target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswscale.a)
target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a)
endif()
if(USE_SYSTEM_LIBPNG)
target_link_libraries(rpcs3 ${PNG_LIBRARIES})
if (USE_SYSTEM_LIBPNG)
target_link_libraries(rpcs3 ${PNG_LIBRARIES})
else()
target_link_libraries(rpcs3 png16_static)
target_link_libraries(rpcs3 png16_static)
endif()
endif()
# For some reason GCC 7 requires manually linking with -latomic
if(CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7))
if (CMAKE_COMPILER_IS_GNUCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7))
target_link_libraries(rpcs3 -latomic)
endif()
if(LLVM_FOUND)
target_link_libraries(rpcs3 ${LLVM_LIBS})
target_link_libraries(rpcs3 ${LLVM_LIBS})
endif()
target_link_libraries(rpcs3 ${RPCS3_QT_LIBS})
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
if(MSVC)
# Under Windows, some QT DLLs need to be in the same directory of the compiled
# RPCS3 binary, so call the windeployqt tool that will take care of copying
# them from the local QT installation at the end of the build.
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations --debug ${CMAKE_BINARY_DIR}/bin
)
else()
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations ${CMAKE_BINARY_DIR}/bin
)
endif()
if (MSVC)
# Under Windows, some QT DLLs need to be in the same directory of the compiled
# RPCS3 binary, so call the windeployqt tool that will take care of copying
# them from the local QT installation at the end of the build.
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations --debug ${CMAKE_BINARY_DIR}/bin
)
else()
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations ${CMAKE_BINARY_DIR}/bin
)
endif()
endif()
cotire(rpcs3)
if (UNIX)
# Copy icons to executable directory
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/Icons)
endif()
# Unix installation
if(UNIX AND NOT APPLE)
# Install the binary
@@ -475,9 +455,4 @@ if(UNIX AND NOT APPLE)
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps)
install(FILES rpcs3.desktop
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
# Install other files
install(DIRECTORY ../bin/Icons
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/rpcs3)
install(DIRECTORY ../bin/GuiConfigs
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/rpcs3)
endif()
+25 -65
View File
@@ -4,19 +4,27 @@
#include "sha1.h"
#include "key_vault.h"
#include "Utilities/StrFmt.h"
#include "Emu/System.h"
#include "Emu/VFS.h"
#include "unpkg.h"
bool pkg_install(const std::string& path, atomic_t<double>& sync)
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync, const std::string& pkg_filepath)
{
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
std::vector<fs::file> filelist;
filelist.emplace_back(fs::file{path});
u32 cur_file = 0;
u64 cur_offset = 0;
u64 cur_file_offset = 0;
u32 cur_file=0;
fs::file original_file(pkg_filepath);
original_file.seek(pkg_f.pos());
filelist.push_back(std::move(original_file));
// Save current file offset (probably zero)
const u64 start_offset = pkg_f.pos();
u64 cur_offset = start_offset;
u64 cur_file_offset = start_offset;
// Get basic PKG information
PKGHeader header;
auto archive_seek = [&](const s64 new_offset, const fs::seek_mode damode = fs::seek_set)
{
@@ -65,8 +73,6 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
return num_read;
};
// Get basic PKG information
PKGHeader header;
if (archive_read(&header, sizeof(header)) != sizeof(header))
{
@@ -102,18 +108,18 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
}
}
if (header.pkg_size > filelist[0].size())
if (header.pkg_size > pkg_f.size())
{
// Check if multi-files pkg
if (path.size() < 7 || path.compare(path.size() - 7, 7, "_00.pkg", 7) != 0)
//Check if multi-files pkg
if (pkg_filepath.length() < 7 || pkg_filepath.substr(pkg_filepath.length() - 7).compare("_00.pkg") != 0)
{
LOG_ERROR(LOADER, "PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
return false;
}
std::string name_wo_number = path.substr(0, path.size() - 7);
u64 cursize = filelist[0].size();
while (cursize < header.pkg_size)
std::string name_wo_number = pkg_filepath.substr(0, pkg_filepath.length() - 7);
u64 cursize = pkg_f.size();
while (cursize != header.pkg_size)
{
std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
@@ -125,7 +131,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
}
cursize += archive_file.size();
filelist.emplace_back(std::move(archive_file));
filelist.push_back(std::move(archive_file));
}
}
@@ -137,12 +143,6 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
be_t<u32> drm_type{0};
be_t<u32> content_type{0};
std::string install_id;
// Read title ID and use it as an installation directory
install_id.resize(9);
archive_seek(55);
archive_read(&install_id.front(), install_id.size());
archive_seek(header.pkg_info_off);
@@ -179,50 +179,18 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
break;
}
case 0xA:
{
if (packet.size > 8)
{
// Read an actual installation directory (DLC)
install_id.resize(packet.size);
archive_read(&install_id.front(), packet.size);
install_id = install_id.c_str() + 8;
continue;
}
break;
}
}
archive_seek(packet.size, fs::seek_cur);
}
// If false, an existing directory is being overwritten: cannot cancel the operation
bool was_null = true;
// Get full path and create the directory
const std::string dir = Emu.GetHddDir() + "game/" + install_id + '/';
if (!fs::create_dir(dir))
{
if (fs::g_tls_error == fs::error::exist)
{
was_null = false;
}
else
{
LOG_ERROR(LOADER, "PKG: Could not create the installation directory %s", dir);
return false;
}
}
// Allocate buffer with BUF_SIZE size or more if required
const std::unique_ptr<u128[]> buf(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * header.file_count) / sizeof(u128)]);
// Define decryption subfunction (`psp` arg selects the key for specific block)
auto decrypt = [&](u64 offset, u64 size, const uchar* key) -> u64
{
archive_seek(header.data_offset + offset);
archive_seek(start_offset + header.data_offset + offset);
// Read the data and set available size
const u64 read = archive_read(buf.get(), size);
@@ -366,16 +334,8 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (sync.fetch_add((block_size + 0.0) / header.data_size) < 0.)
{
if (was_null)
{
LOG_ERROR(LOADER, "Package installation cancelled: %s", dir);
out.close();
fs::remove_all(dir, true);
return false;
}
// Cannot cancel the installation
sync += 1.;
LOG_ERROR(LOADER, "Package installation cancelled: %s", dir);
return false;
}
}
+1 -1
View File
@@ -57,4 +57,4 @@ struct PKGEntry
be_t<u32> pad; // Padding (zeros)
};
bool pkg_install(const std::string& path, atomic_t<double>&);
bool pkg_install(const class fs::file& pkg_f, const std::string& dir, atomic_t<double>&, const std::string& pkg_filepath);
+36 -351
View File
@@ -148,40 +148,20 @@ void WriteEhdr(const fs::file& f, Elf32_Ehdr& ehdr)
Write8(f, ehdr.e_data);
Write8(f, ehdr.e_curver);
Write8(f, ehdr.e_os_abi);
if (ehdr.e_data == 1)
{
Write64LE(f, ehdr.e_abi_ver);
Write16LE(f, ehdr.e_type);
Write16LE(f, ehdr.e_machine);
Write32LE(f, ehdr.e_version);
Write32LE(f, ehdr.e_entry);
Write32LE(f, ehdr.e_phoff);
Write32LE(f, ehdr.e_shoff);
Write32LE(f, ehdr.e_flags);
Write16LE(f, ehdr.e_ehsize);
Write16LE(f, ehdr.e_phentsize);
Write16LE(f, ehdr.e_phnum);
Write16LE(f, ehdr.e_shentsize);
Write16LE(f, ehdr.e_shnum);
Write16LE(f, ehdr.e_shstrndx);
}
else
{
Write64(f, ehdr.e_abi_ver);
Write16(f, ehdr.e_type);
Write16(f, ehdr.e_machine);
Write32(f, ehdr.e_version);
Write32(f, ehdr.e_entry);
Write32(f, ehdr.e_phoff);
Write32(f, ehdr.e_shoff);
Write32(f, ehdr.e_flags);
Write16(f, ehdr.e_ehsize);
Write16(f, ehdr.e_phentsize);
Write16(f, ehdr.e_phnum);
Write16(f, ehdr.e_shentsize);
Write16(f, ehdr.e_shnum);
Write16(f, ehdr.e_shstrndx);
}
Write64(f, ehdr.e_abi_ver);
Write16(f, ehdr.e_type);
Write16(f, ehdr.e_machine);
Write32(f, ehdr.e_version);
Write32(f, ehdr.e_entry);
Write32(f, ehdr.e_phoff);
Write32(f, ehdr.e_shoff);
Write32(f, ehdr.e_flags);
Write16(f, ehdr.e_ehsize);
Write16(f, ehdr.e_phentsize);
Write16(f, ehdr.e_phnum);
Write16(f, ehdr.e_shentsize);
Write16(f, ehdr.e_shnum);
Write16(f, ehdr.e_shstrndx);
}
void WritePhdr(const fs::file& f, Elf32_Phdr& phdr)
@@ -210,32 +190,6 @@ void WriteShdr(const fs::file& f, Elf32_Shdr& shdr)
Write32(f, shdr.sh_entsize);
}
void WritePhdrLE(const fs::file& f, Elf32_Phdr& phdr)
{
Write32LE(f, phdr.p_type);
Write32LE(f, phdr.p_offset);
Write32LE(f, phdr.p_vaddr);
Write32LE(f, phdr.p_paddr);
Write32LE(f, phdr.p_filesz);
Write32LE(f, phdr.p_memsz);
Write32LE(f, phdr.p_flags);
Write32LE(f, phdr.p_align);
}
void WriteShdrLE(const fs::file& f, Elf32_Shdr& shdr)
{
Write32LE(f, shdr.sh_name);
Write32LE(f, shdr.sh_type);
Write32LE(f, shdr.sh_flags);
Write32LE(f, shdr.sh_addr);
Write32LE(f, shdr.sh_offset);
Write32LE(f, shdr.sh_size);
Write32LE(f, shdr.sh_link);
Write32LE(f, shdr.sh_info);
Write32LE(f, shdr.sh_addralign);
Write32LE(f, shdr.sh_entsize);
}
void AppInfo::Load(const fs::file& f)
{
@@ -246,15 +200,6 @@ void AppInfo::Load(const fs::file& f)
padding = Read64(f);
}
void AppInfo::LoadLE(const fs::file& f)
{
authid = Read64LE(f);
vendor_id = Read32LE(f);
self_type = Read32LE(f);
version = Read64(f);
padding = Read64(f);
}
void AppInfo::Show()
{
LOG_NOTICE(LOADER, "AuthID: 0x%llx", authid);
@@ -273,16 +218,6 @@ void SectionInfo::Load(const fs::file& f)
encrypted = Read32(f);
}
void SectionInfo::LoadLE(const fs::file& f)
{
offset = Read64LE(f);
size = Read64LE(f);
compressed = Read32LE(f);
unknown1 = Read32LE(f);
unknown2 = Read32LE(f);
encrypted = Read32LE(f);
}
void SectionInfo::Show()
{
LOG_NOTICE(LOADER, "Offset: 0x%llx", offset);
@@ -301,14 +236,6 @@ void SCEVersionInfo::Load(const fs::file& f)
unknown = Read32(f);
}
void SCEVersionInfo::LoadLE(const fs::file& f)
{
subheader_type = Read32LE(f);
present = Read32LE(f);
size = Read32LE(f);
unknown = Read32LE(f);
}
void SCEVersionInfo::Show()
{
LOG_NOTICE(LOADER, "Sub-header type: 0x%08x", subheader_type);
@@ -363,65 +290,6 @@ void ControlInfo::Load(const fs::file& f)
}
}
void ControlInfo::LoadLE(const fs::file& f)
{
type = Read32LE(f);
size = Read32LE(f);
next = Read64LE(f);
if (type == 1)
{
control_flags.ctrl_flag1 = Read32LE(f);
control_flags.unknown1 = Read32LE(f);
control_flags.unknown2 = Read32LE(f);
control_flags.unknown3 = Read32LE(f);
control_flags.unknown4 = Read32LE(f);
control_flags.unknown5 = Read32LE(f);
control_flags.unknown6 = Read32LE(f);
control_flags.unknown7 = Read32LE(f);
}
else if (type == 2)
{
if (size == 0x30)
{
f.read(file_digest_30.digest, 20);
file_digest_30.unknown = Read64LE(f);
}
else if (size == 0x40)
{
f.read(file_digest_40.digest1, 20);
f.read(file_digest_40.digest2, 20);
file_digest_40.unknown = Read64LE(f);
}
}
else if (type == 3)
{
npdrm.magic = Read32LE(f);
npdrm.unknown1 = Read32LE(f);
npdrm.license = Read32LE(f);
npdrm.type = Read32LE(f);
f.read(npdrm.content_id, 48);
f.read(npdrm.digest, 16);
f.read(npdrm.invdigest, 16);
f.read(npdrm.xordigest, 16);
npdrm.unknown2 = Read64LE(f);
npdrm.unknown3 = Read64LE(f);
}
else if (type == 5)
{
f.read(type5.unk, 0x100);
}
else if (type == 6)
{
type6.unknown1 = Read32LE(f);
f.read(type6.unk, 0xFC);
}
else if (type == 7)
{
f.read(type7.unk, 0x40);
}
}
void ControlInfo::Show()
{
LOG_NOTICE(LOADER, "Type: 0x%08x", type);
@@ -766,19 +634,6 @@ void SceHeader::Load(const fs::file& f)
se_esize = Read64(f);
}
void SceHeader::LoadLE(const fs::file& f)
{
se_magic = Read32(f);
se_hver = Read32LE(f);
se_flags = Read16LE(f);
se_type = Read16LE(f);
se_meta = Read32LE(f);
se_hsize = Read64LE(f);
se_esize = Read64LE(f);
Read64LE(f);
Read64LE(f);
}
void SelfHeader::Load(const fs::file& f)
{
se_htype = Read64(f);
@@ -793,11 +648,6 @@ void SelfHeader::Load(const fs::file& f)
pad = Read64(f);
}
void SelfHeader::LoadLE(const fs::file& f)
{
f.read(this, sizeof(*this));
}
SCEDecrypter::SCEDecrypter(const fs::file& s)
: sce_f(s)
, data_buf_length(0)
@@ -1035,22 +885,11 @@ SELFDecrypter::SELFDecrypter(const fs::file& s)
{
}
static bool isVita(const SceHeader hdr)
{
return (hdr.se_hver == 3);
}
bool SELFDecrypter::LoadHeaders(bool isElf32)
{
// Read SCE header.
self_f.seek(0);
sce_hdr.LoadLE(self_f);
if (!isVita(sce_hdr))
{
self_f.seek(0);
sce_hdr.Load(self_f);
}
sce_hdr.Load(self_f);
// Check SCE magic.
if (!sce_hdr.CheckMagic())
@@ -1060,26 +899,11 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
}
// Read SELF header.
if (!isVita(sce_hdr))
{
self_hdr.Load(self_f);
}
else
{
self_hdr.LoadLE(self_f);
}
self_hdr.Load(self_f);
// Read the APP INFO.
self_f.seek(self_hdr.se_appinfooff);
if (!isVita(sce_hdr))
{
app_info.Load(self_f);
}
else
{
app_info.LoadLE(self_f);
}
app_info.Load(self_f);
// Read ELF header.
self_f.seek(self_hdr.se_elfoff);
@@ -1102,14 +926,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
for(u32 i = 0; i < elf32_hdr.e_phnum; ++i)
{
phdr32_arr.emplace_back();
if (!isVita(sce_hdr))
{
phdr32_arr.back().Load(self_f);
}
else
{
phdr32_arr.back().LoadLE(self_f);
}
phdr32_arr.back().Load(self_f);
}
}
else
@@ -1139,26 +956,12 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
for(u32 i = 0; i < ((isElf32) ? elf32_hdr.e_phnum : elf64_hdr.e_phnum); ++i)
{
secinfo_arr.emplace_back();
if (!isVita(sce_hdr))
{
secinfo_arr.back().Load(self_f);
}
else
{
secinfo_arr.back().LoadLE(self_f);
}
secinfo_arr.back().Load(self_f);
}
// Read SCE version info.
self_f.seek(self_hdr.se_sceveroff);
if (!isVita(sce_hdr))
{
scev_info.Load(self_f);
}
else
{
scev_info.LoadLE(self_f);
}
scev_info.Load(self_f);
// Read control info.
ctrlinfo_arr.clear();
@@ -1169,14 +972,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
{
ctrlinfo_arr.emplace_back();
ControlInfo &cinfo = ctrlinfo_arr.back();
if (!isVita(sce_hdr))
{
cinfo.Load(self_f);
}
else
{
cinfo.LoadLE(self_f);
}
cinfo.Load(self_f);
i += cinfo.size;
}
@@ -1196,14 +992,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
for(u32 i = 0; i < elf32_hdr.e_shnum; ++i)
{
shdr32_arr.emplace_back();
if (!isVita(sce_hdr))
{
shdr32_arr.back().Load(self_f);
}
else
{
shdr32_arr.back().LoadLE(self_f);
}
shdr32_arr.back().Load(self_f);
}
}
else
@@ -1368,8 +1157,6 @@ bool SELFDecrypter::LoadMetadata(u8* klic_key)
memcpy(metadata_iv, keyset.riv, 0x10);
// Check DEBUG flag.
if (sce_hdr.se_flags == 0x00c0)
return true;
if ((sce_hdr.se_flags & 0x8000) != 0x8000)
{
// Decrypt the NPDRM layer.
@@ -1432,14 +1219,6 @@ bool SELFDecrypter::DecryptData()
}
}
if (meta_hdr.section_count == 0)
{
for (unsigned int i = 0; i < secinfo_arr.size(); i++)
{
data_buf_length += secinfo_arr[i].size;
}
}
// Allocate a buffer to store decrypted data.
data_buf = std::make_unique<u8[]>(data_buf_length);
@@ -1487,16 +1266,6 @@ bool SELFDecrypter::DecryptData()
}
}
if (meta_hdr.section_count == 0)
{
for (unsigned int i = 0; i < secinfo_arr.size(); i++)
{
self_f.seek(secinfo_arr[i].offset);
self_f.read(data_buf.get() + data_buf_offset, secinfo_arr[i].size);
data_buf_offset += secinfo_arr[i].size;
}
}
return true;
}
@@ -1516,75 +1285,20 @@ fs::file SELFDecrypter::MakeElf(bool isElf32)
// Write program headers.
for (u32 i = 0; i < elf32_hdr.e_phnum; ++i)
{
if (elf32_hdr.e_data == 1)
{
WritePhdrLE(e, phdr32_arr[i]);
}
else
{
WritePhdr(e, phdr32_arr[i]);
}
WritePhdr(e, phdr32_arr[i]);
}
if (meta_hdr.section_count != 0)
for (unsigned int i = 0; i < meta_hdr.section_count; i++)
{
for (unsigned int i = 0; i < meta_hdr.section_count; i++)
// PHDR type.
if (meta_shdr[i].type == 2)
{
// PHDR type.
if (meta_shdr[i].type == 2)
{
// Seek to the program header data offset and write the data.
e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset);
e.write(data_buf.get() + data_buf_offset, meta_shdr[i].data_size);
// Advance the data buffer offset by data size.
data_buf_offset += meta_shdr[i].data_size;
}
}
}
else
{
for (unsigned int i = 0; i < phdr32_arr.size(); i++)
{
// Decompress if necessary.
if (secinfo_arr[i].compressed == 2)
{
// Store the length in writeable memory space.
std::unique_ptr<uLongf> decomp_buf_length(new uLongf);
memcpy(decomp_buf_length.get(), &phdr32_arr[i].p_filesz, sizeof(uLongf));
/// Create a pointer to a buffer for decompression.
std::unique_ptr<u8[]> decomp_buf(new u8[phdr32_arr[i].p_filesz]);
// Create a buffer separate from data_buf to uncompress.
std::unique_ptr<u8[]> zlib_buf(new u8[data_buf_length]);
memcpy(zlib_buf.get(), data_buf.get(), data_buf_length);
// Use zlib uncompress on the new buffer.
// decomp_buf_length changes inside the call to uncompress, so it must be a pointer to correct type (in writeable mem space).
int rv = uncompress(decomp_buf.get(), decomp_buf_length.get(), zlib_buf.get() + data_buf_offset, data_buf_length);
// Check for errors (TODO: Probably safe to remove this once these changes have passed testing.)
switch (rv)
{
case Z_MEM_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_MEM_ERROR!"); break;
case Z_BUF_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_BUF_ERROR!"); break;
case Z_DATA_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_DATA_ERROR!"); break;
default: break;
}
// Seek to the program header data offset and write the data.
e.seek(phdr32_arr[i].p_offset);
e.write(decomp_buf.get(), phdr32_arr[i].p_filesz);
}
else
{
// Seek to the program header data offset and write the data.
e.seek(phdr32_arr[i].p_offset);
e.write(data_buf.get() + data_buf_offset, secinfo_arr[i].size);
}
// Seek to the program header data offset and write the data.
e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset);
e.write(data_buf.get() + data_buf_offset, meta_shdr[i].data_size);
// Advance the data buffer offset by data size.
data_buf_offset += secinfo_arr[i].size;
data_buf_offset += meta_shdr[i].data_size;
}
}
@@ -1595,14 +1309,7 @@ fs::file SELFDecrypter::MakeElf(bool isElf32)
for (u32 i = 0; i < elf32_hdr.e_shnum; ++i)
{
if (elf32_hdr.e_data == 1)
{
WriteShdrLE(e, shdr32_arr[i]);
}
else
{
WriteShdr(e, shdr32_arr[i]);
}
WriteShdr(e, shdr32_arr[i]);
}
}
}
@@ -1717,20 +1424,8 @@ static bool IsSelfElf32(const fs::file& f)
SceHeader hdr;
SelfHeader sh;
hdr.LoadLE(f);
if (!isVita(hdr))
{
f.seek(0);
hdr.Load(f);
sh.Load(f);
}
else
{
sh.LoadLE(f);
}
hdr.Load(f);
sh.Load(f);
// Locate the class byte and check it.
u8 elf_class[0x8];
@@ -1756,23 +1451,13 @@ static bool CheckDebugSelf(fs::file& s)
// Check for DEBUG version.
if (key_version == 0x80 || key_version == 0xc0)
{
s.seek(0x04);
const u16 version = s.read<le_t<u16>>();
if (version == 3)
{
return false;
}
LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");
// Get the real elf offset.
s.seek(0x10);
const u64 realoffset = key_version == 0x80 ? +s.read<be_t<u64>>() : +s.read<le_t<u64>>();
// Start at the real elf offset.
s.seek(realoffset);
s.seek(key_version == 0x80 ? +s.read<be_t<u64>>() : +s.read<le_t<u64>>());
// Write the real ELF file back.
fs::file e = fs::make_stream<std::vector<u8>>();
@@ -1875,4 +1560,4 @@ std::array<u8, 0x10> get_default_self_klic()
std::array<u8, 0x10> key;
std::copy(std::begin(NP_KLIC_FREE), std::end(NP_KLIC_FREE), std::begin(key));
return key;
}
}
-29
View File
@@ -11,7 +11,6 @@ struct AppInfo
u64 padding;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -25,7 +24,6 @@ struct SectionInfo
u32 encrypted;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -37,7 +35,6 @@ struct SCEVersionInfo
u32 unknown;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -95,33 +92,9 @@ struct ControlInfo
u64 unknown3;
} npdrm;
// type 5 0x110 bytes
struct
{
u32 pad;
u8 unk[0x100];
} type5;
// type 6 0x110 bytes
struct
{
u32 pad;
u32 unknown1;
u8 unk[0xFC];
} type6;
// type 7 0x50 bytes
struct
{
u32 pad;
u8 unk[0x40];
} type7;
};
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -344,7 +317,6 @@ struct SceHeader
u64 se_esize;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show(){}
bool CheckMagic() const { return se_magic == 0x53434500; }
};
@@ -363,7 +335,6 @@ struct SelfHeader
u64 pad;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show(){}
};
+1 -1
View File
@@ -31,7 +31,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+4 -6
View File
@@ -50,8 +50,6 @@ OpenALThread::OpenALThread()
{
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
}
m_buffers = std::make_unique<ALuint[]>(g_cfg.audio.frames);
}
OpenALThread::~OpenALThread()
@@ -85,7 +83,7 @@ void OpenALThread::Close()
if (alIsSource(m_source))
alDeleteSources(1, &m_source);
alDeleteBuffers(g_cfg.audio.frames, m_buffers.get());
alDeleteBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alDeleteBuffers");
}
@@ -100,7 +98,7 @@ void OpenALThread::Open(const void* src, int size)
alGenSources(1, &m_source);
checkForAlError("alGenSources");
alGenBuffers(g_cfg.audio.frames, m_buffers.get());
alGenBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alGenBuffers");
alSourcei(m_source, AL_LOOPING, AL_FALSE);
@@ -108,13 +106,13 @@ void OpenALThread::Open(const void* src, int size)
m_buffer_size = size;
for (int i = 0; i < g_cfg.audio.frames; ++i)
for (uint i = 0; i<g_al_buffers_count; ++i)
{
alBufferData(m_buffers[i], m_format, src, m_buffer_size, 48000);
checkForAlError("alBufferData");
}
alSourceQueueBuffers(m_source, g_cfg.audio.frames, m_buffers.get());
alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
checkForAlError("alSourceQueueBuffers");
Play();
}
+3 -2
View File
@@ -2,14 +2,15 @@
#include "Emu/Audio/AudioThread.h"
#include "3rdparty/OpenAL/include/alext.h"
#include <memory>
class OpenALThread : public AudioThread
{
private:
static const uint g_al_buffers_count = 24;
ALint m_format;
ALuint m_source;
std::unique_ptr<ALuint[]> m_buffers;
ALuint m_buffers[g_al_buffers_count];
ALsizei m_buffer_size;
public:
+39 -74
View File
@@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Utilities/GSL.h"
#include "Emu/System.h"
#include "ALSAThread.h"
@@ -8,12 +9,10 @@
#include <alsa/asoundlib.h>
static thread_local snd_pcm_t* s_tls_handle{nullptr};
static thread_local snd_pcm_hw_params_t* s_tls_hw_params{nullptr};
static thread_local snd_pcm_sw_params_t* s_tls_sw_params{nullptr};
static void error(int err, const char* reason)
{
LOG_ERROR(GENERAL, "ALSA: %s failed: %s\n", reason, snd_strerror(err));
fprintf(stderr, "ALSA: %s failed: %s\n", reason, snd_strerror(err));
}
static bool check(int err, const char* reason)
@@ -29,88 +28,55 @@ static bool check(int err, const char* reason)
ALSAThread::ALSAThread()
{
snd_pcm_hw_params_t* hw_params{nullptr};
auto at_ret = gsl::finally([&]()
{
if (hw_params)
{
snd_pcm_hw_params_free(hw_params);
}
});
if (!check(snd_pcm_open(&s_tls_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK), "snd_pcm_open"))
return;
if (!check(snd_pcm_hw_params_malloc(&s_tls_hw_params), "snd_pcm_hw_params_malloc"))
if (!check(snd_pcm_hw_params_malloc(&hw_params), "snd_pcm_hw_params_malloc"))
return;
if (!check(snd_pcm_hw_params_any(s_tls_handle, s_tls_hw_params), "snd_pcm_hw_params_any"))
if (!check(snd_pcm_hw_params_any(s_tls_handle, hw_params), "snd_pcm_hw_params_any"))
return;
if (!check(snd_pcm_hw_params_set_access(s_tls_handle, s_tls_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED), "snd_pcm_hw_params_set_access"))
if (!check(snd_pcm_hw_params_set_access(s_tls_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED), "snd_pcm_hw_params_set_access"))
return;
if (!check(snd_pcm_hw_params_set_format(s_tls_handle, s_tls_hw_params, g_cfg.audio.convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
if (!check(snd_pcm_hw_params_set_format(s_tls_handle, hw_params, g_cfg.audio.convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
return;
uint rate = 48000;
if (!check(snd_pcm_hw_params_set_rate_near(s_tls_handle, s_tls_hw_params, &rate, nullptr), "snd_pcm_hw_params_set_rate_near"))
if (!check(snd_pcm_hw_params_set_rate(s_tls_handle, hw_params, 48000, 0), "snd_pcm_hw_params_set_rate_near"))
return;
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, s_tls_hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
return;
//uint period = 5333;
//if (!check(snd_pcm_hw_params_set_period_time_near(s_tls_handle, s_tls_hw_params, &period, nullptr), "snd_pcm_hw_params_set_period_time_near"))
// return;
//if (!check(snd_pcm_hw_params_set_periods(s_tls_handle, s_tls_hw_params, 4, 0), "snd_pcm_hw_params_set_periods"))
// return;
snd_pcm_uframes_t bufsize_frames = g_cfg.audio.frames * 256;
snd_pcm_uframes_t period_frames = 256;
if (!check(snd_pcm_hw_params_set_buffer_size_near(s_tls_handle, s_tls_hw_params, &bufsize_frames), "snd_pcm_hw_params_set_buffer_size_near"))
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 8 * 256), "snd_pcm_hw_params_set_buffer_size"))
return;
if (!check(snd_pcm_hw_params_set_period_size_near(s_tls_handle, s_tls_hw_params, &period_frames, 0), "snd_pcm_hw_params_set_period_size"))
if (!check(snd_pcm_hw_params_set_period_size(s_tls_handle, hw_params, 256, 0), "snd_pcm_hw_params_set_period_size"))
return;
if (!check(snd_pcm_hw_params(s_tls_handle, s_tls_hw_params), "snd_pcm_hw_params"))
return;
//if (!check(snd_pcm_hw_params_set_periods(s_tls_handle, hw_params, 2, 0), "snd_pcm_hw_params_set_periods"))
// return;
if (!check(snd_pcm_hw_params_get_buffer_size(s_tls_hw_params, &bufsize_frames), "snd_pcm_hw_params_get_buffer_size"))
return;
if (!check(snd_pcm_hw_params_get_period_size(s_tls_hw_params, &period_frames, nullptr), "snd_pcm_hw_params_get_period_size"))
return;
if (!check(snd_pcm_sw_params_malloc(&s_tls_sw_params), "snd_pcm_sw_params_malloc"))
return;
if (!check(snd_pcm_sw_params_current(s_tls_handle, s_tls_sw_params), "snd_pcm_sw_params_current"))
return;
period_frames *= g_cfg.audio.startt;
if (!check(snd_pcm_sw_params_set_start_threshold(s_tls_handle, s_tls_sw_params, period_frames), "snd_pcm_sw_params_set_start_threshold"))
return;
if (!check(snd_pcm_sw_params_set_stop_threshold(s_tls_handle, s_tls_sw_params, bufsize_frames), "snd_pcm_sw_params_set_stop_threshold"))
return;
if (!check(snd_pcm_sw_params(s_tls_handle, s_tls_sw_params), "snd_pcm_sw_params"))
if (!check(snd_pcm_hw_params(s_tls_handle, hw_params), "snd_pcm_hw_params"))
return;
if (!check(snd_pcm_prepare(s_tls_handle), "snd_pcm_prepare"))
return;
LOG_NOTICE(GENERAL, "ALSA: bufsize_frames=%u, period_frames=%u", bufsize_frames, period_frames);
}
ALSAThread::~ALSAThread()
{
if (s_tls_sw_params)
{
snd_pcm_sw_params_free(s_tls_sw_params);
}
if (s_tls_hw_params)
{
snd_pcm_hw_params_free(s_tls_hw_params);
}
if (s_tls_handle)
{
snd_pcm_close(s_tls_handle);
@@ -139,30 +105,29 @@ void ALSAThread::AddData(const void* src, int size)
size /= g_cfg.audio.convert_to_u16 ? 2 : 4;
size /= g_cfg.audio.downmix_to_2ch ? 2 : 8;
int res = snd_pcm_writei(s_tls_handle, src, size);
int res;
if (res == -EAGAIN)
while (true)
{
LOG_WARNING(GENERAL, "ALSA: EAGAIN");
return;
}
if (res < 0)
{
res = snd_pcm_recover(s_tls_handle, res, 0);
if (res < 0)
{
LOG_WARNING(GENERAL, "ALSA: failed to recover (%d)", res);
return;
}
res = snd_pcm_writei(s_tls_handle, src, size);
if (res == -EAGAIN)
{
continue;
}
else if (res == -EPIPE)
{
snd_pcm_prepare(s_tls_handle);
}
else
{
break;
}
}
if (res != size)
{
LOG_WARNING(GENERAL, "ALSA: error (%d)", res);
error(res, "snd_pcm_writei");
}
}
+1 -1
View File
@@ -121,7 +121,7 @@ void XAudio2Thread::xa27_open()
return;
}
s_tls_source_voice->SetVolume(g_cfg.audio.downmix_to_2ch ? 1.0f : 4.0f);
s_tls_source_voice->SetVolume(g_cfg.audio.downmix_to_2ch ? 1.0 : 4.0);
}
void XAudio2Thread::xa27_add(const void* src, int size)
-12
View File
@@ -1,13 +1 @@
#ifdef LLVM_AVAILABLE
#include "CPUTranslator.h"
cpu_translator::cpu_translator(llvm::LLVMContext& context, llvm::Module* module, bool is_be)
: m_context(context)
, m_module(module)
, m_is_be(is_be)
{
}
#endif
-749
View File
@@ -1,750 +1 @@
#pragma once
#ifdef LLVM_AVAILABLE
#include "restore_new.h"
#ifdef _MSC_VER
#pragma warning(push, 0)
#endif
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include "define_new_memleakdetect.h"
#include "../Utilities/types.h"
#include "../Utilities/StrFmt.h"
#include "../Utilities/BEType.h"
#include "../Utilities/BitField.h"
#include <unordered_map>
#include <map>
#include <unordered_set>
#include <set>
#include <array>
#include <vector>
template <typename T = void>
struct llvm_value_t
{
static_assert(std::is_same<T, void>::value, "llvm_value_t<> error: unknown type");
using type = void;
static constexpr uint esize = 0;
static constexpr bool is_int = false;
static constexpr bool is_sint = false;
static constexpr bool is_uint = false;
static constexpr bool is_float = false;
static constexpr uint is_vector = false;
static constexpr uint is_pointer = false;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getVoidTy(context);
}
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
return value;
}
llvm::Value* value;
// llvm_value_t() = default;
// llvm_value_t(llvm::Value* value)
// : value(value)
// {
// }
};
template <>
struct llvm_value_t<bool> : llvm_value_t<void>
{
using type = bool;
using base = llvm_value_t<void>;
using base::base;
static constexpr uint esize = 1;
static constexpr uint is_int = true;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getInt1Ty(context);
}
};
template <>
struct llvm_value_t<char> : llvm_value_t<void>
{
using type = char;
using base = llvm_value_t<void>;
using base::base;
static constexpr uint esize = 8;
static constexpr bool is_int = true;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getInt8Ty(context);
}
};
template <>
struct llvm_value_t<s8> : llvm_value_t<char>
{
using type = s8;
using base = llvm_value_t<char>;
using base::base;
static constexpr bool is_sint = true;
};
template <>
struct llvm_value_t<u8> : llvm_value_t<char>
{
using type = u8;
using base = llvm_value_t<char>;
using base::base;
static constexpr bool is_uint = true;
};
template <>
struct llvm_value_t<s16> : llvm_value_t<s8>
{
using type = s16;
using base = llvm_value_t<s8>;
using base::base;
static constexpr uint esize = 16;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getInt16Ty(context);
}
};
template <>
struct llvm_value_t<u16> : llvm_value_t<s16>
{
using type = u16;
using base = llvm_value_t<s16>;
using base::base;
static constexpr bool is_sint = false;
static constexpr bool is_uint = true;
};
template <>
struct llvm_value_t<s32> : llvm_value_t<s8>
{
using type = s32;
using base = llvm_value_t<s8>;
using base::base;
static constexpr uint esize = 32;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getInt32Ty(context);
}
};
template <>
struct llvm_value_t<u32> : llvm_value_t<s32>
{
using type = u32;
using base = llvm_value_t<s32>;
using base::base;
static constexpr bool is_sint = false;
static constexpr bool is_uint = true;
};
template <>
struct llvm_value_t<s64> : llvm_value_t<s8>
{
using type = s64;
using base = llvm_value_t<s8>;
using base::base;
static constexpr uint esize = 64;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getInt64Ty(context);
}
};
template <>
struct llvm_value_t<u64> : llvm_value_t<s64>
{
using type = u64;
using base = llvm_value_t<s64>;
using base::base;
static constexpr bool is_sint = false;
static constexpr bool is_uint = true;
};
template <>
struct llvm_value_t<s128> : llvm_value_t<s8>
{
using type = s128;
using base = llvm_value_t<s8>;
using base::base;
static constexpr uint esize = 128;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getIntNTy(context, 128);
}
};
template <>
struct llvm_value_t<u128> : llvm_value_t<s128>
{
using type = u128;
using base = llvm_value_t<s128>;
using base::base;
static constexpr bool is_sint = false;
static constexpr bool is_uint = true;
};
template <>
struct llvm_value_t<f32> : llvm_value_t<void>
{
using type = f32;
using base = llvm_value_t<void>;
using base::base;
static constexpr uint esize = 32;
static constexpr bool is_float = true;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getFloatTy(context);
}
};
template <>
struct llvm_value_t<f64> : llvm_value_t<void>
{
using type = f64;
using base = llvm_value_t<void>;
using base::base;
static constexpr uint esize = 64;
static constexpr bool is_float = true;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::Type::getDoubleTy(context);
}
};
template <typename T>
struct llvm_value_t<T*> : llvm_value_t<T>
{
static_assert(!std::is_void<T>::value, "llvm_value_t<> error: invalid pointer to void type");
using type = T*;
using base = llvm_value_t<T>;
using base::base;
static constexpr uint is_pointer = llvm_value_t<T>::is_pointer + 1;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm_value_t<T>::get_type(context)->getPointerTo();
}
};
template <typename T, uint N>
struct llvm_value_t<T[N]> : llvm_value_t<T>
{
static_assert(!llvm_value_t<T>::is_vector, "llvm_value_t<> error: invalid multidimensional vector");
static_assert(!llvm_value_t<T>::is_pointer, "llvm_value_t<>: vector of pointers is not allowed");
using type = T[N];
using base = llvm_value_t<T>;
using base::base;
static constexpr uint is_vector = N;
static constexpr uint is_pointer = 0;
static llvm::Type* get_type(llvm::LLVMContext& context)
{
return llvm::VectorType::get(llvm_value_t<T>::get_type(context), N);
}
};
template <typename T, typename A1, typename A2>
struct llvm_add_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint || llvm_value_t<T>::is_float, "llvm_add_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateAdd(v1, v2);
}
if (llvm_value_t<T>::is_float)
{
return ir->CreateFAdd(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_add_t<typename T1::type, T1, T2> operator +(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T, typename A1, typename A2>
struct llvm_sub_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint || llvm_value_t<T>::is_float, "llvm_sub_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateSub(v1, v2);
}
if (llvm_value_t<T>::is_float)
{
return ir->CreateFSub(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_sub_t<typename T1::type, T1, T2> operator -(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T, typename A1, typename A2>
struct llvm_mul_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint || llvm_value_t<T>::is_float, "llvm_mul_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateMul(v1, v2);
}
if (llvm_value_t<T>::is_float)
{
return ir->CreateFMul(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_mul_t<typename T1::type, T1, T2> operator *(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T, typename A1, typename A2>
struct llvm_div_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint || llvm_value_t<T>::is_float, "llvm_div_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_sint)
{
return ir->CreateSDiv(v1, v2);
}
if (llvm_value_t<T>::is_uint)
{
return ir->CreateUDiv(v1, v2);
}
if (llvm_value_t<T>::is_float)
{
return ir->CreateFDiv(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_div_t<typename T1::type, T1, T2> operator /(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T, typename A1>
struct llvm_neg_t
{
using type = T;
A1 a1;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint || llvm_value_t<T>::is_float, "llvm_neg_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateNeg(v1);
}
if (llvm_value_t<T>::is_float)
{
return ir->CreateFNeg(v1);
}
}
};
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::esize>>
inline llvm_neg_t<typename T1::type, T1> operator -(T1 a1)
{
return {a1};
}
// Constant int helper
struct llvm_int_t
{
u64 value;
u64 eval(llvm::IRBuilder<>*) const
{
return value;
}
};
template <typename T, typename A1, typename A2>
struct llvm_shl_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint, "llvm_shl_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_sint)
{
return ir->CreateShl(v1, v2);
}
if (llvm_value_t<T>::is_uint)
{
return ir->CreateShl(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_shl_t<typename T1::type, T1, T2> operator <<(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::is_int>>
inline llvm_shl_t<typename T1::type, T1, llvm_int_t> operator <<(T1 a1, u64 a2)
{
return {a1, llvm_int_t{a2}};
}
template <typename T, typename A1, typename A2>
struct llvm_shr_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint, "llvm_shr_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_sint)
{
return ir->CreateAShr(v1, v2);
}
if (llvm_value_t<T>::is_uint)
{
return ir->CreateLShr(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_shr_t<typename T1::type, T1, T2> operator >>(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::is_int>>
inline llvm_shr_t<typename T1::type, T1, llvm_int_t> operator >>(T1 a1, u64 a2)
{
return {a1, llvm_int_t{a2}};
}
template <typename T, typename A1, typename A2>
struct llvm_and_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_int, "llvm_and_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateAnd(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_and_t<typename T1::type, T1, T2> operator &(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::is_int>>
inline llvm_and_t<typename T1::type, T1, llvm_int_t> operator &(T1 a1, u64 a2)
{
return {a1, llvm_int_t{a2}};
}
template <typename T, typename A1, typename A2>
struct llvm_or_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_int, "llvm_or_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateOr(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_or_t<typename T1::type, T1, T2> operator |(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::is_int>>
inline llvm_or_t<typename T1::type, T1, llvm_int_t> operator |(T1 a1, u64 a2)
{
return {a1, llvm_int_t{a2}};
}
template <typename T, typename A1, typename A2>
struct llvm_xor_t
{
using type = T;
A1 a1;
A2 a2;
static_assert(llvm_value_t<T>::is_int, "llvm_xor_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
const auto v2 = a2.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateXor(v1, v2);
}
}
};
template <typename T1, typename T2, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<std::is_same<typename T1::type, typename T2::type>::value>>
inline llvm_xor_t<typename T1::type, T1, T2> operator ^(T1 a1, T2 a2)
{
return {a1, a2};
}
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::is_int>>
inline llvm_xor_t<typename T1::type, T1, llvm_int_t> operator ^(T1 a1, u64 a2)
{
return {a1, llvm_int_t{a2}};
}
template <typename T, typename A1>
struct llvm_not_t
{
using type = T;
A1 a1;
static_assert(llvm_value_t<T>::is_int, "llvm_not_t<>: invalid type");
llvm::Value* eval(llvm::IRBuilder<>* ir) const
{
const auto v1 = a1.eval(ir);
if (llvm_value_t<T>::is_int)
{
return ir->CreateNot(v1);
}
}
};
template <typename T1, typename = decltype(std::declval<T1>().eval(0)), typename = std::enable_if_t<llvm_value_t<typename T1::type>::is_int>>
inline llvm_not_t<typename T1::type, T1> operator ~(T1 a1)
{
return {a1};
}
class cpu_translator
{
protected:
cpu_translator(llvm::LLVMContext& context, llvm::Module* module, bool is_be);
// LLVM context
llvm::LLVMContext& m_context;
// Module to which all generated code is output to
llvm::Module* const m_module;
// Endianness, affects vector element numbering (TODO)
const bool m_is_be;
// IR builder
llvm::IRBuilder<>* m_ir;
public:
// Convert a C++ type to an LLVM type (TODO: remove)
template <typename T>
llvm::Type* GetType()
{
return llvm_value_t<T>::get_type(m_context);
}
template <typename T>
llvm::Type* get_type()
{
return llvm_value_t<T>::get_type(m_context);
}
template <typename T>
using value_t = llvm_value_t<T>;
template <typename T>
auto eval(T expr)
{
value_t<typename T::type> result;
result.value = expr.eval(m_ir);
return result;
}
// Get unsigned addition carry into the sign bit (s = a + b)
template <typename T>
static inline auto ucarry(T a, T b, T s)
{
return ((a ^ b) & ~s) | (a & b);
}
// Get signed addition overflow into the sign bit (s = a + b)
template <typename T>
static inline auto scarry(T a, T b, T s)
{
return (b ^ s) & ~(a ^ b);
}
// Get signed subtraction overflow into the sign bit (d = a - b)
template <typename T>
static inline auto sborrow(T a, T b, T d)
{
return (a ^ b) & (a ^ d);
}
// Bitwise select (c ? a : b)
template <typename T>
static inline auto merge(T c, T a, T b)
{
return (a & c) | (b & ~c);
}
// Average: (a + b + 1) >> 1
template <typename T>
static inline auto avg(T a, T b)
{
return (a >> 1) + (b >> 1) + ((a | b) & 1);
}
};
#endif
+102 -148
View File
@@ -3,7 +3,6 @@
#include "Emu/Memory/vm.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/System.h"
#include "MFC.h"
const bool s_use_rtm = utils::has_rtm();
@@ -51,13 +50,6 @@ void fmt_class_string<MFC>::format(std::string& out, u64 arg)
case MFC_BARRIER_CMD: return "BARRIER";
case MFC_EIEIO_CMD: return "EIEIO";
case MFC_SYNC_CMD: return "SYNC";
case MFC_BARRIER_MASK:
case MFC_FENCE_MASK:
case MFC_LIST_MASK:
case MFC_START_MASK:
case MFC_RESULT_MASK:
break;
}
return unknown;
@@ -143,142 +135,107 @@ void mfc_thread::cpu_task()
if (queue_size)
{
u32 fence_mask = 0; // Using this instead of stall_mask to avoid a possible race condition
u32 barrier_mask = 0;
bool first = true;
for (u32 i = 0; i < spu.mfc_queue.size(); i++, first = false)
auto& cmd = spu.mfc_queue[0];
if ((cmd.cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) == MFC_PUTQLLUC_CMD)
{
auto& cmd = spu.mfc_queue[i];
auto& data = vm::ps3::_ref<decltype(spu.rdata)>(cmd.eal);
const auto to_write = spu._ref<decltype(spu.rdata)>(cmd.lsa & 0x3ffff);
// this check all revolves around a potential 'stalled list' in the queue as its the one thing that can cause out of order mfc list execution currently
// a list with barrier hard blocks that tag until it's been dealt with
// and a new command that has a fence cant be executed until the stalled list has been dealt with
if ((cmd.size != 0) && ((barrier_mask & (1u << cmd.tag)) || ((cmd.cmd & MFC_FENCE_MASK) && ((1 << cmd.tag) & fence_mask))))
continue;
cmd.size = 0;
no_updates = 0;
if ((cmd.cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) == MFC_PUTQLLUC_CMD)
vm::reservation_acquire(cmd.eal, 128);
// Store unconditionally
if (s_use_rtm && utils::transaction_enter())
{
auto& data = vm::ps3::_ref<decltype(spu.rdata)>(cmd.eal);
const auto to_write = spu._ref<decltype(spu.rdata)>(cmd.lsa & 0x3ffff);
if (!vm::reader_lock{vm::try_to_lock})
{
_xabort(0);
}
cmd.size = 0;
data = to_write;
vm::reservation_update(cmd.eal, 128);
vm::notify(cmd.eal, 128);
_xend();
}
else
{
vm::writer_lock lock(0);
data = to_write;
vm::reservation_update(cmd.eal, 128);
vm::notify(cmd.eal, 128);
}
}
else if (cmd.cmd & MFC_LIST_MASK)
{
struct list_element
{
be_t<u16> sb; // Stall-and-Notify bit (0x8000)
be_t<u16> ts; // List Transfer Size
be_t<u32> ea; // External Address Low
};
if (cmd.size && (spu.ch_stall_mask & (1u << cmd.tag)) == 0)
{
cmd.lsa &= 0x3fff0;
const list_element item = spu._ref<list_element>(cmd.eal & 0x3fff8);
const u32 size = item.ts;
const u32 addr = item.ea;
if (size)
{
spu_mfc_cmd transfer;
transfer.eal = addr;
transfer.eah = 0;
transfer.lsa = cmd.lsa | (addr & 0xf);
transfer.tag = cmd.tag;
transfer.cmd = MFC(cmd.cmd & ~MFC_LIST_MASK);
transfer.size = size;
spu.do_dma_transfer(transfer);
cmd.lsa += std::max<u32>(size, 16);
}
cmd.eal += 8;
cmd.size -= 8;
no_updates = 0;
vm::reservation_acquire(cmd.eal, 128);
// Store unconditionally
if (s_use_rtm && utils::transaction_enter())
if (item.sb & 0x8000)
{
if (!vm::reader_lock{ vm::try_to_lock })
spu.ch_stall_stat.push_or(spu, 1 << cmd.tag);
const u32 evt = spu.ch_event_stat.fetch_or(SPU_EVENT_SN);
if (evt & SPU_EVENT_WAITING)
{
_xabort(0);
spu.notify();
}
data = to_write;
vm::reservation_update(cmd.eal, 128);
vm::notify(cmd.eal, 128);
_xend();
}
else
{
vm::writer_lock lock(0);
data = to_write;
vm::reservation_update(cmd.eal, 128);
vm::notify(cmd.eal, 128);
}
}
else if (cmd.cmd & MFC_LIST_MASK && LIKELY(cmd.cmd != MFC_SYNC_CMD))
{
struct list_element
{
be_t<u16> sb; // Stall-and-Notify bit (0x8000)
be_t<u16> ts; // List Transfer Size
be_t<u32> ea; // External Address Low
};
if (cmd.size && (spu.ch_stall_mask & (1u << cmd.tag)) == 0)
{
cmd.lsa &= 0x3fff0;
// try to get the whole list done in one go
while (cmd.size != 0)
else if (evt & SPU_EVENT_INTR_ENABLED)
{
const list_element item = spu._ref<list_element>(cmd.eal & 0x3fff8);
const u32 size = item.ts;
const u32 addr = item.ea;
if (size)
{
spu_mfc_cmd transfer;
transfer.eal = addr;
transfer.eah = 0;
transfer.lsa = cmd.lsa | (addr & 0xf);
transfer.tag = cmd.tag;
transfer.cmd = MFC(cmd.cmd & ~MFC_LIST_MASK);
transfer.size = size;
spu.do_dma_transfer(transfer);
cmd.lsa += std::max<u32>(size, 16);
}
cmd.eal += 8;
cmd.size -= 8;
no_updates = 0;
// dont stall for last 'item' in list
if ((item.sb & 0x8000) && (cmd.size != 0))
{
spu.ch_stall_mask |= (1 << cmd.tag);
spu.ch_stall_stat.push_or(spu, 1 << cmd.tag);
const u32 evt = spu.ch_event_stat.fetch_or(SPU_EVENT_SN);
if (evt & SPU_EVENT_WAITING)
{
spu.notify();
}
break;
}
spu.state += cpu_flag::suspend;
}
}
}
}
else if (LIKELY(cmd.size))
{
spu.do_dma_transfer(cmd);
cmd.size = 0;
}
else if (UNLIKELY((cmd.cmd & ~0xc) == MFC_BARRIER_CMD))
{
// TODO (MFC_BARRIER_CMD, MFC_EIEIO_CMD, MFC_SYNC_CMD)
_mm_mfence();
}
if (cmd.size != 0 && (cmd.cmd & MFC_BARRIER_MASK))
barrier_mask |= (1 << cmd.tag);
else if (cmd.size != 0)
fence_mask |= (1 << cmd.tag);
}
else if (UNLIKELY((cmd.cmd & ~0xc) == MFC_BARRIER_CMD))
{
// Raw barrier commands / sync commands are tag agnostic and hard sync the mfc list
// Need to gaurentee everything ahead of it has processed before this
if (first)
cmd.size = 0;
else
break;
}
else if (LIKELY(cmd.size))
{
spu.do_dma_transfer(cmd);
cmd.size = 0;
}
if (!cmd.size && first)
{
spu.mfc_queue.end_pop();
no_updates = 0;
break;
}
else if (!cmd.size && i == 1)
{
// nasty hack, shoving stalled list down one
// this *works* from the idea that the only thing that could have been passed over in position 0 is a stalled list
// todo: this can still create a situation where we say the mfc queue is full when its actually not, which will cause a rough deadlock between spu and mfc
// which will causes a situation where the spu is waiting for the queue to open up but hasnt signaled the stall yet
spu.mfc_queue[1] = spu.mfc_queue[0];
spu.mfc_queue.end_pop();
no_updates = 0;
break;
}
if (!cmd.size)
{
spu.mfc_queue.end_pop();
no_updates = 0;
}
}
@@ -288,21 +245,26 @@ void mfc_thread::cpu_task()
{
// Mask incomplete transfers
u32 completed = spu.ch_tag_mask;
for (u32 i = 0; i < spu.mfc_queue.size(); i++)
{
for (u32 i = 0; i < spu.mfc_queue.size(); i++)
const auto& _cmd = spu.mfc_queue[i];
if (_cmd.size)
{
const auto& _cmd = spu.mfc_queue[i];
if (_cmd.size)
if (spu.ch_tag_upd == 1)
{
completed &= ~(1u << _cmd.tag);
}
else
{
completed = 0;
break;
}
}
}
if (completed && spu.ch_tag_upd.compare_and_swap_test(1, 0))
{
spu.ch_tag_stat.push(spu, completed);
no_updates = 0;
}
else if (spu.ch_tag_mask == completed && spu.ch_tag_upd.compare_and_swap_test(2, 0))
if (completed && spu.ch_tag_upd.exchange(0))
{
spu.ch_tag_stat.push(spu, completed);
no_updates = 0;
@@ -311,6 +273,7 @@ void mfc_thread::cpu_task()
test_state();
}
if (no_updates++)
{
if (no_updates >= 3)
@@ -376,12 +339,3 @@ void mfc_thread::add_spu(spu_ptr _spu)
run();
}
void mfc_thread::on_spawn()
{
if (g_cfg.core.thread_scheduler_enabled)
{
// Bind to same set with the SPUs
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(thread_class::spu));
}
}
-2
View File
@@ -113,6 +113,4 @@ public:
virtual void cpu_task() override;
virtual void add_spu(spu_ptr _spu);
virtual void on_spawn() override;
};
+1
View File
@@ -8,6 +8,7 @@ extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
}
#include "cellPamf.h"
+2 -4
View File
@@ -57,8 +57,6 @@ void audio_config::on_init(const std::shared_ptr<void>& _this)
void audio_config::on_task()
{
thread_ctrl::set_native_priority(1);
AudioDumper m_dump(g_cfg.audio.dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
float buf2ch[2 * BUFFER_SIZE]{}; // intermediate buffer for 2 channels
@@ -339,8 +337,8 @@ void audio_config::on_task()
case 8: m_dump.WriteData(&buf8ch, sizeof(buf8ch)); break; // write file data (8 ch)
}
cellAudio.trace("Audio perf: (access=%d, AddData=%d, events=%d, dump=%d)",
stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
cellAudio.trace("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
}
}
-2
View File
@@ -164,8 +164,6 @@ s32 cellCameraInit()
camera->attr[CELL_CAMERA_AGCHIGH] = { 64 };
break;
}
default:
cellCamera.todo("Trying to init cellCamera with un-researched camera type.");
}
// TODO: Some other default attributes? Need to check the actual behaviour on a real PS3.
+1 -1
View File
@@ -554,7 +554,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
//Something happens
}
//Something happens?
return CELL_OK;
return -1;
}
s32 cellFontRenderCharGlyphImageVertical()
+73 -81
View File
@@ -94,7 +94,7 @@ struct content_permission final
{
try
{
if (temp.size() > 1)
if (!temp.empty())
{
fs::remove_all(temp);
}
@@ -115,7 +115,7 @@ s32 cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 e
if (dir.size() != 9)
{
return (s32)CELL_HDDGAME_ERROR_PARAM;
return CELL_HDDGAME_ERROR_PARAM;
}
vm::var<CellHddGameCBResult> result;
@@ -144,7 +144,7 @@ s32 cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 e
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
const auto& psf = psf::load_object(fs::file(local_dir +"/PARAM.SFO"));
// Some following fields may be zero in old FW 1.00 version PARAM.SFO
// Some following fields may be zero in old FW 1.00 version PARAM.SFO
if (psf.count("PARENTAL_LEVEL") != 0) get->getParam.parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
if (psf.count("ATTRIBUTE") != 0) get->getParam.attribute = psf.at("ATTRIBUTE").as_integer();
if (psf.count("RESOLUTION") != 0) get->getParam.resolution = psf.at("RESOLUTION").as_integer();
@@ -165,7 +165,7 @@ s32 cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName, u32 e
if (result->result != CELL_HDDGAME_CBRESULT_OK && result->result != CELL_HDDGAME_CBRESULT_OK_CANCEL)
{
return (s32)CELL_HDDGAME_ERROR_CBRESULT;
return CELL_HDDGAME_ERROR_CBRESULT;
}
// TODO ?
@@ -186,7 +186,7 @@ s32 cellHddGameGetSizeKB(vm::ptr<u32> size)
if (!fs::is_dir(local_dir))
{
return (s32)CELL_HDDGAME_ERROR_FAILURE;
return CELL_HDDGAME_ERROR_FAILURE;
}
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
@@ -196,8 +196,7 @@ s32 cellHddGameGetSizeKB(vm::ptr<u32> size)
s32 cellHddGameSetSystemVer()
{
UNIMPLEMENTED_FUNC(cellGame);
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
s32 cellHddGameExitBroken()
@@ -224,8 +223,7 @@ s32 cellGameDataGetSizeKB(vm::ptr<u32> size)
s32 cellGameDataSetSystemVer()
{
UNIMPLEMENTED_FUNC(cellGame);
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
s32 cellGameDataExitBroken()
@@ -248,43 +246,51 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
size->sysSizeKB = 0;
}
if (!type)
{
return CELL_GAME_ERROR_PARAM;
}
// According to testing (in debug mode) cellGameBootCheck doesn't return an error code, when PARAM.SFO doesn't exist.
psf::registry sfo = psf::load_object(fs::file(vfs::get("/app_home/../PARAM.SFO")));
if (Emu.GetCat() == "DG")
const std::string& category = psf::get_string(sfo, "CATEGORY");
if (category == "DG")
{
*type = CELL_GAME_GAMETYPE_DISC;
*attributes = 0; // TODO
// TODO: dirName might be a read only string when BootCheck is called on a disc game. (e.g. Ben 10 Ultimate Alien: Cosmic Destruction)
if (dirName) strcpy_trunc(*dirName, ""); // ???
if (!fxm::make<content_permission>("", psf::load_object(fs::file(vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO")))))
if (!fxm::make<content_permission>("", std::move(sfo)))
{
return CELL_GAME_ERROR_BUSY;
}
}
else if (Emu.GetCat() == "GD")
else if (category == "AP" || category == "AV" || category == "HG" || category == "AT" || category == "AM" || category == "SF")
{
*type = CELL_GAME_GAMETYPE_HDD;
*attributes = 0; // TODO
if (dirName) strcpy_trunc(*dirName, Emu.GetTitleID());
if (!fxm::make<content_permission>(Emu.GetTitleID(), std::move(sfo)))
{
return CELL_GAME_ERROR_BUSY;
}
}
else if (category == "GD")
{
*type = CELL_GAME_GAMETYPE_DISC;
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
if (dirName) strcpy_trunc(*dirName, Emu.GetTitleID()); // ???
if (!fxm::make<content_permission>("", psf::load_object(fs::file(vfs::get("/dev_hdd0/game/" + Emu.GetTitleID() + "/PARAM.SFO")))))
if (!fxm::make<content_permission>("", std::move(sfo)))
{
return CELL_GAME_ERROR_BUSY;
}
}
else
{
*type = CELL_GAME_GAMETYPE_HDD;
*attributes = 0; // TODO
if (dirName) strcpy_trunc(*dirName, Emu.GetTitleID());
if (!fxm::make<content_permission>(Emu.GetTitleID(), psf::load_object(fs::file(vfs::get("/dev_hdd0/game/" + Emu.GetTitleID() + "/PARAM.SFO")))))
{
return CELL_GAME_ERROR_BUSY;
}
// Hack: When there is no (or unknown) CATEGORY returned, instead of throwing an exception
// we assume it's a disk game.
*type = CELL_GAME_GAMETYPE_DISC;
*attributes = 0;
cellGame.error("cellGameBootCheck(): Unknown CATEGORY: %s", category);
}
return CELL_OK;
@@ -304,16 +310,18 @@ error_code cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> r
size->sysSizeKB = 0;
}
if (Emu.GetCat() != "GD")
psf::registry sfo = psf::load_object(fs::file(vfs::get("/app_home/../PARAM.SFO")));
if (psf::get_string(sfo, "CATEGORY") != "GD")
{
return CELL_GAME_ERROR_NOTPATCH;
}
if (!fxm::make<content_permission>(Emu.GetTitleID(), psf::load_object(fs::file(vfs::get("/dev_hdd0/game/" + Emu.GetTitleID() + "/PARAM.SFO")))))
if (!fxm::make<content_permission>(Emu.GetTitleID(), std::move(sfo)))
{
return CELL_GAME_ERROR_BUSY;
}
return CELL_OK;
}
@@ -321,9 +329,9 @@ error_code cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameC
{
cellGame.warning("cellGameDataCheck(type=%d, dirName=%s, size=*0x%x)", type, dirName, size);
if ((type - 1) >= 3 || (type != CELL_GAME_GAMETYPE_DISC && !dirName))
if ((type - 1) >= 3)
{
return {CELL_GAME_ERROR_PARAM, type};
return CELL_GAME_ERROR_PARAM;
}
if (size)
@@ -367,7 +375,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
}
const auto prm = fxm::get<content_permission>();
if (!prm)
{
return CELL_GAME_ERROR_FAILURE;
@@ -404,7 +412,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
strcpy_trunc(*contentInfoPath, dir);
strcpy_trunc(*usrdirPath, dir + "/USRDIR");
verify(HERE), fxm::remove<content_permission>();
return CELL_OK;
}
@@ -412,7 +420,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
{
cellGame.error("cellGameDataCheckCreate2(version=0x%x, dirName=%s, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
//older sdk. it might not care about game type.
//older sdk. it might not care about game type.
if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1)
{
@@ -421,7 +429,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
// TODO: output errors (errDialog)
const std::string dir = "/dev_hdd0/game/"s + dirName.get_ptr();
const std::string& dir = "/dev_hdd0/game/"s + dirName.get_ptr();
vm::var<CellGameDataCBResult> cbResult;
vm::var<CellGameDataStatGet> cbGet;
@@ -431,7 +439,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
cbGet->hddFreeSizeKB = 40000000; //40 GB
strcpy_trunc(cbGet->contentInfoPath, dir);
strcpy_trunc(cbGet->gameDataPath, dir + "/USRDIR");
@@ -444,7 +452,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
cbGet->sizeKB = CELL_GAMEDATA_SIZEKB_NOTCALC;
cbGet->sysSizeKB = 0;
psf::registry sfo = psf::load_object(fs::file(vfs::get(Emu.GetCat() == "DG" ? "/dev_bdvd/PS3_GAME/PARAM.SFO"s : "/dev_hdd0/game/" + Emu.GetTitleID() + "/PARAM.SFO")));
psf::registry sfo = psf::load_object(fs::file(vfs::get("/app_home/../PARAM.SFO")));
cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL;
cbGet->getParam.parentalLevel = psf::get_integer(sfo, "PARENTAL_LEVEL", 0);
@@ -456,58 +464,52 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
strcpy_trunc(cbGet->getParam.titleLang[i], psf::get_string(sfo, fmt::format("TITLE_%02d", i)));
}
funcStat(ppu, cbResult, cbGet, cbSet);
switch ((s32)cbResult->result)
{
case CELL_GAMEDATA_CBRESULT_OK_CANCEL:
{
// TODO: do not process game data(directory)
cellGame.warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL");
return CELL_OK;
}
case CELL_GAMEDATA_CBRESULT_OK:
{
// Game confirmed that it wants to create directory
const std::string usrdir = dir + "/USRDIR";
const std::string vusrdir = vfs::get(usrdir);
if (!fs::is_dir(vusrdir) && !fs::create_path(vusrdir))
{
return {CELL_GAME_ERROR_ACCESS_ERROR, usrdir};
}
case CELL_GAMEDATA_CBRESULT_OK:
//game confirmed that it wants to create directory
if (!fs::is_dir(vfs::get(dir + "/USRDIR")) && !fs::create_path(vfs::get(dir + "/USRDIR")))
{
cellGame.error("cellGameDataCheckCreate2(): folder creation failed");
return CELL_GAME_ERROR_NOSPACE; //don't know which error. picked one at random
}
if (cbSet->setParam)
{
psf::assign(sfo, "CATEGORY", psf::string(3, "GD"));
psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, cbSet->setParam->titleId));
psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->title));
psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, cbSet->setParam->dataVersion));
psf::assign(sfo, "PARENTAL_LEVEL", cbSet->setParam->parentalLevel.value());
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
{
if (!cbSet->setParam->titleLang[i][0])
{
continue;
}
psf::assign(sfo, fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->titleLang[i]));
}
const auto vdir = vfs::get(dir);
//older SDK does not define not settable values, hopefully it doesn't just change some values(overwrite)
psf::registry sfo_write =
{
{ "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, cbSet->setParam->titleId) },
{ "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->title) },
{ "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, cbSet->setParam->dataVersion) },
{ "PARENTAL_LEVEL", cbSet->setParam->parentalLevel.value() }
};
//sfo_write.emplace("PARENTAL_LEVEL", cbSet->setParam->parentalLevel.value()); // I don't care about age restrictions.
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
{
sfo_write.emplace(fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->titleLang[i]));
}
if (!fs::is_dir(vdir))
{
return {CELL_GAME_ERROR_INTERNAL, dir};
cellGame.fatal("directory where param.sfo is to be created does not exist");
return CELL_GAME_ERROR_INTERNAL;
}
psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), sfo_write);
psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), sfo);
}
return CELL_OK;
}
case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result
cellGame.error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE");
return CELL_GAMEDATA_ERROR_CBRESULT;
@@ -657,11 +659,6 @@ error_code cellGameGetParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
{
cellGame.warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize);
if (!buf || bufsize == 0)
{
return CELL_GAME_ERROR_PARAM;
}
const auto prm = fxm::get<content_permission>();
if (!prm)
@@ -688,11 +685,6 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
{
cellGame.warning("cellGameSetParamString(id=%d, buf=*0x%x)", id, buf);
if (!buf)
{
return CELL_GAME_ERROR_PARAM;
}
const auto prm = fxm::get<content_permission>();
if (!prm)
@@ -717,7 +709,7 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
case CELL_GAME_PARAMID_APP_VER: max_size = CELL_GAME_SYSP_APP_VER_SIZE; break;
}
psf::assign(prm->sfo, key, psf::string(max_size, buf.get_ptr()));
prm->sfo.emplace(key, psf::string(max_size, buf.get_ptr()));
return CELL_OK;
}
+5 -5
View File
@@ -100,7 +100,7 @@ u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode)
((led&(CELL_KB_LED_CAPS_LOCK)) ? 0 : 0x20) :
((led&(CELL_KB_LED_CAPS_LOCK)) ? 0x20 : 0);
return rawcode + 0x5D;
}
}
if (rawcode >= 0x1E && rawcode <= 0x26) return rawcode + 0x13; // '1' - '9'
if (rawcode == 0x27) return 0x30; // '0'
if (rawcode == 0x28) return 0x0A; // '\n'
@@ -136,7 +136,7 @@ error_code cellKbGetInfo(vm::ptr<CellKbInfo> info)
{
info->status[i] = current_info.status[i];
}
return CELL_OK;
}
@@ -165,7 +165,7 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
}
current_data.len = 0;
return CELL_OK;
}
@@ -180,7 +180,7 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
KbConfig& current_config = handler->GetConfig(port_no);
current_config.code_type = type;
return CELL_OK;
@@ -203,7 +203,7 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
KbConfig& current_config = handler->GetConfig(port_no);
current_config.read_mode = rmode;
+8 -13
View File
@@ -74,7 +74,7 @@ s32 cellMouseGetInfo(vm::ptr<CellMouseInfo> info)
for (u32 i=0; i<CELL_MAX_MICE; i++) info->vendor_id[i] = current_info.vendor_id[i];
for (u32 i=0; i<CELL_MAX_MICE; i++) info->product_id[i] = current_info.product_id[i];
for (u32 i=0; i<CELL_MAX_MICE; i++) info->status[i] = current_info.status[i];
return CELL_OK;
}
@@ -96,7 +96,7 @@ s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr<CellMouseInfoTablet> info)
info->is_supported = 0; // Unimplemented: (0=Tablet mode is not supported)
info->mode = 1; // Unimplemented: (1=Mouse mode)
return CELL_OK;
}
@@ -115,7 +115,7 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
}
MouseData& current_data = handler->GetData(port_no);
data->update = current_data.update;
data->buttons = current_data.buttons;
@@ -134,27 +134,22 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
{
sys_io.todo("cellMouseGetDataList(port_no=%d, data=0x%x", port_no, data);
if (g_cfg.io.mouse == mouse_handler::null)
return CELL_MOUSE_ERROR_NO_DEVICE;
else
{
data->list_num = 0;
return CELL_OK;
}
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
s32 cellMouseSetTabletMode(u32 port_no, u32 mode)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
+13 -97
View File
@@ -2,7 +2,6 @@
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/RSX/GSRender.h"
#include "cellSysutil.h"
#include "cellMsgDialog.h"
@@ -24,7 +23,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
return CELL_MSGDIALOG_ERROR_PARAM;
}
const MsgDialogType _type = {type ^ CELL_MSGDIALOG_TYPE_BG_INVISIBLE};
const MsgDialogType _type = { type };
switch (_type.button_type.unshifted())
{
@@ -61,6 +60,13 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
default: return CELL_MSGDIALOG_ERROR_PARAM;
}
const auto dlg = fxm::import<MsgDialogBase>(Emu.GetCallbacks().get_msg_dialog);
if (!dlg)
{
return CELL_SYSUTIL_ERROR_BUSY;
}
if (_type.se_mute_on)
{
// TODO
@@ -75,33 +81,6 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
cellSysutil.error(msgString.get_ptr());
}
if (auto rsxthr = fxm::get<GSRender>())
{
if (auto dlg = rsxthr->shell_open_message_dialog())
{
dlg->show(msgString.get_ptr(), _type, [callback, userData](s32 status)
{
if (callback)
{
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
callback(ppu, status, userData);
return CELL_OK;
});
}
});
return CELL_OK;
}
}
const auto dlg = fxm::import<MsgDialogBase>(Emu.GetCallbacks().get_msg_dialog);
if (!dlg)
{
return CELL_SYSUTIL_ERROR_BUSY;
}
dlg->type = _type;
dlg->on_close = [callback, userData, wptr = std::weak_ptr<MsgDialogBase>(dlg)](s32 status)
@@ -234,33 +213,6 @@ s32 cellMsgDialogClose(f32 delay)
{
cellSysutil.warning("cellMsgDialogClose(delay=%f)", delay);
extern u64 get_system_time();
const u64 wait_until = get_system_time() + static_cast<s64>(std::max<float>(delay, 0.0f) * 1000);
if (auto rsxthr = fxm::get<GSRender>())
{
if (auto dlg = rsxthr->shell_get_current_dialog())
{
thread_ctrl::spawn("cellMsgDialogClose() Thread", [=]
{
while (get_system_time() < wait_until)
{
if (Emu.IsStopped())
return;
if (rsxthr->shell_get_current_dialog() != dlg)
return;
std::this_thread::sleep_for(1ms);
}
dlg->close();
});
return CELL_OK;
}
}
const auto dlg = fxm::get<MsgDialogBase>();
if (!dlg)
@@ -268,6 +220,10 @@ s32 cellMsgDialogClose(f32 delay)
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
}
extern u64 get_system_time();
const u64 wait_until = get_system_time() + static_cast<s64>(std::max<float>(delay, 0.0f) * 1000);
thread_ctrl::spawn("cellMsgDialogClose() Thread", [=]()
{
while (dlg->state == MsgDialogState::Open && get_system_time() < wait_until)
@@ -287,14 +243,6 @@ s32 cellMsgDialogAbort()
{
cellSysutil.warning("cellMsgDialogAbort()");
if (auto rsxthr = fxm::get<GSRender>())
{
if (rsxthr->shell_close_dialog())
{
return CELL_OK;
}
}
const auto dlg = fxm::get<MsgDialogBase>();
if (!dlg)
@@ -315,20 +263,6 @@ s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::cptr<char> msgStrin
{
cellSysutil.warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString=%s)", progressBarIndex, msgString);
if (!msgString)
{
return CELL_MSGDIALOG_ERROR_PARAM;
}
if (auto rsxthr = fxm::get<GSRender>())
{
if (auto dlg2 = rsxthr->shell_get_current_dialog())
{
if (auto casted = dynamic_cast<rsx::overlays::message_dialog*>(dlg2))
return casted->progress_bar_set_message(progressBarIndex, msgString.get_ptr());
}
}
const auto dlg = fxm::get<MsgDialogBase>();
if (!dlg)
@@ -336,7 +270,7 @@ s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::cptr<char> msgStrin
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
}
if (progressBarIndex >= dlg->type.progress_bar_count)
if (progressBarIndex >= dlg->type.progress_bar_count || !msgString)
{
return CELL_MSGDIALOG_ERROR_PARAM;
}
@@ -353,15 +287,6 @@ s32 cellMsgDialogProgressBarReset(u32 progressBarIndex)
{
cellSysutil.warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex);
if (auto rsxthr = fxm::get<GSRender>())
{
if (auto dlg2 = rsxthr->shell_get_current_dialog())
{
if (auto casted = dynamic_cast<rsx::overlays::message_dialog*>(dlg2))
return casted->progress_bar_reset(progressBarIndex);
}
}
const auto dlg = fxm::get<MsgDialogBase>();
if (!dlg)
@@ -386,15 +311,6 @@ s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta)
{
cellSysutil.warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta);
if (auto rsxthr = fxm::get<GSRender>())
{
if (auto dlg2 = rsxthr->shell_get_current_dialog())
{
if (auto casted = dynamic_cast<rsx::overlays::message_dialog*>(dlg2))
return casted->progress_bar_increment(progressBarIndex, (f32)delta);
}
}
const auto dlg = fxm::get<MsgDialogBase>();
if (!dlg)
-1
View File
@@ -84,7 +84,6 @@ public:
virtual ~MsgDialogBase();
virtual void Create(const std::string& msg) = 0;
virtual void CreateOsk(const std::string& msg, char16_t* osk_text, u32 charlimit) = 0;
virtual void SetMsg(const std::string& msg) = 0;
virtual void ProgressBarSetMsg(u32 progressBarIndex, const std::string& msg) = 0;
virtual void ProgressBarReset(u32 progressBarIndex) = 0;
virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) = 0;
+7 -39
View File
@@ -202,7 +202,7 @@ error_code cellNetCtlGetNatInfo(vm::ptr<CellNetCtlNatInfo> natInfo)
cellNetCtl.error("cellNetCtlGetNatInfo : CELL_NET_CTL_ERROR_INVALID_SIZE");
return CELL_NET_CTL_ERROR_INVALID_SIZE;
}
return CELL_OK;
}
@@ -266,37 +266,21 @@ error_code cellGameUpdateTerm()
return CELL_OK;
}
error_code cellGameUpdateCheckStartAsync(ppu_thread& ppu, vm::cptr<CellGameUpdateParam> param, vm::ptr<CellGameUpdateCallback> cb_func, vm::ptr<void> userdata)
error_code cellGameUpdateCheckStartAsync(vm::cptr<CellGameUpdateParam> param, vm::ptr<CellGameUpdateCallback> cb_func, vm::ptr<void> userdata)
{
cellNetCtl.todo("cellGameUpdateCheckStartAsync(param=*0x%x, cb_func=*0x%x, userdata=*0x%x)", param, cb_func, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb_func(ppu, CELL_OK, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
}
error_code cellGameUpdateCheckFinishAsync(ppu_thread& ppu, vm::ptr<CellGameUpdateCallback> cb_func, vm::ptr<void> userdata)
error_code cellGameUpdateCheckFinishAsync(vm::ptr<CellGameUpdateCallback> cb_func, vm::ptr<void> userdata)
{
cellNetCtl.todo("cellGameUpdateCheckFinishAsync(cb_func=*0x%x, userdata=*0x%x)", cb_func, userdata);
const u32 PROCESSING_COMPLETE = 5;
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb_func(ppu, PROCESSING_COMPLETE, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
}
error_code cellGameUpdateCheckStartWithoutDialogAsync(ppu_thread& ppu, vm::ptr<CellGameUpdateCallback> cb_func, vm::ptr<void> userdata)
error_code cellGameUpdateCheckStartWithoutDialogAsync(vm::ptr<CellGameUpdateCallback> cb_func, vm::ptr<void> userdata)
{
cellNetCtl.todo("cellGameUpdateCheckStartWithoutDialogAsync(cb_func=*0x%x, userdata=*0x%x)", cb_func, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb_func(ppu, CELL_OK, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
}
@@ -306,37 +290,21 @@ error_code cellGameUpdateCheckAbort()
return CELL_OK;
}
error_code cellGameUpdateCheckStartAsyncEx(ppu_thread& ppu, vm::cptr<CellGameUpdateParam> param, vm::ptr<CellGameUpdateCallbackEx> cb_func, vm::ptr<void> userdata)
error_code cellGameUpdateCheckStartAsyncEx(vm::cptr<CellGameUpdateParam> param, vm::ptr<CellGameUpdateCallbackEx> cb_func, vm::ptr<void> userdata)
{
cellNetCtl.todo("cellGameUpdateCheckStartAsyncEx(param=*0x%x, cb_func=*0x%x, userdata=*0x%x)", param, cb_func, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb_func(ppu, vm::make_var(CellGameUpdateResult{ CELL_OK, CELL_OK, 0x0, 0x0}), userdata);
return CELL_OK;
});
return CELL_OK;
}
error_code cellGameUpdateCheckFinishAsyncEx(ppu_thread& ppu, vm::ptr<CellGameUpdateCallbackEx> cb_func, vm::ptr<void> userdata)
error_code cellGameUpdateCheckFinishAsyncEx(vm::ptr<CellGameUpdateCallbackEx> cb_func, vm::ptr<void> userdata)
{
cellNetCtl.todo("cellGameUpdateCheckFinishAsyncEx(cb_func=*0x%x, userdata=*0x%x)", cb_func, userdata);
const s32 PROCESSING_COMPLETE = 5;
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb_func(ppu, vm::make_var(CellGameUpdateResult{ PROCESSING_COMPLETE, CELL_OK, 0x0, 0x0}), userdata);
return CELL_OK;
});
return CELL_OK;
}
error_code cellGameUpdateCheckStartWithoutDialogAsyncEx(ppu_thread& ppu, vm::ptr<CellGameUpdateCallbackEx> cb_func, vm::ptr<void> userdata)
error_code cellGameUpdateCheckStartWithoutDialogAsyncEx(vm::ptr<CellGameUpdateCallbackEx> cb_func, vm::ptr<void> userdata)
{
cellNetCtl.todo("cellGameUpdateCheckStartWithoutDialogAsyncEx(cb_func=*0x%x, userdata=*0x%x)", cb_func, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb_func(ppu, vm::make_var(CellGameUpdateResult{ CELL_OK, CELL_OK, 0x0, 0x0}), userdata);
return CELL_OK;
});
return CELL_OK;
}
+70 -99
View File
@@ -45,15 +45,14 @@ s32 cellPadClearBuf(u32 port_no)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
//Set 'm_buffer_cleared' to force a resend of everything
//might as well also reset everything in our pad 'buffer' to nothing as well
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
auto& pads = handler->GetPads();
auto pad = pads[port_no];
pad->m_buffer_cleared = true;
pad->m_analog_left_x = pad->m_analog_left_y = pad->m_analog_right_x = pad->m_analog_right_y = 128;
@@ -66,7 +65,7 @@ s32 cellPadClearBuf(u32 port_no)
//~399 on sensor y is a level non moving controller
pad->m_sensor_y = 399;
pad->m_sensor_x = pad->m_sensor_z = pad->m_sensor_g = 512;
return CELL_OK;
}
@@ -79,18 +78,19 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
auto& pads = handler->GetPads();
const PadInfo& rinfo = handler->GetInfo();
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
//We have a choice here of NO_DEVICE or READ_FAILED...lets try no device for now
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
auto pad = pads[port_no];
u16 d1Initial, d2Initial;
d1Initial = pad->m_digital_1;
d2Initial = pad->m_digital_2;
@@ -107,21 +107,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_LEFT:
case CELL_PAD_CTRL_LEFT:
if (pad->m_press_left != button.m_value) btnChanged = true;
pad->m_press_left = button.m_value;
break;
case CELL_PAD_CTRL_DOWN:
case CELL_PAD_CTRL_DOWN:
if (pad->m_press_down != button.m_value) btnChanged = true;
pad->m_press_down = button.m_value;
pad->m_press_down = button.m_value;
break;
case CELL_PAD_CTRL_RIGHT:
case CELL_PAD_CTRL_RIGHT:
if (pad->m_press_right != button.m_value) btnChanged = true;
pad->m_press_right = button.m_value;
pad->m_press_right = button.m_value;
break;
case CELL_PAD_CTRL_UP:
case CELL_PAD_CTRL_UP:
if (pad->m_press_up != button.m_value) btnChanged = true;
pad->m_press_up = button.m_value;
pad->m_press_up = button.m_value;
break;
//These arent pressure btns
case CELL_PAD_CTRL_R3:
@@ -144,9 +144,9 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
break;
case CELL_PAD_CTRL_CROSS:
if (pad->m_press_cross != button.m_value) btnChanged = true;
pad->m_press_cross = button.m_value;
pad->m_press_cross = button.m_value;
break;
case CELL_PAD_CTRL_CIRCLE:
case CELL_PAD_CTRL_CIRCLE:
if (pad->m_press_circle != button.m_value) btnChanged = true;
pad->m_press_circle = button.m_value;
break;
@@ -154,21 +154,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
if (pad->m_press_triangle != button.m_value) btnChanged = true;
pad->m_press_triangle = button.m_value;
break;
case CELL_PAD_CTRL_R1:
case CELL_PAD_CTRL_R1:
if (pad->m_press_R1 != button.m_value) btnChanged = true;
pad->m_press_R1 = button.m_value;
pad->m_press_R1 = button.m_value;
break;
case CELL_PAD_CTRL_L1:
case CELL_PAD_CTRL_L1:
if (pad->m_press_L1 != button.m_value) btnChanged = true;
pad->m_press_L1 = button.m_value;
pad->m_press_L1 = button.m_value;
break;
case CELL_PAD_CTRL_R2:
case CELL_PAD_CTRL_R2:
if (pad->m_press_R2 != button.m_value) btnChanged = true;
pad->m_press_R2 = button.m_value;
pad->m_press_R2 = button.m_value;
break;
case CELL_PAD_CTRL_L2:
case CELL_PAD_CTRL_L2:
if (pad->m_press_L2 != button.m_value) btnChanged = true;
pad->m_press_L2 = button.m_value;
pad->m_press_L2 = button.m_value;
break;
default: break;
}
@@ -186,21 +186,21 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
{
switch (stick.m_offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
pad->m_analog_left_x = stick.m_value;
pad->m_analog_left_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
pad->m_analog_left_y = stick.m_value;
pad->m_analog_left_y = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
pad->m_analog_right_x = stick.m_value;
pad->m_analog_right_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
pad->m_analog_right_y = stick.m_value;
pad->m_analog_right_y = stick.m_value;
break;
default: break;
}
@@ -235,6 +235,7 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
btnChanged = true;
}
// the real hardware only fills the buffer up to "len" elements (16 bit each)
if (pad->m_port_setting & CELL_PAD_SETTING_SENSOR_ON)
{
@@ -265,7 +266,7 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
}
pad->m_buffer_cleared = false;
// only update parts of the output struct depending on the controller setting
if (data->len > CELL_PAD_LEN_NO_CHANGE)
{
@@ -327,7 +328,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
const auto& pads = handler->GetPads();
auto& pads = handler->GetPads();
// TODO: Support other types of controllers
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
@@ -336,7 +337,6 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
break;
info->port_status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = pads[i]->m_port_setting;
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
@@ -359,11 +359,7 @@ s32 cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
// todo: support for 'unique' controllers, which goes in offsets 24+ in padData
@@ -390,11 +386,7 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadDa
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
// TODO: This is used just to get data from a BD/CEC remote,
@@ -422,11 +414,7 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
handler->SetRumble(port_no, param->motor[1], param->motor[0] > 0);
@@ -450,7 +438,7 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
const auto& pads = handler->GetPads();
auto& pads = handler->GetPads();
for (u32 i=0; i<CELL_MAX_PADS; ++i)
{
@@ -482,7 +470,7 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
const auto& pads = handler->GetPads();
auto& pads = handler->GetPads();
for (u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
{
@@ -512,15 +500,13 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto& pads = handler->GetPads();
//Should return the same as device capability mask, psl1ght has it backwards in pad->h
info->info[0] = pad->m_device_capability;
info->info[0] = pads[port_no]->m_device_capability;
return CELL_OK;
}
@@ -538,15 +524,12 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
pad->m_port_setting = port_setting;
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
auto& pads = handler->GetPads();
pads[port_no]->m_port_setting = port_setting;
return CELL_OK;
}
@@ -563,14 +546,12 @@ s32 cellPadInfoPressMode(u32 port_no)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
return (pad->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
const auto& pads = handler->GetPads();
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
}
s32 cellPadInfoSensorMode(u32 port_no)
@@ -586,14 +567,12 @@ s32 cellPadInfoSensorMode(u32 port_no)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
return (pad->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
const auto& pads = handler->GetPads();
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
}
s32 cellPadSetPressMode(u32 port_no, u32 mode)
@@ -612,17 +591,15 @@ s32 cellPadSetPressMode(u32 port_no, u32 mode)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
auto& pads = handler->GetPads();
if (mode)
pad->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
else
pad->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
return CELL_OK;
}
@@ -643,17 +620,15 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
if (port_no >= rinfo.max_connect)
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto& pads = handler->GetPads();
const auto pad = pads[port_no];
auto& pads = handler->GetPads();
if (mode)
pad->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
else
pad->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
return CELL_OK;
}
@@ -686,16 +661,12 @@ s32 cellPadLddGetPortNo(s32 handle)
{
sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle);
if (handle < 0)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
// CELL_OK would return port 0 (Nascar [BLUS30932] stopped looking for custom controllers after a few seconds, fixing normal input)
return CELL_PAD_ERROR_EBUSY;
return CELL_OK;
}
s32 cellPadLddUnregisterController(s32 handle)
+12 -65
View File
@@ -1,6 +1,5 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "cellSysutil.h"
namespace vm { using namespace ps3; }
@@ -21,16 +20,6 @@ enum
CELL_PHOTO_EXPORT_UTIL_ERROR_INITIALIZE = 0x8002c20a,
};
struct CellPhotoExportSetParam
{
vm::bptr<char> photo_title;
vm::bptr<char> game_title;
vm::bptr<char> game_comment;
vm::bptr<void> reserved;
};
using CellPhotoExportUtilFinishCallback = void(s32 result, vm::ptr<void> userdata);
s32 cellPhotoInitialize()
{
UNIMPLEMENTED_FUNC(cellPhotoExport);
@@ -49,81 +38,39 @@ s32 cellPhotoRegistFromFile()
return CELL_OK;
}
error_code cellPhotoExportInitialize(u32 version, u32 container, vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellPhotoExportInitialize()
{
cellPhotoExport.todo("cellPhotoExportInitialize(version=0x%x, container=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, container, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellPhotoExport);
return CELL_OK;
}
error_code cellPhotoExportInitialize2(u32 version, vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellPhotoExportInitialize2()
{
cellPhotoExport.todo("cellPhotoExportInitialize2(version=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellPhotoExport);
return CELL_OK;
}
error_code cellPhotoExportFinalize(vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellPhotoExportFinalize()
{
cellPhotoExport.todo("cellPhotoExportFinalize(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellPhotoExport);
return CELL_OK;
}
error_code cellPhotoExportFromFile(vm::cptr<char> srcHddDir, vm::cptr<char> srcHddFile, vm::ptr<CellPhotoExportSetParam> param, vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellPhotoExportFromFile()
{
cellPhotoExport.todo("cellPhotoExportFromFile(srcHddDir=%s, srcHddFile=%s, param=*0x%x, funcFinish=*0x%x, userdata=*0x%x)", srcHddDir, srcHddFile, param, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellPhotoExport);
return CELL_OK;
}
error_code cellPhotoExportFromFileWithCopy(vm::cptr<char> srcHddDir, vm::cptr<char> srcHddFile, vm::ptr<CellPhotoExportSetParam> param, vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellPhotoExportFromFileWithCopy()
{
cellPhotoExport.todo("cellPhotoExportFromFileWithCopy(srcHddDir=%s, srcHddFile=%s, param=*0x%x, funcFinish=*0x%x, userdata=*0x%x)", srcHddDir, srcHddFile, param, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellPhotoExport);
return CELL_OK;
}
error_code cellPhotoExportProgress(vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellPhotoExportProgress()
{
cellPhotoExport.todo("cellPhotoExportProgress(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, 0xFFFF, userdata); // 0-0xFFFF where 0xFFFF = 100%
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellPhotoExport);
return CELL_OK;
}
+5 -58
View File
@@ -1,22 +1,10 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
#include "cellSysutil.h"
namespace vm { using namespace ps3; }
logs::channel cellRec("cellRec");
enum
{
CELL_REC_STATUS_UNLOAD = 0,
CELL_REC_STATUS_OPEN = 1,
CELL_REC_STATUS_START = 2,
CELL_REC_STATUS_STOP = 3,
CELL_REC_STATUS_CLOSE = 4,
CELL_REC_STATUS_ERR = 10
};
struct CellRecSpursParam
{
vm::bptr<struct CellSpurs> pSpurs;
@@ -58,40 +46,15 @@ struct CellRecParam
using CellRecCallback = void(s32 recStatus, s32 recError, vm::ptr<void> userdata);
struct rec_t
{
vm::ptr<CellRecCallback> cb;
vm::ptr<void> cbUserData;
};
error_code cellRecOpen(vm::cptr<char> pDirName, vm::cptr<char> pFileName, vm::cptr<CellRecParam> pParam, u32 container, vm::ptr<CellRecCallback> cb, vm::ptr<void> cbUserData)
s32 cellRecOpen(vm::cptr<char> pDirName, vm::cptr<char> pFileName, vm::cptr<CellRecParam> pParam, u32 container, vm::ptr<CellRecCallback> cb, vm::ptr<void> cbUserData)
{
cellRec.todo("cellRecOpen(pDirName=%s, pFileName=%s, pParam=*0x%x, container=0x%x, cb=*0x%x, cbUserData=*0x%x)", pDirName, pFileName, pParam, container, cb, cbUserData);
const auto rec = fxm::make_always<rec_t>();
rec->cb = cb;
rec->cbUserData = cbUserData;
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
cb(ppu, CELL_REC_STATUS_OPEN, CELL_OK, cbUserData);
return CELL_OK;
});
return CELL_OK;
}
error_code cellRecClose(s32 isDiscard)
s32 cellRecClose(s32 isDiscard)
{
cellRec.todo("cellRecClose(isDiscard=0x%x)", isDiscard);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto rec = fxm::get_always<rec_t>();
rec->cb(ppu, CELL_REC_STATUS_CLOSE, CELL_OK, rec->cbUserData);
return CELL_OK;
});
return CELL_OK;
}
@@ -100,31 +63,15 @@ void cellRecGetInfo(s32 info, vm::ptr<u64> pValue)
cellRec.todo("cellRecGetInfo(info=0x%x, pValue=*0x%x)", info, pValue);
}
error_code cellRecStop()
s32 cellRecStop()
{
cellRec.todo("cellRecStop()");
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto rec = fxm::get_always<rec_t>();
rec->cb(ppu, CELL_REC_STATUS_STOP, CELL_OK, rec->cbUserData);
return CELL_OK;
});
return CELL_OK;
}
error_code cellRecStart()
s32 cellRecStart()
{
cellRec.todo("cellRecStart()");
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto rec = fxm::get_always<rec_t>();
rec->cb(ppu, CELL_REC_STATUS_START, CELL_OK, rec->cbUserData);
return CELL_OK;
});
return CELL_OK;
}
@@ -134,7 +81,7 @@ u32 cellRecQueryMemSize(vm::cptr<CellRecParam> pParam)
return 1 * 1024 * 1024; // dummy memory size
}
error_code cellRecSetInfo(s32 setInfo, u64 value)
s32 cellRecSetInfo(s32 setInfo, u64 value)
{
cellRec.todo("cellRecSetInfo(setInfo=0x%x, value=0x%x)", setInfo, value);
return CELL_OK;
+63 -120
View File
@@ -37,8 +37,7 @@ enum : u32
SAVEDATA_OP_FIXED_SAVE = 6,
SAVEDATA_OP_FIXED_LOAD = 7,
SAVEDATA_OP_LIST_DELETE = 13,
SAVEDATA_OP_FIXED_DELETE = 14,
SAVEDATA_OP_FIXED_DELETE = 14,
};
namespace
@@ -53,7 +52,6 @@ namespace
CellSaveDataStatSet statSet;
CellSaveDataFileGet fileGet;
CellSaveDataFileSet fileSet;
CellSaveDataDoneGet doneGet;
};
}
@@ -83,12 +81,11 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
vm::ptr<CellSaveDataStatSet> statSet = g_savedata_context.ptr(&savedata_context::statSet);
vm::ptr<CellSaveDataFileGet> fileGet = g_savedata_context.ptr(&savedata_context::fileGet);
vm::ptr<CellSaveDataFileSet> fileSet = g_savedata_context.ptr(&savedata_context::fileSet);
vm::ptr<CellSaveDataDoneGet> doneGet = g_savedata_context.ptr(&savedata_context::doneGet);
//TODO: get current user ID
// userId(0) = CELL_SYSUTIL_USERID_CURRENT
// path of the specified user (00000001 by default)
const std::string base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u));
const std::string& base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u));
result->userdata = userdata; // probably should be assigned only once (allows the callback to change it)
@@ -101,9 +98,9 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
listGet->dirNum = 0;
listGet->dirListNum = 0;
listGet->dirList.set(setBuf->buf.addr());
std::memset(listGet->reserved, 0, sizeof(listGet->reserved));
memset(listGet->reserved, 0, sizeof(listGet->reserved));
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), {"|"});
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
// get the saves matching the supplied prefix
for (auto&& entry : fs::dir(base_dir))
@@ -152,7 +149,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (fs::is_file(base_dir + entry.name + "/ICON0.PNG"))
{
fs::file icon = fs::file(base_dir + entry.name + "/ICON0.PNG");
u64 iconSize = icon.size();
u32 iconSize = icon.size();
std::vector<uchar> iconData;
icon.read(iconData, iconSize);
save_entry2.iconBuf = iconData;
@@ -207,11 +204,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
auto& dir = *dir_list++;
strcpy_trunc(dir.dirName, entry.dirName);
strcpy_trunc(dir.listParam, entry.listParam);
std::memset(dir.reserved, 0, sizeof(dir.reserved));
memset(dir.reserved, 0, sizeof(dir.reserved));
}
s32 selected = -1;
s32 focused = -1;
if (funcList)
{
@@ -221,14 +217,14 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (result->result < 0)
{
//TODO: display dialog
cellSaveData.warning("savedata_op(): funcList returned result=%d.", result->result);
cellSaveData.warning("savedata_op(): funcList returned < 0.");
return CELL_SAVEDATA_ERROR_CBRESULT;
}
// if the callback has returned ok, lets return OK.
// typically used at game launch when no list is actually required.
// CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM is only valid for funcFile and funcDone
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
{
return CELL_OK;
}
@@ -247,6 +243,19 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
return true;
}), save_entries.end());
// Add any new data (not currently supported by the UI)
//if (listSet->newData)
//{
// SaveDataEntry *_saveDataEntry = new SaveDataEntry();
// _saveDataEntry->dirName = listSet->newData->dirName.get_ptr();
// save_entry.dirName = listSet->newData->dirName.get_ptr();
// save_entries.emplace_back(*_saveDataEntry);
//}
// Focus save data
s32 focused = -1;
switch (const u32 pos_type = listSet->focusPosition)
{
case CELL_SAVEDATA_FOCUSPOS_DIRNAME:
@@ -314,49 +323,22 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
return CELL_SAVEDATA_ERROR_PARAM;
}
}
}
auto delete_save = [&](const std::string& del_path)
{
strcpy_trunc(doneGet->dirName, save_entries[selected].dirName);
doneGet->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB
doneGet->sizeKB = 0;
doneGet->excResult = CELL_OK;
std::memset(doneGet->reserved, 0, sizeof(doneGet->reserved));
// Display Save Data List but do so asynchronously in the GUI thread.
bool hasNewData = (bool)listSet->newData; // newData
atomic_t<bool> dlg_result(false);
const fs::dir _dir{del_path};
for (auto&& file : _dir)
Emu.CallAfter([&]()
{
if (!file.is_directory)
{
doneGet->sizeKB += ::align(file.size, 4096);
selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, hasNewData, listSet);
dlg_result = true;
});
if (!fs::remove_file(del_path + file.name))
{
doneGet->excResult = CELL_SAVEDATA_ERROR_FAILURE;
}
}
}
if (!_dir)
while (!dlg_result)
{
doneGet->excResult = CELL_SAVEDATA_ERROR_NODATA;
thread_ctrl::wait_for(1000);
}
if (!doneGet->excResult && !fs::remove_dir(del_path))
{
doneGet->excResult = CELL_SAVEDATA_ERROR_FAILURE;
}
funcDone(ppu, result, doneGet);
};
while (funcList)
{
// Display Save Data List asynchronously in the GUI thread.
selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, operation, listSet);
// UI returns -1 for new save games
if (selected == -1)
{
@@ -369,29 +351,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
return CELL_CANCEL;
}
if (operation == SAVEDATA_OP_LIST_DELETE)
{
delete_save(base_dir + save_entries[selected].dirName + '/');
if (result->result < 0)
{
cellSaveData.warning("savedata_op(): funcDone returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
}
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
{
return CELL_OK;
}
// CELL_SAVEDATA_CBRESULT_OK_NEXT expected
save_entries.erase(save_entries.cbegin() + selected);
focused = save_entries.empty() ? -1 : selected;
selected = -1;
continue;
}
break;
}
if (funcFixed)
@@ -400,7 +359,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
funcFixed(ppu, result, listGet, fixedSet);
// skip all following steps if OK_LAST
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
{
return CELL_OK;
}
@@ -411,8 +370,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
// depends on fixedSet->option
// 0 = none
// 1 = skip confirmation dialog
cellSaveData.warning("savedata_op(): funcFixed returned result=%d.", result->result);
cellSaveData.warning("savedata_op(): funcFixed returned < 0.");
return CELL_SAVEDATA_ERROR_CBRESULT;
}
@@ -435,18 +394,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
save_entry.dirName = fixedSet->dirName.get_ptr();
}
if (operation == SAVEDATA_OP_FIXED_DELETE)
{
delete_save(base_dir + save_entries[selected].dirName + '/');
if (result->result < 0)
{
cellSaveData.warning("savedata_op(): funcDone_ returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
}
return CELL_OK;
}
}
if (selected >= 0)
@@ -557,15 +504,15 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (result->result < 0)
{
cellSaveData.warning("savedata_op(): funcStat returned result=%d.", result->result);
cellSaveData.warning("savedata_op(): funcStat returned 0x%x", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
}
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
{
return CELL_OK;
}
if (statSet->setParam)
{
// Update PARAM.SFO
@@ -587,7 +534,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
}
//else if (psf.empty())
//{
// // setParam is specified if something required updating.
// // setParam is specified if something required updating.
// // Do not exit. Recreate mode will handle the rest
// //return CELL_OK;
//}
@@ -597,7 +544,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
case CELL_SAVEDATA_RECREATE_NO:
{
//CELL_SAVEDATA_RECREATE_NO = overwrite and let the user know, not data is corrupt.
//cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
//cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
//TODO: if this is a save, and it's not auto, then show a dialog
// fallthrough
}
@@ -644,7 +591,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
// Create save directory if necessary
if (psf.size() && save_entry.isNew && !fs::create_dir(dir_path))
{
{
cellSaveData.warning("savedata_op(): failed to create %s", dir_path);
return CELL_SAVEDATA_ERROR_ACCESS_ERROR;
}
@@ -660,7 +607,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (result->result < 0)
{
cellSaveData.warning("savedata_op(): funcFile returned result=%d.", result->result);
cellSaveData.warning("savedata_op(): funcFile returned < 0.");
return CELL_SAVEDATA_ERROR_CBRESULT;
}
@@ -724,16 +671,11 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
fs::file file(dir_path + file_path, fs::read);
if (!file)
{
cellSaveData.error("Failed to open file %s%s", dir_path, file_path);
cellSaveData.error("savedata file not found");
return CELL_SAVEDATA_ERROR_FAILURE;
}
file.seek(fileSet->fileOffset);
std::vector<uchar> buf;
buf.resize(std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
buf.resize(file.read(buf.data(), buf.size()));
std::memcpy(fileSet->fileBuf.get_ptr(), buf.data(), buf.size());
fileGet->excSize = ::size32(buf);
fileGet->excSize = static_cast<u32>(file.read(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
break;
}
@@ -741,9 +683,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
{
fs::file file(dir_path + file_path, fs::write + fs::create);
file.seek(fileSet->fileOffset);
const auto start = static_cast<uchar*>(fileSet->fileBuf.get_ptr());
std::vector<uchar> buf(start, start + std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
fileGet->excSize = ::narrow<u32>(file.write(buf.data(), buf.size()));
fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
file.trunc(file.pos()); // truncate
break;
}
@@ -759,9 +699,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
{
fs::file file(dir_path + file_path, fs::write + fs::create);
file.seek(fileSet->fileOffset);
const auto start = static_cast<uchar*>(fileSet->fileBuf.get_ptr());
std::vector<uchar> buf(start, start + std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
fileGet->excSize = ::narrow<u32>(file.write(buf.data(), buf.size()));
fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
break;
}
@@ -782,8 +720,9 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
return CELL_OK;
}
static NEVER_INLINE s32 savedata_get_list_item(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB, u32 userId)
s32 static NEVER_INLINE save_op_get_list_item(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB, u32 userId)
{
//TODO: accurately get the current user
if (userId == 0)
{
@@ -867,6 +806,7 @@ s32 cellSaveDataListLoad(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf
version, setList, setBuf, funcList, funcStat, funcFile, container);
return savedata_op(ppu, SAVEDATA_OP_LIST_LOAD, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
}
s32 cellSaveDataFixedSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
@@ -887,13 +827,14 @@ s32 cellSaveDataFixedLoad2(ppu_thread& ppu, u32 version, PSetList setList, PSetB
return savedata_op(ppu, SAVEDATA_OP_FIXED_LOAD, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, 0, vm::null);
}
s32 cellSaveDataFixedSave(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
s32 cellSaveDataFixedSave(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
PFuncStat funcStat, PFuncFile funcFile, u32 container)
{
cellSaveData.warning("cellSaveDataFixedSave(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x)",
version, setList, setBuf, funcFixed, funcStat, funcFile, container);
return savedata_op(ppu, SAVEDATA_OP_FIXED_SAVE, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, vm::null, 0, vm::null);
}
s32 cellSaveDataFixedLoad(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed,
@@ -973,10 +914,10 @@ s32 cellSaveDataDelete(u32 container)
s32 cellSaveDataFixedDelete(ppu_thread& ppu, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
{
cellSaveData.warning("cellSaveDataFixedDelete(setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)",
cellSaveData.todo("cellSaveDataFixedDelete(setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)",
setList, setBuf, funcFixed, funcDone, container, userdata);
return savedata_op(ppu, SAVEDATA_OP_FIXED_DELETE, 0, vm::null, 1, setList, setBuf, vm::null, funcFixed, vm::null, vm::null, container, 2, userdata, 0, funcDone);
return CELL_OK;
}
s32 cellSaveDataUserListSave(ppu_thread& ppu, u32 version, u32 userId, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
@@ -1045,24 +986,26 @@ s32 cellSaveDataUserListAutoLoad(ppu_thread& ppu, u32 version, u32 userId, u32 e
s32 cellSaveDataUserFixedDelete(ppu_thread& ppu, u32 userId, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
{
cellSaveData.error("cellSaveDataUserFixedDelete(userId=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)",
cellSaveData.todo("cellSaveDataUserFixedDelete(userId=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)",
userId, setList, setBuf, funcFixed, funcDone, container, userdata);
return savedata_op(ppu, SAVEDATA_OP_FIXED_DELETE, 0, vm::null, 1, setList, setBuf, vm::null, funcFixed, vm::null, vm::null, container, 6, userdata, userId, funcDone);
return CELL_OK;
}
void cellSaveDataEnableOverlay(s32 enable)
{
cellSaveData.error("cellSaveDataEnableOverlay(enable=%d)", enable);
return;
}
// Functions (Extensions)
// Functions (Extensions)
s32 cellSaveDataListDelete(ppu_thread& ppu, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
{
cellSaveData.warning("cellSaveDataListDelete(setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)", setList, setBuf, funcList, funcDone, container, userdata);
UNIMPLEMENTED_FUNC(cellSaveData);
return savedata_op(ppu, SAVEDATA_OP_LIST_DELETE, 0, vm::null, 0, setList, setBuf, funcList, vm::null, vm::null, vm::null, container, 0x40, userdata, 0, funcDone);
return CELL_OK;
}
s32 cellSaveDataListImport(ppu_thread& ppu, PSetList setList, u32 maxSizeKB, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
@@ -1096,15 +1039,15 @@ s32 cellSaveDataFixedExport(ppu_thread& ppu, vm::cptr<char> dirName, u32 maxSize
s32 cellSaveDataGetListItem(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
{
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB);
return savedata_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, 0);
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, 0);
}
s32 cellSaveDataUserListDelete(ppu_thread& ppu, u32 userId, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
{
cellSaveData.error("cellSaveDataUserListDelete(userId=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)", userId, setList, setBuf, funcList, funcDone, container, userdata);
UNIMPLEMENTED_FUNC(cellSaveData);
return savedata_op(ppu, SAVEDATA_OP_LIST_DELETE, 0, vm::null, 0, setList, setBuf, funcList, vm::null, vm::null, vm::null, container, 0x40, userdata, userId, funcDone);
return CELL_OK;
}
s32 cellSaveDataUserListImport(ppu_thread& ppu, u32 userId, PSetList setList, u32 maxSizeKB, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
@@ -1139,7 +1082,7 @@ s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<Cell
{
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x, userID=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB, userId);
return savedata_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, userId);
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, userId);
}
void cellSysutil_SaveData_init()
+1 -1
View File
@@ -291,5 +291,5 @@ class SaveDialogBase
public:
virtual ~SaveDialogBase();
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet) = 0;
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet) = 0;
};
+42 -326
View File
@@ -1,422 +1,138 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "cellSearch.h"
#include "cellSysutil.h"
logs::channel cellSearch("cellSearch");
template<>
void fmt_class_string<CellSearchError>::format(std::string& out, u64 arg)
s32 cellSearchInitialize(CellSearchMode mode, u32 container, vm::ptr<CellSearchSystemCallback> func, vm::ptr<u32> userData)
{
format_enum(out, arg, [](auto error)
{
switch (error)
{
STR_CASE(CELL_SEARCH_CANCELED);
STR_CASE(CELL_SEARCH_ERROR_PARAM);
STR_CASE(CELL_SEARCH_ERROR_BUSY);
STR_CASE(CELL_SEARCH_ERROR_NO_MEMORY);
STR_CASE(CELL_SEARCH_ERROR_UNKNOWN_MODE);
STR_CASE(CELL_SEARCH_ERROR_ALREADY_INITIALIZED);
STR_CASE(CELL_SEARCH_ERROR_NOT_INITIALIZED);
STR_CASE(CELL_SEARCH_ERROR_FINALIZING);
STR_CASE(CELL_SEARCH_ERROR_NOT_SUPPORTED_SEARCH);
STR_CASE(CELL_SEARCH_ERROR_CONTENT_OBSOLETE);
STR_CASE(CELL_SEARCH_ERROR_CONTENT_NOT_FOUND);
STR_CASE(CELL_SEARCH_ERROR_NOT_LIST);
STR_CASE(CELL_SEARCH_ERROR_OUT_OF_RANGE);
STR_CASE(CELL_SEARCH_ERROR_INVALID_SEARCHID);
STR_CASE(CELL_SEARCH_ERROR_ALREADY_GOT_RESULT);
STR_CASE(CELL_SEARCH_ERROR_NOT_SUPPORTED_CONTEXT);
STR_CASE(CELL_SEARCH_ERROR_INVALID_CONTENTTYPE);
STR_CASE(CELL_SEARCH_ERROR_DRM);
STR_CASE(CELL_SEARCH_ERROR_TAG);
STR_CASE(CELL_SEARCH_ERROR_GENERIC);
}
cellSearch.warning("cellSearchInitialize()");
return unknown;
});
}
struct search_t
{
vm::ptr<CellSearchSystemCallback> func;
vm::ptr<void> userData;
};
struct search_object_t
{
// TODO: Figured out the correct values to set here
static const u32 id_base = 1;
static const u32 id_step = 1;
static const u32 id_count = 64;
static const u32 invalid = 0xFFFFFFFF;
};
error_code cellSearchInitialize(CellSearchMode mode, u32 container, vm::ptr<CellSearchSystemCallback> func, vm::ptr<void> userData)
{
cellSearch.warning("cellSearchInitialize(mode=0x%x, container=0x%x, func=*0x%x, userData=*0x%x)", (u32) mode, container, func, userData);
const auto search = fxm::make_always<search_t>();
search->func = func;
search->userData = userData;
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
func(ppu, CELL_SEARCH_EVENT_INITIALIZE_RESULT, CELL_OK, vm::null, userData);
return CELL_OK;
});
// TODO: Store the arguments somewhere so we can use them later.
return CELL_OK;
}
error_code cellSearchFinalize()
s32 cellSearchFinalize()
{
cellSearch.warning("cellSearchFinalize()");
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto search = fxm::get_always<search_t>();
search->func(ppu, CELL_SEARCH_EVENT_FINALIZE_RESULT, CELL_OK, vm::null, search->userData);
return CELL_OK;
});
return CELL_OK;
}
error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
s32 cellSearchStartListSearch()
{
cellSearch.todo("cellSearchStartListSearch(type=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", (u32) type, (u32) sortOrder, outSearchId);
if (!outSearchId)
{
return CELL_SEARCH_ERROR_PARAM;
}
*outSearchId = idm::make<search_object_t>();
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto search = fxm::get_always<search_t>();
vm::var<CellSearchResultParam> resultParam;
resultParam->searchId = *outSearchId;
resultParam->resultNum = 0; // TODO
search->func(ppu, CELL_SEARCH_EVENT_LISTSEARCH_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchStartContentSearchInList(vm::cptr<CellSearchContentId> listId, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
s32 cellSearchStartContentSearchInList()
{
cellSearch.todo("cellSearchStartContentSearchInList(listId=*0x%x, sortKey=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", listId, (u32) sortKey, (u32) sortOrder, outSearchId);
if (!listId || !outSearchId)
{
return CELL_SEARCH_ERROR_PARAM;
}
*outSearchId = idm::make<search_object_t>();
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto search = fxm::get_always<search_t>();
vm::var<CellSearchResultParam> resultParam;
resultParam->searchId = *outSearchId;
resultParam->resultNum = 0; // TODO
search->func(ppu, CELL_SEARCH_EVENT_CONTENTSEARCH_INLIST_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
s32 cellSearchStartContentSearch()
{
cellSearch.todo("cellSearchStartContentSearch(type=0x%x, sortKey=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", (u32) type, (u32) sortKey, (u32) sortOrder, outSearchId);
if (!outSearchId)
{
return CELL_SEARCH_ERROR_PARAM;
}
*outSearchId = idm::make<search_object_t>();
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto search = fxm::get_always<search_t>();
vm::var<CellSearchResultParam> resultParam;
resultParam->searchId = *outSearchId;
resultParam->resultNum = 0; // TODO
search->func(ppu, CELL_SEARCH_EVENT_CONTENTSEARCH_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchStartSceneSearchInVideo(vm::cptr<CellSearchContentId> videoId, CellSearchSceneSearchType searchType, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
s32 cellSearchStartSceneSearchInVideo()
{
cellSearch.todo("cellSearchStartSceneSearchInVideo(videoId=*0x%x, searchType=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", videoId, (u32) searchType, (u32) sortOrder, outSearchId);
if (!videoId || !outSearchId)
{
return CELL_SEARCH_ERROR_PARAM;
}
*outSearchId = idm::make<search_object_t>();
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto search = fxm::get_always<search_t>();
vm::var<CellSearchResultParam> resultParam;
resultParam->searchId = *outSearchId;
resultParam->resultNum = 0; // TODO
search->func(ppu, CELL_SEARCH_EVENT_SCENESEARCH_INVIDEO_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchStartSceneSearch(CellSearchSceneSearchType searchType, vm::cptr<char> gameTitle, vm::cpptr<char> tags, u32 tagNum, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
s32 cellSearchStartSceneSearch()
{
cellSearch.todo("cellSearchStartSceneSearch(searchType=0x%x, gameTitle=%s, tags=**0x%x, tagNum=0x%x, sortKey=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", (u32) searchType, gameTitle, tags, tagNum, (u32) sortKey, (u32) sortOrder, outSearchId);
if (!gameTitle || !outSearchId)
{
return CELL_SEARCH_ERROR_PARAM;
}
*outSearchId = idm::make<search_object_t>();
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
const auto search = fxm::get_always<search_t>();
vm::var<CellSearchResultParam> resultParam;
resultParam->searchId = *outSearchId;
resultParam->resultNum = 0; // TODO
search->func(ppu, CELL_SEARCH_EVENT_SCENESEARCH_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
return CELL_OK;
});
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoByOffset(CellSearchId searchId, s32 offset, vm::ptr<void> infoBuffer, vm::ptr<CellSearchContentType> outContentType, vm::ptr<CellSearchContentId> outContentId)
s32 cellSearchGetContentInfoByOffset()
{
cellSearch.todo("cellSearchGetContentInfoByOffset(searchId=0x%x, offset=0x%x, infoBuffer=*0x%x, outContentType=*0x%x, outContentId=*0x%x)", searchId, offset, infoBuffer, outContentType, outContentId);
if (!outContentType)
{
return CELL_SEARCH_ERROR_PARAM;
}
const auto searchObject = idm::get<search_object_t>(searchId);
if (!searchObject)
{
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoByContentId(vm::cptr<CellSearchContentId> contentId, vm::ptr<void> infoBuffer, vm::ptr<CellSearchContentType> outContentType)
s32 cellSearchGetContentInfoByContentId()
{
cellSearch.todo("cellSearchGetContentInfoByContentId(contentId=*0x%x, infoBuffer=*0x%x, outContentType=*0x%x)", contentId, infoBuffer, outContentType);
if (!outContentType)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetOffsetByContentId(CellSearchId searchId, vm::cptr<CellSearchContentId> contentId, vm::ptr<s32> outOffset)
s32 cellSearchGetOffsetByContentId()
{
cellSearch.todo("cellSearchGetOffsetByContentId(searchId=0x%x, contentId=*0x%x, outOffset=*0x%x)", searchId, contentId, outOffset);
if (!outOffset)
{
return CELL_SEARCH_ERROR_PARAM;
}
const auto searchObject = idm::get<search_object_t>(searchId);
if (!searchObject)
{
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentIdByOffset(CellSearchId searchId, s32 offset, vm::ptr<CellSearchContentType> outContentType, vm::ptr<CellSearchContentId> outContentId, vm::ptr<CellSearchTimeInfo> outTimeInfo)
s32 cellSearchGetContentIdByOffset()
{
cellSearch.todo("cellSearchGetContentIdByOffset(searchId=0x%x, offset=0x%x, outContentType=*0x%x, outContentId=*0x%x, outTimeInfo=*0x%x)", searchId, offset, outContentType, outContentId, outTimeInfo);
if (!outContentType || !outContentId)
{
return CELL_SEARCH_ERROR_PARAM;
}
const auto searchObject = idm::get<search_object_t>(searchId);
if (!searchObject)
{
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoGameComment(vm::cptr<CellSearchContentId> contentId, vm::ptr<char> gameComment)
s32 cellSearchGetContentInfoGameComment()
{
cellSearch.todo("cellSearchGetContentInfoGameComment(contentId=*0x%x, gameComment=*0x%x)", contentId, gameComment);
if (!gameComment)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptr<CellSearchContentId> contentId, CellSearchRepeatMode repeatMode, CellSearchContextOption option, vm::ptr<CellMusicSelectionContext> outContext)
s32 cellSearchGetMusicSelectionContext()
{
cellSearch.todo("cellSearchGetMusicSelectionContext(searchId=0x%x, contentId=*0x%x, repeatMode=0x%x, option=0x%x, outContext=*0x%x)", searchId, contentId, (u32) repeatMode, (u32) option, outContext);
if (!outContext)
{
return CELL_SEARCH_ERROR_PARAM;
}
const auto searchObject = idm::get<search_object_t>(searchId);
if (!searchObject)
{
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetMusicSelectionContextOfSingleTrack(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellMusicSelectionContext> outContext)
s32 cellSearchGetMusicSelectionContextOfSingleTrack()
{
cellSearch.todo("cellSearchGetMusicSelectionContextOfSingleTrack(contentId=*0x%x, outContext=*0x%x)", contentId, outContext);
if (!contentId || !outContext)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoPath(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellSearchContentInfoPath> infoPath)
s32 cellSearchGetContentInfoPath()
{
cellSearch.todo("cellSearchGetContentInfoPath(contentId=*0x%x, infoPath=*0x%x)", contentId, infoPath);
if (!infoPath)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoPathMovieThumb(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellSearchContentInfoPathMovieThumb> infoMt)
s32 cellSearchGetContentInfoPathMovieThumb()
{
cellSearch.todo("cellSearchGetContentInfoPathMovieThumb(contentId=*0x%x, infoMt=*0x%x)", contentId, infoMt);
if (!infoMt)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchPrepareFile(vm::cptr<char> path)
s32 cellSearchPrepareFile()
{
cellSearch.todo("cellSearchPrepareFile(path=%s)", path);
if (!path)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoDeveloperData(vm::cptr<CellSearchContentId> contentId, vm::ptr<char> developerData)
s32 cellSearchGetContentInfoDeveloperData()
{
cellSearch.todo("cellSearchGetContentInfoDeveloperData(contentId=*0x%x, developerData=*0x%x)", contentId, developerData);
if (!contentId || !developerData)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchGetContentInfoSharable(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellSearchSharableType> sharable)
s32 cellSearchGetContentInfoSharable()
{
cellSearch.todo("cellSearchGetContentInfoSharable(contentId=*0x%x, sharable=*0x%x)", contentId, sharable);
if (!contentId || !sharable)
{
return CELL_SEARCH_ERROR_PARAM;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchCancel(CellSearchId searchId)
s32 cellSearchCancel()
{
cellSearch.todo("cellSearchCancel(searchId=0x%x)", searchId);
const auto searchObject = idm::get<search_object_t>(searchId);
if (!searchObject)
{
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
}
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
error_code cellSearchEnd(CellSearchId searchId)
s32 cellSearchEnd()
{
cellSearch.warning("cellSearchEnd(searchId=0x%x)", searchId);
const auto searchObject = idm::get<search_object_t>(searchId);
if (!searchObject)
{
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
}
idm::remove<search_object_t>(searchId);
UNIMPLEMENTED_FUNC(cellSearch);
return CELL_OK;
}
+17 -78
View File
@@ -1,7 +1,9 @@
#pragma once
namespace vm { using namespace ps3; }
// Error Codes
enum CellSearchError : u32
enum
{
CELL_SEARCH_CANCELED = 1,
CELL_SEARCH_ERROR_PARAM = 0x8002C801,
@@ -28,20 +30,17 @@ enum CellSearchError : u32
// Constants
enum
{
CELL_SEARCH_CONTENT_ID_SIZE = 16,
CELL_SEARCH_TITLE_LEN_MAX = 384,
CELL_SEARCH_TAG_NUM_MAX = 6,
CELL_SEARCH_TAG_LEN_MAX = 63,
CELL_MUSIC_SELECTION_CONTEXT_SIZE = 2048,
CELL_SEARCH_PATH_LEN_MAX = 63,
CELL_SEARCH_MTOPTION_LEN_MAX = 63,
CELL_SEARCH_DEVELOPERDATA_LEN_MAX = 64,
CELL_SEARCH_GAMECOMMENT_SIZE_MAX = 1024,
CELL_SEARCH_CONTENT_BUFFER_SIZE_MAX = 2048,
CELL_SEARCH_CONTENT_ID_SIZE = 16,
CELL_SEARCH_TITLE_LEN_MAX = 384,
CELL_SEARCH_TAG_NUM_MAX = 6,
CELL_SEARCH_TAG_LEN_MAX = 63,
CELL_MUSIC_SELECTION_CONTEXT_SIZE = 2048,
CELL_SEARCH_PATH_LEN_MAX = 63,
CELL_SEARCH_MTOPTION_LEN_MAX = 63,
};
// Sort keys
enum CellSearchSortKey : s32
enum : s32
{
CELL_SEARCH_SORTKEY_NONE = 0,
CELL_SEARCH_SORTKEY_DEFAULT = 1,
@@ -57,15 +56,15 @@ enum CellSearchSortKey : s32
};
// Sort order
enum CellSearchSortOrder : s32
enum : s32
{
CELL_SEARCH_SORTORDER_NONE = 0,
CELL_SEARCH_SORTORDER_ASCENDING = 1,
CELL_SEARCH_SORTORDER_DESCENDING = 2,
CELL_SEARCH_SOFTORDER_DESCENDING = 2,
};
// Content types
enum CellSearchContentType : s32
enum : s32
{
CELL_SEARCH_CONTENTTYPE_NONE = 0,
CELL_SEARCH_CONTENTTYPE_MUSIC = 1,
@@ -123,22 +122,15 @@ enum CellSearchSceneType : s32
// List types
enum CellSearchListType : s32
{
CELL_SEARCH_LISTTYPE_NONE = 0,
CELL_SEARCH_LISTTYPE_MUSIC_ALBUM = 1,
CELL_SEARCH_LISTTYPE_MUSIC_GENRE = 2,
CELL_SEARCH_LISTTYPE_MUSIC_ARTIST = 3,
CELL_SEARCH_LISTTYPE_PHOTO_YEAR = 4,
CELL_SEARCH_LISTTYPE_PHOTO_MONTH = 5,
CELL_SEARCH_LISTTYPE_PHOTO_ALBUM = 6,
CELL_SEARCH_LISTTYPE_PHOTO_PLAYLIST = 7,
CELL_SEARCH_LISTTYPE_VIDEO_ALBUM = 8,
CELL_SEARCH_LISTTYPE_MUSIC_PLAYLIST = 9,
};
// Content status
enum CellSearchContentStatus : s32
{
CELL_SEARCH_CONTENTSTATUS_NONE,
CELL_SEARCH_CONTENTSTATUS_AVAILABLE,
CELL_SEARCH_CONTENTSTATUS_NOT_SUPPORTED,
CELL_SEARCH_CONTENTSTATUS_BROKEN,
@@ -147,7 +139,7 @@ enum CellSearchContentStatus : s32
// Search orientation
enum CellSearchOrientation : s32
{
CELL_SEARCH_ORIENTATION_UNKNOWN = 0,
CELL_SEARCH_ORIENTATION_UNKNOWN,
CELL_SEARCH_ORIENTATION_TOP_LEFT,
CELL_SEARCH_ORIENTATION_TOP_RIGHT,
CELL_SEARCH_ORIENTATION_BOTTOM_RIGHT,
@@ -173,60 +165,7 @@ enum CellSearchEvent : s32
CELL_SEARCH_EVENT_SCENESEARCH_RESULT,
};
enum CellSearchListSearchType : s32
{
CELL_SEARCH_LISTSEARCHTYPE_NONE = 0,
CELL_SEARCH_LISTSEARCHTYPE_MUSIC_ALBUM,
CELL_SEARCH_LISTSEARCHTYPE_MUSIC_GENRE,
CELL_SEARCH_LISTSEARCHTYPE_MUSIC_ARTIST,
CELL_SEARCH_LISTSEARCHTYPE_PHOTO_YEAR,
CELL_SEARCH_LISTSEARCHTYPE_PHOTO_MONTH,
CELL_SEARCH_LISTSEARCHTYPE_PHOTO_ALBUM,
CELL_SEARCH_LISTSEARCHTYPE_PHOTO_PLAYLIST,
CELL_SEARCH_LISTSEARCHTYPE_VIDEO_ALBUM,
CELL_SEARCH_LISTSEARCHTYPE_MUSIC_PLAYLIST,
};
enum CellSearchContentSearchType : s32
{
CELL_SEARCH_CONTENTSEARCHTYPE_NONE = 0,
CELL_SEARCH_CONTENTSEARCHTYPE_MUSIC_ALL,
CELL_SEARCH_CONTENTSEARCHTYPE_PHOTO_ALL,
CELL_SEARCH_CONTENTSEARCHTYPE_VIDEO_ALL,
};
enum CellSearchSceneSearchType : s32
{
CELL_SEARCH_SCENESEARCHTYPE_NONE = 0,
CELL_SEARCH_SCENESEARCHTYPE_CHAPTER,
CELL_SEARCH_SCENESEARCHTYPE_CLIP_HIGHLIGHT,
CELL_SEARCH_SCENESEARCHTYPE_CLIP_USER,
CELL_SEARCH_SCENESEARCHTYPE_CLIP,
CELL_SEARCH_SCENESEARCHTYPE_ALL,
};
enum CellSearchRepeatMode : s32
{
CELL_SEARCH_REPEATMODE_NONE = 0,
CELL_SEARCH_REPEATMODE_REPEAT1,
CELL_SEARCH_REPEATMODE_ALL,
CELL_SEARCH_REPEATMODE_NOREPEAT1,
};
enum CellSearchContextOption : s32
{
CELL_SEARCH_CONTEXTOPTION_NONE = 0,
CELL_SEARCH_CONTEXTOPTION_SHUFFLE,
};
enum CellSearchSharableType : s32
{
CELL_SEARCH_SHARABLETYPE_PROHIBITED = 0,
CELL_SEARCH_SHARABLETYPE_PERMITTED,
};
using CellSearchId = s32;
using CellSearchSystemCallback = void(CellSearchEvent event, s32 result, vm::ps3::cptr<void> param, vm::ps3::ptr<void> userData);
using CellSearchSystemCallback = void(CellSearchEvent event, s32 result, vm::cptr<u32> param, vm::ptr<u32> userData);
struct CellSearchContentId
{
@@ -235,7 +174,7 @@ struct CellSearchContentId
struct CellSearchResultParam
{
be_t<CellSearchId> searchId;
be_t<s32> searchId;
be_t<u32> resultNum;
};
-21
View File
@@ -474,18 +474,6 @@ s32 _ZN4cxml8Document5ClearEv()
return CELL_OK;
}
s32 _ZN4cxml8Document5WriteEPFiPKvjPvES3_()
{
UNIMPLEMENTED_FUNC(cellSysutil);
return CELL_OK;
}
s32 _ZN4cxml8Document12RegisterFileEPKvjPNS_4FileE()
{
UNIMPLEMENTED_FUNC(cellSysutil);
return CELL_OK;
}
s32 _ZN4cxml8Document13CreateElementEPKciPNS_7ElementE()
{
UNIMPLEMENTED_FUNC(cellSysutil);
@@ -558,12 +546,6 @@ s32 _ZN8cxmlutil6GetIntERKN4cxml7ElementEPKcPi()
return CELL_OK;
}
s32 _ZN8cxmlutil7SetFileERKN4cxml7ElementEPKcRKNS0_4FileE()
{
UNIMPLEMENTED_FUNC(cellSysutil);
return CELL_OK;
}
s32 _ZN8cxmlutil8GetFloatERKN4cxml7ElementEPKcPf()
{
UNIMPLEMENTED_FUNC(cellSysutil);
@@ -700,8 +682,6 @@ DECLARE(ppu_module_manager::cellSysutil)("cellSysutil", []()
REG_FUNC(cellSysutil, _ZN4cxml8DocumentC1Ev);
REG_FUNC(cellSysutil, _ZN4cxml8DocumentD1Ev);
REG_FUNC(cellSysutil, _ZN4cxml8Document5ClearEv);
REG_FUNC(cellSysutil, _ZN4cxml8Document5WriteEPFiPKvjPvES3_);
REG_FUNC(cellSysutil, _ZN4cxml8Document12RegisterFileEPKvjPNS_4FileE);
REG_FUNC(cellSysutil, _ZN4cxml8Document13CreateElementEPKciPNS_7ElementE);
REG_FUNC(cellSysutil, _ZN4cxml8Document14SetHeaderMagicEPKc);
REG_FUNC(cellSysutil, _ZN4cxml8Document16CreateFromBufferEPKvjb);
@@ -716,7 +696,6 @@ DECLARE(ppu_module_manager::cellSysutil)("cellSysutil", []()
REG_FUNC(cellSysutil, _ZN8cxmlutil6SetIntERKN4cxml7ElementEPKci);
REG_FUNC(cellSysutil, _ZN8cxmlutil6GetIntERKN4cxml7ElementEPKcPi);
REG_FUNC(cellSysutil, _ZN8cxmlutil7SetFileERKN4cxml7ElementEPKcRKNS0_4FileE);
REG_FUNC(cellSysutil, _ZN8cxmlutil8GetFloatERKN4cxml7ElementEPKcPf);
REG_FUNC(cellSysutil, _ZN8cxmlutil9GetStringERKN4cxml7ElementEPKcPS5_Pj);
REG_FUNC(cellSysutil, _ZN8cxmlutil9SetStringERKN4cxml7ElementEPKcS5_);
+1 -4
View File
@@ -40,9 +40,6 @@ error_code cellUserInfoGetStat(u32 id, vm::ptr<CellUserInfoUserStat> stat)
id = 1;
}
if (!stat)
return CELL_USERINFO_ERROR_PARAM;
const std::string& path = vfs::get(fmt::format("/dev_hdd0/home/%08d/", id));
if (!fs::is_dir(path))
@@ -107,7 +104,7 @@ error_code cellUserInfoGetList(vm::ptr<u32> listNum, vm::ptr<CellUserInfoUserLis
// TODO: Properly set the current user ID here, once implemented
*currentUserId = 1;
}
return CELL_OK;
}
+7 -9
View File
@@ -64,7 +64,6 @@ struct vdec_thread : ppu_thread
{
AVCodec* codec{};
AVCodecContext* ctx{};
SwsContext* sws{};
const s32 type;
const u32 profile;
@@ -148,7 +147,6 @@ struct vdec_thread : ppu_thread
{
avcodec_close(ctx);
avcodec_free_context(&ctx);
sws_freeContext(sws);
}
virtual std::string dump() const override
@@ -363,7 +361,7 @@ struct vdec_thread : ppu_thread
{
au_count--;
}
while (std::lock_guard<std::mutex>{mutex}, max_frames && out.size() > max_frames)
{
thread_ctrl::wait();
@@ -485,7 +483,7 @@ s32 cellVdecClose(ppu_thread& ppu, u32 handle)
vdec->cmd_push({vdec_cmd::close, 0});
vdec->max_frames = 0;
}
vdec->notify();
vdec->join();
idm::remove<ppu_thread>(handle);
@@ -588,7 +586,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
}
vdec->notify();
if (outBuff)
{
const int w = frame->width;
@@ -634,7 +632,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
}
}
vdec->sws = sws_getCachedContext(vdec->sws, w, h, in_f, w, h, out_f, SWS_POINT, NULL, NULL, NULL);
std::unique_ptr<SwsContext, void(*)(SwsContext*)> sws(sws_getContext(w, h, in_f, w, h, out_f, SWS_POINT, NULL, NULL, NULL), sws_freeContext);
u8* in_data[4] = { frame->data[0], frame->data[1], frame->data[2], alpha_plane.get() };
int in_line[4] = { frame->linesize[0], frame->linesize[1], frame->linesize[2], w * 1 };
@@ -650,7 +648,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
out_line[2] = w / 2;
}
sws_scale(vdec->sws, in_data, in_line, 0, h, out_data, out_line);
sws_scale(sws.get(), in_data, in_line, 0, h, out_data, out_line);
//const u32 buf_size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128);
@@ -773,7 +771,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
avc->transfer_characteristics = CELL_VDEC_AVC_TC_ITU_R_BT_709_5;
avc->matrix_coefficients = CELL_VDEC_AVC_MXC_ITU_R_BT_709_5; // important
avc->timing_info_present_flag = true;
switch (frc)
{
case CELL_VDEC_FRC_24000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_24000DIV1001; break;
@@ -840,7 +838,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
mp2->horizontal_size = frame->width;
mp2->vertical_size = frame->height;
mp2->aspect_ratio_information = CELL_VDEC_MPEG2_ARI_SAR_1_1; // ???
switch (frc)
{
case CELL_VDEC_FRC_24000DIV1001: mp2->frame_rate_code = CELL_VDEC_MPEG2_FRC_24000DIV1001; break;
+12 -75
View File
@@ -1,99 +1,36 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "cellSysutil.h"
namespace vm { using namespace ps3; }
logs::channel cellVideoExport("cellVideoExport");
struct CellVideoExportSetParam
s32 cellVideoExportProgress()
{
vm::bptr<char> title;
vm::bptr<char> game_title;
vm::bptr<char> game_comment;
be_t<s32> editable;
vm::bptr<void> reserved2;
};
using CellVideoExportUtilFinishCallback = void(s32 result, vm::ptr<void> userdata);
error_code cellVideoExportProgress(vm::ptr<CellVideoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
{
cellVideoExport.todo("cellVideoExportProgress(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, 0xFFFF, userdata); // 0-0xFFFF where 0xFFFF = 100%
return CELL_OK;
});
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
error_code cellVideoExportInitialize2(u32 version, vm::ptr<CellVideoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellVideoExportInitialize2()
{
cellVideoExport.todo("cellVideoExportInitialize2(version=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
error_code cellVideoExportInitialize(u32 version, u32 container, vm::ptr<CellVideoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellVideoExportInitialize()
{
cellVideoExport.todo("cellVideoExportInitialize(version=0x%x, container=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, container, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
error_code cellVideoExportFromFileWithCopy(vm::cptr<char> srcHddDir, vm::cptr<char> srcHddFile, vm::ptr<CellVideoExportSetParam> param, vm::ptr<CellVideoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellVideoExportFromFileWithCopy()
{
cellVideoExport.todo("cellVideoExportFromFileWithCopy(srcHddDir=%s, srcHddFile=%s, param=*0x%x, funcFinish=*0x%x, userdata=*0x%x)", srcHddDir, srcHddFile, param, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
error_code cellVideoExportFromFile(vm::cptr<char> srcHddDir, vm::cptr<char> srcHddFile, vm::ptr<CellVideoExportSetParam> param, vm::ptr<CellVideoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellVideoExportFromFile()
{
cellVideoExport.todo("cellVideoExportFromFile(srcHddDir=%s, srcHddFile=%s, param=*0x%x, funcFinish=*0x%x, userdata=*0x%x)", srcHddDir, srcHddFile, param, funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
error_code cellVideoExportFinalize(vm::ptr<CellVideoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
s32 cellVideoExportFinalize()
{
cellVideoExport.todo("cellVideoExportFinalize(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
{
funcFinish(ppu, CELL_OK, userdata);
return CELL_OK;
});
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}

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