Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8238b8455 | |||
| cbf35ffdb5 | |||
| f90ddeabd0 | |||
| 372b9f9dc2 | |||
| a58a63aa72 | |||
| 4a220aa518 | |||
| c3a7eac375 | |||
| 82c31a9f73 | |||
| c530e3cf3d | |||
| 8e6fe717ab | |||
| d9350149e2 | |||
| 918a277e62 | |||
| 7a01b2ccb1 | |||
| b0742e08d9 | |||
| 9d635139ed | |||
| 788469a66e | |||
| f2df1da3a1 | |||
| a4fec2de6f | |||
| 56a0a3a608 | |||
| 6060c6a342 | |||
| 29453f6d16 | |||
| 65642c28c6 | |||
| 0ada09bfd3 | |||
| d49ee7886c | |||
| f4f4f16cdc | |||
| c1830965f5 | |||
| 4f14116a04 | |||
| d85dee5be4 | |||
| c2d9a0e512 | |||
| db9b2055ce | |||
| acfae4a34e | |||
| e80afa2b77 | |||
| 357decdfdc | |||
| c958715a19 | |||
| 9aba3e21fd | |||
| 52664cc501 | |||
| a13c875e75 | |||
| c47fb72015 |
@@ -1,24 +0,0 @@
|
||||
<!---
|
||||
|
||||
THIS IS NOT A SUPPORT FORUM, FOR SUPPORT GO TO:
|
||||
https://forums.rpcs3.net
|
||||
or our discord:
|
||||
https://discord.me/RPCS3
|
||||
|
||||
PLEASE READ THE GUIDELINES BEFORE OPENING AN ISSUE:
|
||||
https://github.com/RPCS3/rpcs3/blob/master/.github/CONTRIBUTING.md
|
||||
|
||||
====================================================
|
||||
|
||||
When submitting an issue, please check the following:
|
||||
|
||||
- You have read the above.
|
||||
- You have provided the version (commit hash) of RPCS3 you are using.
|
||||
- You have provided sufficient detail for the issue to be reproduced.
|
||||
- You have provided system specs.
|
||||
- Please also provide:
|
||||
- For crashes, a backtrace.
|
||||
- For graphical issues, comparison screenshots with real hardware.
|
||||
|
||||
Remember that the GitHub Issue Tracker is not the place to ask for support or to submit Game Compatibility reports. You must use our forums for that.
|
||||
--->
|
||||
@@ -41,10 +41,6 @@
|
||||
/Vulkan/Vulkan-build
|
||||
/Vulkan/glslang-build
|
||||
|
||||
# Themes
|
||||
!/bin/GuiConfigs/
|
||||
/bin/GuiConfigs/*.ini
|
||||
|
||||
/bin/rpcs3.ini
|
||||
/bin/rpcs3.ipdb
|
||||
/bin/rpcs3.iobj
|
||||
@@ -59,7 +55,7 @@ rpcs3/git-version.h
|
||||
|
||||
# Visual Studio Files
|
||||
.vs/*
|
||||
.vscode/*
|
||||
*.ipch
|
||||
*.vspx
|
||||
*.psess
|
||||
*.VC.*
|
||||
@@ -75,7 +71,6 @@ rpcs3/git-version.h
|
||||
!/bin/dev_hdd0/game/
|
||||
/bin/dev_hdd0/game/*
|
||||
!/bin/dev_hdd0/game/TEST12345/
|
||||
/bin/dev_hdd0/disc/*
|
||||
|
||||
# Ignore other system generated files
|
||||
bin/dev_hdd0/*.txt
|
||||
@@ -93,10 +88,6 @@ CMakeCache.txt
|
||||
rpcs3/cotire/*
|
||||
rpcs3/rpcs3_*_cotire.cmake
|
||||
|
||||
# kdevelop
|
||||
*.kdev4
|
||||
.kdev4/*
|
||||
|
||||
# Qt
|
||||
moc_*.cpp
|
||||
qrc_resources.cpp
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
ignore = dirty
|
||||
[submodule "llvm"]
|
||||
path = llvm
|
||||
url = https://github.com/RPCS3/llvm
|
||||
branch = release_60
|
||||
url = https://github.com/llvm-mirror/llvm
|
||||
[submodule "rsx_program_decompiler"]
|
||||
path = rsx_program_decompiler
|
||||
url = https://github.com/RPCS3/rsx_program_decompiler
|
||||
[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,20 +27,19 @@
|
||||
[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
|
||||
[submodule "rsx-debugger"]
|
||||
path = rsx-debugger
|
||||
url = https://github.com/RPCS3/rsx-debugger.git
|
||||
[submodule "3rdparty/zlib"]
|
||||
path = 3rdparty/zlib
|
||||
url = https://github.com/madler/zlib
|
||||
[submodule "3rdparty/hidapi"]
|
||||
path = 3rdparty/hidapi
|
||||
url = https://github.com/RPCS3/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
|
||||
url = https://github.com/Zangetsu38/hidapi
|
||||
branch = master
|
||||
@@ -1,5 +1,6 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
os:
|
||||
- linux
|
||||
@@ -16,74 +17,81 @@ cache:
|
||||
directories:
|
||||
- $HOME/hombebrew_cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: BXyNziNYFLqLtY6Q58BDEUpRJr81HUtHpxf2Sr646bDcbG0Rf2rb2utqHZJ1Om926WdH7RqHuoVti4dr2X1lh4nHMkLD7MrIrfIkNN5T9aZdk19uw9IyMtz/cXon7/wqVo24tVqtBI0UghFxKii/GTDJEvRKgfpPp1e1vKSNGa4=
|
||||
# Which Travis environment to run Coverity on
|
||||
- coverity_scan_run_condition='"$TRAVIS_OS_NAME" = linux -a "$CC" = gcc'
|
||||
# Test mode is for testing if it's working with Coverity. Change to true if testing, to avoid reaching the quota.
|
||||
- coverity_scan_script_test_mode=false
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
include:
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: WITHOUT_LLVM="yes"
|
||||
|
||||
|
||||
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";
|
||||
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01';
|
||||
fi;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
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 ;
|
||||
sudo add-apt-repository ppa:beineri/opt-qt59-trusty -y;
|
||||
sudo apt-get update;
|
||||
sudo apt-get install qt59base -y --allow-unauthenticated;
|
||||
fi;
|
||||
|
||||
# Add coverall for C++ so coverall.io could be triggered. Even it should be --coverage and gcov.
|
||||
# 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;
|
||||
pip install --user cpp-coveralls requests[security];
|
||||
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/libvulkan-dev_1.0.21.0+dfsg1-1~16.04.1_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.21.0+dfsg1-1~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.21.0+dfsg1-1~16.04.1_amd64.deb libvulkan-dev_1.0.21.0+dfsg1-1~16.04.1_amd64.deb;
|
||||
else
|
||||
brew update;
|
||||
brew update; brew update;
|
||||
brew install ccache glew llvm40;
|
||||
fi;
|
||||
|
||||
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
|
||||
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
- source /opt/qt59/bin/qt59-env.sh
|
||||
- mkdir build
|
||||
- cd build
|
||||
- export CMAKE_PREFIX_PATH=~/Qt/5.10.1/gcc_64/lib/cmake
|
||||
- export CXXFLAGS="$CXXFLAGS -DTRAVIS=true";
|
||||
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
|
||||
- if [ -z "$WITHOUT_LLVM" ]; then
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
|
||||
else
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/#$TRAVIS_PULL_REQUEST";
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DWITHOUT_LLVM=ON;
|
||||
fi;
|
||||
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr -G Ninja;
|
||||
- ninja
|
||||
- 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.1/gcc_64/lib;
|
||||
DESTDIR=appdir ninja install ; find appdir/ ;
|
||||
- if [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export LD_LIBRARY_PATH=${PWD}/3rdparty/libpng:/opt/qt59/lib/:$LD_LIBRARY_PATH ;
|
||||
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.1/gcc_64/bin/:${PATH} ;
|
||||
./linuxdeployqt*.AppImage --appimage-extract ;
|
||||
unset QTDIR; unset QT_PLUGIN_PATH ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
|
||||
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
mkdir ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.10.1/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
|
||||
cp ~/Qt/5.10.1/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
cp ~/Qt/5.10.1/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.10.1/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
|
||||
rm ./appdir/usr/lib/libfreetype.so.6 ;
|
||||
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
|
||||
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage ;
|
||||
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
|
||||
COMM_TAG="$(git describe --tags $(git rev-list --tags --max-count=1))"
|
||||
COMM_COUNT="$(git rev-list --count HEAD)"
|
||||
curl "${UPLOAD_URL}${TRAVIS_COMMIT:0:8}&t=${COMM_TAG}&a=${COMM_COUNT}" --upload-file ./RPCS3*.AppImage;
|
||||
zip -r9 rpcs3.zip ./RPCS3*.AppImage;
|
||||
if [ -z "$WITHOUT_LLVM" ]; then
|
||||
export LLVM="-LLVM";
|
||||
fi;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}${LLVM}_linux64 --upload-file rpcs3.zip;
|
||||
fi;
|
||||
|
||||
script:
|
||||
@@ -91,17 +99,15 @@ script:
|
||||
#- echo "--Shell Export Lists START--" ; export -p; echo "--Shell Export Lists STOP--";
|
||||
# And to ensure the versions of toolchain
|
||||
- echo "--CXX version?"; "$CXX" --version; echo "--CXX version confirmed";
|
||||
#- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j 3; fi
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:jonathonf/binutils' # We need to update binutils to a newer version to link against the ffmpeg libs on.
|
||||
packages:
|
||||
- binutils
|
||||
- cmake
|
||||
- ninja-build
|
||||
- libasound2-dev
|
||||
- libopenal-dev
|
||||
- freeglut3-dev
|
||||
@@ -111,16 +117,23 @@ 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.1 manually because the version trusty provides is too old.
|
||||
# We need to install qt 5.8 manually because the version trusty provides is too old.
|
||||
#- qtbase5-dev
|
||||
- libudev-dev
|
||||
- libevdev-dev
|
||||
- libpulse-dev
|
||||
coverity_scan:
|
||||
project:
|
||||
name: $TRAVIS_REPO_SLUG
|
||||
description: "PS3 emulator/debugger"
|
||||
notification_email: nekotekina@gmail.com
|
||||
build_command: "make -j 3"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
after_success:
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "$TRAVIS_OS_NAME" = linux ]; then coveralls --extension .c --extension .cpp --extension .h; fi
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
@@ -393,72 +393,6 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_BFORMAT
|
||||
#define AL_EXT_BFORMAT 1
|
||||
#define AL_FORMAT_BFORMAT2D_8 0x20021
|
||||
#define AL_FORMAT_BFORMAT2D_16 0x20022
|
||||
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
|
||||
#define AL_FORMAT_BFORMAT3D_8 0x20031
|
||||
#define AL_FORMAT_BFORMAT3D_16 0x20032
|
||||
#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_MULAW_BFORMAT
|
||||
#define AL_EXT_MULAW_BFORMAT 1
|
||||
#define AL_FORMAT_BFORMAT2D_MULAW 0x10031
|
||||
#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
|
||||
#endif
|
||||
|
||||
#ifndef ALC_SOFT_HRTF
|
||||
#define ALC_SOFT_HRTF 1
|
||||
#define ALC_HRTF_SOFT 0x1992
|
||||
#define ALC_DONT_CARE_SOFT 0x0002
|
||||
#define ALC_HRTF_STATUS_SOFT 0x1993
|
||||
#define ALC_HRTF_DISABLED_SOFT 0x0000
|
||||
#define ALC_HRTF_ENABLED_SOFT 0x0001
|
||||
#define ALC_HRTF_DENIED_SOFT 0x0002
|
||||
#define ALC_HRTF_REQUIRED_SOFT 0x0003
|
||||
#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
|
||||
#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
|
||||
#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994
|
||||
#define ALC_HRTF_SPECIFIER_SOFT 0x1995
|
||||
#define ALC_HRTF_ID_SOFT 0x1996
|
||||
typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index);
|
||||
typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index);
|
||||
ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_gain_clamp_ex
|
||||
#define AL_SOFT_gain_clamp_ex 1
|
||||
#define AL_GAIN_LIMIT_SOFT 0x200E
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_source_resampler
|
||||
#define AL_SOFT_source_resampler
|
||||
#define AL_NUM_RESAMPLERS_SOFT 0x1210
|
||||
#define AL_DEFAULT_RESAMPLER_SOFT 0x1211
|
||||
#define AL_SOURCE_RESAMPLER_SOFT 0x1212
|
||||
#define AL_RESAMPLER_NAME_SOFT 0x1213
|
||||
typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_source_spatialize
|
||||
#define AL_SOFT_source_spatialize
|
||||
#define AL_SOURCE_SPATIALIZE_SOFT 0x1214
|
||||
#define AL_AUTO_SOFT 0x0002
|
||||
#endif
|
||||
|
||||
#ifndef ALC_SOFT_output_limiter
|
||||
#define ALC_SOFT_output_limiter
|
||||
#define ALC_OUTPUT_LIMITER_SOFT 0x199A
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -345,7 +345,7 @@ typedef struct {
|
||||
/* Driving Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
|
||||
{ 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
{ 1.0000f, 0.0000f, 3.1623f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
|
||||
{ 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
@@ -18,6 +18,9 @@ EXPORTS
|
||||
alDeleteBuffers
|
||||
alDeleteEffects
|
||||
alDeleteFilters
|
||||
alDeleteFontsoundsSOFT
|
||||
alDeletePresetsSOFT
|
||||
alDeleteSoundfontsSOFT
|
||||
alDeleteSources
|
||||
alDisable
|
||||
alDistanceModel
|
||||
@@ -32,10 +35,17 @@ EXPORTS
|
||||
alFilterfv
|
||||
alFilteri
|
||||
alFilteriv
|
||||
alFontsound2iSOFT
|
||||
alFontsoundModulatoriSOFT
|
||||
alFontsoundiSOFT
|
||||
alFontsoundivSOFT
|
||||
alGenAuxiliaryEffectSlots
|
||||
alGenBuffers
|
||||
alGenEffects
|
||||
alGenFilters
|
||||
alGenFontsoundsSOFT
|
||||
alGenPresetsSOFT
|
||||
alGenSoundfontsSOFT
|
||||
alGenSources
|
||||
alGetAuxiliaryEffectSlotf
|
||||
alGetAuxiliaryEffectSlotfv
|
||||
@@ -64,6 +74,8 @@ EXPORTS
|
||||
alGetFilteriv
|
||||
alGetFloat
|
||||
alGetFloatv
|
||||
alGetFontsoundModulatorivSOFT
|
||||
alGetFontsoundivSOFT
|
||||
alGetInteger
|
||||
alGetInteger64SOFT
|
||||
alGetInteger64vSOFT
|
||||
@@ -74,7 +86,9 @@ EXPORTS
|
||||
alGetListenerfv
|
||||
alGetListeneri
|
||||
alGetListeneriv
|
||||
alGetPresetivSOFT
|
||||
alGetProcAddress
|
||||
alGetSoundfontivSOFT
|
||||
alGetSource3dSOFT
|
||||
alGetSource3f
|
||||
alGetSource3i
|
||||
@@ -88,7 +102,6 @@ EXPORTS
|
||||
alGetSourcei64vSOFT
|
||||
alGetSourceiv
|
||||
alGetString
|
||||
alGetStringiSOFT
|
||||
alIsAuxiliaryEffectSlot
|
||||
alIsBuffer
|
||||
alIsBufferFormatSupportedSOFT
|
||||
@@ -96,6 +109,9 @@ EXPORTS
|
||||
alIsEnabled
|
||||
alIsExtensionPresent
|
||||
alIsFilter
|
||||
alIsFontsoundSOFT
|
||||
alIsPresetSOFT
|
||||
alIsSoundfontSOFT
|
||||
alIsSource
|
||||
alListener3f
|
||||
alListener3i
|
||||
@@ -103,7 +119,21 @@ EXPORTS
|
||||
alListenerfv
|
||||
alListeneri
|
||||
alListeneriv
|
||||
alLoadSoundfontSOFT
|
||||
alMidiEventSOFT
|
||||
alMidiGainSOFT
|
||||
alMidiPauseSOFT
|
||||
alMidiPlaySOFT
|
||||
alMidiResetSOFT
|
||||
alMidiSoundfontSOFT
|
||||
alMidiSoundfontvSOFT
|
||||
alMidiStopSOFT
|
||||
alMidiSysExSOFT
|
||||
alPresetFontsoundsSOFT
|
||||
alPresetiSOFT
|
||||
alPresetivSOFT
|
||||
alProcessUpdatesSOFT
|
||||
alSoundfontPresetsSOFT
|
||||
alSource3dSOFT
|
||||
alSource3f
|
||||
alSource3i
|
||||
@@ -145,9 +175,7 @@ EXPORTS
|
||||
alcGetIntegerv
|
||||
alcGetProcAddress
|
||||
alcGetString
|
||||
alcGetStringiSOFT
|
||||
alcGetThreadContext
|
||||
alcIsAmbisonicFormatSupportedSOFT
|
||||
alcIsExtensionPresent
|
||||
alcIsRenderFormatSupportedSOFT
|
||||
alcLoopbackOpenDeviceSOFT
|
||||
@@ -155,6 +183,5 @@ EXPORTS
|
||||
alcOpenDevice
|
||||
alcProcessContext
|
||||
alcRenderSamplesSOFT
|
||||
alcResetDeviceSOFT
|
||||
alcSetThreadContext
|
||||
alcSuspendContext
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
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)
|
||||
option(USE_NATIVE_INSTRUCTIONS "USE_NATIVE_INSTRUCTIONS makes rpcs3 compile with -march=native, which is useful for local builds, but not good for packages." ON)
|
||||
option(VULKAN_PREBUILT "" OFF)
|
||||
|
||||
if (WITH_GDB)
|
||||
add_definitions(-DWITH_GDB_DEBUGGER)
|
||||
@@ -37,6 +35,8 @@ if (NOT USE_SYSTEM_LIBPNG)
|
||||
add_subdirectory( 3rdparty/libpng )
|
||||
endif()
|
||||
|
||||
option(VULKAN_PREBUILT "" OFF)
|
||||
|
||||
# TODO: do real installation, including copying directory structure
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_BINARY_DIR}/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${PROJECT_BINARY_DIR}/bin")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Getting Started
|
||||
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](https://forums.rpcs3.net).
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](http://www.emunewz.net/forum/forumdisplay.php?fid=172).
|
||||
|
||||
# Issue Reporting
|
||||
|
||||
@@ -13,7 +13,7 @@ Before getting started using the emulator, read the [Quickstart Guide](https://r
|
||||
- Use understandable English. It doesn't need to be perfect, but clear enough to understand your message.
|
||||
- While reporting issues, don't forget to include details about your system (OS, CPU, GPU, etc.), as well as the RPCS3.log file.
|
||||
|
||||
Submitting your test results for Commercial Games must be done on our forums. Please read the [Game Compatibility](https://github.com/RPCS3/rpcs3/wiki/Game-Compatibility) wiki page before doing so.
|
||||
Submitting your test results for Commercial Games must be done on our forums' [Commercial Games](http://www.emunewz.net/forum/forumdisplay.php?fid=193) section. If there's already a thread for the game you want to report post in it, otherwise please make a new thread following the [Guidelines for submitting new games](http://www.emunewz.net/forum/showthread.php?tid=174376).
|
||||
|
||||
# Contributing
|
||||
|
||||
@@ -3,13 +3,14 @@ RPCS3
|
||||
|
||||
[](https://travis-ci.org/RPCS3/rpcs3)
|
||||
[](https://ci.appveyor.com/project/rpcs3/rpcs3/branch/master)
|
||||
[](https://scan.coverity.com/projects/3960)
|
||||
|
||||
The world's first open-source PlayStation 3 emulator/debugger written in C++ for Windows and Linux.
|
||||
|
||||
You can find some basic information in our [**website**](https://rpcs3.net/).
|
||||
For discussion about this emulator and PS3 emulation please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
For discussion about this emulator and PS3 emulation please visit our [**forums**](http://www.emunewz.net/forum/forumdisplay.php?fid=172) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
|
||||
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
[**Support Lead Developer Nekotekina on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
|
||||
|
||||
## Development
|
||||
@@ -20,26 +21,24 @@ 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/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.10+](https://www.qt.io/download-open-source/) (required; add QTDIR environment variable if you do not want to use the Visual Studio Qt Plugin: e.g. `<QtInstallFolder>\5.10.1\msvc2015_64\`)
|
||||
* [Qt 5.9+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.9\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.10+](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`
|
||||
**If you have a NVIDIA GPU, you may need to install the libglvnd package.**
|
||||
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel libGLEW`
|
||||
|
||||
### MacOS
|
||||
MacOS is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
|
||||
### Mac OSX
|
||||
Mac OSX is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
|
||||
* Xcode 6+ (tested with Xcode 6.4)
|
||||
* Install with Homebrew: `brew install glew llvm qt cmake`
|
||||
* Install with Homebrew: `brew install glew`
|
||||
|
||||
|
||||
## Building on Windows:
|
||||
@@ -48,61 +47,38 @@ 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 e.g `<QtInstallFolder>\5.10.1\msvc2015_64\` </br>
|
||||
|
||||
|
||||
Open `rpcs3.sln`
|
||||
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.9\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.10.1\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.8\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:
|
||||
## Building on Linux & Mac OSX:
|
||||
|
||||
1) `git clone https://github.com/RPCS3/rpcs3.git` </br>
|
||||
2) `cd rpcs3/` </br>
|
||||
3) `git submodule update --init` </br>
|
||||
4) `cd ../ && mkdir rpcs3_build && cd rpcs3_build`
|
||||
4) `cmake ../rpcs3/ && make GitVersion && make` </br>
|
||||
4) `cmake CMakeLists.txt && make GitVersion && make` </br>
|
||||
5) Run RPCS3 with `./bin/rpcs3` </br>
|
||||
|
||||
If you are on MacOS and want to build with brew llvm and qt don't forget to add the following environment variables
|
||||
|
||||
* `LLVM_DIR=/usr/local/opt/llvm/` (or wherever llvm was installed).
|
||||
* `Qt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5` (or wherever qt was installed).
|
||||
If you are on OSX and want to build with llvm don't forget to add `-DLLVM_DIR=...` (or wherever llvm brew was installed) to cmake invocation.
|
||||
|
||||
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
|
||||
|
||||
|
||||
## CMake Build Options (Linux & Mac OS)
|
||||
## CMake Build Options (Linux & Mac OSX)
|
||||
|
||||
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*)
|
||||
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*) </br>
|
||||
Build against the shared libpng instead of using the builtin one. libpng 1.6+ highly recommended. Try this option if you get version conflict errors or only see black game icons.
|
||||
|
||||
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*)
|
||||
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*) </br>
|
||||
Build against the shared ffmpeg libraries instead of using the builtin patched version. Try this if the builtin version breaks the OpenGL renderer for you.
|
||||
|
||||
- ```-DWITHOUT_LLVM=ON/OFF``` (default = *OFF*)
|
||||
This forces RPCS3 to build without LLVM, not recommended.
|
||||
|
||||
- ```-DWITH_GDB=ON/OFF``` (default = *OFF*)
|
||||
This Builds RPCS3 with support for debugging PS3 games using gdb.
|
||||
|
||||
- ```-DUSE_VULKAN=ON/OFF``` (default = *ON*)
|
||||
This builds RPCS3 with Vulkan support.
|
||||
|
||||
- ```-DUSE_NATIVE_INSTRUCTIONS=ON/OFF``` (default = *ON*)
|
||||
This builds rpcs3 with -march=native, which is useful for local builds, but not good for packages.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
logs::channel cfg("CFG");
|
||||
@@ -50,11 +48,6 @@ namespace cfg
|
||||
static void decode(const YAML::Node& data, class _base& rhs);
|
||||
}
|
||||
|
||||
std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
|
||||
{
|
||||
return {std::to_string(min), std::to_string(max)};
|
||||
}
|
||||
|
||||
bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
{
|
||||
// TODO: this could be rewritten without exceptions (but it should be as safe as possible and provide logs)
|
||||
@@ -89,8 +82,6 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
|
||||
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
|
||||
{
|
||||
u64 max = -1;
|
||||
|
||||
for (u64 i = 0;; i++)
|
||||
{
|
||||
std::string var;
|
||||
@@ -108,8 +99,6 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
max = i;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -119,22 +108,14 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
|
||||
if (pos != value.size())
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): unexpected characters (pos=%zu)", value, pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val > max)
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out) *out = val;
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
catch (...)
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): invalid enum value: %s", value, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -202,12 +183,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)
|
||||
@@ -290,19 +268,14 @@ std::string cfg::node::to_string() const
|
||||
YAML::Emitter out;
|
||||
cfg::encode(out, *this);
|
||||
|
||||
return {out.c_str(), out.size()};
|
||||
return{ out.c_str(), out.size() };
|
||||
}
|
||||
|
||||
bool cfg::node::from_string(const std::string& value) try
|
||||
bool cfg::node::from_string(const std::string& value)
|
||||
{
|
||||
cfg::decode(YAML::Load(value), *this);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
cfg.fatal("%s thrown: %s", typeid(e).name(), e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
void cfg::node::from_default()
|
||||
{
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
// Format min and max values
|
||||
std::vector<std::string> make_int_range(s64 min, s64 max);
|
||||
|
||||
// Convert string to signed integer
|
||||
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
|
||||
|
||||
@@ -118,7 +115,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 +147,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 +214,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)
|
||||
@@ -257,16 +249,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);
|
||||
}
|
||||
};
|
||||
|
||||
// Alias for 32 bit int
|
||||
@@ -281,7 +263,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)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <typeinfo>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
@@ -75,25 +74,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;
|
||||
}
|
||||
|
||||
@@ -109,10 +93,6 @@ static fs::error to_error(DWORD e)
|
||||
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
|
||||
case ERROR_DIRECTORY: return fs::error::inval;
|
||||
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 +103,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>
|
||||
@@ -148,7 +127,6 @@ static fs::error to_error(int e)
|
||||
case EEXIST: return fs::error::exist;
|
||||
case EINVAL: return fs::error::inval;
|
||||
case EACCES: return fs::error::acces;
|
||||
case ENOTEMPTY: return fs::error::notempty;
|
||||
default: fmt::throw_exception("Unknown system error: %d.", e);
|
||||
}
|
||||
}
|
||||
@@ -531,7 +509,7 @@ bool fs::remove_dir(const std::string& path)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fs::rename(const std::string& from, const std::string& to, bool overwrite)
|
||||
bool fs::rename(const std::string& from, const std::string& to)
|
||||
{
|
||||
const auto device = get_virtual_device(from);
|
||||
|
||||
@@ -546,43 +524,14 @@ bool fs::rename(const std::string& from, const std::string& to, bool overwrite)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
const auto ws1 = to_wchar(from);
|
||||
const auto ws2 = to_wchar(to);
|
||||
|
||||
if (!MoveFileExW(ws1.get(), ws2.get(), overwrite ? MOVEFILE_REPLACE_EXISTING : 0))
|
||||
if (!MoveFileW(to_wchar(from).get(), to_wchar(to).get()))
|
||||
{
|
||||
DWORD error1 = GetLastError();
|
||||
|
||||
if (overwrite && error1 == ERROR_ACCESS_DENIED && is_dir(from) && is_dir(to))
|
||||
{
|
||||
if (RemoveDirectoryW(ws2.get()))
|
||||
{
|
||||
if (MoveFileW(ws1.get(), ws2.get()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
error1 = GetLastError();
|
||||
CreateDirectoryW(ws2.get(), NULL); // TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
error1 = GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
g_tls_error = to_error(error1);
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
if (!overwrite && exists(to))
|
||||
{
|
||||
g_tls_error = fs::error::exist;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::rename(from.c_str(), to.c_str()) != 0)
|
||||
{
|
||||
g_tls_error = to_error(errno);
|
||||
@@ -696,17 +645,18 @@ bool fs::truncate_file(const std::string& path, u64 length)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Open the file
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE_END_OF_FILE_INFO _eof;
|
||||
_eof.EndOfFile.QuadPart = length;
|
||||
LARGE_INTEGER distance;
|
||||
distance.QuadPart = length;
|
||||
|
||||
if (!SetFileInformationByHandle(handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
|
||||
// Seek and truncate
|
||||
if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -735,7 +685,7 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Open the file
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
@@ -814,13 +764,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
disp = test(mode & fs::trunc) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
||||
}
|
||||
|
||||
DWORD share = FILE_SHARE_READ;
|
||||
if (!test(mode & fs::unshare))
|
||||
{
|
||||
share |= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
}
|
||||
|
||||
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, share, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -828,7 +772,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return;
|
||||
}
|
||||
|
||||
class windows_file final : public file_base, public get_native_handle
|
||||
class windows_file final : public file_base
|
||||
{
|
||||
const HANDLE m_handle;
|
||||
|
||||
@@ -866,15 +810,23 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
bool trunc(u64 length) override
|
||||
{
|
||||
FILE_END_OF_FILE_INFO _eof;
|
||||
_eof.EndOfFile.QuadPart = length;
|
||||
LARGE_INTEGER old, pos;
|
||||
|
||||
if (!SetFileInformationByHandle(m_handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
|
||||
pos.QuadPart = 0;
|
||||
if (!SetFilePointerEx(m_handle, pos, &old, FILE_CURRENT)) // get old position
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
pos.QuadPart = length;
|
||||
if (!SetFilePointerEx(m_handle, pos, NULL, FILE_BEGIN)) // set new position
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
verify("file::trunc" HERE), SetEndOfFile(m_handle), SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -927,11 +879,6 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
return size.QuadPart;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<windows_file>(handle);
|
||||
@@ -955,14 +902,7 @@ 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
|
||||
class unix_file final : public file_base
|
||||
{
|
||||
const int m_fd;
|
||||
|
||||
@@ -1034,7 +974,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);
|
||||
@@ -1051,11 +991,6 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
return file_info.st_size;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<unix_file>(fd);
|
||||
@@ -1131,20 +1066,6 @@ fs::file::file(const void* ptr, std::size_t size)
|
||||
m_file = std::make_unique<memory_stream>(ptr, size);
|
||||
}
|
||||
|
||||
fs::native_handle fs::file::get_handle() const
|
||||
{
|
||||
if (auto getter = dynamic_cast<get_native_handle*>(m_file.get()))
|
||||
{
|
||||
return getter->get();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fs::dir::xnull() const
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("fs::dir is null");
|
||||
@@ -1258,12 +1179,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 +1279,7 @@ std::string fs::get_data_dir(const std::string& prefix, const std::string& locat
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
buf.push_back(c);
|
||||
}
|
||||
|
||||
@@ -1482,7 +1398,6 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
|
||||
case fs::error::noent: return "Not found";
|
||||
case fs::error::exist: return "Already exists";
|
||||
case fs::error::acces: return "Access violation";
|
||||
case fs::error::notempty: return "Not empty";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
|
||||
@@ -10,12 +10,6 @@
|
||||
|
||||
namespace fs
|
||||
{
|
||||
#ifdef _WIN32
|
||||
using native_handle = void*;
|
||||
#else
|
||||
using native_handle = int;
|
||||
#endif
|
||||
|
||||
// File open mode flags
|
||||
enum class open_mode : u32
|
||||
{
|
||||
@@ -25,7 +19,6 @@ namespace fs
|
||||
create,
|
||||
trunc,
|
||||
excl,
|
||||
unshare,
|
||||
|
||||
__bitset_enum_max
|
||||
};
|
||||
@@ -36,7 +29,6 @@ namespace fs
|
||||
constexpr auto create = +open_mode::create; // Create file if it doesn't exist
|
||||
constexpr auto trunc = +open_mode::trunc; // Clear opened file if it's not empty
|
||||
constexpr auto excl = +open_mode::excl; // Failure if the file already exists (used with `create`)
|
||||
constexpr auto unshare = +open_mode::unshare; // Prevent opening the file twice
|
||||
|
||||
constexpr auto rewrite = open_mode::write + open_mode::create + open_mode::trunc;
|
||||
|
||||
@@ -63,12 +55,6 @@ namespace fs
|
||||
s64 ctime;
|
||||
};
|
||||
|
||||
// Native handle getter
|
||||
struct get_native_handle
|
||||
{
|
||||
virtual native_handle get() = 0;
|
||||
};
|
||||
|
||||
// File handle base
|
||||
struct file_base
|
||||
{
|
||||
@@ -159,7 +145,7 @@ namespace fs
|
||||
bool create_path(const std::string& path);
|
||||
|
||||
// Rename (move) file or directory
|
||||
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
||||
bool rename(const std::string& from, const std::string& to);
|
||||
|
||||
// Copy file contents
|
||||
bool copy_file(const std::string& from, const std::string& to, bool overwrite);
|
||||
@@ -361,9 +347,6 @@ namespace fs
|
||||
if (seek(0), !read(result)) xfail();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get native handle if available
|
||||
native_handle get_handle() const;
|
||||
};
|
||||
|
||||
class dir final
|
||||
@@ -422,7 +405,7 @@ namespace fs
|
||||
|
||||
class iterator
|
||||
{
|
||||
const dir* m_parent;
|
||||
dir* m_parent;
|
||||
dir_entry m_entry;
|
||||
|
||||
public:
|
||||
@@ -432,7 +415,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 +441,7 @@ namespace fs
|
||||
|
||||
iterator& operator++()
|
||||
{
|
||||
*this = {m_parent, mode::from_current};
|
||||
*this = { m_parent, mode::from_current };
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -468,14 +451,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 };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -502,7 +485,6 @@ namespace fs
|
||||
noent,
|
||||
exist,
|
||||
acces,
|
||||
notempty,
|
||||
};
|
||||
|
||||
// Error code returned
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "fcntl.h"
|
||||
#include"fcntl.h"
|
||||
#endif
|
||||
|
||||
extern void ppu_set_breakpoint(u32 addr);
|
||||
@@ -365,7 +365,7 @@ std::string GDBDebugServer::get_reg(std::shared_ptr<ppu_thread> thread, u32 rid)
|
||||
return std::string(8, 'x');
|
||||
default:
|
||||
if (rid > 70) return "";
|
||||
return (rid > 31)
|
||||
return (rid > 31)
|
||||
? u64_to_padded_hex(reinterpret_cast<u64&>(thread->fpr[rid - 32])) //fpr
|
||||
: u64_to_padded_hex(thread->gpr[rid]); //gpr
|
||||
}
|
||||
@@ -453,12 +453,13 @@ bool GDBDebugServer::cmd_thread_info(gdb_cmd & cmd)
|
||||
result += u64_to_padded_hex(static_cast<u64>(cpu.id));
|
||||
};
|
||||
idm::select<ppu_thread>(on_select);
|
||||
idm::select<ARMv7Thread>(on_select);
|
||||
idm::select<RawSPUThread>(on_select);
|
||||
idm::select<SPUThread>(on_select);
|
||||
|
||||
//todo: this may exceed max command length
|
||||
result = "m" + result + "l";
|
||||
|
||||
|
||||
return send_cmd_ack(result);;
|
||||
}
|
||||
|
||||
@@ -767,7 +768,7 @@ void GDBDebugServer::on_task()
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
if (client_socket) {
|
||||
closesocket(client_socket);
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "File.h"
|
||||
#include "Log.h"
|
||||
#include "mutex.h"
|
||||
#include "sysinfo.h"
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -30,8 +29,6 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "JIT.h"
|
||||
@@ -49,11 +46,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 +53,6 @@ static void* const s_memory = []() -> void*
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return utils::memory_reserve(s_memory_size);
|
||||
}();
|
||||
@@ -71,8 +62,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 +78,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);
|
||||
@@ -123,13 +89,13 @@ extern void jit_finalize()
|
||||
// Helper class
|
||||
struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
{
|
||||
std::unordered_map<std::string, u64>& m_link;
|
||||
std::unordered_map<std::string, std::uintptr_t>& m_link;
|
||||
|
||||
std::array<u8, 16>* m_tramps{};
|
||||
|
||||
u8* m_code_addr{}; // TODO
|
||||
|
||||
MemoryManager(std::unordered_map<std::string, u64>& table)
|
||||
MemoryManager(std::unordered_map<std::string, std::uintptr_t>& table)
|
||||
: m_link(table)
|
||||
{
|
||||
}
|
||||
@@ -196,7 +162,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 +183,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 +208,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 +225,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 +252,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 +275,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)
|
||||
@@ -376,54 +343,32 @@ public:
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Created module: %s", module->getName().data());
|
||||
}
|
||||
|
||||
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
{
|
||||
if (fs::file cached{path, fs::read})
|
||||
std::string name = m_path;
|
||||
name.append(module->getName());
|
||||
|
||||
if (fs::file cached{name, fs::read})
|
||||
{
|
||||
auto buf = llvm::MemoryBuffer::getNewUninitMemBuffer(cached.size());
|
||||
cached.read(const_cast<char*>(buf->getBufferStart()), buf->getBufferSize());
|
||||
return buf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
{
|
||||
std::string path = m_path;
|
||||
path.append(module->getName());
|
||||
|
||||
if (auto buf = load(path))
|
||||
{
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Loaded module: %s", module->getName().data());
|
||||
return buf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, std::string _cpu)
|
||||
: m_link(_link)
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, std::uintptr_t>& _link, std::string _cpu)
|
||||
: m_link(std::move(_link))
|
||||
, m_cpu(std::move(_cpu))
|
||||
{
|
||||
if (m_cpu.empty())
|
||||
{
|
||||
m_cpu = llvm::sys::getHostCPUName();
|
||||
|
||||
if (m_cpu == "sandybridge" ||
|
||||
m_cpu == "ivybridge" ||
|
||||
m_cpu == "haswell" ||
|
||||
m_cpu == "broadwell" ||
|
||||
m_cpu == "skylake" ||
|
||||
m_cpu == "skylake-avx512" ||
|
||||
m_cpu == "cannonlake")
|
||||
{
|
||||
if (!utils::has_avx())
|
||||
{
|
||||
m_cpu = "nehalem";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string result;
|
||||
@@ -485,11 +430,6 @@ void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void jit_compiler::add(const std::string& path)
|
||||
{
|
||||
m_engine->addObjectFile(std::move(llvm::object::ObjectFile::createObjectFile(*ObjectCache::load(path)).get()));
|
||||
}
|
||||
|
||||
void jit_compiler::fin()
|
||||
{
|
||||
m_engine->finalizeObject();
|
||||
|
||||
@@ -49,12 +49,9 @@ public:
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// Add module (path to obj cache dir)
|
||||
// Add module
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
|
||||
// Add object (path to obj file)
|
||||
void add(const std::string& path);
|
||||
|
||||
// Finalize
|
||||
void fin();
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,265 +0,0 @@
|
||||
/*
|
||||
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
|
||||
* https://github.com/corporateshark/LUrlParser
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "LUrlParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
// check if the scheme name is valid
|
||||
static bool IsSchemeValid( const std::string& SchemeName )
|
||||
{
|
||||
for ( auto c : SchemeName )
|
||||
{
|
||||
if ( !isalpha( c ) && c != '+' && c != '-' && c != '.' ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LUrlParser::clParseURL::GetPort( int* OutPort ) const
|
||||
{
|
||||
if ( !IsValid() ) { return false; }
|
||||
|
||||
int Port = atoi( m_Port.c_str() );
|
||||
|
||||
if ( Port <= 0 || Port > 65535 ) { return false; }
|
||||
|
||||
if ( OutPort ) { *OutPort = Port; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// based on RFC 1738 and RFC 3986
|
||||
LUrlParser::clParseURL LUrlParser::clParseURL::ParseURL( const std::string& URL )
|
||||
{
|
||||
LUrlParser::clParseURL Result;
|
||||
|
||||
const char* CurrentString = URL.c_str();
|
||||
|
||||
/*
|
||||
* <scheme>:<scheme-specific-part>
|
||||
* <scheme> := [a-z\+\-\.]+
|
||||
* For resiliency, programs interpreting URLs should treat upper case letters as equivalent to lower case in scheme names
|
||||
*/
|
||||
|
||||
// try to read scheme
|
||||
{
|
||||
const char* LocalString = strchr( CurrentString, ':' );
|
||||
|
||||
if ( !LocalString )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoUrlCharacter );
|
||||
}
|
||||
|
||||
// save the scheme name
|
||||
Result.m_Scheme = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
if ( !IsSchemeValid( Result.m_Scheme ) )
|
||||
{
|
||||
return clParseURL( LUrlParserError_InvalidSchemeName );
|
||||
}
|
||||
|
||||
// scheme should be lowercase
|
||||
std::transform( Result.m_Scheme.begin(), Result.m_Scheme.end(), Result.m_Scheme.begin(), ::tolower );
|
||||
|
||||
// skip ':'
|
||||
CurrentString = LocalString+1;
|
||||
}
|
||||
|
||||
/*
|
||||
* //<user>:<password>@<host>:<port>/<url-path>
|
||||
* any ":", "@" and "/" must be normalized
|
||||
*/
|
||||
|
||||
// skip "//"
|
||||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
|
||||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
|
||||
|
||||
// check if the user name and password are specified
|
||||
bool bHasUserName = false;
|
||||
|
||||
const char* LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString )
|
||||
{
|
||||
if ( *LocalString == '@' )
|
||||
{
|
||||
// user name and password are specified
|
||||
bHasUserName = true;
|
||||
break;
|
||||
}
|
||||
else if ( *LocalString == '/' )
|
||||
{
|
||||
// end of <host>:<port> specification
|
||||
bHasUserName = false;
|
||||
break;
|
||||
}
|
||||
|
||||
LocalString++;
|
||||
}
|
||||
|
||||
// user name and password
|
||||
LocalString = CurrentString;
|
||||
|
||||
if ( bHasUserName )
|
||||
{
|
||||
// read user name
|
||||
while ( *LocalString && *LocalString != ':' && *LocalString != '@' ) LocalString++;
|
||||
|
||||
Result.m_UserName = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
// proceed with the current pointer
|
||||
CurrentString = LocalString;
|
||||
|
||||
if ( *CurrentString == ':' )
|
||||
{
|
||||
// skip ':'
|
||||
CurrentString++;
|
||||
|
||||
// read password
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '@' ) LocalString++;
|
||||
|
||||
Result.m_Password = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// skip '@'
|
||||
if ( *CurrentString != '@' )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoAtSign );
|
||||
}
|
||||
|
||||
CurrentString++;
|
||||
}
|
||||
|
||||
bool bHasBracket = ( *CurrentString == '[' );
|
||||
|
||||
// go ahead, read the host name
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString )
|
||||
{
|
||||
if ( bHasBracket && *LocalString == ']' )
|
||||
{
|
||||
// end of IPv6 address
|
||||
LocalString++;
|
||||
break;
|
||||
}
|
||||
else if ( !bHasBracket && ( *LocalString == ':' || *LocalString == '/' ) )
|
||||
{
|
||||
// port number is specified
|
||||
break;
|
||||
}
|
||||
|
||||
LocalString++;
|
||||
}
|
||||
|
||||
Result.m_Host = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
|
||||
// is port number specified?
|
||||
if ( *CurrentString == ':' )
|
||||
{
|
||||
CurrentString++;
|
||||
|
||||
// read port number
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '/' ) LocalString++;
|
||||
|
||||
Result.m_Port = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// end of string
|
||||
if ( !*CurrentString )
|
||||
{
|
||||
Result.m_ErrorCode = LUrlParserError_Ok;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// skip '/'
|
||||
if ( *CurrentString != '/' )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoSlash );
|
||||
}
|
||||
|
||||
CurrentString++;
|
||||
|
||||
// parse the path
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '#' && *LocalString != '?' ) LocalString++;
|
||||
|
||||
Result.m_Path = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
|
||||
// check for query
|
||||
if ( *CurrentString == '?' )
|
||||
{
|
||||
// skip '?'
|
||||
CurrentString++;
|
||||
|
||||
// read query
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '#' ) LocalString++;
|
||||
|
||||
Result.m_Query = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// check for fragment
|
||||
if ( *CurrentString == '#' )
|
||||
{
|
||||
// skip '#'
|
||||
CurrentString++;
|
||||
|
||||
// read fragment
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString ) LocalString++;
|
||||
|
||||
Result.m_Fragment = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
Result.m_ErrorCode = LUrlParserError_Ok;
|
||||
|
||||
return Result;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
|
||||
* https://github.com/corporateshark/LUrlParser
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace LUrlParser
|
||||
{
|
||||
enum LUrlParserError
|
||||
{
|
||||
LUrlParserError_Ok = 0,
|
||||
LUrlParserError_Uninitialized = 1,
|
||||
LUrlParserError_NoUrlCharacter = 2,
|
||||
LUrlParserError_InvalidSchemeName = 3,
|
||||
LUrlParserError_NoDoubleSlash = 4,
|
||||
LUrlParserError_NoAtSign = 5,
|
||||
LUrlParserError_UnexpectedEndOfLine = 6,
|
||||
LUrlParserError_NoSlash = 7,
|
||||
};
|
||||
|
||||
class clParseURL
|
||||
{
|
||||
public:
|
||||
LUrlParserError m_ErrorCode;
|
||||
std::string m_Scheme;
|
||||
std::string m_Host;
|
||||
std::string m_Port;
|
||||
std::string m_Path;
|
||||
std::string m_Query;
|
||||
std::string m_Fragment;
|
||||
std::string m_UserName;
|
||||
std::string m_Password;
|
||||
|
||||
clParseURL()
|
||||
: m_ErrorCode( LUrlParserError_Uninitialized )
|
||||
{}
|
||||
|
||||
/// return 'true' if the parsing was successful
|
||||
bool IsValid() const { return m_ErrorCode == LUrlParserError_Ok; }
|
||||
|
||||
/// helper to convert the port number to int, return 'true' if the port is valid (within the 0..65535 range)
|
||||
bool GetPort( int* OutPort ) const;
|
||||
|
||||
/// parse the URL
|
||||
static clParseURL ParseURL( const std::string& URL );
|
||||
|
||||
private:
|
||||
explicit clParseURL( LUrlParserError ErrorCode )
|
||||
: m_ErrorCode( ErrorCode )
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace LUrlParser
|
||||
@@ -3,25 +3,16 @@
|
||||
#include "StrFmt.h"
|
||||
#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 <sys/mman.h>
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
static std::string empty_string()
|
||||
{
|
||||
return {};
|
||||
@@ -45,7 +36,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,86 +44,38 @@ 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;
|
||||
|
||||
class file_writer
|
||||
{
|
||||
// Could be memory-mapped file
|
||||
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
|
||||
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);
|
||||
|
||||
virtual ~file_writer();
|
||||
virtual ~file_writer() = default;
|
||||
|
||||
// Append raw data
|
||||
void log(logs::level sev, const char* text, std::size_t size);
|
||||
};
|
||||
|
||||
struct channel_info
|
||||
{
|
||||
channel* pointer = nullptr;
|
||||
level enabled = level::notice;
|
||||
|
||||
void set_level(level value)
|
||||
{
|
||||
enabled = value;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
pointer->enabled = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct stored_message
|
||||
{
|
||||
message m;
|
||||
u64 stamp;
|
||||
std::string prefix;
|
||||
std::string text;
|
||||
void log(const char* text, std::size_t size);
|
||||
};
|
||||
|
||||
struct file_listener : public file_writer, public listener
|
||||
{
|
||||
file_listener(const std::string& name);
|
||||
|
||||
virtual ~file_listener() = default;
|
||||
file_listener(const std::string& name)
|
||||
: file_writer(name)
|
||||
, listener()
|
||||
{
|
||||
const std::string& start = fmt::format("\xEF\xBB\xBF" "RPCS3 v%s\n", rpcs3::version.to_string());
|
||||
file_writer::log(start.data(), start.size());
|
||||
}
|
||||
|
||||
// Encode level, current thread name, channel name and write log message
|
||||
virtual void log(u64 stamp, const message& msg, const std::string& prefix, const std::string& text) override;
|
||||
|
||||
// Channel registry
|
||||
std::unordered_map<std::string, channel_info> channels;
|
||||
|
||||
// Messages for delayed listener initialization
|
||||
std::vector<stored_message> messages;
|
||||
};
|
||||
|
||||
static file_listener* get_logger()
|
||||
{
|
||||
// Use magic static
|
||||
static file_listener logger("RPCS3");
|
||||
static file_listener logger("RPCS3.log");
|
||||
return &logger;
|
||||
}
|
||||
|
||||
@@ -177,18 +119,35 @@ namespace logs
|
||||
channel HLE("HLE");
|
||||
channel PPU("PPU");
|
||||
channel SPU("SPU");
|
||||
channel ARMv7("ARMv7");
|
||||
|
||||
struct channel_info
|
||||
{
|
||||
channel* pointer = nullptr;
|
||||
level enabled = level::notice;
|
||||
|
||||
void set_level(level value)
|
||||
{
|
||||
enabled = value;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
pointer->enabled = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Channel registry mutex
|
||||
semaphore<> g_mutex;
|
||||
|
||||
// Must be set to true in main()
|
||||
atomic_t<bool> g_init{false};
|
||||
// Channel registry
|
||||
std::unordered_map<std::string, channel_info> g_channels;
|
||||
|
||||
void reset()
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
for (auto&& pair : get_logger()->channels)
|
||||
for (auto&& pair : g_channels)
|
||||
{
|
||||
pair.second.set_level(level::notice);
|
||||
}
|
||||
@@ -198,18 +157,7 @@ namespace logs
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
get_logger()->channels[ch_name].set_level(value);
|
||||
}
|
||||
|
||||
// Must be called in main() to stop accumulating messages in g_messages
|
||||
void set_init()
|
||||
{
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
get_logger()->messages.clear();
|
||||
g_init = true;
|
||||
}
|
||||
g_channels[ch_name].set_level(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,19 +170,11 @@ void logs::listener::add(logs::listener* _new)
|
||||
// Get first (main) listener
|
||||
listener* lis = get_logger();
|
||||
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
// Install new listener at the end of linked list
|
||||
while (lis->m_next || !lis->m_next.compare_and_swap_test(nullptr, _new))
|
||||
{
|
||||
lis = lis->m_next;
|
||||
}
|
||||
|
||||
// Send initial messages
|
||||
for (const auto& msg : get_logger()->messages)
|
||||
{
|
||||
_new->log(msg.stamp, msg.m, msg.prefix, msg.text);
|
||||
}
|
||||
}
|
||||
|
||||
void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u64* args)
|
||||
@@ -247,7 +187,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
auto& info = get_logger()->channels[ch->name];
|
||||
auto& info = g_channels[ch->name];
|
||||
|
||||
if (info.pointer && info.pointer != ch)
|
||||
{
|
||||
@@ -267,30 +207,13 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
}
|
||||
|
||||
// Get text
|
||||
thread_local std::string text; text.clear();
|
||||
std::string text;
|
||||
fmt::raw_append(text, fmt, sup, args);
|
||||
std::string prefix = g_tls_log_prefix();
|
||||
|
||||
// Get first (main) listener
|
||||
listener* lis = get_logger();
|
||||
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
if (!g_init)
|
||||
{
|
||||
while (lis)
|
||||
{
|
||||
lis->log(stamp, *this, prefix, text);
|
||||
lis = lis->m_next;
|
||||
}
|
||||
|
||||
// Store message additionally
|
||||
get_logger()->messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Send message to all listeners
|
||||
while (lis)
|
||||
{
|
||||
@@ -302,280 +225,28 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
[[noreturn]] extern void catch_all_exceptions();
|
||||
|
||||
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::rewrite + fs::append))
|
||||
{
|
||||
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 log 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;
|
||||
#else
|
||||
m_file.trunc(s_log_size);
|
||||
m_fptr = (uchar*)::mmap(0, s_log_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file.get_handle(), 0);
|
||||
#endif
|
||||
|
||||
verify(name.c_str()), m_fptr;
|
||||
|
||||
// Rotate backups (TODO)
|
||||
fs::remove_file(fs::get_config_dir() + name + "1.log.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;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::thread([]{ report_fatal_error("Unknown error" HERE); }).detach();
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop writer thread
|
||||
while (m_out << 24 < m_buf)
|
||||
{
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
m_out = -1;
|
||||
m_writer.join();
|
||||
|
||||
if (m_fout2)
|
||||
{
|
||||
m_zs.avail_in = 0;
|
||||
m_zs.next_in = nullptr;
|
||||
|
||||
do
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
while (m_zs.avail_out == 0);
|
||||
|
||||
deflateEnd(&m_zs);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
UnmapViewOfFile(m_fptr);
|
||||
CloseHandle(m_fmap);
|
||||
#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;
|
||||
}
|
||||
|
||||
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||
{
|
||||
if (!m_fptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: write bigger fragment directly in blocking manner
|
||||
while (size && size <= 0xffffff)
|
||||
{
|
||||
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;
|
||||
catch_all_exceptions();
|
||||
}
|
||||
}
|
||||
|
||||
logs::file_listener::file_listener(const std::string& name)
|
||||
: file_writer(name)
|
||||
, listener()
|
||||
void logs::file_writer::log(const char* text, std::size_t size)
|
||||
{
|
||||
// Write UTF-8 BOM
|
||||
file_writer::log(logs::level::always, "\xEF\xBB\xBF", 3);
|
||||
|
||||
// Write initial message
|
||||
stored_message ver;
|
||||
ver.m.ch = nullptr;
|
||||
ver.m.sev = level::always;
|
||||
ver.stamp = 0;
|
||||
ver.text = fmt::format("RPCS3 v%s | %s\n%s", rpcs3::version.to_string(), rpcs3::get_branch(), utils::get_system_info());
|
||||
|
||||
file_writer::log(logs::level::always, ver.text.data(), ver.text.size());
|
||||
file_writer::log(logs::level::always, "\n", 1);
|
||||
messages.emplace_back(std::move(ver));
|
||||
m_file.write(text, size);
|
||||
}
|
||||
|
||||
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
|
||||
{
|
||||
thread_local std::string text;
|
||||
std::string text; text.reserve(prefix.size() + _text.size() + 200);
|
||||
|
||||
// Used character: U+00B7 (Middle Dot)
|
||||
switch (msg.sev)
|
||||
@@ -588,7 +259,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
|
||||
@@ -604,8 +274,8 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
text += prefix;
|
||||
text += "} ";
|
||||
}
|
||||
|
||||
if (msg.ch && '\0' != *msg.ch->name)
|
||||
|
||||
if ('\0' != *msg.ch->name)
|
||||
{
|
||||
text += msg.ch->name;
|
||||
text += msg.sev == level::todo ? " TODO: " : ": ";
|
||||
@@ -614,9 +284,9 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
{
|
||||
text += "TODO: ";
|
||||
}
|
||||
|
||||
|
||||
text += _text;
|
||||
text += '\n';
|
||||
|
||||
file_writer::log(msg.sev, text.data(), text.size());
|
||||
file_writer::log(text.data(), text.size());
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ namespace logs
|
||||
extern channel HLE;
|
||||
extern channel PPU;
|
||||
extern channel SPU;
|
||||
extern channel ARMv7;
|
||||
|
||||
// Log level control: set all channels to level::notice
|
||||
void reset();
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
class MTProgressDialog : public wxDialog
|
||||
{
|
||||
wxGauge** m_gauge;
|
||||
wxStaticText** m_msg;
|
||||
|
||||
wxArrayLong m_maximum;
|
||||
const u8 m_cores;
|
||||
|
||||
static const uint layout = 16;
|
||||
static const uint maxdial = 65536;
|
||||
wxArrayInt m_lastupdate;
|
||||
|
||||
public:
|
||||
MTProgressDialog(wxWindow* parent, const wxSize& size, const wxString& title,
|
||||
const wxString& msg, const wxArrayLong& maximum, const u8 cores)
|
||||
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition)
|
||||
, m_maximum(maximum)
|
||||
, m_cores(cores)
|
||||
{
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_gauge = new wxGauge*[m_cores];
|
||||
m_msg = new wxStaticText*[m_cores];
|
||||
|
||||
m_lastupdate.SetCount(cores);
|
||||
|
||||
for(uint i=0; i<m_cores; ++i)
|
||||
{
|
||||
m_lastupdate[i] = -1;
|
||||
|
||||
m_msg[i] = new wxStaticText(this, wxID_ANY, msg);
|
||||
sizer->Add(m_msg[i], 0, wxLEFT | wxTOP, layout);
|
||||
|
||||
m_gauge[i] = new wxGauge(this, wxID_ANY, maxdial,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxGA_HORIZONTAL );
|
||||
|
||||
sizer->Add(m_gauge[i], 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, layout);
|
||||
m_gauge[i]->SetValue(0);
|
||||
|
||||
sizer->AddSpacer(5);
|
||||
}
|
||||
|
||||
SetSizerAndFit(sizer);
|
||||
if(size != wxDefaultSize)
|
||||
{
|
||||
SetSize(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxSize ws;
|
||||
ws.x = 400;
|
||||
ws.y = GetSize().y + 8;
|
||||
SetSize(ws);
|
||||
}
|
||||
|
||||
m_maximum.SetCount(m_cores);
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
void Update(const u8 thread_id, const u64 value, const wxString& msg)
|
||||
{
|
||||
if(thread_id > m_cores) return;
|
||||
|
||||
const int curupdate = (int)(((double)value/(double)m_maximum[thread_id])*1000);
|
||||
if(curupdate == m_lastupdate[thread_id]) return;
|
||||
m_lastupdate[thread_id] = curupdate;
|
||||
|
||||
m_msg[thread_id]->SetLabel(msg);
|
||||
|
||||
if(value >= (u32)m_maximum[thread_id]) return;
|
||||
m_gauge[thread_id]->SetValue(((double)value / (double)m_maximum[thread_id]) * maxdial);
|
||||
}
|
||||
|
||||
const u32 GetMaxValue(const uint thread_id) const
|
||||
{
|
||||
if(thread_id > m_cores) return 0;
|
||||
return m_maximum[thread_id];
|
||||
}
|
||||
|
||||
void SetMaxFor(const uint thread_id, const u64 val)
|
||||
{
|
||||
if(thread_id > m_cores) return;
|
||||
m_maximum[thread_id] = val;
|
||||
m_lastupdate[thread_id] = 0;
|
||||
}
|
||||
|
||||
virtual void Close(bool force = false)
|
||||
{
|
||||
m_lastupdate.Empty();
|
||||
m_maximum.Empty();
|
||||
|
||||
wxDialog::Close(force);
|
||||
}
|
||||
};
|
||||
@@ -257,8 +257,8 @@ struct fmt::cfmt_src
|
||||
|
||||
void skip(std::size_t extra)
|
||||
{
|
||||
sup += extra + 1;
|
||||
args += extra + 1;
|
||||
++sup += extra;
|
||||
++args += extra;
|
||||
}
|
||||
|
||||
std::size_t fmt_string(std::string& out, std::size_t extra) const
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,12 +3,7 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#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 +13,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 +28,20 @@ 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)
|
||||
{
|
||||
std::string _msg = msg + "\n"
|
||||
"HOW TO REPORT ERRORS: Check the FAQ, README, other sources.\n"
|
||||
"Please, don't send incorrect reports. Thanks for understanding.\n";
|
||||
|
||||
#ifdef _WIN32
|
||||
_msg += "Press (Ctrl+C) to copy this message.";
|
||||
MessageBoxA(0, _msg.c_str(), "Fatal error", MB_ICONERROR); // TODO: unicode message
|
||||
#else
|
||||
std::printf("Fatal error: \n%s", _msg.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
[[noreturn]] void catch_all_exceptions()
|
||||
{
|
||||
try
|
||||
@@ -53,6 +56,8 @@ thread_local u64 g_tls_fault_spu = 0;
|
||||
{
|
||||
report_fatal_error("Unhandled exception (unknown)");
|
||||
}
|
||||
|
||||
std::abort();
|
||||
}
|
||||
|
||||
enum x64_reg_t : u32
|
||||
@@ -90,7 +95,7 @@ enum x64_reg_t : u32
|
||||
X64R_XMM13,
|
||||
X64R_XMM14,
|
||||
X64R_XMM15,
|
||||
|
||||
|
||||
X64R_AL,
|
||||
X64R_CL,
|
||||
X64R_DL,
|
||||
@@ -99,7 +104,7 @@ enum x64_reg_t : u32
|
||||
X64R_CH,
|
||||
X64R_DH,
|
||||
X64R_BH,
|
||||
|
||||
|
||||
X64_NOT_SET,
|
||||
X64_IMM8,
|
||||
X64_IMM16,
|
||||
@@ -176,7 +181,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
|
||||
{
|
||||
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): LOCK prefix found twice", (size_t)code - out_length);
|
||||
}
|
||||
|
||||
|
||||
lock = true;
|
||||
continue;
|
||||
}
|
||||
@@ -186,7 +191,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
|
||||
{
|
||||
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): REPNE/REPNZ prefix found twice", (size_t)code - out_length);
|
||||
}
|
||||
|
||||
|
||||
repne = true;
|
||||
continue;
|
||||
}
|
||||
@@ -196,7 +201,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
|
||||
{
|
||||
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): REP/REPE/REPZ prefix found twice", (size_t)code - out_length);
|
||||
}
|
||||
|
||||
|
||||
repe = true;
|
||||
continue;
|
||||
}
|
||||
@@ -225,7 +230,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
|
||||
{
|
||||
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): operand-size override prefix found twice", (size_t)code - out_length);
|
||||
}
|
||||
|
||||
|
||||
oso = true;
|
||||
continue;
|
||||
}
|
||||
@@ -917,7 +922,7 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_
|
||||
else if (reg == X64_IMM32)
|
||||
{
|
||||
const s32 imm_value = *(s32*)(RIP(context) + i_size - 4);
|
||||
|
||||
|
||||
switch (d_size)
|
||||
{
|
||||
case 4: out_value = (u32)imm_value; return true;
|
||||
@@ -965,8 +970,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;
|
||||
}
|
||||
@@ -1231,7 +1236,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size), vm::page_allocated | (is_writing ? vm::page_writable : vm::page_readable)))
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size)))
|
||||
{
|
||||
if (cpu)
|
||||
{
|
||||
@@ -1241,60 +1246,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
|
||||
if (cpu)
|
||||
{
|
||||
if (fxm::check<page_fault_notification_entries>())
|
||||
{
|
||||
for (const auto& entry : fxm::get<page_fault_notification_entries>()->entries)
|
||||
{
|
||||
auto mem = vm::get(vm::any, entry.start_addr);
|
||||
if (!mem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.start_addr <= addr && addr <= addr + mem->size - 1)
|
||||
{
|
||||
// Place the page fault event onto table so that other functions [sys_mmapper_free_address and ppu pagefault funcs]
|
||||
// know that this thread is page faulted and where.
|
||||
|
||||
auto pf_entries = fxm::get_always<page_fault_event_entries>();
|
||||
{
|
||||
semaphore_lock pf_lock(pf_entries->pf_mutex);
|
||||
page_fault_event pf_event{ cpu->id, addr };
|
||||
pf_entries->events.emplace_back(pf_event);
|
||||
}
|
||||
|
||||
// Now, we notify the game that a page fault occurred so it can rectify it.
|
||||
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
|
||||
be_t<u64> data1 = addr;
|
||||
be_t<u64> data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) + cpu->id; // TODO: fix hack for now that assumes PPU thread always.
|
||||
be_t<u64> data3 = vm::check_addr(addr, a_size, vm::page_readable) ? SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY : SYS_MEMORY_PAGE_FAULT_CAUSE_NON_MAPPED;
|
||||
|
||||
LOG_ERROR(MEMORY, "Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
|
||||
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped");
|
||||
|
||||
error_code sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
|
||||
|
||||
// If we fail due to being busy, wait a bit and try again.
|
||||
while (sending_error == CELL_EBUSY)
|
||||
{
|
||||
lv2_obj::sleep(*cpu, 1000);
|
||||
thread_ctrl::wait_for(1000);
|
||||
sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
|
||||
}
|
||||
|
||||
if (sending_error)
|
||||
{
|
||||
fmt::throw_exception("Unknown error %x while trying to pass page fault.", sending_error.value);
|
||||
}
|
||||
|
||||
lv2_obj::sleep(*cpu);
|
||||
thread_ctrl::wait();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
cpu->check_state();
|
||||
@@ -1459,6 +1413,13 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
|
||||
|
||||
msg += fmt::format("RPCS3 image base: %p.\n", GetModuleHandle(NULL));
|
||||
|
||||
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
msg += "\n"
|
||||
"Illegal instruction exception occured.\n"
|
||||
"Note that your CPU must support SSSE3 extension.\n";
|
||||
}
|
||||
|
||||
// TODO: print registers and the callstack
|
||||
|
||||
// Report fatal error
|
||||
@@ -1471,11 +1432,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 +1485,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 +1513,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
|
||||
@@ -1707,7 +1669,7 @@ bool thread_ctrl::_wait_for(u64 usec)
|
||||
}
|
||||
}
|
||||
_lock{_this->m_mutex};
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
// Mutex is unlocked at the start and after the waiting
|
||||
@@ -1747,7 +1709,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 +1819,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, ¶m);
|
||||
|
||||
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, ¶m))
|
||||
{
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace utils
|
||||
void memory_decommit(void* pointer, std::size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
verify(HERE), ::VirtualFree(pointer, size, MEM_DECOMMIT);
|
||||
verify(HERE), ::VirtualFree(pointer, 0, MEM_DECOMMIT);
|
||||
#else
|
||||
verify(HERE), ::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
||||
@@ -10,18 +10,13 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case patch_type::load: return "load";
|
||||
case patch_type::byte: return "byte";
|
||||
case patch_type::le16: return "le16";
|
||||
case patch_type::le32: return "le32";
|
||||
case patch_type::le64: return "le64";
|
||||
case patch_type::bef32: return "bef32";
|
||||
case patch_type::bef64: return "bef64";
|
||||
case patch_type::be16: return "be16";
|
||||
case patch_type::be32: return "be32";
|
||||
case patch_type::be64: return "be64";
|
||||
case patch_type::lef32: return "lef32";
|
||||
case patch_type::lef64: return "lef64";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
@@ -32,89 +27,35 @@ 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;
|
||||
cfg::try_to_enum_value(&type64, &fmt_class_string<patch_type>::format, patch[0].Scalar());
|
||||
|
||||
struct patch info{};
|
||||
struct patch info;
|
||||
info.type = static_cast<patch_type>(type64);
|
||||
info.offset = patch[1].as<u32>(0);
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case patch_type::load:
|
||||
{
|
||||
// Special syntax: copy named sequence (must be loaded before)
|
||||
const auto found = m_map.find(patch[1].Scalar());
|
||||
|
||||
if (found != m_map.end())
|
||||
{
|
||||
// Address modifier (optional)
|
||||
const u32 mod = patch[2].as<u32>(0);
|
||||
|
||||
for (const auto& rd : found->second)
|
||||
{
|
||||
info = rd;
|
||||
info.offset += mod;
|
||||
data.emplace_back(info);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: error
|
||||
break;
|
||||
}
|
||||
case patch_type::bef32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
info.value_as<f32>() = patch[2].as<f32>();
|
||||
break;
|
||||
}
|
||||
case patch_type::bef64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
info.value_as<f64>() = patch[2].as<f64>();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
info.value = patch[2].as<u64>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
info.offset = patch[1].as<u32>();
|
||||
info.value = patch[2].as<u64>();
|
||||
data.emplace_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
{
|
||||
const auto found = m_map.find(name);
|
||||
|
||||
if (found == m_map.cend())
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply modifications sequentially
|
||||
@@ -124,11 +65,6 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
|
||||
switch (p.type)
|
||||
{
|
||||
case patch_type::load:
|
||||
{
|
||||
// Invalid in this context
|
||||
break;
|
||||
}
|
||||
case patch_type::byte:
|
||||
{
|
||||
*ptr = static_cast<u8>(p.value);
|
||||
@@ -140,13 +76,11 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::le32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::le64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
@@ -157,19 +91,15 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::be32:
|
||||
case patch_type::bef32:
|
||||
{
|
||||
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::be64:
|
||||
case patch_type::bef64:
|
||||
{
|
||||
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found->second.size();
|
||||
}
|
||||
|
||||
@@ -7,18 +7,13 @@
|
||||
|
||||
enum class patch_type
|
||||
{
|
||||
load,
|
||||
byte,
|
||||
le16,
|
||||
le32,
|
||||
le64,
|
||||
lef32,
|
||||
lef64,
|
||||
be16,
|
||||
be32,
|
||||
be64,
|
||||
bef32,
|
||||
bef64,
|
||||
};
|
||||
|
||||
class patch_engine
|
||||
@@ -28,12 +23,6 @@ class patch_engine
|
||||
patch_type type;
|
||||
u32 offset;
|
||||
u64 value;
|
||||
|
||||
template <typename T>
|
||||
T& value_as()
|
||||
{
|
||||
return *reinterpret_cast<T*>(reinterpret_cast<char*>(&value));
|
||||
}
|
||||
};
|
||||
|
||||
// Database
|
||||
@@ -43,6 +32,6 @@ public:
|
||||
// Load from file
|
||||
void append(const std::string& path);
|
||||
|
||||
// Apply patch (returns the number of entries applied)
|
||||
std::size_t apply(const std::string& name, u8* dst) const;
|
||||
// Apply patch
|
||||
void apply(const std::string& name, u8* dst) const;
|
||||
};
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -47,6 +47,4 @@ public:
|
||||
imp_wake(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr u64 max_timeout = u64{UINT32_MAX} / 1000 * 1000000;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
Copyright (C) 2011-2012 Andrzej Krzemienski
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0
|
||||
(see accompanying file LICENSE_1_0.txt or a copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
The idea and interface is based on Boost.Optional library
|
||||
authored by Fernando Luis Cacciola Carballal
|
||||
|
||||
Home at https://github.com/akrzemi1/Optional
|
||||
@@ -731,9 +731,9 @@ struct area_base
|
||||
{
|
||||
return{ x1 * size.width, y1 * size.height, x2 * size.width, y2 * size.height };
|
||||
}
|
||||
constexpr area_base operator * (const f32& value) const
|
||||
constexpr area_base operator * (const T& value) const
|
||||
{
|
||||
return{ (T)(x1 * value), (T)(y1 * value), (T)(x2 * value), (T)(y2 * value) };
|
||||
return{ x1 * value, y1 * value, x2 * value, y2 * value };
|
||||
}
|
||||
|
||||
template<typename NT>
|
||||
|
||||
@@ -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 (
|
||||
@@ -48,40 +47,14 @@ if errorlevel 1 (
|
||||
echo // This is a generated file. > "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION "unknown" >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_BRANCH "unknown" >> "%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%"
|
||||
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
|
||||
|
||||
rem // Don't modify the file if it already has the current version.
|
||||
if exist "%GIT_VERSION_FILE%" (
|
||||
@@ -94,7 +67,6 @@ 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. >> "%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%"
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace rpcs3
|
||||
{
|
||||
template<typename T>
|
||||
static size_t hash_base(T value)
|
||||
{
|
||||
return static_cast<size_t>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static size_t hash_struct(const T& value)
|
||||
{
|
||||
// FNV 64-bit
|
||||
size_t result = 14695981039346656037ull;
|
||||
const unsigned char *bytes = reinterpret_cast<const unsigned char*>(&value);
|
||||
|
||||
for (size_t n = 0; n < sizeof(T); ++n)
|
||||
{
|
||||
result ^= bytes[n];
|
||||
result *= 1099511628211ull;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
#include "mutex.h"
|
||||
#include "sync.h"
|
||||
|
||||
#include <climits>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// TLS variable for tracking owned mutexes
|
||||
thread_local std::vector<shared_mutex*> g_tls_locks;
|
||||
#include <limits.h>
|
||||
|
||||
void shared_mutex::imp_lock_shared(s64 _old)
|
||||
{
|
||||
@@ -222,14 +217,12 @@ void shared_mutex::imp_unlock(s64 _old)
|
||||
|
||||
void shared_mutex::imp_lock_upgrade()
|
||||
{
|
||||
// TODO
|
||||
unlock_shared();
|
||||
lock();
|
||||
}
|
||||
|
||||
void shared_mutex::imp_lock_degrade()
|
||||
{
|
||||
// TODO
|
||||
unlock();
|
||||
lock_shared();
|
||||
}
|
||||
@@ -257,78 +250,3 @@ bool shared_mutex::try_lock_degrade()
|
||||
// TODO
|
||||
return m_value.compare_and_swap_test(0, c_one - c_min);
|
||||
}
|
||||
|
||||
safe_reader_lock::safe_reader_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_is_owned(false)
|
||||
{
|
||||
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||
{
|
||||
m_is_owned = true;
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
g_tls_locks.emplace_back(&m_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
}
|
||||
|
||||
safe_reader_lock::~safe_reader_lock()
|
||||
{
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
safe_writer_lock::safe_writer_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_is_owned(false)
|
||||
, m_is_upgraded(false)
|
||||
{
|
||||
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||
{
|
||||
m_is_owned = true;
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
g_tls_locks.emplace_back(&m_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
if (m_mutex.is_reading())
|
||||
{
|
||||
m_is_upgraded = true;
|
||||
m_mutex.lock_upgrade();
|
||||
}
|
||||
}
|
||||
|
||||
safe_writer_lock::~safe_writer_lock()
|
||||
{
|
||||
if (m_is_upgraded)
|
||||
{
|
||||
m_mutex.lock_degrade();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.unlock();
|
||||
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
@@ -95,11 +95,6 @@ public:
|
||||
imp_lock_degrade();
|
||||
}
|
||||
}
|
||||
|
||||
bool is_reading() const
|
||||
{
|
||||
return (m_value.load() % c_one) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Simplified shared (reader) lock implementation.
|
||||
@@ -176,56 +171,3 @@ public:
|
||||
unlock();
|
||||
}
|
||||
};
|
||||
|
||||
// Safe reader lock. Can be recursive above other safe locks (reader or writer).
|
||||
class safe_reader_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_is_owned;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
safe_reader_lock(const safe_reader_lock&) = delete;
|
||||
|
||||
explicit safe_reader_lock(shared_mutex& mutex);
|
||||
|
||||
~safe_reader_lock();
|
||||
};
|
||||
|
||||
// Safe writer lock. Can be recursive above other safe locks. Performs upgrade and degrade operations above existing reader lock if necessary.
|
||||
class safe_writer_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_is_owned;
|
||||
bool m_is_upgraded;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
safe_writer_lock(const safe_writer_lock&) = delete;
|
||||
|
||||
explicit safe_writer_lock(shared_mutex& mutex);
|
||||
|
||||
~safe_writer_lock();
|
||||
};
|
||||
|
||||
@@ -61,9 +61,10 @@ rXmlDocument::rXmlDocument() : handle()
|
||||
{
|
||||
}
|
||||
|
||||
void rXmlDocument::Read(const std::string& data)
|
||||
void rXmlDocument::Load(const std::string & path)
|
||||
{
|
||||
handle.load_buffer(data.data(), data.size());
|
||||
// TODO: Unsure of use of c_str.
|
||||
handle.load_file(path.c_str());
|
||||
}
|
||||
|
||||
std::shared_ptr<rXmlNode> rXmlDocument::GetRoot()
|
||||
|
||||
@@ -24,7 +24,7 @@ struct rXmlDocument
|
||||
rXmlDocument();
|
||||
rXmlDocument(const rXmlDocument& other) = delete;
|
||||
rXmlDocument &operator=(const rXmlDocument& other) = delete;
|
||||
void Read(const std::string& data);
|
||||
void Load(const std::string & path);
|
||||
std::shared_ptr<rXmlNode> GetRoot();
|
||||
|
||||
pugi::xml_document handle;
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
#include "sysinfo.h"
|
||||
#include "StrFmt.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#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;
|
||||
std::string brand;
|
||||
|
||||
if (get_cpuid(0x80000000, 0)[0] >= 0x80000004)
|
||||
{
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
brand.append(reinterpret_cast<const char*>(get_cpuid(0x80000002 + i, 0).data()), 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
brand = "Unknown CPU";
|
||||
}
|
||||
|
||||
brand.erase(0, brand.find_first_not_of(' '));
|
||||
brand.erase(brand.find_last_not_of(' ') + 1);
|
||||
|
||||
while (auto found = brand.find(" ") + 1)
|
||||
{
|
||||
brand.erase(brand.begin() + found);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::SYSTEM_INFO sysInfo;
|
||||
::GetNativeSystemInfo(&sysInfo);
|
||||
::MEMORYSTATUSEX memInfo;
|
||||
memInfo.dwLength = sizeof(memInfo);
|
||||
::GlobalMemoryStatusEx(&memInfo);
|
||||
const u32 num_proc = sysInfo.dwNumberOfProcessors;
|
||||
const u64 mem_total = memInfo.ullTotalPhys;
|
||||
#else
|
||||
const u32 num_proc = ::sysconf(_SC_NPROCESSORS_ONLN);
|
||||
const u64 mem_total = ::sysconf(_SC_PHYS_PAGES) * ::sysconf(_SC_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
||||
|
||||
if (has_avx())
|
||||
{
|
||||
result += " | AVX";
|
||||
|
||||
if (has_avx2())
|
||||
{
|
||||
result += '+';
|
||||
}
|
||||
|
||||
if (has_512())
|
||||
{
|
||||
result += '+';
|
||||
}
|
||||
|
||||
if (has_xop())
|
||||
{
|
||||
result += 'x';
|
||||
}
|
||||
}
|
||||
|
||||
if (has_rtm())
|
||||
{
|
||||
result += " | TSX";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
inline std::array<u32, 4> get_cpuid(u32 func, u32 subfunc)
|
||||
{
|
||||
int regs[4];
|
||||
#ifdef _MSC_VER
|
||||
__cpuidex(regs, func, subfunc);
|
||||
#else
|
||||
__asm__ volatile("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (func), "c" (subfunc));
|
||||
#endif
|
||||
return {0u+regs[0], 0u+regs[1], 0u+regs[2], 0u+regs[3]};
|
||||
}
|
||||
|
||||
bool has_ssse3();
|
||||
|
||||
bool has_avx();
|
||||
|
||||
bool has_avx2();
|
||||
|
||||
bool has_rtm();
|
||||
|
||||
bool has_512();
|
||||
|
||||
bool has_xop();
|
||||
|
||||
inline bool transaction_enter()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const auto status = _xbegin();
|
||||
|
||||
if (status == _XBEGIN_STARTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(status & _XABORT_RETRY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_system_info();
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
#define SAFE_BUFFERS
|
||||
#define NEVER_INLINE __attribute__((noinline))
|
||||
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#define thread_local __thread
|
||||
#endif
|
||||
|
||||
#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size")
|
||||
@@ -48,7 +49,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 +535,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)
|
||||
{
|
||||
@@ -938,7 +919,7 @@ struct error_code
|
||||
error_code() = default;
|
||||
|
||||
// Implementation must be provided specially
|
||||
static s32 error_report(const fmt_type_info* sup, u64 arg, const fmt_type_info* sup2, u64 arg2);
|
||||
static s32 error_report(const fmt_type_info* sup, u64 arg);
|
||||
|
||||
// Helper type
|
||||
enum class not_an_error : s32
|
||||
@@ -959,7 +940,7 @@ struct error_code
|
||||
|
||||
// Not an error constructor
|
||||
template<typename ET, typename = decltype(ET::__not_an_error)>
|
||||
error_code(const ET& value, std::nullptr_t = nullptr)
|
||||
error_code(const ET& value, int = 0)
|
||||
: value(static_cast<s32>(value))
|
||||
{
|
||||
}
|
||||
@@ -967,14 +948,7 @@ struct error_code
|
||||
// Error constructor
|
||||
template<typename ET, typename = std::enable_if_t<is_error<ET>::value>>
|
||||
error_code(const ET& value)
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value), nullptr, 0))
|
||||
{
|
||||
}
|
||||
|
||||
// Error constructor (2 args)
|
||||
template<typename ET, typename T2, typename = std::enable_if_t<is_error<ET>::value>>
|
||||
error_code(const ET& value, const T2& value2)
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value), fmt::get_type_info<fmt_unveil_t<T2>>(), fmt_unveil<T2>::get(value2)))
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -1,107 +1,41 @@
|
||||
version: '0.0.2-{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
|
||||
$commTag = $(git describe --tags $(git rev-list --tags --max-count=1))
|
||||
$commCount = $(git rev-list --count HEAD)
|
||||
$commHash = $env:APPVEYOR_REPO_COMMIT.Substring(0,8)
|
||||
|
||||
if ($env:APPVEYOR_PULL_REQUEST_NUMBER) {
|
||||
$env:BUILD = "{0}-{1}" -f $commTag, $commHash
|
||||
}
|
||||
else {
|
||||
$env:BUILD = "{0}-{1}-{2}" -f $commTag, $commCount, $commHash
|
||||
}
|
||||
|
||||
$env:AVVER = "{0}-{1}" -f $commTag.TrimStart("v"), $env:APPVEYOR_BUILD_NUMBER
|
||||
$env:RPCS3 = "rpcs3-{0}_win64.7z" -f $env:BUILD
|
||||
|
||||
- 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:RPCS3 .\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:RPCS3 -algorithm SHA256).Hash > ("{0}.sha256" -f $env:RPCS3)
|
||||
(get-filehash openssl_win64.7z -algorithm SHA256).Hash > "openssl_win64.7z.sha256"
|
||||
|
||||
clone_folder: C:\rpcs3
|
||||
clone_depth: 3
|
||||
test: off
|
||||
|
||||
artifacts:
|
||||
- path: $(RPCS3)
|
||||
name: rpcs3
|
||||
- path: $(RPCS3).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
|
||||
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
|
||||
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
|
||||
- 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=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -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\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.2-$(Date)-$(COMMIT_SHA)_win64'
|
||||
type: zip
|
||||
|
||||
cache:
|
||||
- llvmlibs.7z -> appveyor.yml
|
||||
- vulkan.7z -> appveyor.yml
|
||||
- zlib.7z -> appveyor.yml
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -1,330 +0,0 @@
|
||||
/*
|
||||
Kuroi (Dark) Theme for RPCS3
|
||||
by Ani @ https://github.com/AniLeo
|
||||
r1 (2017.08.15)
|
||||
*/
|
||||
|
||||
/*
|
||||
Color Scheme
|
||||
(Darker to Lighter)
|
||||
|
||||
Black
|
||||
> 292929
|
||||
> 323232
|
||||
> 333333
|
||||
> 3d3d3d
|
||||
> 404040
|
||||
> 444444
|
||||
|
||||
Light Grey
|
||||
> 828790
|
||||
> bdc3c7
|
||||
> ecf0f1
|
||||
|
||||
> b1b1b1
|
||||
> 7f8c8d
|
||||
|
||||
Green
|
||||
> 2ecc71
|
||||
|
||||
Red
|
||||
> e74c3c
|
||||
*/
|
||||
|
||||
/* Every widget */
|
||||
QWidget {
|
||||
background-color: #323232;
|
||||
color: #bdc3c7;
|
||||
alternate-background-color: #3d3d3d;
|
||||
}
|
||||
|
||||
/* Mouse tooltips */
|
||||
QToolTip {
|
||||
border: 0.05em solid #323232;
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Table headers */
|
||||
QHeaderView::section {
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
padding-left: 0.2em;
|
||||
border: 0.05em solid #323232;
|
||||
}
|
||||
|
||||
/* Settings Dialog: Tabs */
|
||||
QTabBar::tab {
|
||||
color: #ecf0f1;
|
||||
border: 0.05em 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;
|
||||
}
|
||||
QTabBar::tab:last {
|
||||
margin-right: 0em;
|
||||
}
|
||||
QTabBar::tab:!selected {
|
||||
color: #b1b1b1;
|
||||
border-bottom-style: solid;
|
||||
margin-top: 0.15em;
|
||||
background-color: #292929;
|
||||
}
|
||||
QTabBar::tab:hover {
|
||||
background-color: #333333;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border-radius: 0.1em;
|
||||
border: 0.05em solid #ecf0f1;
|
||||
margin-top: 0.05em;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
}
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #e74c3c; /* Red */
|
||||
}
|
||||
QCheckBox::indicator::disabled {
|
||||
background-color: #7f8c8d; /* Gray */
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border-radius: 0.4em;
|
||||
border: 0.05em solid;
|
||||
border-color: white;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QRadioButton::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
}
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #e74c3c; /* Red */
|
||||
}
|
||||
QRadioButton::indicator::disabled {
|
||||
background-color: #7f8c8d; /* Gray */
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background-color: #404040;
|
||||
color: #fff;
|
||||
border: 0.05em solid #1e1e1e;
|
||||
border-radius: 0.15em;
|
||||
padding-bottom: 0.2em;
|
||||
padding-left: 0.4em;
|
||||
}
|
||||
QComboBox::disabled {
|
||||
background-color: #828790;
|
||||
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;
|
||||
}
|
||||
QPushButton::disabled {
|
||||
background-color: #444444;
|
||||
color: #828790;
|
||||
}
|
||||
|
||||
/* Log and Debugger borders */
|
||||
QTextEdit {
|
||||
border: 0.05em 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;
|
||||
}
|
||||
|
||||
/* Disable ugly borders */
|
||||
QTabWidget::pane {
|
||||
border: 0em solid #828790;
|
||||
}
|
||||
|
||||
/* Top menu bar */
|
||||
QMenuBar::item:selected {
|
||||
background: #444444;
|
||||
}
|
||||
QMenu::item {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 0.75em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
QMenu::item:selected {
|
||||
background: #444444;
|
||||
border: 0.05em solid #bdc3c7;
|
||||
}
|
||||
QMenu::item:disabled {
|
||||
background-color: #444444;
|
||||
color: #828790;
|
||||
}
|
||||
|
||||
/* Libraries list */
|
||||
QListWidget::item:selected {
|
||||
background-color: #3d3d3d;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
QListWidget::item:hover {
|
||||
background-color: #4c4b4b;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #bdc3c7;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QLabel#gamegrid_font {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
QToolButton::disabled {
|
||||
background-color: #828790;
|
||||
}
|
||||
QToolButton::hover {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
/* 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: #444444;
|
||||
}
|
||||
|
||||
/* Set Log colors */
|
||||
QTextEdit#log_frame {
|
||||
background-color: #000000; /* 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: #000000; /* Black */
|
||||
}
|
||||
QLabel#tty_text {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
|
||||
/* RSX Debugger */
|
||||
QLabel#rsx_debugger_display_buffer {
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Kernel Explorer */
|
||||
QDialog#kernel_explorer {
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Memory Viewer */
|
||||
QDialog#memory_viewer {
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_address_panel {
|
||||
color: #00cbff; /* Font Color: Blue */
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_hex_panel {
|
||||
color: #bdc3c7; /* Font Color: Grey */
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_ascii_panel {
|
||||
color: #bdc3c7; /* Font Color: Grey */
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Debugger colors */
|
||||
QLabel#debugger_frame_breakpoint {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#debugger_frame_pc {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #00ff00; /* Green */
|
||||
}
|
||||
@@ -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 */
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1 @@
|
||||
make_fself compiled.elf EBOOT.BIN
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "ps3emu_api.h"
|
||||
|
||||
ps3emu_api::ps3emu_api(const std::string &path)
|
||||
{
|
||||
load(path);
|
||||
}
|
||||
|
||||
bool ps3emu_api::load(const std::string &path)
|
||||
{
|
||||
if (!m_library.load(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_no_errors = true;
|
||||
|
||||
if (!m_library.get(get_api_version, "ps3emu_api_get_api_version") || get_api_version() != ps3emu_api_version)
|
||||
{
|
||||
is_no_errors = false;
|
||||
}
|
||||
|
||||
is_no_errors = is_no_errors && m_library.get(initialize, "ps3emu_api_initialize");
|
||||
is_no_errors = is_no_errors && m_library.get(destroy, "ps3emu_api_destroy");
|
||||
|
||||
is_no_errors = is_no_errors && m_library.get(get_version_string, "ps3emu_api_get_version_string");
|
||||
is_no_errors = is_no_errors && m_library.get(get_version_number, "ps3emu_api_get_version_number");
|
||||
is_no_errors = is_no_errors && m_library.get(get_name_string, "ps3emu_api_get_name_string");
|
||||
|
||||
is_no_errors = is_no_errors && m_library.get(load_elf, "ps3emu_api_load_elf");
|
||||
|
||||
is_no_errors = is_no_errors && m_library.get(set_state, "ps3emu_api_set_state");
|
||||
is_no_errors = is_no_errors && m_library.get(get_state, "ps3emu_api_get_state");
|
||||
|
||||
if (!is_no_errors)
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ps3emu_api::loaded() const
|
||||
{
|
||||
return m_library.loaded();
|
||||
}
|
||||
|
||||
void ps3emu_api::close()
|
||||
{
|
||||
initialize = nullptr;
|
||||
destroy = nullptr;
|
||||
get_version_string = nullptr;
|
||||
get_version_number = nullptr;
|
||||
get_name_string = nullptr;
|
||||
load_elf = nullptr;
|
||||
set_state = nullptr;
|
||||
get_state = nullptr;
|
||||
|
||||
m_library.close();
|
||||
}
|
||||
|
||||
ps3emu_api::operator bool() const
|
||||
{
|
||||
return loaded();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <Utilities/dynamic_library.h>
|
||||
#include <string>
|
||||
#include "ps3emu_api_enums.h"
|
||||
#include "ps3emu_api_structs.h"
|
||||
|
||||
class ps3emu_api
|
||||
{
|
||||
utils::dynamic_library m_library;
|
||||
|
||||
public:
|
||||
ps3emu_api() = default;
|
||||
ps3emu_api(const std::string &path);
|
||||
|
||||
unsigned int(*get_api_version)() = nullptr;
|
||||
ps3emu_api_error_code(*initialize)(const ps3emu_api_initialize_callbacks *callbacks) = nullptr;
|
||||
ps3emu_api_error_code(*destroy)() = nullptr;
|
||||
|
||||
ps3emu_api_error_code(*get_version_string)(char *dest_buffer, int dest_buffer_size) = nullptr;
|
||||
ps3emu_api_error_code(*get_version_number)(int *version_number) = nullptr;
|
||||
ps3emu_api_error_code(*get_name_string)(char *dest_buffer, int dest_buffer_size) = nullptr;
|
||||
|
||||
ps3emu_api_error_code(*load_elf)(const char *path) = nullptr;
|
||||
|
||||
ps3emu_api_error_code(*set_state)(ps3emu_api_state state) = nullptr;
|
||||
ps3emu_api_error_code(*get_state)(ps3emu_api_state *state) = nullptr;
|
||||
|
||||
bool load(const std::string &path);
|
||||
bool loaded() const;
|
||||
void close();
|
||||
|
||||
explicit operator bool() const;
|
||||
};
|
||||
|
||||