Compare commits

..

4 Commits

Author SHA1 Message Date
Zangetsu38 b4f96ed45e Fix 2017-09-01 23:33:33 +02:00
Zangetsu38 1a3f9f72cf Update LLVM 5.0 2017-09-01 23:33:32 +02:00
Zion Nimchuk bc46f7c0c3 Initial LLVM 5 port 2017-09-01 23:33:32 +02:00
Zangetsu38 bec46a9ba2 Update Project to Visual Studio 2017. 2017-09-01 22:12:07 +02:00
320 changed files with 12333 additions and 23235 deletions
-24
View File
@@ -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/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.
--->
+1
View File
@@ -59,6 +59,7 @@ rpcs3/git-version.h
# Visual Studio Files
.vs/*
*.ipch
*.vspx
*.psess
*.VC.*
+10 -7
View File
@@ -8,13 +8,16 @@
[submodule "llvm"]
path = llvm
url = https://github.com/llvm-mirror/llvm
branch = release_40
branch = release_50
[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
@@ -31,13 +34,13 @@
[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
[submodule "3rdparty/Optional"]
path = 3rdparty/Optional
url = https://github.com/akrzemi1/Optional.git
url = https://github.com/Zangetsu38/hidapi
branch = master
+43 -14
View File
@@ -1,5 +1,6 @@
language: cpp
sudo: required
dist: trusty
os:
- linux
@@ -16,10 +17,19 @@ 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
git:
submodules: false
@@ -30,6 +40,7 @@ before_install:
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 ;
@@ -37,24 +48,33 @@ before_install:
export QT_QPA_PLATFORM=minimal ;
./qt-unified-linux-x64-online.run --script qt-installer-noninteractive.qs --no-force-installations ;
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
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/libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
sudo dpkg -i libglew1.13_1.13.0-2_amd64.deb libglew-dev_1.13.0-2_amd64.deb libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
else
brew update;
brew update; brew update;
brew install ccache glew llvm40;
fi;
# We need to update binutils to a newer version to link against the ffmpeg libs on.
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
sudo add-apt-repository ppa:jonathonf/binutils -y ;
sudo apt-get update ;
sudo apt-get install binutils -y;
ld --version ;
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
- mkdir build
- cd build
- export CMAKE_PREFIX_PATH=~/Qt/5.9.2/gcc_64/lib/cmake
- export CMAKE_PREFIX_PATH=~/Qt/5.9.1/gcc_64/lib/cmake
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
else
@@ -63,21 +83,21 @@ before_script:
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
- make -j 3
- # AppImage generation
- if [ -n "$UPLOAD_URL" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
export LD_LIBRARY_PATH=~/Qt/5.9.2/gcc_64/lib;
- if [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
export LD_LIBRARY_PATH=~/Qt/5.9.1/gcc_64/lib;
make DESTDIR=appdir install ; find appdir/ ;
find ../bin ;
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" ;
chmod a+x linuxdeployqt*.AppImage ;
export PATH=~/Qt/5.9.2/gcc_64/bin/:${PATH} ;
export PATH=~/Qt/5.9.1/gcc_64/bin/:${PATH} ;
./linuxdeployqt*.AppImage --appimage-extract ;
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
mkdir ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.2/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
cp ~/Qt/5.9.2/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
cp ~/Qt/5.9.2/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.2/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
cp ~/Qt/5.9.1/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
@@ -89,15 +109,14 @@ 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
- libasound2-dev
- libopenal-dev
@@ -115,8 +134,18 @@ addons:
- libstdc++-5-dev
- lib32stdc++6
- zlib1g-dev
# We need to install qt 5.9.2 manually because the version trusty provides is too old.
# We need to install qt 5.9.1 manually because the version trusty provides is too old.
#- qtbase5-dev
- libudev-dev
- libevdev-dev
- 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
Submodule 3rdparty/Optional deleted from f27e79084a
+14 -23
View File
@@ -3,6 +3,7 @@ RPCS3
[![Build Status](https://travis-ci.org/RPCS3/rpcs3.svg?branch=master)](https://travis-ci.org/RPCS3/rpcs3)
[![Build status](https://ci.appveyor.com/api/projects/status/411c4clmiohtx7eo/branch/master?svg=true)](https://ci.appveyor.com/project/rpcs3/rpcs3/branch/master)
[![Coverity Status](https://img.shields.io/coverity/scan/3960.svg)](https://scan.coverity.com/projects/3960)
The world's first open-source PlayStation 3 emulator/debugger written in C++ for Windows and Linux.
@@ -20,23 +21,22 @@ 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.8+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.8\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
* [Qt 5.9+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.9\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
### Linux
* [Qt 5.7+](https://www.qt.io/download-open-source/)
* [Qt 5.9+](https://www.qt.io/download-open-source/)
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev 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 qt5-devel vulkan-devel glew glew-devel`
**If you have a NVIDIA GPU, you may need to install the libglvnd package.**
### 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`
@@ -47,7 +47,7 @@ To initialize the repository don't forget to execute `git submodule update --ini
### Configuring Qt
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.8\msvc2015_64\` </br>
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.8\msvc2015_64`. </br>
@@ -58,16 +58,15 @@ To initialize the repository don't forget to execute `git submodule update --ini
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
If you are on OSX 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).
@@ -75,22 +74,14 @@ If you are on MacOS and want to build with brew llvm and qt don't forget to add
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.
## License
-2
View File
@@ -3,8 +3,6 @@
#include "yaml-cpp/yaml.h"
#include <typeinfo>
namespace cfg
{
logs::channel cfg("CFG");
+17 -13
View File
@@ -8,7 +8,6 @@
#include <algorithm>
#include <cstring>
#include <cerrno>
#include <typeinfo>
using namespace std::literals::string_literals;
@@ -95,8 +94,6 @@ static fs::error to_error(DWORD e)
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;
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
}
}
@@ -131,7 +128,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);
}
}
@@ -679,17 +675,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);
@@ -718,7 +715,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());
@@ -849,15 +846,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;
}
@@ -1453,7 +1458,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;
-1
View File
@@ -502,7 +502,6 @@ namespace fs
noent,
exist,
acces,
notempty,
};
// Error code returned
+2 -2
View File
@@ -258,11 +258,11 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
}
virtual 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(addr, load_addr, size);
return RTDyldMemoryManager::deregisterEHFrames();
}
};
+23
View File
@@ -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.
-265
View File
@@ -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;
}
-78
View File
@@ -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
+49 -50
View File
@@ -76,30 +76,6 @@ namespace logs
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;
};
struct file_listener : public file_writer, public listener
{
file_listener(const std::string& name);
@@ -108,12 +84,6 @@ namespace logs
// 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()
@@ -165,9 +135,39 @@ namespace logs
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;
}
}
};
struct stored_message
{
message m;
u64 stamp;
std::string prefix;
std::string text;
};
// Channel registry mutex
semaphore<> g_mutex;
// Channel registry
std::unordered_map<std::string, channel_info> g_channels;
// Messages for delayed listener initialization
std::vector<stored_message> g_messages;
// Must be set to true in main()
atomic_t<bool> g_init{false};
@@ -175,7 +175,7 @@ namespace logs
{
semaphore_lock lock(g_mutex);
for (auto&& pair : get_logger()->channels)
for (auto&& pair : g_channels)
{
pair.second.set_level(level::notice);
}
@@ -185,7 +185,7 @@ namespace logs
{
semaphore_lock lock(g_mutex);
get_logger()->channels[ch_name].set_level(value);
g_channels[ch_name].set_level(value);
}
// Must be called in main() to stop accumulating messages in g_messages
@@ -194,7 +194,7 @@ namespace logs
if (!g_init)
{
semaphore_lock lock(g_mutex);
get_logger()->messages.clear();
g_messages.clear();
g_init = true;
}
}
@@ -218,7 +218,7 @@ void logs::listener::add(logs::listener* _new)
}
// Send initial messages
for (const auto& msg : get_logger()->messages)
for (const auto& msg : g_messages)
{
_new->log(msg.stamp, msg.m, msg.prefix, msg.text);
}
@@ -234,7 +234,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)
{
@@ -274,10 +274,10 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
}
// Store message additionally
get_logger()->messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
g_messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
}
}
// Send message to all listeners
while (lis)
{
@@ -289,11 +289,11 @@ 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)
: m_name(fs::get_config_dir() + name)
{
try
{
if (!m_file.open(fs::get_config_dir() + name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
if (!m_file.open(m_name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
{
fmt::throw_exception("Can't create file %s (error %s)", name, fs::g_tls_error);
}
@@ -306,13 +306,11 @@ logs::file_writer::file_writer(const std::string& name)
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;
verify(m_name.c_str()), m_fptr;
std::memset(m_fptr, '\n', s_log_size);
// Rotate backups (TODO)
fs::remove_file(fs::get_config_dir() + name + "1.gz");
fs::create_dir(fs::get_config_dir() + "old_logs");
fs::rename(fs::get_config_dir() + m_name + ".gz", fs::get_config_dir() + "old_logs/" + m_name + ".gz", true);
fs::rename(m_name + ".gz", m_name + "1.gz", true);
}
catch (...)
{
@@ -339,7 +337,7 @@ logs::file_writer::~file_writer()
if (deflate(&zs, Z_FINISH) != Z_STREAM_ERROR)
{
fs::file(fs::get_config_dir() + m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
fs::file(m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
}
if (deflateEnd(&zs) != Z_OK)
@@ -350,10 +348,12 @@ logs::file_writer::~file_writer()
#ifdef _WIN32
UnmapViewOfFile(m_fptr);
CloseHandle(m_fmap);
m_file.seek(m_size);
SetEndOfFile(m_file.get_handle());
#else
::munmap(m_fptr, s_log_size);
#endif
m_file.trunc(m_size);
#endif
}
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
@@ -395,11 +395,10 @@ logs::file_listener::file_listener(const std::string& name)
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());
ver.text = fmt::format("RPCS3 v%s\n%s", rpcs3::version.to_string(), 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));
g_messages.emplace_back(std::move(ver));
}
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
@@ -432,7 +431,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
text += prefix;
text += "} ";
}
if (msg.ch && '\0' != *msg.ch->name)
{
text += msg.ch->name;
@@ -442,7 +441,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
{
text += "TODO: ";
}
text += _text;
text += '\n';
+98
View File
@@ -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);
}
};
+11 -75
View File
@@ -3,10 +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 <typeinfo>
#ifdef _WIN32
#include <Windows.h>
@@ -1261,60 +1258,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();
@@ -1884,30 +1830,20 @@ void thread_ctrl::set_native_priority(int priority)
HANDLE _this_thread = GetCurrentThread();
INT native_priority = THREAD_PRIORITY_NORMAL;
if (priority > 0)
switch (priority)
{
default:
case 0:
break;
case 1:
native_priority = THREAD_PRIORITY_ABOVE_NORMAL;
if (priority < 0)
break;
case -1:
native_priority = THREAD_PRIORITY_BELOW_NORMAL;
if (!SetThreadPriority(_this_thread, native_priority))
{
LOG_ERROR(GENERAL, "SetThreadPriority() failed: 0x%x", GetLastError());
break;
}
#else
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, &param);
if (priority > 0)
param.sched_priority = sched_get_priority_max(policy);
if (priority < 0)
param.sched_priority = sched_get_priority_min(policy);
if (int err = pthread_setschedparam(pthread_self(), policy, &param))
{
LOG_ERROR(GENERAL, "pthraed_setschedparam() failed: %d", err);
}
SetThreadPriority(_this_thread, native_priority);
#endif
}
+1 -1
View File
@@ -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
+1 -30
View File
@@ -10,7 +10,6 @@ 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";
@@ -46,33 +45,10 @@ void patch_engine::append(const std::string& patch)
struct patch info{};
info.type = static_cast<patch_type>(type64);
info.offset = patch[1].as<u32>(0);
info.offset = patch[1].as<u32>();
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:
{
@@ -114,11 +90,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);
-1
View File
@@ -7,7 +7,6 @@
enum class patch_type
{
load,
byte,
le16,
le32,
+10
View File
@@ -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
+2 -2
View File
@@ -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>
-30
View File
@@ -16,7 +16,6 @@ rem // Official git repository and contact information can be found at
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,43 +47,15 @@ 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 HEAD by default
for /F %%I IN ('call %GIT% rev-list HEAD --count') do set GIT_VERSION=%%I
rem // If we're in AppVeyor and we're building for master: Get commit count from unshallowed upstream
if defined APPVEYOR (
if not defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
call %GIT% remote add upstream https://github.com/RPCS3/RPCS3.git
call %GIT% fetch --unshallow upstream
for /F %%I IN ('call %GIT% rev-list --count upstream/master') do set GIT_VERSION=%%I
)
)
if defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
if "%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"=="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 (
set GIT_BRANCH=%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%
)
) else (
for /F %%I IN ('call %GIT% rev-parse --abbrev-ref HEAD') do set GIT_BRANCH=%%I
)
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=%GIT_VERSION%-%%I
rem // Echo obtained GIT_VERSION for debug purposes if needed
echo %GIT_VERSION%
rem // Don't modify the file if it already has the current version.
if exist "%GIT_VERSION_FILE%" (
findstr /C:"%GIT_VERSION%" "%GIT_VERSION_FILE%" > NUL
@@ -96,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 -83
View File
@@ -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
}
-58
View File
@@ -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();
};
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -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()
+1 -1
View File
@@ -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 -21
View File
@@ -48,7 +48,7 @@
#define CONCATENATE_DETAIL(x, y) x ## y
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
#define STRINGIZE_DETAIL(x) #x ""
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
#define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")"
@@ -534,26 +534,6 @@ inline u64 cntlz64(u64 arg, bool nonzero = false)
#endif
}
inline u32 cnttz32(u32 arg, bool nonzero = false)
{
#ifdef _MSC_VER
ulong res;
return _BitScanForward(&res, arg) || nonzero ? res : 32;
#else
return arg || nonzero ? __builtin_ctzll(arg) : 32;
#endif
}
inline u64 cnttz64(u64 arg, bool nonzero = false)
{
#ifdef _MSC_VER
ulong res;
return _BitScanForward64(&res, arg) || nonzero ? res : 64;
#else
return arg || nonzero ? __builtin_ctzll(arg) : 64;
#endif
}
// Helper function, used by ""_u16, ""_u32, ""_u64
constexpr u8 to_u8(char c)
{
+1 -1
View File
@@ -19,7 +19,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,20 +39,20 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>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>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>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>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>
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,24 +39,24 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
+34 -72
View File
@@ -1,82 +1,44 @@
#---------------------------------#
# general configuration #
#---------------------------------#
version: '0.0.3-{build}'
# version format
version: '0.0.4-{build}'
os: Visual Studio 2017
platform: x64
clone_folder: C:\rpcs3
clone_depth: 3
test: off
#---------------------------------#
# environment configuration #
#---------------------------------#
configuration:
# Release
- ReleaseLLVM
# Build worker image (VM template)
image: Visual Studio 2015
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
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
- set CXXFLAGS=-DBRANCH=%BRANCH%
- if %configuration%==Release (cmake -G "Visual Studio 15 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 15 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
# clone directory
clone_folder: c:\projects\rpcs3
build_script:
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
# set clone depth
clone_depth: 3 # clone entire repository history if not defined
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.1\msvc2017_64
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
- set PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%QTDIR%;%PATH%
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
# environment variables
environment:
QTDIR: C:\Qt\5.9.1\msvc2015_64
artifacts:
- path: bin
name: 'rpcs3-v0.0.3-$(Date)-$(COMMIT_SHA)_win64'
type: zip
# build cache to preserve files/folders between builds
cache:
- llvmlibs.7z -> appveyor.yml
- vulkan.7z -> appveyor.yml
# scripts that run after cloning repository
install:
- git submodule 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
#---------------------------------#
# build configuration #
#---------------------------------#
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
platform: x64
# build Configuration, i.e. Debug, Release, etc.
configuration: Release - LLVM
build:
parallel: true # enable MSBuild parallel builds
project: rpcs3.sln # path to Visual Studio solution or project
# MSBuild verbosity level
verbosity: normal
# scripts to run before build
before_build:
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
- set PATH=%PATH%;%QTDIR%
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
- 7z x llvmlibs.7z -aos -o%APPVEYOR_BUILD_FOLDER% > null
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
- 7z x vulkan.7z -aos -o"%APPVEYOR_BUILD_FOLDER%\lib\%CONFIGURATION%-%PLATFORM%" > null
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
before_package:
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.exp
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.lib
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.pdb
- set COMMIT_DATE=%APPVEYOR_REPO_COMMIT_TIMESTAMP:~0,10%
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
#---------------------------------#
# tests configuration #
#---------------------------------#
# to disable automatic tests
test: off
#---------------------------------#
# artifacts configuration #
#---------------------------------#
# pushing entire folder as a zip archive
artifacts:
- path: bin
name: 'rpcs3-v0.0.4-$(COMMIT_DATE)-$(COMMIT_SHA)_win64'
- zlib.7z -> appveyor.yml
+1 -1
View File
@@ -93,7 +93,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+41 -123
View File
@@ -40,7 +40,7 @@ QWidget {
/* Mouse tooltips */
QToolTip {
border: 0.05em solid #323232;
border: 1px solid #323232;
background-color: #323232;
color: #ecf0f1;
}
@@ -49,29 +49,29 @@ QToolTip {
QHeaderView::section {
background-color: #323232;
color: #ecf0f1;
padding-left: 0.2em;
border: 0.05em solid #323232;
padding-left: 4px;
border: 1px solid #323232;
}
/* Settings Dialog: Tabs */
QTabBar::tab {
color: #ecf0f1;
border: 0.05em solid #444;
border: 1px solid #444;
border-bottom-style: none;
background-color: #333333;
padding-left: 0.9em;
padding-right: 0.9em;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin-right: -0.2em;
padding-left: 16px;
padding-right: 16px;
padding-top: 4px;
padding-bottom: 4px;
margin-right: -2px;
}
QTabBar::tab:last {
margin-right: 0em;
margin-right: 0px;
}
QTabBar::tab:!selected {
color: #b1b1b1;
border-bottom-style: solid;
margin-top: 0.15em;
margin-top: 3px;
background-color: #292929;
}
QTabBar::tab:hover {
@@ -81,11 +81,11 @@ QTabBar::tab:hover {
/* Checkboxes */
QCheckBox::indicator {
border-radius: 0.1em;
border: 0.05em solid #ecf0f1;
margin-top: 0.05em;
width: 0.8em;
height: 0.8em;
border-radius: 2px;
border: 1px solid #ecf0f1;
width: 10px;
height: 10px;
margin-top: 1px;
}
QCheckBox::indicator:checked {
background-color: #2ecc71; /* Green */
@@ -99,11 +99,11 @@ QCheckBox::indicator::disabled {
/* Radio Buttons */
QRadioButton::indicator {
border-radius: 0.4em;
border: 0.05em solid;
border-color: white;
width: 0.8em;
height: 0.8em;
border-radius: 6px;
border: 1px solid #ecf0f1;
width: 10px;
height: 10px;
margin-top: 1px;
}
QRadioButton::indicator:checked {
background-color: #2ecc71; /* Green */
@@ -119,10 +119,10 @@ QRadioButton::indicator::disabled {
QComboBox {
background-color: #404040;
color: #fff;
border: 0.05em solid #1e1e1e;
border-radius: 0.15em;
padding-bottom: 0.2em;
padding-left: 0.4em;
border: 1px solid #1e1e1e;
border-radius: 3px;
padding-bottom: 2px;
padding-left: 4px;
}
QComboBox::disabled {
background-color: #828790;
@@ -131,15 +131,15 @@ QComboBox::disabled {
/* Group Boxes (Settings Dialog) */
QGroupBox {
margin-top: 1em;
font-size: 8pt;
border: 0.05em solid #bdc3c7;
border-radius: 0.3em;
margin-top: 17px;
font-size: 13px;
border: 1px solid #bdc3c7;
border-radius: 4px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top;
padding: 0.3em 0.5em 0.3em 0.5em;
subcontrol-position: top center;
padding: 5px 10px 5px 10px;
color: #fff;
}
@@ -154,19 +154,19 @@ QPushButton::disabled {
/* Log and Debugger borders */
QTextEdit {
border: 0.05em solid #828790;
border: 1px solid #828790;
}
/* For dock buttons to be visible */
QDockWidget::close-button, QDockWidget::float-button {
background-color: #bdc3c7;
border: 0.05em solid #000;
border-radius: 0.3em;
border: 1px solid #000;
border-radius: 4px;
}
/* Disable ugly borders */
QTabWidget::pane {
border: 0em solid #828790;
border: 0px solid #828790;
}
/* Top menu bar */
@@ -174,14 +174,14 @@ QMenuBar::item:selected {
background: #444444;
}
QMenu::item {
padding-left: 1.5em;
padding-right: 0.75em;
padding-top: 0.25em;
padding-bottom: 0.25em;
padding-left: 20px;
padding-right: 15px;
padding-top: 4px;
padding-bottom: 4px;
}
QMenu::item:selected {
background: #444444;
border: 0.05em solid #bdc3c7;
border: 1px solid #bdc3c7;
}
QMenu::item:disabled {
background-color: #444444;
@@ -223,7 +223,7 @@ QLabel#color_button {
/* Seachbar on main toolbar */
QLineEdit#mw_searchbar {
margin-left: 0.7em;
margin-left:14px;
color: #ecf0f1;
}
@@ -246,85 +246,3 @@ QLabel#gamelist_icon_background_color {
QLabel#gamelist_toolbar_icon_color {
background-color: #e3e3e3;
}
/* 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 */
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
Submodule llvm updated: 4423e35117...a3b2103ffc
+8 -8
View File
@@ -18,12 +18,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,30 +39,30 @@
<NMakePreprocessorDefinitions>
</NMakePreprocessorDefinitions>
<NMakeBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakePreprocessorDefinitions />
<NMakeBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
</NMakeCleanCommandLine>
</PropertyGroup>
+1 -1
View File
@@ -32,7 +32,7 @@ Controller.prototype.ComponentSelectionPageCallback = function() {
var widget = gui.currentPageWidget();
widget.deselectAll();
widget.selectComponent("qt.592.gcc_64");
widget.selectComponent("qt.591.gcc_64");
gui.clickButton(buttons.NextButton);
}
+2 -2
View File
@@ -20,14 +20,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
+2 -2
View File
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26430.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
EndProject
+19 -77
View File
@@ -6,31 +6,25 @@ set(CMAKE_CXX_STANDARD 14)
include(CheckCCompilerFlag)
# Qt section
find_package(Qt5 5.7 COMPONENTS Widgets)
find_package(Qt5 5.9 COMPONENTS Widgets)
if (WIN32)
find_package(Qt5WinExtras REQUIRED)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS})
else()
find_package(Qt5DBus)
if (Qt5DBus_FOUND)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus)
add_definitions(-DHAVE_QTDBUS)
else()
set(RPCS3_QT_LIBS Qt5::Widgets)
endif()
include_directories(${Qt5Widgets_INCLUDE_DIRS})
set(RPCS3_QT_LIBS Qt5::Widgets)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
endif()
# Let's make sure we have Qt before we continue
if (NOT Qt5Widgets_FOUND)
if (Qt5Widgets_VERSION VERSION_LESS 5.7.0)
message("Minimum supported Qt5 version is 5.7! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if (Qt5Widgets_VERSION VERSION_LESS 5.9.0)
message("Minimum supported Qt5 version is 5.9! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if ("${CMAKE_SYSTEM}" MATCHES "Linux")
message(FATAL_ERROR "Most distros do not provide an up-to-date version of Qt.
If you're on Ubuntu or Linux Mint, there are PPAs you can use to install an up-to-date qt5 version.
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-trusty
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-trusty
just make sure to run
source /opt/qt59/bin/qt59-env.sh
before re-running cmake")
@@ -44,7 +38,7 @@ before re-running cmake")
message("CMake was unable to find Qt5!")
if (WIN32)
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.8\\msvc2017_64\\)")
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.9\\msvc2017_64\\)")
elseif("${CMAKE_SYSTEM}" MATCHES "Linux")
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
else()
@@ -140,17 +134,15 @@ else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /DYNAMICBASE:NO /BASE:0x10000 /FIXED")
endif()
set(ADDITIONAL_LIBS "")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
#on some Linux distros shm_unlink and similar functions are in librt only
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "rt")
set(ADDITIONAL_LIBS "rt" "X11")
elseif(NOT MSVC AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
#it seems like glibc includes the iconv functions we use but other libc
#implementations like the one on OSX don't seem implement them
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "iconv")
endif()
if(UNIX AND NOT APPLE)
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "X11")
set(ADDITIONAL_LIBS "iconv")
else()
set(ADDITIONAL_LIBS "")
endif()
if(NOT RPCS3_SRC_DIR)
@@ -166,29 +158,6 @@ find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
if (NOT WITHOUT_LLVM)
find_package(LLVM 4.0 CONFIG)
if (NOT LLVM_FOUND)
message("System LLVM was not found, LLVM will be built from the submodule.")
set(LLVM_TARGETS_TO_BUILD "X86" CACHE INTERNAL "")
option(LLVM_BUILD_RUNTIME OFF)
option(LLVM_BUILD_TOOLS OFF)
option(LLVM_INCLUDE_DOCS OFF)
option(LLVM_INCLUDE_EXAMPLES OFF)
option(LLVM_INCLUDE_TESTS OFF)
option(LLVM_INCLUDE_TOOLS OFF)
option(LLVM_INCLUDE_UTILS OFF)
option(WITH_POLLY OFF)
# LLVM needs to be built out-of-tree
add_subdirectory(../llvm ../llvm_build)
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/")
# now tries to find LLVM again
find_package(LLVM 4.0 CONFIG)
if (NOT LLVM_FOUND)
message(WARNING "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
endif()
endif()
endif()
@@ -201,7 +170,6 @@ else()
option(USE_ALSA "ALSA audio backend" ON)
option(USE_PULSE "PulseAudio audio backend" ON)
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
option(USE_VULKAN "Vulkan render backend" ON)
endif()
if(USE_ALSA)
@@ -231,15 +199,6 @@ if(USE_LIBEVDEV)
list(APPEND ADDITIONAL_LIBS ${LIBEVDEV_LDFLAGS})
endif()
endif()
if(NOT WIN32 AND USE_VULKAN)
find_package(Vulkan)
if(VULKAN_FOUND)
add_definitions(-DHAVE_VULKAN)
list(APPEND ADDITIONAL_LIBS ${VULKAN_LIBRARY})
else()
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
endif()
endif()
# Select the version of libpng to use, default is builtin
if(USE_SYSTEM_LIBPNG)
@@ -282,7 +241,6 @@ ${LLVM_INCLUDE_DIRS}
"${RPCS3_SRC_DIR}/../3rdparty/GL"
"${RPCS3_SRC_DIR}/../3rdparty/stblib"
"${RPCS3_SRC_DIR}/../3rdparty/cereal/include"
"${RPCS3_SRC_DIR}/../3rdparty/Optional"
)
if(WIN32)
@@ -297,9 +255,9 @@ else()
add_definitions(${LLVM_DEFINITIONS})
add_definitions(-DLLVM_AVAILABLE)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler)
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler)
else()
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
endif()
if (NOT MSVC)
@@ -333,7 +291,7 @@ RPCS3_SRC
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit/*.cpp"
)
if (NOT WIN32 AND VULKAN_FOUND)
if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
# Compile glslang and SPIRV modules needed for glsl compilation
file(
GLOB_RECURSE
@@ -342,6 +300,7 @@ if (NOT WIN32 AND VULKAN_FOUND)
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/MachineIndependent/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/OSDependent/Unix/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/OGLCompilersDLL/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/hlsl/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/SPIRV/*.cpp"
)
@@ -350,7 +309,8 @@ endif()
#File exclusion section
if(NOT WIN32 AND NOT VULKAN_FOUND)
#Ignore vulkan if not on windows or linux
if(NOT WIN32 AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux")
set (EXCLUDE_FILES "/RSX/VK/")
endif()
@@ -393,13 +353,10 @@ else()
if(APPLE)
target_link_libraries(rpcs3 hidapi-mac "-framework CoreFoundation" "-framework IOKit")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(rpcs3 hidapi-hidraw udev)
target_link_libraries(rpcs3 hidapi-hidraw udev vulkan)
else()
target_link_libraries(rpcs3 hidapi-libusb usb)
endif()
if(VULKAN_FOUND)
target_link_libraries(rpcs3 ${VULKAN_LIBRARIES})
endif()
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
if (USE_SYSTEM_FFMPEG)
link_libraries(${FFMPEG_LIBRARY_DIR})
@@ -427,21 +384,6 @@ target_link_libraries(rpcs3 ${RPCS3_QT_LIBS})
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
if (MSVC)
# Under Windows, some QT DLLs need to be in the same directory of the compiled
# RPCS3 binary, so call the windeployqt tool that will take care of copying
# them from the local QT installation at the end of the build.
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations --debug ${CMAKE_BINARY_DIR}/bin
)
else()
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations ${CMAKE_BINARY_DIR}/bin
)
endif()
endif()
cotire(rpcs3)
# Unix installation
+6 -7
View File
@@ -4,7 +4,6 @@
#include "sha1.h"
#include "key_vault.h"
#include "Utilities/StrFmt.h"
#include "Emu/VFS.h"
#include "unpkg.h"
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync, const std::string& pkg_filepath)
@@ -121,7 +120,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
u64 cursize = pkg_f.size();
while (cursize != header.pkg_size)
{
std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
std::string archive_filename = fmt::format("%s_%2d.pkg", name_wo_number, filelist.size());
fs::file archive_file(archive_filename);
if (!archive_file)
@@ -286,7 +285,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : dec_key.data());
std::string name{reinterpret_cast<char*>(buf.get()), entry.name_size};
const std::string name(reinterpret_cast<char*>(buf.get()), entry.name_size);
LOG_NOTICE(LOADER, "Entry 0x%08x: %s", entry.type, name);
@@ -304,17 +303,17 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
case 0x15:
case 0x16:
{
const std::string path = dir + vfs::escape(name);
const std::string path = dir + name;
const bool did_overwrite = fs::is_file(path);
if (did_overwrite && (entry.type & PKG_FILE_ENTRY_OVERWRITE) == 0)
if (did_overwrite && (entry.type&PKG_FILE_ENTRY_OVERWRITE) == 0)
{
LOG_NOTICE(LOADER, "Didn't overwrite %s", name);
break;
}
if (fs::file out{path, fs::rewrite})
if (fs::file out{ path, fs::rewrite })
{
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
{
@@ -359,7 +358,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
case PKG_FILE_ENTRY_FOLDER:
case 0x12:
{
const std::string path = dir + vfs::escape(name);
const std::string path = dir + name;
if (fs::create_dir(path))
{
+1 -1
View File
@@ -31,7 +31,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+4 -6
View File
@@ -50,8 +50,6 @@ OpenALThread::OpenALThread()
{
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
}
m_buffers = std::make_unique<ALuint[]>(g_cfg.audio.frames);
}
OpenALThread::~OpenALThread()
@@ -85,7 +83,7 @@ void OpenALThread::Close()
if (alIsSource(m_source))
alDeleteSources(1, &m_source);
alDeleteBuffers(g_cfg.audio.frames, m_buffers.get());
alDeleteBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alDeleteBuffers");
}
@@ -100,7 +98,7 @@ void OpenALThread::Open(const void* src, int size)
alGenSources(1, &m_source);
checkForAlError("alGenSources");
alGenBuffers(g_cfg.audio.frames, m_buffers.get());
alGenBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alGenBuffers");
alSourcei(m_source, AL_LOOPING, AL_FALSE);
@@ -108,13 +106,13 @@ void OpenALThread::Open(const void* src, int size)
m_buffer_size = size;
for (int i = 0; i < g_cfg.audio.frames; ++i)
for (uint i = 0; i<g_al_buffers_count; ++i)
{
alBufferData(m_buffers[i], m_format, src, m_buffer_size, 48000);
checkForAlError("alBufferData");
}
alSourceQueueBuffers(m_source, g_cfg.audio.frames, m_buffers.get());
alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
checkForAlError("alSourceQueueBuffers");
Play();
}
+3 -2
View File
@@ -2,14 +2,15 @@
#include "Emu/Audio/AudioThread.h"
#include "3rdparty/OpenAL/include/alext.h"
#include <memory>
class OpenALThread : public AudioThread
{
private:
static const uint g_al_buffers_count = 24;
ALint m_format;
ALuint m_source;
std::unique_ptr<ALuint[]> m_buffers;
ALuint m_buffers[g_al_buffers_count];
ALsizei m_buffer_size;
public:
+1 -1
View File
@@ -59,7 +59,7 @@ ALSAThread::ALSAThread()
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
return;
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, g_cfg.audio.frames * 256), "snd_pcm_hw_params_set_buffer_size"))
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 8 * 256), "snd_pcm_hw_params_set_buffer_size"))
return;
if (!check(snd_pcm_hw_params_set_period_size(s_tls_handle, hw_params, 256, 0), "snd_pcm_hw_params_set_period_size"))
-1
View File
@@ -4,7 +4,6 @@
#include "CPUThread.h"
#include "Emu/IdManager.h"
#include "Utilities/GDBDebugServer.h"
#include <typeinfo>
#ifdef _WIN32
#include <Windows.h>
+25 -55
View File
@@ -12,34 +12,6 @@
logs::channel cellAudio("cellAudio");
template <>
void fmt_class_string<CellAudioError>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](CellAudioError value)
{
switch (value)
{
STR_CASE(CELL_AUDIO_ERROR_ALREADY_INIT);
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM);
STR_CASE(CELL_AUDIO_ERROR_NOT_INIT);
STR_CASE(CELL_AUDIO_ERROR_PARAM);
STR_CASE(CELL_AUDIO_ERROR_PORT_FULL);
STR_CASE(CELL_AUDIO_ERROR_PORT_ALREADY_RUN);
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_OPEN);
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_RUN);
STR_CASE(CELL_AUDIO_ERROR_TRANS_EVENT);
STR_CASE(CELL_AUDIO_ERROR_PORT_OPEN);
STR_CASE(CELL_AUDIO_ERROR_SHAREDMEMORY);
STR_CASE(CELL_AUDIO_ERROR_MUTEX);
STR_CASE(CELL_AUDIO_ERROR_EVENT_QUEUE);
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND);
STR_CASE(CELL_AUDIO_ERROR_TAG_NOT_FOUND);
}
return unknown;
});
}
void audio_config::on_init(const std::shared_ptr<void>& _this)
{
m_buffer.set(vm::alloc(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, vm::main));
@@ -57,8 +29,6 @@ void audio_config::on_init(const std::shared_ptr<void>& _this)
void audio_config::on_task()
{
thread_ctrl::set_native_priority(1);
AudioDumper m_dump(g_cfg.audio.dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
float buf2ch[2 * BUFFER_SIZE]{}; // intermediate buffer for 2 channels
@@ -339,12 +309,12 @@ void audio_config::on_task()
case 8: m_dump.WriteData(&buf8ch, sizeof(buf8ch)); break; // write file data (8 ch)
}
cellAudio.trace("Audio perf: (access=%d, AddData=%d, events=%d, dump=%d)",
stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
cellAudio.trace("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
}
}
error_code cellAudioInit()
s32 cellAudioInit()
{
cellAudio.warning("cellAudioInit()");
@@ -359,7 +329,7 @@ error_code cellAudioInit()
return CELL_OK;
}
error_code cellAudioQuit()
s32 cellAudioQuit()
{
cellAudio.warning("cellAudioQuit()");
@@ -374,7 +344,7 @@ error_code cellAudioQuit()
return CELL_OK;
}
error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
{
cellAudio.warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum);
@@ -474,7 +444,7 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
return CELL_OK;
}
error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
{
cellAudio.warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig);
@@ -509,7 +479,7 @@ error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> port
return CELL_OK;
}
error_code cellAudioPortStart(u32 portNum)
s32 cellAudioPortStart(u32 portNum)
{
cellAudio.warning("cellAudioPortStart(portNum=%d)", portNum);
@@ -534,7 +504,7 @@ error_code cellAudioPortStart(u32 portNum)
}
}
error_code cellAudioPortClose(u32 portNum)
s32 cellAudioPortClose(u32 portNum)
{
cellAudio.warning("cellAudioPortClose(portNum=%d)", portNum);
@@ -559,7 +529,7 @@ error_code cellAudioPortClose(u32 portNum)
}
}
error_code cellAudioPortStop(u32 portNum)
s32 cellAudioPortStop(u32 portNum)
{
cellAudio.warning("cellAudioPortStop(portNum=%d)", portNum);
@@ -584,7 +554,7 @@ error_code cellAudioPortStop(u32 portNum)
}
}
error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
{
cellAudio.trace("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp);
@@ -614,7 +584,7 @@ error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
return CELL_OK;
}
error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
{
cellAudio.trace("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag);
@@ -657,7 +627,7 @@ error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
return CELL_OK;
}
error_code cellAudioSetPortLevel(u32 portNum, float level)
s32 cellAudioSetPortLevel(u32 portNum, float level)
{
cellAudio.trace("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level);
@@ -692,7 +662,7 @@ error_code cellAudioSetPortLevel(u32 portNum, float level)
return CELL_OK;
}
error_code cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
{
cellAudio.warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key);
@@ -723,7 +693,7 @@ error_code cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
error_code cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
{
cellAudio.todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags);
@@ -737,7 +707,7 @@ error_code cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key,
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
error_code cellAudioSetNotifyEventQueue(u64 key)
s32 cellAudioSetNotifyEventQueue(u64 key)
{
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
@@ -763,7 +733,7 @@ error_code cellAudioSetNotifyEventQueue(u64 key)
return CELL_OK;
}
error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
@@ -772,7 +742,7 @@ error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
return CELL_OK;
}
error_code cellAudioRemoveNotifyEventQueue(u64 key)
s32 cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
@@ -798,7 +768,7 @@ error_code cellAudioRemoveNotifyEventQueue(u64 key)
return CELL_AUDIO_ERROR_TRANS_EVENT;
}
error_code cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
@@ -807,7 +777,7 @@ error_code cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
return CELL_OK;
}
error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
{
cellAudio.trace("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
@@ -842,7 +812,7 @@ error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float
return CELL_OK;
}
error_code cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
{
cellAudio.trace("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
@@ -911,7 +881,7 @@ error_code cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, flo
return CELL_OK;
}
error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
{
cellAudio.trace("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume);
@@ -965,25 +935,25 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
return CELL_OK;
}
error_code cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
{
cellAudio.todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume);
return CELL_OK;
}
error_code cellAudioSendAck(u64 data3)
s32 cellAudioSendAck(u64 data3)
{
cellAudio.todo("cellAudioSendAck(data3=0x%llx)", data3);
return CELL_OK;
}
error_code cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
{
cellAudio.todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice);
return CELL_OK;
}
error_code cellAudioUnsetPersonalDevice(s32 iPersonalStream)
s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream)
{
cellAudio.todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream);
return CELL_OK;
+1 -1
View File
@@ -5,7 +5,7 @@
namespace vm { using namespace ps3; }
// Error codes
enum CellAudioError : u32
enum
{
CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701,
CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702,
+1 -1
View File
@@ -152,7 +152,7 @@ s32 cellVideoOutSetCopyControl(u32 videoOut, u32 control)
DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
{
REG_VAR(cellSysutilAvconfExt, g_gamma).flag(MFF_HIDDEN).init = []
REG_VNID(cellSysutilAvconfExt, 0x00000000u, g_gamma).init = []
{
// Test
*g_gamma = 1.0f;
+1 -1
View File
@@ -554,7 +554,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
//Something happens
}
//Something happens?
return CELL_OK;
return -1;
}
s32 cellFontRenderCharGlyphImageVertical()
+8 -8
View File
@@ -1035,22 +1035,22 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsChangeFileSizeWithoutAllocation);
REG_FUNC(sys_fs, cellFsChmod);
REG_FUNC(sys_fs, cellFsChown);
REG_FUNC(sys_fs, cellFsClose).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsClosedir).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsClose).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsClosedir).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsFcntl);
REG_FUNC(sys_fs, cellFsFdatasync);
REG_FUNC(sys_fs, cellFsFGetBlockSize).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsFGetBlockSize).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsFGetBlockSize2);
REG_FUNC(sys_fs, cellFsFstat).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsFsync);
REG_FUNC(sys_fs, cellFsFtruncate).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsFtruncate).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsGetBlockSize);
REG_FUNC(sys_fs, cellFsGetBlockSize2);
REG_FUNC(sys_fs, cellFsGetDirectoryEntries);
REG_FUNC(sys_fs, cellFsGetFreeSize);
REG_FUNC(sys_fs, cellFsGetPath);
REG_FUNC(sys_fs, cellFsLink);
REG_FUNC(sys_fs, cellFsLseek).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsLseek).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsLsnGetCDA);
REG_FUNC(sys_fs, cellFsLsnGetCDASize);
REG_FUNC(sys_fs, cellFsLsnLock);
@@ -1063,8 +1063,8 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsOpen);
REG_FUNC(sys_fs, cellFsOpen2);
REG_FUNC(sys_fs, cellFsOpendir);
REG_FUNC(sys_fs, cellFsRead).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsReaddir).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsRead).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsReaddir).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsReadWithOffset);
REG_FUNC(sys_fs, cellFsRegisterConversionCallback);
REG_FUNC(sys_fs, cellFsRename);
@@ -1095,6 +1095,6 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsUnlink);
REG_FUNC(sys_fs, cellFsUnregisterL10nCallbacks);
REG_FUNC(sys_fs, cellFsUtime);
REG_FUNC(sys_fs, cellFsWrite).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsWrite).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsWriteWithOffset);
});
-10
View File
@@ -659,11 +659,6 @@ error_code cellGameGetParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
{
cellGame.warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize);
if (!buf || bufsize == 0)
{
return CELL_GAME_ERROR_PARAM;
}
const auto prm = fxm::get<content_permission>();
if (!prm)
@@ -690,11 +685,6 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
{
cellGame.warning("cellGameSetParamString(id=%d, buf=*0x%x)", id, buf);
if (!buf)
{
return CELL_GAME_ERROR_PARAM;
}
const auto prm = fxm::get<content_permission>();
if (!prm)
+6 -6
View File
@@ -595,7 +595,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
return CELL_GCM_ERROR_INVALID_VALUE;
}
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
{
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@@ -603,7 +603,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
{
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ENUM");
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ENUM;
}
@@ -1171,7 +1171,7 @@ s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segment
const auto& put = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put;
const auto& get = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).get;
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2 || segmentSize >= 0x80000000)
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2)
{
return CELL_GCM_ERROR_FAILURE;
}
@@ -1220,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
return CELL_GCM_ERROR_INVALID_VALUE;
}
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
{
cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@@ -1484,5 +1484,5 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
REG_FUNC(cellGcmSys, cellGcmGpadCaptureSnapshot);
// Special
REG_FUNC(cellGcmSys, cellGcmCallback).flag(MFF_HIDDEN);
});
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
});
+52 -62
View File
@@ -1,6 +1,5 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Utilities/LUrlParser.h"
#include "cellHttpUtil.h"
@@ -15,15 +14,50 @@ logs::channel cellHttpUtil("cellHttpUtil");
s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
{
cellHttpUtil.trace("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
LUrlParser::clParseURL URL = LUrlParser::clParseURL::ParseURL(str.get_ptr());
if ( URL.IsValid() )
#ifdef _WIN32
URL_COMPONENTS stUrlComp;
ZeroMemory(&stUrlComp, sizeof(URL_COMPONENTS));
stUrlComp.dwStructSize = sizeof(URL_COMPONENTS);
wchar_t lpszScheme[MAX_PATH] = { 0 };
wchar_t lpszHostName[MAX_PATH] = { 0 };
wchar_t lpszPath[MAX_PATH] = { 0 };
wchar_t lpszUserName[MAX_PATH] = { 0 };
wchar_t lpszPassword[MAX_PATH] = { 0 };
stUrlComp.lpszScheme = lpszScheme;
stUrlComp.dwSchemeLength = MAX_PATH;
stUrlComp.lpszHostName = lpszHostName;
stUrlComp.dwHostNameLength = MAX_PATH;
stUrlComp.lpszUrlPath = lpszPath;
stUrlComp.dwUrlPathLength = MAX_PATH;
stUrlComp.lpszUserName = lpszUserName;
stUrlComp.dwUserNameLength = MAX_PATH;
stUrlComp.lpszPassword = lpszPassword;
stUrlComp.dwPasswordLength = MAX_PATH;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
LPCWSTR stupidTypeUrlString = converter.from_bytes(str.get_ptr()).c_str();
if (!::WinHttpCrackUrl(stupidTypeUrlString, (DWORD)(LONG_PTR)wcslen(stupidTypeUrlString), ICU_ESCAPE, &stUrlComp))
{
std::string scheme = URL.m_Scheme;
std::string host = URL.m_Host;
std::string path = URL.m_Path;
std::string username = URL.m_UserName;
std::string password = URL.m_Password;
cellHttpUtil.error("Error %u in WinHttpCrackUrl.\n", GetLastError());
}
else
{
std::string scheme = converter.to_bytes(lpszScheme);
std::string host = converter.to_bytes(lpszHostName);
std::string path = converter.to_bytes(lpszPath);
std::string username = converter.to_bytes(lpszUserName);
std::string password = converter.to_bytes(lpszPassword);
u32 schemeOffset = 0;
u32 hostOffset = scheme.length() + 1;
@@ -33,13 +67,10 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
u32 totalSize = passwordOffset + password.length() + 1;
//called twice, first to setup pool, then to populate.
if (!uri)
{
if (!uri) {
*required = totalSize;
return CELL_OK;
}
else
{
} else {
std::strncpy((char*)vm::base(pool.addr() + schemeOffset), (char*)scheme.c_str(), scheme.length() + 1);
std::strncpy((char*)vm::base(pool.addr() + hostOffset), (char*)host.c_str(), host.length() + 1);
std::strncpy((char*)vm::base(pool.addr() + pathOffset), (char*)path.c_str(), path.length() + 1);
@@ -51,55 +82,14 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
uri->path.set(pool.addr() + pathOffset);
uri->username.set(pool.addr() + usernameOffset);
uri->password.set(pool.addr() + passwordOffset);
uri->port = stUrlComp.nPort;
}
}
if (URL.m_Port != "")
{
int port = stoi(URL.m_Port);
uri->port = port;
}
else
{
uri->port = (u32)80;
}
return CELL_OK;
}
}
else
{
std::string parseError;
switch(URL.m_ErrorCode)
{
case LUrlParser::LUrlParserError_Ok:
parseError = "No error, URL was parsed fine";
break;
case LUrlParser::LUrlParserError_Uninitialized:
parseError = "Error, LUrlParser is uninitialized";
break;
case LUrlParser::LUrlParserError_NoUrlCharacter:
parseError = "Error, the URL has invalid characters";
break;
case LUrlParser::LUrlParserError_InvalidSchemeName:
parseError = "Error, the URL has an invalid scheme";
break;
case LUrlParser::LUrlParserError_NoDoubleSlash:
parseError = "Error, the URL did not contain a double slash";
break;
case LUrlParser::LUrlParserError_NoAtSign:
parseError = "Error, the URL did not contain an @ sign";
break;
case LUrlParser::LUrlParserError_UnexpectedEndOfLine:
parseError = "Error, unexpectedly got the end of the line";
break;
case LUrlParser::LUrlParserError_NoSlash:
parseError = "Error, URI didn't contain a slash";
break;
default:
parseError = "Error, unkown error #" + std::to_string(static_cast<int>(URL.m_ErrorCode));
break;
}
cellHttpUtil.error("%s, while parsing URI, %s.", parseError, str.get_ptr());
return -1;
}
#else
cellHttpUtil.todo("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
#endif
return CELL_OK;
}
s32 cellHttpUtilParseUriPath(vm::ptr<CellHttpUriPath> path, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
-9
View File
@@ -177,9 +177,6 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
if (!handler)
return CELL_KB_ERROR_UNINITIALIZED;
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
KbConfig& current_config = handler->GetConfig(port_no);
current_config.code_type = type;
@@ -200,9 +197,6 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
if (!handler)
return CELL_KB_ERROR_UNINITIALIZED;
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
KbConfig& current_config = handler->GetConfig(port_no);
current_config.read_mode = rmode;
@@ -219,9 +213,6 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
if (!handler)
return CELL_KB_ERROR_UNINITIALIZED;
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
const KbConfig& current_config = handler->GetConfig(port_no);
config->arrange = current_config.arrange;
config->read_mode = current_config.read_mode;
+8 -13
View File
@@ -74,7 +74,7 @@ s32 cellMouseGetInfo(vm::ptr<CellMouseInfo> info)
for (u32 i=0; i<CELL_MAX_MICE; i++) info->vendor_id[i] = current_info.vendor_id[i];
for (u32 i=0; i<CELL_MAX_MICE; i++) info->product_id[i] = current_info.product_id[i];
for (u32 i=0; i<CELL_MAX_MICE; i++) info->status[i] = current_info.status[i];
return CELL_OK;
}
@@ -96,7 +96,7 @@ s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr<CellMouseInfoTablet> info)
info->is_supported = 0; // Unimplemented: (0=Tablet mode is not supported)
info->mode = 1; // Unimplemented: (1=Mouse mode)
return CELL_OK;
}
@@ -115,7 +115,7 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
}
MouseData& current_data = handler->GetData(port_no);
data->update = current_data.update;
data->buttons = current_data.buttons;
@@ -134,27 +134,22 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
{
sys_io.todo("cellMouseGetDataList(port_no=%d, data=0x%x", port_no, data);
if (g_cfg.io.mouse == mouse_handler::null)
return CELL_MOUSE_ERROR_NO_DEVICE;
else
{
data->list_num = 0;
return CELL_OK;
}
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
s32 cellMouseSetTabletMode(u32 port_no, u32 mode)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
-4
View File
@@ -156,10 +156,6 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
{
strcpy_trunc(info->netmask, "255.255.255.255");
}
else if (code == CELL_NET_CTL_INFO_HTTP_PROXY_CONFIG)
{
info->http_proxy_config = 0;
}
return CELL_OK;
}
+144 -179
View File
@@ -3,7 +3,7 @@
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "pad_thread.h"
#include "Emu/Io/PadHandler.h"
#include "cellPad.h"
extern logs::channel sys_io;
@@ -12,7 +12,7 @@ s32 cellPadInit(u32 max_connect)
{
sys_io.warning("cellPadInit(max_connect=%d)", max_connect);
const auto handler = fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler);
const auto handler = fxm::import<PadHandlerBase>(Emu.GetCallbacks().get_pad_handler);
if (!handler)
return CELL_PAD_ERROR_ALREADY_INITIALIZED;
@@ -26,7 +26,7 @@ s32 cellPadEnd()
{
sys_io.notice("cellPadEnd()");
if (!fxm::remove<pad_thread>())
if (!fxm::remove<PadHandlerBase>())
return CELL_PAD_ERROR_UNINITIALIZED;
return CELL_OK;
@@ -36,7 +36,7 @@ s32 cellPadClearBuf(u32 port_no)
{
sys_io.trace("cellPadClearBuf(port_no=%d)", port_no);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -51,20 +51,20 @@ s32 cellPadClearBuf(u32 port_no)
//Set 'm_buffer_cleared' to force a resend of everything
//might as well also reset everything in our pad 'buffer' to nothing as well
auto& pads = handler->GetPads();
auto pad = pads[port_no];
std::vector<Pad>& pads = handler->GetPads();
Pad& pad = pads[port_no];
pad->m_buffer_cleared = true;
pad->m_analog_left_x = pad->m_analog_left_y = pad->m_analog_right_x = pad->m_analog_right_y = 128;
pad.m_buffer_cleared = true;
pad.m_analog_left_x = pad.m_analog_left_y = pad.m_analog_right_x = pad.m_analog_right_y = 128;
pad->m_digital_1 = pad->m_digital_2 = 0;
pad->m_press_right = pad->m_press_left = pad->m_press_up = pad->m_press_down = 0;
pad->m_press_triangle = pad->m_press_circle = pad->m_press_cross = pad->m_press_square = 0;
pad->m_press_L1 = pad->m_press_L2 = pad->m_press_R1 = pad->m_press_R2 = 0;
pad.m_digital_1 = pad.m_digital_2 = 0;
pad.m_press_right = pad.m_press_left = pad.m_press_up = pad.m_press_down = 0;
pad.m_press_triangle = pad.m_press_circle = pad.m_press_cross = pad.m_press_square = 0;
pad.m_press_L1 = pad.m_press_L2 = pad.m_press_R1 = pad.m_press_R2 = 0;
//~399 on sensor y is a level non moving controller
pad->m_sensor_y = 399;
pad->m_sensor_x = pad->m_sensor_z = pad->m_sensor_g = 512;
pad.m_sensor_y = 399;
pad.m_sensor_x = pad.m_sensor_z = pad.m_sensor_g = 512;
return CELL_OK;
}
@@ -73,12 +73,12 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
{
sys_io.trace("cellPadGetData(port_no=%d, data=*0x%x)", port_no, data);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
auto& pads = handler->GetPads();
std::vector<Pad>& pads = handler->GetPads();
const PadInfo& rinfo = handler->GetInfo();
@@ -89,39 +89,39 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
auto pad = pads[port_no];
Pad& pad = pads[port_no];
u16 d1Initial, d2Initial;
d1Initial = pad->m_digital_1;
d2Initial = pad->m_digital_2;
d1Initial = pad.m_digital_1;
d2Initial = pad.m_digital_2;
bool btnChanged = false;
for(Button& button : pad->m_buttons)
for(Button& button : pad.m_buttons)
{
//here we check btns, and set pad accordingly,
//if something changed, set btnChanged
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
{
if (button.m_pressed) pad->m_digital_1 |= button.m_outKeyCode;
else pad->m_digital_1 &= ~button.m_outKeyCode;
if (button.m_pressed) pad.m_digital_1 |= button.m_outKeyCode;
else pad.m_digital_1 &= ~button.m_outKeyCode;
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_LEFT:
if (pad->m_press_left != button.m_value) btnChanged = true;
pad->m_press_left = button.m_value;
if (pad.m_press_left != button.m_value) btnChanged = true;
pad.m_press_left = button.m_value;
break;
case CELL_PAD_CTRL_DOWN:
if (pad->m_press_down != button.m_value) btnChanged = true;
pad->m_press_down = button.m_value;
if (pad.m_press_down != button.m_value) btnChanged = true;
pad.m_press_down = button.m_value;
break;
case CELL_PAD_CTRL_RIGHT:
if (pad->m_press_right != button.m_value) btnChanged = true;
pad->m_press_right = button.m_value;
if (pad.m_press_right != button.m_value) btnChanged = true;
pad.m_press_right = button.m_value;
break;
case CELL_PAD_CTRL_UP:
if (pad->m_press_up != button.m_value) btnChanged = true;
pad->m_press_up = button.m_value;
if (pad.m_press_up != button.m_value) btnChanged = true;
pad.m_press_up = button.m_value;
break;
//These arent pressure btns
case CELL_PAD_CTRL_R3:
@@ -133,42 +133,42 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
}
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{
if (button.m_pressed) pad->m_digital_2 |= button.m_outKeyCode;
else pad->m_digital_2 &= ~button.m_outKeyCode;
if (button.m_pressed) pad.m_digital_2 |= button.m_outKeyCode;
else pad.m_digital_2 &= ~button.m_outKeyCode;
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_SQUARE:
if (pad->m_press_square != button.m_value) btnChanged = true;
pad->m_press_square = button.m_value;
if (pad.m_press_square != button.m_value) btnChanged = true;
pad.m_press_square = button.m_value;
break;
case CELL_PAD_CTRL_CROSS:
if (pad->m_press_cross != button.m_value) btnChanged = true;
pad->m_press_cross = button.m_value;
if (pad.m_press_cross != button.m_value) btnChanged = true;
pad.m_press_cross = button.m_value;
break;
case CELL_PAD_CTRL_CIRCLE:
if (pad->m_press_circle != button.m_value) btnChanged = true;
pad->m_press_circle = button.m_value;
if (pad.m_press_circle != button.m_value) btnChanged = true;
pad.m_press_circle = button.m_value;
break;
case CELL_PAD_CTRL_TRIANGLE:
if (pad->m_press_triangle != button.m_value) btnChanged = true;
pad->m_press_triangle = button.m_value;
if (pad.m_press_triangle != button.m_value) btnChanged = true;
pad.m_press_triangle = button.m_value;
break;
case CELL_PAD_CTRL_R1:
if (pad->m_press_R1 != button.m_value) btnChanged = true;
pad->m_press_R1 = button.m_value;
if (pad.m_press_R1 != button.m_value) btnChanged = true;
pad.m_press_R1 = button.m_value;
break;
case CELL_PAD_CTRL_L1:
if (pad->m_press_L1 != button.m_value) btnChanged = true;
pad->m_press_L1 = button.m_value;
if (pad.m_press_L1 != button.m_value) btnChanged = true;
pad.m_press_L1 = button.m_value;
break;
case CELL_PAD_CTRL_R2:
if (pad->m_press_R2 != button.m_value) btnChanged = true;
pad->m_press_R2 = button.m_value;
if (pad.m_press_R2 != button.m_value) btnChanged = true;
pad.m_press_R2 = button.m_value;
break;
case CELL_PAD_CTRL_L2:
if (pad->m_press_L2 != button.m_value) btnChanged = true;
pad->m_press_L2 = button.m_value;
if (pad.m_press_L2 != button.m_value) btnChanged = true;
pad.m_press_L2 = button.m_value;
break;
default: break;
}
@@ -182,131 +182,96 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
}
}
for (const AnalogStick& stick : pad->m_sticks)
for (const AnalogStick& stick : pad.m_sticks)
{
switch (stick.m_offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
pad->m_analog_left_x = stick.m_value;
if (pad.m_analog_left_x != stick.m_value) btnChanged = true;
pad.m_analog_left_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
pad->m_analog_left_y = stick.m_value;
if (pad.m_analog_left_y != stick.m_value) btnChanged = true;
pad.m_analog_left_y = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
pad->m_analog_right_x = stick.m_value;
if (pad.m_analog_right_x != stick.m_value) btnChanged = true;
pad.m_analog_right_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
pad->m_analog_right_y = stick.m_value;
if (pad.m_analog_right_y != stick.m_value) btnChanged = true;
pad.m_analog_right_y = stick.m_value;
break;
default: break;
}
}
for (const AnalogSensor& sensor : pad->m_sensors)
for (const AnalogSensor& sensor : pad.m_sensors)
{
switch (sensor.m_offset)
{
case CELL_PAD_BTN_OFFSET_SENSOR_X:
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
pad->m_sensor_x = sensor.m_value;
if (pad.m_sensor_x != sensor.m_value) btnChanged = true;
pad.m_sensor_x = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
pad->m_sensor_y = sensor.m_value;
if (pad.m_sensor_y != sensor.m_value) btnChanged = true;
pad.m_sensor_y = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
pad->m_sensor_z = sensor.m_value;
if (pad.m_sensor_z != sensor.m_value) btnChanged = true;
pad.m_sensor_z = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_G:
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
pad->m_sensor_g = sensor.m_value;
if (pad.m_sensor_g != sensor.m_value) btnChanged = true;
pad.m_sensor_g = sensor.m_value;
break;
default: break;
}
}
if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2)
if (d1Initial != pad.m_digital_1 || d2Initial != pad.m_digital_2)
{
btnChanged = true;
}
// the real hardware only fills the buffer up to "len" elements (16 bit each)
if (pad->m_port_setting & CELL_PAD_SETTING_SENSOR_ON)
{
// report back new data every ~10 ms even if the input doesn't change
// this is observed behaviour when using a Dualshock 3 controller
static std::chrono::time_point<steady_clock> last_update[CELL_PAD_MAX_PORT_NUM] = { };
const std::chrono::time_point<steady_clock> now = steady_clock::now();
//not sure if this should officially change with capabilities/portsettings :(
data->len = 24;
if (btnChanged || pad->m_buffer_cleared || (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update[port_no]).count() >= 10))
{
data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON;
last_update[port_no] = now;
}
else
{
data->len = CELL_PAD_LEN_NO_CHANGE;
}
}
else if (btnChanged || pad->m_buffer_cleared)
if (pad.m_buffer_cleared)
{
// only give back valid data if a controller state changed
data->len = (pad->m_port_setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT;
pad.m_buffer_cleared = false;
}
else
else if (!btnChanged)
{
// report no state changes
data->len = CELL_PAD_LEN_NO_CHANGE;
}
pad->m_buffer_cleared = false;
// only update parts of the output struct depending on the controller setting
if (data->len > CELL_PAD_LEN_NO_CHANGE)
{
memset(data->button, 0, sizeof(data->button));
data->button[0] = 0x0; // always 0
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad->m_digital_1;
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad->m_digital_2;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad->m_analog_right_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad->m_analog_right_y;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad->m_analog_left_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad->m_analog_left_y;
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad->m_press_right;
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad->m_press_left;
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad->m_press_up;
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad->m_press_down;
}
if (data->len >= CELL_PAD_LEN_CHANGE_PRESS_ON)
{
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad->m_press_triangle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad->m_press_circle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad->m_press_cross;
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad->m_press_square;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad->m_press_L1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad->m_press_L2;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad->m_press_R1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad->m_press_R2;
}
if (data->len == CELL_PAD_LEN_CHANGE_SENSOR_ON)
{
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad->m_sensor_x;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad->m_sensor_y;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad->m_sensor_z;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad->m_sensor_g;
data->len = 0;
}
data->button[0] = 0x0; // always 0
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
//lets still send new data anyway, not sure whats expected still
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad.m_digital_1;
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad.m_digital_2;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad.m_analog_right_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad.m_analog_right_y;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad.m_analog_left_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad.m_analog_left_y;
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad.m_press_right;
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad.m_press_left;
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad.m_press_up;
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad.m_press_down;
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad.m_press_triangle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad.m_press_circle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad.m_press_cross;
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad.m_press_square;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad.m_press_L1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad.m_press_L2;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad.m_press_R1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad.m_press_R2;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad.m_sensor_x;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad.m_sensor_y;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad.m_sensor_z;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad.m_sensor_g;
return CELL_OK;
}
@@ -315,7 +280,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
{
sys_io.trace("cellPadPeriphGetInfo(info=*0x%x)", info);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -328,7 +293,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
auto& pads = handler->GetPads();
std::vector<Pad>& pads = handler->GetPads();
// TODO: Support other types of controllers
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
@@ -336,10 +301,10 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
if (i >= pads.size())
break;
info->port_status[i] = pads[i]->m_port_status;
info->port_setting[i] = pads[i]->m_port_setting;
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
info->port_status[i] = pads[i].m_port_status;
info->port_setting[i] = pads[i].m_port_setting;
info->device_capability[i] = pads[i].m_device_capability;
info->device_type[i] = pads[i].m_device_type;
info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD;
info->pclass_profile[i] = 0x0;
}
@@ -350,7 +315,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
s32 cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
{
sys_io.trace("cellPadPeriphGetData(port_no=%d, data=*0x%x)", port_no, data);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -377,7 +342,7 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadDa
{
sys_io.trace("cellPadGetDataExtra(port_no=%d, device_type=*0x%x, device_type=*0x%x)", port_no, device_type, data);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -405,7 +370,7 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
{
sys_io.trace("cellPadSetActDirect(port_no=%d, param=*0x%x)", port_no, param);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -426,7 +391,7 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
{
sys_io.trace("cellPadGetInfo(info=*0x%x)", info);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -438,15 +403,15 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
auto& pads = handler->GetPads();
std::vector<Pad>& pads = handler->GetPads();
for (u32 i=0; i<CELL_MAX_PADS; ++i)
{
if (i >= pads.size())
break;
info->status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->status[i] = pads[i].m_port_status;
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->product_id[i] = 0x0268;
info->vendor_id[i] = 0x054C;
}
@@ -458,7 +423,7 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
{
sys_io.trace("cellPadGetInfo2(info=*0x%x)", info);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -470,18 +435,18 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
auto& pads = handler->GetPads();
std::vector<Pad>& pads = handler->GetPads();
for (u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
{
if (i >= pads.size())
break;
info->port_status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = pads[i]->m_port_setting;
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
info->port_status[i] = pads[i].m_port_status;
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = pads[i].m_port_setting;
info->device_capability[i] = pads[i].m_device_capability;
info->device_type[i] = pads[i].m_device_type;
}
return CELL_OK;
@@ -491,7 +456,7 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
{
sys_io.trace("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr());
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -503,10 +468,10 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto& pads = handler->GetPads();
const std::vector<Pad>& pads = handler->GetPads();
//Should return the same as device capability mask, psl1ght has it backwards in pad->h
info->info[0] = pads[port_no]->m_device_capability;
//Should return the same as device capability mask, psl1ght has it backwards in pad.h
info->info[0] = pads[port_no].m_device_capability;
return CELL_OK;
}
@@ -515,7 +480,7 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
{
sys_io.trace("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -527,8 +492,8 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
auto& pads = handler->GetPads();
pads[port_no]->m_port_setting = port_setting;
std::vector<Pad>& pads = handler->GetPads();
pads[port_no].m_port_setting = port_setting;
return CELL_OK;
}
@@ -537,7 +502,7 @@ s32 cellPadInfoPressMode(u32 port_no)
{
sys_io.trace("cellPadInfoPressMode(port_no=%d)", port_no);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -549,16 +514,16 @@ s32 cellPadInfoPressMode(u32 port_no)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto& pads = handler->GetPads();
const std::vector<Pad>& pads = handler->GetPads();
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
}
s32 cellPadInfoSensorMode(u32 port_no)
{
sys_io.trace("cellPadInfoSensorMode(port_no=%d)", port_no);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -570,16 +535,16 @@ s32 cellPadInfoSensorMode(u32 port_no)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto& pads = handler->GetPads();
const std::vector<Pad>& pads = handler->GetPads();
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
}
s32 cellPadSetPressMode(u32 port_no, u32 mode)
{
sys_io.trace("cellPadSetPressMode(port_no=%d, mode=%d)", port_no, mode);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -594,12 +559,12 @@ s32 cellPadSetPressMode(u32 port_no, u32 mode)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
auto& pads = handler->GetPads();
std::vector<Pad>& pads = handler->GetPads();
if (mode)
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
pads[port_no].m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
else
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
return CELL_OK;
}
@@ -608,7 +573,7 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
{
sys_io.trace("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -623,12 +588,12 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
auto& pads = handler->GetPads();
std::vector<Pad>& pads = handler->GetPads();
if (mode)
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
pads[port_no].m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
else
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
return CELL_OK;
}
@@ -637,7 +602,7 @@ s32 cellPadLddRegisterController()
{
sys_io.todo("cellPadLddRegisterController()");
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -649,7 +614,7 @@ s32 cellPadLddDataInsert(s32 handle, vm::ptr<CellPadData> data)
{
sys_io.todo("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -661,7 +626,7 @@ s32 cellPadLddGetPortNo(s32 handle)
{
sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -673,7 +638,7 @@ s32 cellPadLddUnregisterController(s32 handle)
{
sys_io.todo("cellPadLddUnregisterController(handle=%d)", handle);
const auto handler = fxm::get<pad_thread>();
const auto handler = fxm::get<PadHandlerBase>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
-9
View File
@@ -27,15 +27,6 @@ enum
CELL_PAD_PCLASS_TYPE_NAVIGATION = 0x05,
};
// Length returned in CellPadData struct
enum
{
CELL_PAD_LEN_NO_CHANGE = 0,
CELL_PAD_LEN_CHANGE_DEFAULT = 8,
CELL_PAD_LEN_CHANGE_PRESS_ON = 20,
CELL_PAD_LEN_CHANGE_SENSOR_ON = 24,
};
struct CellPadData
{
be_t<s32> len;
+3 -3
View File
@@ -1,5 +1,7 @@
#pragma once
#include "sys_net.h"
namespace vm { using namespace ps3; }
// Return Codes
@@ -77,9 +79,7 @@ enum
CELL_RUDP_POLL_EV_ERROR = 0x0008,
};
struct sys_net_sockaddr;
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net_sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net::sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
using CellRudpAllocatorFuncAlloc = vm::ptr<void>(u32 size);
using CellRudpAllocatorFuncFree = void(vm::ptr<void> ptr);
+3 -7
View File
@@ -103,15 +103,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
// get the saves matching the supplied prefix
for (auto&& entry : fs::dir(base_dir))
for (const auto& entry : fs::dir(base_dir))
{
if (!entry.is_directory)
{
continue;
}
entry.name = vfs::unescape(entry.name);
for (const auto& prefix : prefix_list)
{
if (entry.name.substr(0, prefix.size()) == prefix)
@@ -455,10 +453,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
auto file_list = statGet->fileList.get_ptr();
for (auto&& entry : fs::dir(dir_path))
for (const auto& entry : fs::dir(dir_path))
{
entry.name = vfs::unescape(entry.name);
// only files, system files ignored, fileNum is limited by setBuf->fileListMax
if (!entry.is_directory && entry.name != "PARAM.SFO" && statGet->fileListNum++ < setBuf->fileListMax)
{
@@ -1087,7 +1083,7 @@ s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<Cell
void cellSysutil_SaveData_init()
{
REG_VAR(cellSysutil, g_savedata_context).flag(MFF_HIDDEN);
REG_VNID(cellSysutil, 0x00000000u, g_savedata_context);
// libsysutil functions:
REG_FUNC(cellSysutil, cellSaveDataEnableOverlay);
+1 -1
View File
@@ -66,5 +66,5 @@ error_code cellSpudllHandleConfigSetDefaultValues(vm::ptr<CellSpudllHandleConfig
DECLARE(ppu_module_manager::cellSpudll)("cellSpudll", []()
{
REG_FUNC(cellSpudll, cellSpudllGetImageSize);
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flag(MFF_PERFECT);
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flags = MFF_PERFECT;
});
+4 -71
View File
@@ -1,21 +1,11 @@
#include "stdafx.h"
#include <bitset>
#include <string>
#include "Emu/Cell/PPUModule.h"
#include "Utilities/File.h"
#include "Emu/VFS.h"
logs::channel cellSsl("cellSsl");
namespace vm { using namespace ps3; }
enum SpecialCerts { BaltimoreCert = 6, Class3G2V2Cert = 13, ClassSSV4Cert = 15, EntrustNetCert = 18, GTECyberTrustGlobalCert = 23 };
s32 cellSslInit(vm::ptr<void> pool, u32 poolSize)
s32 cellSslInit()
{
cellSsl.todo("cellSslInit(pool=0x%x, poolSize=%d)", pool, poolSize);
UNIMPLEMENTED_FUNC(cellSsl);
return CELL_OK;
}
@@ -25,66 +15,9 @@ s32 cellSslEnd()
return CELL_OK;
}
std::string getCert(const std::string certPath, const int certID, const bool isNormalCert)
s32 cellSslCertificateLoader()
{
int newID = certID;
// The 'normal' certs have some special rules for loading.
if (isNormalCert && certID >= BaltimoreCert && certID <= GTECyberTrustGlobalCert)
{
if (certID == BaltimoreCert)
newID = GTECyberTrustGlobalCert;
else if (certID == Class3G2V2Cert)
newID = BaltimoreCert;
else if (certID == EntrustNetCert)
newID = ClassSSV4Cert;
else
newID = certID - 1;
}
std::string filePath = fmt::format("%sCA%02d.cer", certPath, newID);
if (!fs::exists(filePath))
{
cellSsl.error("Can't find certificate file %s, do you have the PS3 firmware installed?", filePath);
return "";
}
return fs::file(filePath).to_string();
}
s32 cellSslCertificateLoader(u64 flag, vm::ptr<char> buffer, u32 size, vm::ptr<u32> required)
{
cellSsl.trace("cellSslCertificateLoader(flag=%llu, buffer=0x%x, size=%zu, required=0x%x)", flag, buffer, size, required);
const std::bitset<58> flagBits(flag);
const std::string certPath = vfs::get("/dev_flash/") + "data/cert/";
if (required)
{
*required = 0;
for (int i = 1; i <= flagBits.size(); i++)
{
if (!flagBits[i-1])
continue;
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
*required += (u32)(getCert(certPath, i, flagBits[BaltimoreCert-1]).size());
}
}
else
{
std::string final;
for (int i = 1; i <= flagBits.size(); i++)
{
if (!flagBits[i-1])
continue;
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
final.append(getCert(certPath, i, flagBits[BaltimoreCert-1]));
}
memset(buffer.get_ptr(), '\0', size - 1);
memcpy(buffer.get_ptr(), final.c_str(), final.size());
}
UNIMPLEMENTED_FUNC(cellSsl);
return CELL_OK;
}
+8 -5
View File
@@ -100,8 +100,11 @@ void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
});
}
// For test
enum systemparam_id_name : s32 {};
template <>
void fmt_class_string<CellSysutilParamId>::format(std::string& out, u64 arg)
void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto value)
{
@@ -130,13 +133,13 @@ void fmt_class_string<CellSysutilParamId>::format(std::string& out, u64 arg)
});
}
s32 cellSysutilGetSystemParamInt(CellSysutilParamId id, vm::ptr<s32> value)
s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
{
cellSysutil.warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, id, value);
// TODO: load this information from config (preferably "sys/" group)
switch (id)
switch(id)
{
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
*value = g_cfg.sys.language;
@@ -205,13 +208,13 @@ s32 cellSysutilGetSystemParamInt(CellSysutilParamId id, vm::ptr<s32> value)
return CELL_OK;
}
s32 cellSysutilGetSystemParamString(CellSysutilParamId id, vm::ptr<char> buf, u32 bufsize)
s32 cellSysutilGetSystemParamString(systemparam_id_name id, vm::ptr<char> buf, u32 bufsize)
{
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, id, buf, bufsize);
memset(buf.get_ptr(), 0, bufsize);
switch (id)
switch(id)
{
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
memcpy(buf.get_ptr(), "Unknown", 8); // for example
+1 -1
View File
@@ -14,7 +14,7 @@ enum
};
// Parameter IDs
enum CellSysutilParamId: s32
enum
{
// Integers
CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111,
+3 -30
View File
@@ -3,8 +3,6 @@
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/Cell/lv2/sys_ppu_thread.h"
#include "sysPrxForUser.h"
extern "C"
{
@@ -76,14 +74,11 @@ struct vdec_thread : ppu_thread
u32 frc_set{}; // Frame Rate Override
u64 next_pts{};
u64 next_dts{};
u64 ppu_tid{};
std::mutex mutex;
std::queue<vdec_frame> out;
u32 max_frames = 60;
atomic_t<u32> au_count{0};
vdec_thread(s32 type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg, u32 prio, u32 stack)
: ppu_thread("HLE Video Decoder", prio, stack)
, type(type)
@@ -356,11 +351,6 @@ struct vdec_thread : ppu_thread
cb_func(*this, id, vcmd == vdec_cmd::decode ? CELL_VDEC_MSG_TYPE_AUDONE : CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, cb_arg);
lv2_obj::sleep(*this);
}
if (vcmd == vdec_cmd::decode)
{
au_count--;
}
while (std::lock_guard<std::mutex>{mutex}, max_frames && out.size() > max_frames)
{
@@ -407,7 +397,7 @@ u32 vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr<C
attr->decoderVerLower = 0x280000; // from dmux
attr->decoderVerUpper = 0x260000;
attr->memSize = 4 * 1024 * 1024; // 4 MB
attr->cmdDepth = 4;
attr->cmdDepth = 16;
return CELL_OK;
}
@@ -425,7 +415,7 @@ s32 cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAttr> att
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr);
}
s32 cellVdecOpen(ppu_thread& ppu, vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
{
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
@@ -435,17 +425,12 @@ s32 cellVdecOpen(ppu_thread& ppu, vm::cptr<CellVdecType> type, vm::cptr<CellVdec
// Hack: store thread id (normally it should be pointer)
*handle = vdec->id;
vm::var<u64> _tid;
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
vdec->ppu_tid = *_tid;
vdec->run();
return CELL_OK;
}
s32 cellVdecOpenEx(ppu_thread& ppu, vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
{
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
@@ -455,11 +440,6 @@ s32 cellVdecOpenEx(ppu_thread& ppu, vm::cptr<CellVdecTypeEx> type, vm::cptr<Cell
// Hack: store thread id (normally it should be pointer)
*handle = vdec->id;
vm::var<u64> _tid;
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
vdec->ppu_tid = *_tid;
vdec->run();
return CELL_OK;
@@ -487,8 +467,6 @@ s32 cellVdecClose(ppu_thread& ppu, u32 handle)
vdec->notify();
vdec->join();
idm::remove<ppu_thread>(handle);
CALL_FUNC(ppu, sys_interrupt_thread_disestablish, ppu, vdec->ppu_tid);
return CELL_OK;
}
@@ -535,11 +513,6 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
return CELL_VDEC_ERROR_ARG;
}
if (vdec->au_count.fetch_op([](u32& c) { if (c < 4) c++; }) >= 4)
{
return CELL_VDEC_ERROR_BUSY;
}
// TODO: check info
vdec->cmd_list
({
+1 -1
View File
@@ -256,7 +256,7 @@ s32 cellVideoOutUnregisterCallback(u32 slot)
void cellSysutil_VideoOut_init()
{
REG_FUNC(cellSysutil, cellVideoOutGetState);
REG_FUNC(cellSysutil, cellVideoOutGetResolution).flag(MFF_PERFECT);
REG_FUNC(cellSysutil, cellVideoOutGetResolution).flags = MFF_PERFECT;
REG_FUNC(cellSysutil, cellVideoOutConfigure);
REG_FUNC(cellSysutil, cellVideoOutGetConfiguration);
REG_FUNC(cellSysutil, cellVideoOutGetDeviceInfo);
+34 -27
View File
@@ -1,14 +1,13 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "sysPrxForUser.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/IdManager.h"
#include "Crypto/unedat.h"
#include "Crypto/unself.h"
#include "cellRtc.h"
#include "sceNp.h"
#include "cellSysutil.h"
logs::channel sceNp("sceNp");
@@ -44,15 +43,7 @@ s32 sceNpTerm()
s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
{
std::array<u8, 0x10> k_licensee{};
if (k_licensee_addr)
{
std::copy_n(k_licensee_addr.get_ptr(), k_licensee.size(), k_licensee.begin());
sceNp.notice("npDrmIsAvailable(): KLicense key %s", *reinterpret_cast<be_t<v128, 1>*>(k_licensee.data()));
}
const std::string enc_drm_path = drm_path.get_ptr();
const std::string& enc_drm_path = drm_path.get_ptr();
if (!fs::is_file(vfs::get(enc_drm_path)))
{
@@ -60,6 +51,20 @@ s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
return CELL_ENOENT;
}
std::string k_licensee_str = "";
std::array<u8, 0x10> k_licensee{0};
if (k_licensee_addr)
{
for (s8 i = 0; i < 0x10; i++)
{
k_licensee[i] = *(k_licensee_addr + i);
k_licensee_str += fmt::format("%02x", k_licensee[i]);
}
sceNp.notice("npDrmIsAvailable(): KLicense key %s", k_licensee_str);
}
auto npdrmkeys = fxm::get_always<LoadedNpdrmKeys_t>();
npdrmkeys->devKlic.fill(0);
@@ -179,29 +184,27 @@ s32 sceNpDrmGetTimelimit(vm::cptr<char> path, vm::ptr<u64> time_remain)
return CELL_OK;
}
s32 sceNpDrmProcessExitSpawn(ppu_thread& ppu, vm::cptr<u8> klicensee, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
s32 sceNpDrmProcessExitSpawn(vm::cptr<u8> klicensee, vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
{
sceNp.warning("sceNpDrmProcessExitSpawn(klicensee=*0x%x, path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", klicensee, path, argv, envp, data, data_size, prio, flags);
sceNp.warning("sceNpDrmProcessExitSpawn() -> sys_game_process_exitspawn");
if (s32 error = npDrmIsAvailable(klicensee, path))
{
return error;
}
sceNp.warning("klicensee: 0x%x", klicensee);
npDrmIsAvailable(klicensee, path);
sys_game_process_exitspawn(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
sys_game_process_exitspawn(ppu, path, argv, envp, data, data_size, prio, flags);
return CELL_OK;
}
s32 sceNpDrmProcessExitSpawn2(ppu_thread& ppu, vm::cptr<u8> klicensee, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
s32 sceNpDrmProcessExitSpawn2(vm::cptr<u8> klicensee, vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
{
sceNp.warning("sceNpDrmProcessExitSpawn2(klicensee=*0x%x, path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", klicensee, path, argv, envp, data, data_size, prio, flags);
sceNp.warning("sceNpDrmProcessExitSpawn2() -> sys_game_process_exitspawn2");
if (s32 error = npDrmIsAvailable(klicensee, path))
{
return error;
}
sceNp.warning("klicensee: 0x%x", klicensee);
npDrmIsAvailable(klicensee, path);
sys_game_process_exitspawn2(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
sys_game_process_exitspawn2(ppu, path, argv, envp, data, data_size, prio, flags);
return CELL_OK;
}
@@ -902,12 +905,16 @@ s32 sceNpLookupTitleSmallStorageAsync()
s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr<void> arg)
{
sceNp.warning("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
sceNp.todo("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
if (!callback)
{
return SCE_NP_ERROR_INVALID_ARGUMENT;
}
else
{
return SCE_NP_ERROR_NOT_INITIALIZED;
}
return CELL_OK;
}
+1 -2
View File
@@ -147,8 +147,7 @@ s32 sceNpSnsFbCheckThrottle()
s32 sceNpSnsFbCheckConfig()
{
sceNpSns.todo("sceNpSnsFbCheckConfig()");
return CELL_OK;
fmt::throw_exception("Unimplemented" HERE);
}
s32 sceNpSnsFbLoadThrottle()
+28 -82
View File
@@ -16,10 +16,6 @@
logs::channel sceNpTrophy("sceNpTrophy");
TrophyNotificationBase::~TrophyNotificationBase()
{
}
struct trophy_context_t
{
static const u32 id_base = 1;
@@ -185,8 +181,9 @@ error_code sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunic
sceNpTrophy.warning("sceNpTrophyCreateContext term=%s data=%s num=%d", commId->term, commId->data, commId->num);
if (commId->term)
{
char trimchar[10] = { 0 };
memcpy(trimchar, commId->data, sizeof(trimchar) - 1);
char trimchar[9];
memcpy(trimchar, commId->data, sizeof(trimchar));
trimchar[8] = 0;
deleteTerminateChar(trimchar, commId->term);
name = fmt::format("%s_%02d", trimchar, commId->num);
}
@@ -268,7 +265,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
const size_t kTargetBufferLength = 31;
char target[kTargetBufferLength + 1];
target[kTargetBufferLength] = 0;
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", static_cast<s32>(g_cfg.sys.language)));
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", /*rpcs3::config.system.language.value()*/0));
if (trp.ContainsEntry(target))
{
@@ -290,7 +287,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
for (s32 i = 0; i <= 18; i++)
{
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", i));
if (i != g_cfg.sys.language)
if (i != /*rpcs3::config.system.language.value()*/0)
{
trp.RemoveEntry(target);
}
@@ -401,15 +398,12 @@ error_code sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGa
}
// TODO: Get the path of the current user
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
if (!config)
{
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
}
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM");
// TODO: rXmlDocument can open only real file
verify(HERE), !fs::get_virtual_device(path);
rXmlDocument doc;
doc.Read(config.to_string());
doc.Load(path);
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext())
{
@@ -480,7 +474,7 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
}
if (trophyId < 0 || trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
if (trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
if (ctxt->tropusr->GetTrophyUnlockState(trophyId))
return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;
@@ -489,45 +483,7 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
ctxt->tropusr->Save(trophyPath);
if (platinumId)
{
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
}
if (g_cfg.misc.show_trophy_popups)
{
// Figure out how many zeros are needed for padding. (either 0, 1, or 2)
std::string padding = "";
if (trophyId < 10)
{
padding = "00";
}
else if (trophyId < 100)
{
padding = "0";
}
// Get icon for the notification.
std::string trophyIconPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROP" + padding + std::to_string(trophyId) + ".PNG";
fs::file trophyIconFile = fs::file(vfs::get(trophyIconPath));
u32 iconSize = trophyIconFile.size();
std::vector<uchar> trophyIconData;
trophyIconFile.read(trophyIconData, iconSize);
vm::ptr<SceNpTrophyDetails> details = vm::make_var(SceNpTrophyDetails());
vm::ptr<SceNpTrophyData> _ = vm::make_var(SceNpTrophyData());
s32 ret = sceNpTrophyGetTrophyInfo(context, handle, trophyId, details, _);
if (ret != CELL_OK)
{
sceNpTrophy.error("Failed to get info for trophy dialog. Error code %x", ret);
*details = SceNpTrophyDetails();
}
Emu.CallAfter([det = *details, trophyIconData]() {
Emu.GetCallbacks().get_trophy_notification_dialog()->ShowTrophyNotification(det, trophyIconData);
});
}
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
return CELL_OK;
}
@@ -595,25 +551,15 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
}
// TODO: Get the path of the current user
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
if (!config)
{
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
}
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM");
// TODO: rXmlDocument can open only real file
verify(HERE), !fs::get_virtual_device(path);
rXmlDocument doc;
doc.Read(config.to_string());
auto trophy_base = doc.GetRoot();
if (trophy_base->GetChildren()->GetName() == "trophyconf")
{
trophy_base = trophy_base->GetChildren();
}
doc.Load(path);
bool found = false;
for (std::shared_ptr<rXmlNode> n = trophy_base->GetChildren(); n; n = n->GetNext())
{
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").c_str())))
{
found = true;
@@ -730,21 +676,21 @@ error_code sceNpTrophyGetGameIcon(u32 context, u32 handle, vm::ptr<void> buffer,
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
}
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG"));
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG");
if (!icon_file)
if (!fs::exists(path))
{
return SCE_NP_TROPHY_ERROR_UNKNOWN_FILE;
}
const u32 icon_size = ::size32(icon_file);
fs::file gameIconFile(path);
if (buffer && *size >= icon_size)
if (buffer && *size >= gameIconFile.size())
{
icon_file.read(buffer.get_ptr(), icon_size);
gameIconFile.read(buffer.get_ptr(), gameIconFile.size());
}
*size = icon_size;
*size = gameIconFile.size();
return CELL_OK;
}
@@ -783,21 +729,21 @@ error_code sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::p
return hidden ? SCE_NP_TROPHY_ERROR_HIDDEN : SCE_NP_TROPHY_ERROR_LOCKED;
}
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId)));
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId));
if (!icon_file)
if (!fs::exists(path))
{
return SCE_NP_TROPHY_ERROR_UNKNOWN_FILE;
}
const u32 icon_size = ::size32(icon_file);
fs::file trophyIconFile(path);
if (buffer && *size >= icon_size)
if (buffer && *size >= trophyIconFile.size())
{
icon_file.read(buffer.get_ptr(), icon_size);
trophyIconFile.read(buffer.get_ptr(), trophyIconFile.size());
}
*size = icon_size;
*size = trophyIconFile.size();
return CELL_OK;
}
-11
View File
@@ -137,14 +137,3 @@ enum
};
using SceNpTrophyStatusCallback = s32(u32 context, u32 status, s32 completed, s32 total, vm::ptr<void> arg);
// Forward declare this function since trophyunlock needs it
error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data);
class TrophyNotificationBase
{
public:
virtual ~TrophyNotificationBase();
virtual s32 ShowTrophyNotification(const SceNpTrophyDetails& trophy, const std::vector<uchar>& trophyIconBfr) = 0;
};
+20 -41
View File
@@ -2,10 +2,8 @@
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_mutex.h"
#include "Emu/Cell/lv2/sys_interrupt.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_ss.h"
#include "sysPrxForUser.h"
logs::channel sysPrxForUser("sysPrxForUser");
@@ -15,9 +13,6 @@ extern u64 get_system_time();
extern fs::file g_tty;
vm::gvar<s32> sys_prx_version; // ???
vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
extern vm::gvar<u32> g_ppu_exit_mutex;
s64 sys_time_get_system_time()
{
@@ -26,34 +21,16 @@ s64 sys_time_get_system_time()
return get_system_time();
}
void sys_process_exit(ppu_thread& ppu, s32 status)
s64 _sys_process_atexitspawn()
{
sysPrxForUser.warning("sys_process_exit(status=%d)", status);
sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0);
// TODO (process atexit)
return _sys_process_exit(ppu, status, 0, 0);
sysPrxForUser.todo("_sys_process_atexitspawn()");
return CELL_OK;
}
void _sys_process_atexitspawn(vm::ptr<void()> func)
s64 _sys_process_at_Exitspawn()
{
sysPrxForUser.warning("_sys_process_atexitspawn(0x%x)", func);
if (!*g_ppu_atexitspawn)
{
*g_ppu_atexitspawn = func;
}
}
void _sys_process_at_Exitspawn(vm::ptr<void()> func)
{
sysPrxForUser.warning("_sys_process_at_Exitspawn(0x%x)", func);
if (!*g_ppu_at_Exitspawn)
{
*g_ppu_at_Exitspawn = func;
}
sysPrxForUser.todo("_sys_process_at_Exitspawn");
return CELL_OK;
}
s32 sys_process_is_stack(u32 p)
@@ -72,23 +49,24 @@ s32 sys_process_get_paramsfo(vm::ptr<char> buffer)
return _sys_process_get_paramsfo(buffer);
}
s32 sys_get_random_number(vm::ptr<void> addr, u64 size)
s32 sys_get_random_number(vm::ptr<u8> addr, u64 size)
{
sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size);
if (size > 0x1000)
if (size > 4096)
size = 4096;
for (u32 i = 0; i < (u32)size - 1; i++)
{
return CELL_EINVAL;
addr[i] = rand() % 256;
}
switch (u32 rs = sys_ss_random_number_generator(2, addr, size))
{
case 0x80010501: return CELL_ENOMEM;
case 0x80010503: return CELL_EAGAIN;
case 0x80010509: return CELL_EINVAL;
default: if (rs) return CELL_EABORT;
}
return CELL_OK;
}
s32 __sys_look_ctype_table()
{
UNIMPLEMENTED_FUNC(sysPrxForUser);
return CELL_OK;
}
@@ -253,11 +231,10 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
sysPrxForUser_sys_rsxaudio_init();
REG_VAR(sysPrxForUser, sys_prx_version); // 0x7df066cf
REG_VAR(sysPrxForUser, g_ppu_atexitspawn).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_at_Exitspawn).flag(MFF_HIDDEN);
REG_FUNC(sysPrxForUser, sys_time_get_system_time);
// TODO: split syscalls and liblv2 functions
REG_FUNC(sysPrxForUser, sys_process_exit);
REG_FUNC(sysPrxForUser, _sys_process_atexitspawn);
REG_FUNC(sysPrxForUser, _sys_process_at_Exitspawn);
@@ -266,6 +243,8 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
REG_FUNC(sysPrxForUser, sys_get_random_number);
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
REG_FUNC(sysPrxForUser, console_getc);
REG_FUNC(sysPrxForUser, console_putc);
REG_FUNC(sysPrxForUser, console_write);
-5
View File
@@ -52,9 +52,4 @@ error_code sys_lwcond_signal_all(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
error_code sys_lwcond_signal_to(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
error_code sys_lwcond_wait(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
error_code sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname);
error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih);
void sys_ppu_thread_exit(ppu_thread& CPU, u64 val);
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
+114 -119
View File
@@ -2,153 +2,148 @@
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_mutex.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "sysPrxForUser.h"
extern logs::channel sysPrxForUser;
extern vm::gvar<u32> g_ppu_exit_mutex;
extern vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
extern vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
static u32 get_string_array_size(vm::cpptr<char> list, u32& out_count)
void sys_game_process_exitspawn(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
{
//out_count = 0;
u32 result = 8;
std::string _path = path.get_ptr();
const std::string& from = "//";
const std::string& to = "/";
for (u32 i = 0; list; i++)
size_t start_pos = 0;
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
_path.replace(start_pos, from.length(), to);
start_pos += to.length();
}
sysPrxForUser.todo("sys_game_process_exitspawn()");
sysPrxForUser.warning("path: %s", _path.c_str());
sysPrxForUser.warning("argv: 0x%x", argv_addr);
sysPrxForUser.warning("envp: 0x%x", envp_addr);
sysPrxForUser.warning("data: 0x%x", data_addr);
sysPrxForUser.warning("data_size: 0x%x", data_size);
sysPrxForUser.warning("prio: %d", prio);
sysPrxForUser.warning("flags: %d", flags);
std::vector<std::string> argv;
std::vector<std::string> env;
if (argv_addr)
{
if (const vm::cptr<char> str = list[i])
auto argvp = vm::cpptr<char>::make(argv_addr);
while (argvp && *argvp)
{
out_count++;
result += (((u32)std::strlen(str.get_ptr()) + 0x10) & -0x10) + 8;
continue;
argv.push_back(argvp[0].get_ptr());
argvp++;
}
for (auto &arg : argv)
{
sysPrxForUser.trace("argument: %s", arg.c_str());
}
break;
}
return result;
if (envp_addr)
{
auto envp = vm::cpptr<char>::make(envp_addr);
while (envp && *envp)
{
env.push_back(envp[0].get_ptr());
envp++;
}
for (auto &en : env)
{
sysPrxForUser.trace("env_argument: %s", en.c_str());
}
}
// TODO: execute the file in <path> with the args in argv
// and the environment parameters in envp and copy the data
// from data_addr into the adress space of the new process
// then kill the current process
Emu.Pause();
sysPrxForUser.success("Process finished");
Emu.CallAfter([=, path = vfs::get(_path)]()
{
Emu.Stop();
Emu.BootGame(path, true);
});
}
static u32 get_exitspawn_size(vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32& arg_count, u32& env_count)
void sys_game_process_exitspawn2(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
{
arg_count = 1;
env_count = 0;
std::string _path = path.get_ptr();
const std::string& from = "//";
const std::string& to = "/";
u32 result = (((u32)std::strlen(path.get_ptr()) + 0x10) & -0x10) + 8;
result += get_string_array_size(argv, arg_count);
result += get_string_array_size(envp, env_count);
if ((arg_count + env_count) % 2)
{
result += 8;
}
return result;
}
static void put_string_array(vm::pptr<char, u32, u64> pstr, vm::ptr<char>& str, u32 count, vm::cpptr<char> list)
{
for (u32 i = 0; i < count; i++)
{
const u32 len = (u32)std::strlen(list[i].get_ptr());
std::memcpy(str.get_ptr(), list[i].get_ptr(), len + 1);
pstr[i] = str;
str += (len + 0x10) & -0x10;
size_t start_pos = 0;
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
_path.replace(start_pos, from.length(), to);
start_pos += to.length();
}
pstr[count] = vm::null;
}
sysPrxForUser.warning("sys_game_process_exitspawn2()");
sysPrxForUser.warning("path: %s", _path.c_str());
sysPrxForUser.warning("argv: 0x%x", argv_addr);
sysPrxForUser.warning("envp: 0x%x", envp_addr);
sysPrxForUser.warning("data: 0x%x", data_addr);
sysPrxForUser.warning("data_size: 0x%x", data_size);
sysPrxForUser.warning("prio: %d", prio);
sysPrxForUser.warning("flags: %d", flags);
static void put_exitspawn(vm::ptr<void> out, vm::cptr<char> path, u32 argc, vm::cpptr<char> argv, u32 envc, vm::cpptr<char> envp)
{
vm::pptr<char, u32, u64> pstr = vm::cast(out.addr());
vm::ptr<char> str = vm::static_ptr_cast<char>(out) + (argc + envc + (argc + envc) % 2) * 8 + 0x10;
std::vector<std::string> argv;
std::vector<std::string> env;
const u32 len = (u32)std::strlen(path.get_ptr());
std::memcpy(str.get_ptr(), path.get_ptr(), len + 1);
*pstr++ = str;
str += (len + 0x10) & -0x10;
put_string_array(pstr, str, argc - 1, argv);
put_string_array(pstr + argc, str, envc, envp);
}
static void exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 _flags)
{
sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0);
u32 arg_count = 0;
u32 env_count = 0;
u32 alloc_size = get_exitspawn_size(path, argv, envp, arg_count, env_count);
if (alloc_size > 0x1000)
if (argv_addr)
{
argv = vm::null;
envp = vm::null;
arg_count = 0;
env_count = 0;
alloc_size = get_exitspawn_size(path, vm::null, vm::null, arg_count, env_count);
auto argvp = vm::cpptr<char>::make(argv_addr);
while (argvp && *argvp)
{
argv.push_back(argvp[0].get_ptr());
argvp++;
}
for (auto &arg : argv)
{
sysPrxForUser.trace("argument: %s", arg.c_str());
}
}
alloc_size += 0x30;
if (data_size > 0)
if (envp_addr)
{
alloc_size += 0x1030;
auto envp = vm::cpptr<char>::make(envp_addr);
while (envp && *envp)
{
env.push_back(envp[0].get_ptr());
envp++;
}
for (auto &en : env)
{
sysPrxForUser.trace("env_argument: %s", en.c_str());
}
}
u32 alloc_addr = vm::alloc(alloc_size, vm::main);
// TODO: execute the file in <path> with the args in argv
// and the environment parameters in envp and copy the data
// from data_addr into the adress space of the new process
// then kill the current process
if (!alloc_addr)
Emu.Pause();
sysPrxForUser.success("Process finished");
Emu.CallAfter([=, path = vfs::get(_path)]()
{
// TODO (process atexit)
return _sys_process_exit(ppu, CELL_ENOMEM, 0, 0);
}
Emu.Stop();
Emu.BootGame(path, true);
});
put_exitspawn(vm::cast(alloc_addr + 0x30), path, arg_count, argv, env_count, envp);
if (data_size)
{
std::memcpy(vm::base(alloc_addr + alloc_size - 0x1000), vm::base(data), std::min<u32>(data_size, 0x1000));
}
vm::ptr<sys_exit2_param> arg = vm::cast(alloc_addr);
arg->x0 = 0x85;
arg->this_size = 0x30;
arg->next_size = alloc_size - 0x30;
arg->prio = prio;
arg->flags = _flags;
arg->args = vm::cast(alloc_addr + 0x30);
if ((_flags >> 62) == 0 && *g_ppu_atexitspawn)
{
// Execute atexitspawn
g_ppu_atexitspawn->operator()(ppu);
}
if ((_flags >> 62) == 1 && *g_ppu_at_Exitspawn)
{
// Execute at_Exitspawn
g_ppu_at_Exitspawn->operator()(ppu);
}
// TODO (process atexit)
return _sys_process_exit2(ppu, 0, arg, alloc_size, 0x10000000);
}
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
{
sysPrxForUser.warning("sys_game_process_exitspawn(path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", path, argv, envp, data, data_size, prio, flags);
return exitspawn(ppu, path, argv, envp, data, data_size, prio, (flags & 0xf0) | (1ull << 63));
}
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
{
sysPrxForUser.warning("sys_game_process_exitspawn2(path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", path, argv, envp, data, data_size, prio, flags);
return exitspawn(ppu, path, argv, envp, data, data_size, prio, (flags >> 62) >= 2 ? flags & 0xf0 : flags & 0xc0000000000000f0ull);
return;
}
s32 sys_game_board_storage_read()
+1 -1
View File
@@ -16,5 +16,5 @@ void sys_libc_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
DECLARE(ppu_module_manager::sys_libc)("sys_libc", []()
{
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flag(MFF_FORCED_HLE);
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flags = MFF_FORCED_HLE;
});
+43 -184
View File
@@ -72,51 +72,6 @@ static std::string ps3_fmt(ppu_thread& context, vm::cptr<char> fmt, u32 g_count)
return result;
}
static const std::array<s16, 129> s_ctype_table
{
0,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x408,
8, 8, 8, 8,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x18,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0x10, 0x10, 0x10, 0x10, 0x20,
};
s16 __sys_look_ctype_table(s32 ch)
{
sysPrxForUser.trace("__sys_look_ctype_table(ch=%d)", ch);
verify("__sys_look_ctype_table" HERE), ch >= -1 && ch <= 127;
return s_ctype_table[ch + 1];
}
s32 _sys_tolower(s32 ch)
{
sysPrxForUser.trace("_sys_tolower(ch=%d)", ch);
verify("_sys_tolower" HERE), ch >= -1 && ch <= 127;
return s_ctype_table[ch + 1] & 1 ? ch + 0x20 : ch;
}
s32 _sys_toupper(s32 ch)
{
sysPrxForUser.trace("_sys_toupper(ch=%d)", ch);
verify("_sys_toupper" HERE), ch >= -1 && ch <= 127;
return s_ctype_table[ch + 1] & 2 ? ch - 0x20 : ch;
}
vm::ptr<void> _sys_memset(vm::ptr<void> dst, s32 value, u32 size)
{
sysPrxForUser.trace("_sys_memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size);
@@ -135,26 +90,11 @@ vm::ptr<void> _sys_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
return dst;
}
s32 _sys_memcmp(vm::cptr<u8> buf1, vm::cptr<u8> buf2, u32 size)
s32 _sys_memcmp(vm::cptr<void> buf1, vm::cptr<void> buf2, u32 size)
{
sysPrxForUser.trace("_sys_memcmp(buf1=*0x%x, buf2=*0x%x, size=%d)", buf1, buf2, size);
for (u32 i = 0; i < size; i++)
{
const u8 b1 = buf1[i], b2 = buf2[i];
if (b1 < b2)
{
return -1;
}
if (b1 > b2)
{
return 1;
}
}
return 0;
return std::memcmp(buf1.get_ptr(), buf2.get_ptr(), size);
}
vm::ptr<u8> _sys_memchr(vm::ptr<u8> buf, u8 ch, s32 size)
@@ -189,160 +129,82 @@ vm::ptr<void> _sys_memmove(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
return dst;
}
u32 _sys_strlen(vm::cptr<char> str)
s64 _sys_strlen(vm::cptr<char> str)
{
sysPrxForUser.trace("_sys_strlen(str=%s)", str);
if (!str)
{
return 0;
}
for (u32 i = 0;; i++)
{
if (str[i] == '\0')
{
return i;
}
}
return std::strlen(str.get_ptr());
}
s32 _sys_strcmp(vm::cptr<char> str1, vm::cptr<char> str2)
{
sysPrxForUser.trace("_sys_strcmp(str1=%s, str2=%s)", str1, str2);
for (u32 i = 0;; i++)
{
const u8 ch1 = str1[i], ch2 = str2[i];
if (ch1 < ch2)
return -1;
if (ch1 > ch2)
return 1;
if (ch1 == '\0')
return 0;
}
return std::strcmp(str1.get_ptr(), str2.get_ptr());
}
s32 _sys_strncmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 max)
s32 _sys_strncmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 max)
{
sysPrxForUser.trace("_sys_strncmp(str1=%s, str2=%s, max=%d)", str1, str2, max);
for (u32 i = 0; i < max; i++)
{
const u8 ch1 = str1[i], ch2 = str2[i];
if (ch1 < ch2)
return -1;
if (ch1 > ch2)
return 1;
if (ch1 == '\0')
break;
}
return 0;
return std::strncmp(str1.get_ptr(), str2.get_ptr(), max);
}
vm::ptr<char> _sys_strcat(vm::ptr<char> dst, vm::cptr<char> src)
vm::ptr<char> _sys_strcat(vm::ptr<char> dest, vm::cptr<char> source)
{
sysPrxForUser.trace("_sys_strcat(dst=*0x%x %s, src=%s)", dst, dst, src);
sysPrxForUser.trace("_sys_strcat(dest=*0x%x, source=%s)", dest, source);
auto str = dst;
verify(HERE), std::strcat(dest.get_ptr(), source.get_ptr()) == dest.get_ptr();
while (*str)
{
str++;
}
for (u32 i = 0;; i++)
{
if (!(str[i] = src[i]))
{
return dst;
}
}
return dest;
}
vm::cptr<char> _sys_strchr(vm::cptr<char> str, char ch)
vm::cptr<char> _sys_strchr(vm::cptr<char> str, s32 ch)
{
sysPrxForUser.trace("_sys_strchr(str=%s, ch=%d)", str, ch);
sysPrxForUser.trace("_sys_strchr(str=%s, ch=0x%x)", str, ch);
for (u32 i = 0;; i++)
{
const char ch1 = str[i];
if (ch1 == ch)
return str + i;
if (ch1 == '\0')
return vm::null;
}
return vm::cptr<char>::make(vm::get_addr(strchr(str.get_ptr(), ch)));
}
vm::ptr<char> _sys_strncat(vm::ptr<char> dst, vm::cptr<char> src, u32 max)
vm::ptr<char> _sys_strncat(vm::ptr<char> dest, vm::cptr<char> source, u32 len)
{
sysPrxForUser.trace("_sys_strncat(dst=*0x%x %s, src=%s, max=%u)", dst, dst, src, max);
sysPrxForUser.trace("_sys_strncat(dest=*0x%x, source=%s, len=%d)", dest, source, len);
auto str = dst;
verify(HERE), std::strncat(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr();
while (*str)
{
str++;
}
for (u32 i = 0; i < max; i++)
{
if (!(str[i] = src[i]))
{
return dst;
}
}
str[max] = '\0';
return dst;
return dest;
}
vm::ptr<char> _sys_strcpy(vm::ptr<char> dst, vm::cptr<char> src)
vm::ptr<char> _sys_strcpy(vm::ptr<char> dest, vm::cptr<char> source)
{
sysPrxForUser.trace("_sys_strcpy(dst=*0x%x, src=%s)", dst, src);
sysPrxForUser.trace("_sys_strcpy(dest=*0x%x, source=%s)", dest, source);
for (u32 i = 0;; i++)
{
if (!(dst[i] = src[i]))
{
return dst;
}
}
verify(HERE), std::strcpy(dest.get_ptr(), source.get_ptr()) == dest.get_ptr();
return dest;
}
vm::ptr<char> _sys_strncpy(vm::ptr<char> dst, vm::cptr<char> src, s32 len)
vm::ptr<char> _sys_strncpy(vm::ptr<char> dest, vm::cptr<char> source, u32 len)
{
sysPrxForUser.trace("_sys_strncpy(dst=*0x%x %s, src=%s, len=%d)", dst, dst, src, len);
sysPrxForUser.trace("_sys_strncpy(dest=*0x%x, source=%s, len=%d)", dest, source, len);
if (!dst || !src)
if (!dest || !source)
{
return vm::null;
}
for (s32 i = 0; i < len; i++)
{
if (!(dst[i] = src[i]))
{
for (++i; i < len; i++)
{
dst[i] = '\0';
}
verify(HERE), std::strncpy(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr();
return dst;
}
}
return dst;
return dest;
}
s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 n)
s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 n)
{
sysPrxForUser.trace("_sys_strncasecmp(str1=%s, str2=%s, n=%d)", str1, str2, n);
for (u32 i = 0; i < n; i++)
{
const int ch1 = _sys_tolower(str1[i]), ch2 = _sys_tolower(str2[i]);
const int ch1 = tolower(str1[i]), ch2 = tolower(str2[i]);
if (ch1 < ch2)
return -1;
if (ch1 > ch2)
@@ -353,22 +215,21 @@ s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 n)
return 0;
}
vm::cptr<char> _sys_strrchr(vm::cptr<char> str, char ch)
vm::ptr<char> _sys_strrchr(vm::cptr<char> str, s32 character)
{
sysPrxForUser.trace("_sys_strrchr(str=%s, ch=%d)", str, ch);
sysPrxForUser.trace("_sys_strrchr(str=%s, character=%c)", str, (char)character);
vm::cptr<char> res = vm::null;
return vm::ptr<char>::make(vm::get_addr(strrchr(str.get_ptr(), character)));
}
for (u32 i = 0;; i++)
{
const char ch1 = str[i];
if (ch1 == ch)
res = str + i;
if (ch1 == '\0')
break;
}
s32 _sys_tolower()
{
fmt::throw_exception("Unimplemented" HERE);
}
return res;
s32 _sys_toupper()
{
fmt::throw_exception("Unimplemented" HERE);
}
u32 _sys_malloc(u32 size)
@@ -459,10 +320,6 @@ s32 _sys_qsort()
void sysPrxForUser_sys_libc_init()
{
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
REG_FUNC(sysPrxForUser, _sys_tolower);
REG_FUNC(sysPrxForUser, _sys_toupper);
REG_FUNC(sysPrxForUser, _sys_memset);
REG_FUNC(sysPrxForUser, _sys_memcpy);
REG_FUNC(sysPrxForUser, _sys_memcmp);
@@ -479,6 +336,8 @@ void sysPrxForUser_sys_libc_init()
REG_FUNC(sysPrxForUser, _sys_strncpy);
REG_FUNC(sysPrxForUser, _sys_strncasecmp);
REG_FUNC(sysPrxForUser, _sys_strrchr);
REG_FUNC(sysPrxForUser, _sys_tolower);
REG_FUNC(sysPrxForUser, _sys_toupper);
REG_FUNC(sysPrxForUser, _sys_malloc);
REG_FUNC(sysPrxForUser, _sys_memalign);
File diff suppressed because it is too large Load Diff
+245
View File
@@ -0,0 +1,245 @@
#if defined(__FreeBSD__)
#include <sys/select.h>
#undef fds_bits
#endif
#pragma once
namespace vm { using namespace ps3; }
namespace sys_net
{
// It turns out SOL_SOCKET is equal to 1 on Linux, but 0xffff on Windows, and it appears the PS3 uses 0xffff, like Windows
#define PS3_SOL_SOCKET 0xffff
// Error codes
enum
{
SYS_NET_ENOENT = 2,
SYS_NET_EINTR = 4,
SYS_NET_EBADF = 9,
SYS_NET_ENOMEM = 12,
SYS_NET_EACCES = 13,
SYS_NET_EFAULT = 14,
SYS_NET_EBUSY = 16,
SYS_NET_EINVAL = 22,
SYS_NET_EMFILE = 24,
SYS_NET_ENOSPC = 28,
SYS_NET_EPIPE = 32,
SYS_NET_EAGAIN = 35,
SYS_NET_EWOULDBLOCK = SYS_NET_EAGAIN,
SYS_NET_EINPROGRESS = 36,
SYS_NET_EALREADY = 37,
SYS_NET_EDESTADDRREQ = 39,
SYS_NET_EMSGSIZE = 40,
SYS_NET_EPROTOTYPE = 41,
SYS_NET_ENOPROTOOPT = 42,
SYS_NET_EPROTONOSUPPORT = 43,
SYS_NET_EOPNOTSUPP = 45,
SYS_NET_EPFNOSUPPORT = 46,
SYS_NET_EAFNOSUPPORT = 47,
SYS_NET_EADDRINUSE = 48,
SYS_NET_EADDRNOTAVAIL = 49,
SYS_NET_ENETDOWN = 50,
SYS_NET_ENETUNREACH = 51,
SYS_NET_ECONNABORTED = 53,
SYS_NET_ECONNRESET = 54,
SYS_NET_ENOBUFS = 55,
SYS_NET_EISCONN = 56,
SYS_NET_ENOTCONN = 57,
SYS_NET_ESHUTDOWN = 58,
SYS_NET_ETOOMANYREFS = 59,
SYS_NET_ETIMEDOUT = 60,
SYS_NET_ECONNREFUSED = 61,
SYS_NET_EHOSTDOWN = 64,
SYS_NET_EHOSTUNREACH = 65,
};
// Socket types
enum
{
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_DGRAM_P2P = 6,
SOCK_STREAM_P2P = 10,
};
// Socket options
// Note: All options are prefixed with "OP_" to prevent name conflicts.
enum
{
OP_SO_SNDBUF = 0x1001,
OP_SO_RCVBUF = 0x1002,
OP_SO_SNDLOWAT = 0x1003,
OP_SO_RCVLOWAT = 0x1004,
OP_SO_SNDTIMEO = 0x1005,
OP_SO_RCVTIMEO = 0x1006,
OP_SO_ERROR = 0x1007,
OP_SO_TYPE = 0x1008,
OP_SO_NBIO = 0x1100, // Non-blocking IO
OP_SO_TPPOLICY = 0x1101,
OP_SO_REUSEADDR = 0x0004,
OP_SO_KEEPALIVE = 0x0008,
OP_SO_BROADCAST = 0x0020,
OP_SO_LINGER = 0x0080,
OP_SO_OOBINLINE = 0x0100,
OP_SO_REUSEPORT = 0x0200,
OP_SO_ONESBCAST = 0x0800,
OP_SO_USECRYPTO = 0x1000,
OP_SO_USESIGNATURE = 0x2000,
};
// TCP options
enum
{
OP_TCP_NODELAY = 1,
OP_TCP_MAXSEG = 2,
OP_TCP_MSS_TO_ADVERTISE = 3,
};
// IP protocols
// Note: Proctols are prefixed with "PROTO_" to prevent name conflicts
enum
{
PROTO_IPPROTO_IP = 0,
PROTO_IPPROTO_ICMP = 1,
PROTO_IPPROTO_IGMP = 2,
PROTO_IPPROTO_TCP = 6,
PROTO_IPPROTO_UDP = 17,
PROTO_IPPROTO_ICMPV6 = 58,
};
// only for reference, no need to use it
using in_addr_t = u32;
using in_port_t = u16;
using sa_family_t = u8;
using socklen_t = u32;
struct fd_set
{
be_t<u32> fds_bits[32];
};
struct hostent
{
vm::bptr<char> h_name;
vm::bpptr<char> h_aliases;
be_t<s32> h_addrtype;
be_t<s32> h_length;
vm::bpptr<char> h_addr_list;
};
struct in_addr
{
be_t<u32> s_addr;
};
struct iovec
{
be_t<s32> zero1;
vm::bptr<void> iov_base;
be_t<s32> zero2;
be_t<u32> iov_len;
};
struct ip_mreq
{
be_t<u32> imr_multiaddr;
be_t<u32> imr_interface;
};
struct msghdr
{
be_t<s32> zero1;
vm::bptr<void> msg_name;
be_t<u32> msg_namelen;
be_t<s32> pad1;
be_t<s32> zero2;
vm::bptr<iovec> msg_iov;
be_t<s32> msg_iovlen;
be_t<s32> pad2;
be_t<s32> zero3;
vm::bptr<void> msg_control;
be_t<u32> msg_controllen;
be_t<s32> msg_flags;
};
struct pollfd
{
be_t<s32> fd;
be_t<s16> events;
be_t<s16> revents;
};
struct sockaddr
{
u8 sa_len;
u8 sa_family;
char sa_data[14];
};
struct sockaddr_dl
{
u8 sdl_len;
u8 sdl_family;
be_t<u16> sdl_index;
u8 sdl_type;
u8 sdl_nlen;
u8 sdl_alen;
u8 sdl_slen;
char sdl_data[12];
};
struct sockaddr_in
{
u8 sin_len;
u8 sin_family;
be_t<u16> sin_port;
be_t<u32> sin_addr;
char sin_zero[8];
};
struct sockaddr_in_p2p
{
u8 sin_len;
u8 sin_family;
be_t<u16> sin_port;
be_t<u32> sin_addr;
be_t<u16> sin_vport;
char sin_zero[6];
};
struct timeval
{
be_t<s64> tv_sec;
be_t<s64> tv_usec;
};
struct sys_net_sockinfo_t
{
be_t<s32> s;
be_t<s32> proto;
be_t<s32> recv_queue_length;
be_t<s32> send_queue_length;
in_addr local_adr;
be_t<s32> local_port;
in_addr remote_adr;
be_t<s32> remote_port;
be_t<s32> state;
};
}
struct sys_net_initialize_parameter_t
{
vm::bptr<void> memory;
be_t<s32> memory_size;
be_t<s32> flags;
};
// PS3 libnet socket struct
struct net_socket_t
{
std::intptr_t native_handle;
};
-737
View File
@@ -1,737 +0,0 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
#include "sys_net_.h"
namespace vm { using namespace ps3; }
logs::channel libnet("libnet");
struct sys_net_tls_data
{
be_t<s32> _errno;
be_t<s32> _h_errno;
char addr[16];
};
// TODO
thread_local vm::ptr<sys_net_tls_data> g_tls_net_data{};
static NEVER_INLINE vm::ptr<sys_net_tls_data> get_tls()
{
// Allocate if not initialized
if (!g_tls_net_data)
{
g_tls_net_data.set(vm::alloc(sizeof(decltype(g_tls_net_data)::type), vm::main));
// Initial values
g_tls_net_data->_errno = SYS_NET_EBUSY;
thread_ctrl::atexit([addr = g_tls_net_data.addr()]
{
vm::dealloc_verbose_nothrow(addr, vm::main);
});
}
return g_tls_net_data;
}
s32 sys_net_accept(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
libnet.todo("accept(s=%d, addr=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
return 0;
}
s32 sys_net_bind(s32 s, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
{
libnet.todo("bind(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
return 0;
}
s32 sys_net_connect(s32 s, vm::ptr<sys_net_sockaddr> addr, u32 addrlen)
{
libnet.todo("connect(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
return 0;
}
s32 sys_net_gethostbyaddr()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_gethostbyname()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_getpeername(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_getsockname(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_getsockopt(s32 s, s32 level, s32 optname, vm::ptr<void> optval, vm::ptr<u32> optlen)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
u32 sys_net_inet_addr(vm::cptr<char> cp)
{
libnet.todo("inet_addr(cp=%s)", cp);
return 0xffffffff;
}
s32 sys_net_inet_aton()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_lnaof()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_makeaddr()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_netof()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_network()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
vm::ptr<char> sys_net_inet_ntoa(u32 in)
{
libnet.todo("inet_ntoa(in=0x%x)", in);
return vm::null;
}
vm::cptr<char> sys_net_inet_ntop(s32 af, vm::ptr<void> src, vm::ptr<char> dst, u32 size)
{
libnet.todo("inet_ntop(af=%d, src=%s, dst=*0x%x, size=%d)", af, src, dst, size);
return vm::null;
}
s32 sys_net_inet_pton(s32 af, vm::cptr<char> src, vm::ptr<char> dst)
{
libnet.todo("inet_pton(af=%d, src=%s, dst=*0x%x)", af, src, dst);
return 0;
}
s32 sys_net_listen(s32 s, s32 backlog)
{
libnet.todo("listen(s=%d, backlog=%d)", s, backlog);
return 0;
}
s32 sys_net_recv(s32 s, vm::ptr<void> buf, u32 len, s32 flags)
{
libnet.todo("recv(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
return 0;
}
s32 sys_net_recvfrom(s32 s, vm::ptr<void> buf, u32 len, s32 flags, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
libnet.todo("recvfrom(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, paddrlen=*0x%x)", s, buf, len, flags, addr, paddrlen);
return 0;
}
s32 sys_net_recvmsg(s32 s, vm::ptr<sys_net_msghdr> msg, s32 flags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_send(s32 s, vm::cptr<void> buf, u32 len, s32 flags)
{
libnet.todo("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
return 0;
}
s32 sys_net_sendmsg(s32 s, vm::cptr<sys_net_msghdr> msg, s32 flags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_sendto(s32 s, vm::cptr<void> buf, u32 len, s32 flags, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
{
libnet.todo("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen);
return 0;
}
s32 sys_net_setsockopt(s32 s, s32 level, s32 optname, vm::cptr<void> optval, u32 optlen)
{
libnet.todo("setsockopt(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen);
return 0;
}
s32 sys_net_shutdown(s32 s, s32 how)
{
libnet.todo("shutdown(s=%d, how=%d)", s, how);
return 0;
}
s32 sys_net_socket(s32 family, s32 type, s32 protocol)
{
libnet.todo("socket(family=%d, type=%d, protocol=%d)", family, type, protocol);
return 0;
}
s32 sys_net_socketclose(s32 s)
{
libnet.warning("socketclose(s=%d)", s);
return 0;
}
s32 sys_net_socketpoll(vm::ptr<sys_net_pollfd> fds, s32 nfds, s32 ms)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_socketselect(s32 nfds, vm::ptr<sys_net_fd_set> readfds, vm::ptr<sys_net_fd_set> writefds, vm::ptr<sys_net_fd_set> exceptfds, vm::ptr<sys_net_timeval> timeout)
{
libnet.todo("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x)", nfds, readfds, writefds, exceptfds, timeout);
return 0;
}
s32 sys_net_initialize_network_ex(vm::ptr<sys_net_initialize_parameter_t> param)
{
libnet.todo("sys_net_initialize_network_ex(param=*0x%x)", param);
return CELL_OK;
}
s32 sys_net_get_udpp2p_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_set_udpp2p_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_lib_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_if_ctl()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_if_list()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_netemu_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_routing_table_af()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_sockinfo(s32 s, vm::ptr<sys_net_sockinfo_t> p, s32 n)
{
libnet.todo("sys_net_get_sockinfo(s=%d, p=*0x%x, n=%d)", s, p, n);
return CELL_OK;
}
s32 sys_net_close_dump(s32 id, vm::ptr<s32> pflags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_set_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_show_nameserver()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
vm::ptr<s32> _sys_net_errno_loc()
{
libnet.warning("_sys_net_errno_loc()");
return get_tls().ptr(&sys_net_tls_data::_errno);
}
s32 sys_net_set_resolver_configurations()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_show_route()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_read_dump(s32 id, vm::ptr<void> buf, s32 len, vm::ptr<s32> pflags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_abort_resolver()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_abort_socket()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_set_lib_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_sockinfo_ex()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_open_dump(s32 len, s32 flags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_show_ifconfig()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_finalize_network()
{
libnet.todo("sys_net_finalize_network()");
return CELL_OK;
}
vm::ptr<s32> _sys_net_h_errno_loc()
{
libnet.warning("_sys_net_h_errno_loc()");
return get_tls().ptr(&sys_net_tls_data::_h_errno);
}
s32 sys_net_set_netemu_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_free_thread_context(u64 tid, s32 flags)
{
libnet.todo("sys_net_free_thread_context(tid=0x%x, flags=%d)", tid, flags);
return CELL_OK;
}
s32 _sys_net_lib_abort()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_bnet_control()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 __sys_net_lib_calloc()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_free()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_get_system_time()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_if_nametoindex()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_ioctl()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 __sys_net_lib_malloc()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_rand()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 __sys_net_lib_realloc()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_reset_libnetctl_queue()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_set_libnetctl_queue()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_thread_create()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_thread_exit()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_thread_join()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_clear()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_create()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_destroy()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_signal()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_wait()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sysctl()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_usleep()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_abort()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_close()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_get_if_id()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_get_status()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_if_down()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_get_key_value()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_if_up()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_open()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_get_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_add_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_add_name_server_with_char()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_flush_route()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_set_default_gateway()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_set_ip_and_mask()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_set_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
DECLARE(ppu_module_manager::sys_net)("sys_net", []()
{
REG_FNID(sys_net, "accept", sys_net_accept);
REG_FNID(sys_net, "bind", sys_net_bind);
REG_FNID(sys_net, "connect", sys_net_connect);
REG_FNID(sys_net, "gethostbyaddr", sys_net_gethostbyaddr);
REG_FNID(sys_net, "gethostbyname", sys_net_gethostbyname);
REG_FNID(sys_net, "getpeername", sys_net_getpeername);
REG_FNID(sys_net, "getsockname", sys_net_getsockname);
REG_FNID(sys_net, "getsockopt", sys_net_getsockopt);
REG_FNID(sys_net, "inet_addr", sys_net_inet_addr);
REG_FNID(sys_net, "inet_aton", sys_net_inet_aton);
REG_FNID(sys_net, "inet_lnaof", sys_net_inet_lnaof);
REG_FNID(sys_net, "inet_makeaddr", sys_net_inet_makeaddr);
REG_FNID(sys_net, "inet_netof", sys_net_inet_netof);
REG_FNID(sys_net, "inet_network", sys_net_inet_network);
REG_FNID(sys_net, "inet_ntoa", sys_net_inet_ntoa);
REG_FNID(sys_net, "inet_ntop", sys_net_inet_ntop);
REG_FNID(sys_net, "inet_pton", sys_net_inet_pton);
REG_FNID(sys_net, "listen", sys_net_listen);
REG_FNID(sys_net, "recv", sys_net_recv);
REG_FNID(sys_net, "recvfrom", sys_net_recvfrom);
REG_FNID(sys_net, "recvmsg", sys_net_recvmsg);
REG_FNID(sys_net, "send", sys_net_send);
REG_FNID(sys_net, "sendmsg", sys_net_sendmsg);
REG_FNID(sys_net, "sendto", sys_net_sendto);
REG_FNID(sys_net, "setsockopt", sys_net_setsockopt);
REG_FNID(sys_net, "shutdown", sys_net_shutdown);
REG_FNID(sys_net, "socket", sys_net_socket);
REG_FNID(sys_net, "socketclose", sys_net_socketclose);
REG_FNID(sys_net, "socketpoll", sys_net_socketpoll);
REG_FNID(sys_net, "socketselect", sys_net_socketselect);
REG_FUNC(sys_net, sys_net_initialize_network_ex);
REG_FUNC(sys_net, sys_net_get_udpp2p_test_param);
REG_FUNC(sys_net, sys_net_set_udpp2p_test_param);
REG_FUNC(sys_net, sys_net_get_lib_name_server);
REG_FUNC(sys_net, sys_net_if_ctl);
REG_FUNC(sys_net, sys_net_get_if_list);
REG_FUNC(sys_net, sys_net_get_name_server);
REG_FUNC(sys_net, sys_net_get_netemu_test_param);
REG_FUNC(sys_net, sys_net_get_routing_table_af);
REG_FUNC(sys_net, sys_net_get_sockinfo);
REG_FUNC(sys_net, sys_net_close_dump);
REG_FUNC(sys_net, sys_net_set_test_param);
REG_FUNC(sys_net, sys_net_show_nameserver);
REG_FUNC(sys_net, _sys_net_errno_loc);
REG_FUNC(sys_net, sys_net_set_resolver_configurations);
REG_FUNC(sys_net, sys_net_show_route);
REG_FUNC(sys_net, sys_net_read_dump);
REG_FUNC(sys_net, sys_net_abort_resolver);
REG_FUNC(sys_net, sys_net_abort_socket);
REG_FUNC(sys_net, sys_net_set_lib_name_server);
REG_FUNC(sys_net, sys_net_get_test_param);
REG_FUNC(sys_net, sys_net_get_sockinfo_ex);
REG_FUNC(sys_net, sys_net_open_dump);
REG_FUNC(sys_net, sys_net_show_ifconfig);
REG_FUNC(sys_net, sys_net_finalize_network);
REG_FUNC(sys_net, _sys_net_h_errno_loc);
REG_FUNC(sys_net, sys_net_set_netemu_test_param);
REG_FUNC(sys_net, sys_net_free_thread_context);
REG_FUNC(sys_net, _sys_net_lib_abort);
REG_FUNC(sys_net, _sys_net_lib_bnet_control);
REG_FUNC(sys_net, __sys_net_lib_calloc);
REG_FUNC(sys_net, _sys_net_lib_free);
REG_FUNC(sys_net, _sys_net_lib_get_system_time);
REG_FUNC(sys_net, _sys_net_lib_if_nametoindex);
REG_FUNC(sys_net, _sys_net_lib_ioctl);
REG_FUNC(sys_net, __sys_net_lib_malloc);
REG_FUNC(sys_net, _sys_net_lib_rand);
REG_FUNC(sys_net, __sys_net_lib_realloc);
REG_FUNC(sys_net, _sys_net_lib_reset_libnetctl_queue);
REG_FUNC(sys_net, _sys_net_lib_set_libnetctl_queue);
REG_FUNC(sys_net, _sys_net_lib_thread_create);
REG_FUNC(sys_net, _sys_net_lib_thread_exit);
REG_FUNC(sys_net, _sys_net_lib_thread_join);
REG_FUNC(sys_net, _sys_net_lib_sync_clear);
REG_FUNC(sys_net, _sys_net_lib_sync_create);
REG_FUNC(sys_net, _sys_net_lib_sync_destroy);
REG_FUNC(sys_net, _sys_net_lib_sync_signal);
REG_FUNC(sys_net, _sys_net_lib_sync_wait);
REG_FUNC(sys_net, _sys_net_lib_sysctl);
REG_FUNC(sys_net, _sys_net_lib_usleep);
REG_FUNC(sys_net, sys_netset_abort);
REG_FUNC(sys_net, sys_netset_close);
REG_FUNC(sys_net, sys_netset_get_if_id);
REG_FUNC(sys_net, sys_netset_get_key_value);
REG_FUNC(sys_net, sys_netset_get_status);
REG_FUNC(sys_net, sys_netset_if_down);
REG_FUNC(sys_net, sys_netset_if_up);
REG_FUNC(sys_net, sys_netset_open);
REG_FUNC(sys_net, _sce_net_add_name_server);
REG_FUNC(sys_net, _sce_net_add_name_server_with_char);
REG_FUNC(sys_net, _sce_net_flush_route);
REG_FUNC(sys_net, _sce_net_get_name_server);
REG_FUNC(sys_net, _sce_net_set_default_gateway);
REG_FUNC(sys_net, _sce_net_set_ip_and_mask);
REG_FUNC(sys_net, _sce_net_set_name_server);
});
-41
View File
@@ -1,41 +0,0 @@
#pragma once
#include "Emu/Cell/lv2/sys_net.h"
#include "Emu/Memory/vm.h"
struct sys_net_sockinfo_t
{
be_t<s32> s;
be_t<s32> proto;
be_t<s32> recv_queue_length;
be_t<s32> send_queue_length;
sys_net_in_addr local_adr;
be_t<s32> local_port;
sys_net_in_addr remote_adr;
be_t<s32> remote_port;
be_t<s32> state;
};
struct sys_net_sockinfo_ex_t
{
be_t<s32> s;
be_t<s32> proto;
be_t<s32> recv_queue_length;
be_t<s32> send_queue_length;
sys_net_in_addr local_adr;
be_t<s32> local_port;
sys_net_in_addr remote_adr;
be_t<s32> remote_port;
be_t<s32> state;
be_t<s32> socket_type;
be_t<s32> local_vport;
be_t<s32> remote_vport;
be_t<s32> reserved[8];
};
struct sys_net_initialize_parameter_t
{
vm::ps3::bptr<void> memory;
be_t<s32> memory_size;
be_t<s32> flags;
};
+5 -11
View File
@@ -13,7 +13,6 @@ extern logs::channel sysPrxForUser;
vm::gvar<sys_lwmutex_t> g_ppu_atexit_lwm;
vm::gvar<vm::ptr<void()>[8]> g_ppu_atexit;
vm::gvar<u32> g_ppu_exit_mutex; // sys_process_exit2 mutex
vm::gvar<u32> g_ppu_once_mutex;
vm::gvar<sys_lwmutex_t> g_ppu_prx_lwm;
@@ -113,10 +112,6 @@ void sys_initialize_tls(ppu_thread& ppu, u64 main_thread_id, u32 tls_seg_addr, u
attr->name_u64 = "_lv2ppu\0"_u64;
sys_mutex_create(g_ppu_once_mutex, attr);
attr->recursive = SYS_SYNC_RECURSIVE;
attr->name_u64 = "_lv2tls\0"_u64;
sys_mutex_create(g_ppu_exit_mutex, attr);
lwa->protocol = SYS_SYNC_PRIORITY;
lwa->recursive = SYS_SYNC_RECURSIVE;
lwa->name_u64 = "_lv2prx\0"_u64;
@@ -271,13 +266,12 @@ error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih)
void sysPrxForUser_sys_ppu_thread_init()
{
// Private
REG_VAR(sysPrxForUser, g_ppu_atexit_lwm).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_once_mutex).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_atexit).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_prx_lwm).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_exit_mutex).flag(MFF_HIDDEN);
REG_VNID(sysPrxForUser, 0x00000000u, g_ppu_atexit_lwm);
REG_VNID(sysPrxForUser, 0x00000001u, g_ppu_once_mutex);
REG_VNID(sysPrxForUser, 0x00000002u, g_ppu_atexit);
REG_VNID(sysPrxForUser, 0x00000003u, g_ppu_prx_lwm);
REG_FUNC(sysPrxForUser, sys_initialize_tls).args = {"main_thread_id", "tls_seg_addr", "tls_seg_size", "tls_mem_size"}; // Test
REG_FUNC(sysPrxForUser, sys_initialize_tls);
REG_FUNC(sysPrxForUser, sys_ppu_thread_create);
REG_FUNC(sysPrxForUser, sys_ppu_thread_get_id);
REG_FUNC(sysPrxForUser, sys_ppu_thread_exit);
File diff suppressed because it is too large Load Diff
-747
View File
@@ -6,7 +6,6 @@
#include "Utilities/bit_set.h"
#include "Utilities/BEType.h"
#include "PPUOpcodes.h"
// PPU Function Attributes
enum class ppu_attr : u32
@@ -51,7 +50,6 @@ struct ppu_segment
u32 size;
u32 type;
u32 flags;
u32 filesz;
};
// PPU Module Information
@@ -64,16 +62,6 @@ struct ppu_module
std::vector<ppu_segment> secs;
std::vector<ppu_function> funcs;
// Copy info without functions
void copy_part(const ppu_module& info)
{
name = info.name;
path = info.path;
relocs = info.relocs;
segs = info.segs;
secs = info.secs;
}
void analyse(u32 lib_toc, u32 entry);
void validate(u32 reloc);
};
@@ -942,738 +930,3 @@ struct ppu_iname
return value;
}
};
// PPU Analyser Context
struct ppu_acontext
{
// General-purpose register range
struct spec_gpr
{
// Integral range: normalized undef = (0;UINT64_MAX), unnormalized undefs are possible (when max = min - 1)
// Bit range: constant 0 = (0;0), constant 1 = (1;1), normalized undef = (0;1), unnormalized undef = (1;0)
u64 imin = 0; // Integral range begin
u64 imax = -1; // Integral range end
u64 bmin = 0; // Bit range begin
u64 bmax = -1; // Bit range end
void set_undef()
{
imin = 0;
imax = -1;
bmin = 0;
bmax = -1;
}
// (Number of possible values - 1), 0 = const
u64 div() const
{
return imax - imin;
}
// Return zero bits for zeros, ones for ones or undefs
u64 mask() const
{
return bmin | bmax;
}
// Return one bits for ones, zeros for zeros or undefs
u64 ones() const
{
return bmin & bmax;
}
// Return one bits for undefs
u64 undefs() const
{
return bmin ^ bmax;
}
// Return number of trailing zero bits
u64 tz() const
{
return ::cnttz64(mask());
}
// Range NOT
spec_gpr operator ~() const
{
spec_gpr r;
r.imin = ~imax;
r.imax = ~imin;
r.bmin = ~bmax;
r.bmax = ~bmin;
return r;
}
// Range ADD
spec_gpr operator +(const spec_gpr& rhs) const
{
spec_gpr r{};
const u64 adiv = div();
const u64 bdiv = rhs.div();
// Check overflow, generate normalized range
if (adiv != -1 && bdiv != -1 && adiv <= adiv + bdiv)
{
r = range(imin + rhs.imin, imax + rhs.imax);
}
// Carry for bitrange computation
u64 cmin = 0;
u64 cmax = 0;
const u64 amask = mask();
const u64 bmask = rhs.mask();
const u64 aones = ones();
const u64 bones = rhs.ones();
for (u32 i = 0; i < 64; i++)
{
cmin += ((amask >> i) & 1) + ((bmask >> i) & 1);
cmax += ((aones >> i) & 1) + ((bones >> i) & 1);
// Discover some constant bits
if (cmin == cmax)
{
r.bmin |= (cmin & 1) << i;
r.bmax &= ~((~cmin & 1) << i);
}
cmin >>= 1;
cmax >>= 1;
}
return r;
}
// Range AND
spec_gpr operator &(const spec_gpr& rhs) const
{
// Ignore inverted ranges (TODO)
if (imin > imax || rhs.imin > rhs.imax)
{
return approx(ones() & rhs.ones(), mask() & rhs.mask());
}
// Const (TODO: remove when unnecessary)
if (imin == imax && rhs.imin == rhs.imax)
{
return fixed(imin & rhs.imin);
}
// Swap (TODO: remove when unnecessary)
if (imin == imax || rhs.undefs() > undefs())
{
return rhs & *this;
}
// Copy and attempt to partially preserve integral range
spec_gpr r = *this;
for (u32 i = 63; ~i; i--)
{
const u64 m = 1ull << i;
if (!(rhs.mask() & m))
{
if (r.undefs() & m)
{
// undef -> 0
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin &= ~m;
r.imax &= ~m;
}
else if (r.ones() & m)
{
// 1 -> 0
if ((r.imin ^ r.imax) > (m - 1))
{
r.imin &= ~(m - 1);
r.imax |= (m - 1);
}
r.imin &= ~m;
r.imax &= ~m;
}
}
else if (rhs.undefs() & m)
{
// -> undef
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin &= ~m;
r.imax |= m;
}
}
r.bmin = ones() & rhs.ones();
r.bmax = mask() & rhs.mask();
return r;
}
// Range OR
spec_gpr operator |(const spec_gpr& rhs) const
{
// Ignore inverted ranges (TODO)
if (imin > imax || rhs.imin > rhs.imax)
{
return approx(ones() | rhs.ones(), mask() | rhs.mask());
}
// Const (TODO: remove when unnecessary)
if (imin == imax && rhs.imin == rhs.imax)
{
return fixed(imin | rhs.imin);
}
// Swap (TODO: remove when unnecessary)
if (imin == imax || rhs.undefs() > undefs())
{
return rhs | *this;
}
// Copy and attempt to partially preserve integral range
spec_gpr r = *this;
for (u32 i = 63; ~i; i--)
{
const u64 m = 1ull << i;
if (rhs.ones() & m)
{
if (r.undefs() & m)
{
// undef -> 1
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin |= m;
r.imax |= m;
}
else if (!(r.mask() & m))
{
// 0 -> 1
if ((r.imin ^ r.imax) > (m - 1))
{
r.imin &= ~(m - 1);
r.imax |= (m - 1);
}
r.imin |= m;
r.imax |= m;
}
}
else if (rhs.undefs() & m)
{
// -> undef
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin &= ~m;
r.imax |= m;
}
}
r.bmin = ones() | rhs.ones();
r.bmax = mask() | rhs.mask();
return r;
}
// Range XOR
spec_gpr operator ^(const spec_gpr& rhs)
{
return (~*this & rhs) | (*this & ~rhs);
}
// Check whether the value is in range
bool test(u64 value) const
{
if (imin <= imax)
{
if (value < imin || value > imax)
{
return false;
}
}
else
{
if (value < imin && value > imax)
{
return false;
}
}
if ((value & mask()) != value)
{
return false;
}
if ((value | ones()) != value)
{
return false;
}
return true;
}
// Constant value
static spec_gpr fixed(u64 value)
{
spec_gpr r;
r.imin = value;
r.imax = value;
r.bmin = value;
r.bmax = value;
return r;
}
// Range (tz = number of constant trailing zeros)
static spec_gpr range(u64 min, u64 max, u64 tz = 0)
{
const u64 mask = tz < 64 ? ~0ull << tz : 0ull;
spec_gpr r;
r.bmin = 0;
r.bmax = mask;
// Normalize min/max for tz (TODO)
if (min < max)
{
// Inverted constant MSB mask
const u64 mix = ~0ull >> ::cntlz64(min ^ max, true);
r.bmin |= min & ~mix;
r.bmax &= max | mix;
r.imin = (min + ~mask) & mask;
r.imax = max & mask;
verify("Impossible range" HERE), r.imin <= r.imax;
}
else
{
r.imin = min & mask;
r.imax = (max + ~mask) & mask;
verify("Impossible range" HERE), r.imin >= r.imax;
}
// Fix const values
if (r.imin == r.imax)
{
r.bmin = r.imin;
r.bmax = r.imax;
}
return r;
}
// Make from bitrange (normalize, approximate range values)
static spec_gpr approx(u64 bmin, u64 bmax)
{
spec_gpr r;
r.imin = bmin & ~(bmin ^ bmax);
r.imax = bmax | (bmin ^ bmax);
r.bmin = bmin & ~(bmin ^ bmax);
r.bmax = bmax | (bmin ^ bmax);
return r;
}
} gpr[32]{};
// Vector registers (draft)
struct spec_vec
{
u8 imin8[16]{};
u8 imax8[16]{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
u16 imin16[8]{};
u16 imax16[8]{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
u32 imin32[4]{};
u32 imax32[4]{0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu};
u64 bmin64[2]{};
u64 bmax64[2]{0xffffffffffffffffull, 0xffffffffffffffffull};
};
// Info
u32 cia;
// Analyser step
void UNK(ppu_opcode_t);
void MFVSCR(ppu_opcode_t);
void MTVSCR(ppu_opcode_t);
void VADDCUW(ppu_opcode_t);
void VADDFP(ppu_opcode_t);
void VADDSBS(ppu_opcode_t);
void VADDSHS(ppu_opcode_t);
void VADDSWS(ppu_opcode_t);
void VADDUBM(ppu_opcode_t);
void VADDUBS(ppu_opcode_t);
void VADDUHM(ppu_opcode_t);
void VADDUHS(ppu_opcode_t);
void VADDUWM(ppu_opcode_t);
void VADDUWS(ppu_opcode_t);
void VAND(ppu_opcode_t);
void VANDC(ppu_opcode_t);
void VAVGSB(ppu_opcode_t);
void VAVGSH(ppu_opcode_t);
void VAVGSW(ppu_opcode_t);
void VAVGUB(ppu_opcode_t);
void VAVGUH(ppu_opcode_t);
void VAVGUW(ppu_opcode_t);
void VCFSX(ppu_opcode_t);
void VCFUX(ppu_opcode_t);
void VCMPBFP(ppu_opcode_t);
void VCMPEQFP(ppu_opcode_t);
void VCMPEQUB(ppu_opcode_t);
void VCMPEQUH(ppu_opcode_t);
void VCMPEQUW(ppu_opcode_t);
void VCMPGEFP(ppu_opcode_t);
void VCMPGTFP(ppu_opcode_t);
void VCMPGTSB(ppu_opcode_t);
void VCMPGTSH(ppu_opcode_t);
void VCMPGTSW(ppu_opcode_t);
void VCMPGTUB(ppu_opcode_t);
void VCMPGTUH(ppu_opcode_t);
void VCMPGTUW(ppu_opcode_t);
void VCTSXS(ppu_opcode_t);
void VCTUXS(ppu_opcode_t);
void VEXPTEFP(ppu_opcode_t);
void VLOGEFP(ppu_opcode_t);
void VMADDFP(ppu_opcode_t);
void VMAXFP(ppu_opcode_t);
void VMAXSB(ppu_opcode_t);
void VMAXSH(ppu_opcode_t);
void VMAXSW(ppu_opcode_t);
void VMAXUB(ppu_opcode_t);
void VMAXUH(ppu_opcode_t);
void VMAXUW(ppu_opcode_t);
void VMHADDSHS(ppu_opcode_t);
void VMHRADDSHS(ppu_opcode_t);
void VMINFP(ppu_opcode_t);
void VMINSB(ppu_opcode_t);
void VMINSH(ppu_opcode_t);
void VMINSW(ppu_opcode_t);
void VMINUB(ppu_opcode_t);
void VMINUH(ppu_opcode_t);
void VMINUW(ppu_opcode_t);
void VMLADDUHM(ppu_opcode_t);
void VMRGHB(ppu_opcode_t);
void VMRGHH(ppu_opcode_t);
void VMRGHW(ppu_opcode_t);
void VMRGLB(ppu_opcode_t);
void VMRGLH(ppu_opcode_t);
void VMRGLW(ppu_opcode_t);
void VMSUMMBM(ppu_opcode_t);
void VMSUMSHM(ppu_opcode_t);
void VMSUMSHS(ppu_opcode_t);
void VMSUMUBM(ppu_opcode_t);
void VMSUMUHM(ppu_opcode_t);
void VMSUMUHS(ppu_opcode_t);
void VMULESB(ppu_opcode_t);
void VMULESH(ppu_opcode_t);
void VMULEUB(ppu_opcode_t);
void VMULEUH(ppu_opcode_t);
void VMULOSB(ppu_opcode_t);
void VMULOSH(ppu_opcode_t);
void VMULOUB(ppu_opcode_t);
void VMULOUH(ppu_opcode_t);
void VNMSUBFP(ppu_opcode_t);
void VNOR(ppu_opcode_t);
void VOR(ppu_opcode_t);
void VPERM(ppu_opcode_t);
void VPKPX(ppu_opcode_t);
void VPKSHSS(ppu_opcode_t);
void VPKSHUS(ppu_opcode_t);
void VPKSWSS(ppu_opcode_t);
void VPKSWUS(ppu_opcode_t);
void VPKUHUM(ppu_opcode_t);
void VPKUHUS(ppu_opcode_t);
void VPKUWUM(ppu_opcode_t);
void VPKUWUS(ppu_opcode_t);
void VREFP(ppu_opcode_t);
void VRFIM(ppu_opcode_t);
void VRFIN(ppu_opcode_t);
void VRFIP(ppu_opcode_t);
void VRFIZ(ppu_opcode_t);
void VRLB(ppu_opcode_t);
void VRLH(ppu_opcode_t);
void VRLW(ppu_opcode_t);
void VRSQRTEFP(ppu_opcode_t);
void VSEL(ppu_opcode_t);
void VSL(ppu_opcode_t);
void VSLB(ppu_opcode_t);
void VSLDOI(ppu_opcode_t);
void VSLH(ppu_opcode_t);
void VSLO(ppu_opcode_t);
void VSLW(ppu_opcode_t);
void VSPLTB(ppu_opcode_t);
void VSPLTH(ppu_opcode_t);
void VSPLTISB(ppu_opcode_t);
void VSPLTISH(ppu_opcode_t);
void VSPLTISW(ppu_opcode_t);
void VSPLTW(ppu_opcode_t);
void VSR(ppu_opcode_t);
void VSRAB(ppu_opcode_t);
void VSRAH(ppu_opcode_t);
void VSRAW(ppu_opcode_t);
void VSRB(ppu_opcode_t);
void VSRH(ppu_opcode_t);
void VSRO(ppu_opcode_t);
void VSRW(ppu_opcode_t);
void VSUBCUW(ppu_opcode_t);
void VSUBFP(ppu_opcode_t);
void VSUBSBS(ppu_opcode_t);
void VSUBSHS(ppu_opcode_t);
void VSUBSWS(ppu_opcode_t);
void VSUBUBM(ppu_opcode_t);
void VSUBUBS(ppu_opcode_t);
void VSUBUHM(ppu_opcode_t);
void VSUBUHS(ppu_opcode_t);
void VSUBUWM(ppu_opcode_t);
void VSUBUWS(ppu_opcode_t);
void VSUMSWS(ppu_opcode_t);
void VSUM2SWS(ppu_opcode_t);
void VSUM4SBS(ppu_opcode_t);
void VSUM4SHS(ppu_opcode_t);
void VSUM4UBS(ppu_opcode_t);
void VUPKHPX(ppu_opcode_t);
void VUPKHSB(ppu_opcode_t);
void VUPKHSH(ppu_opcode_t);
void VUPKLPX(ppu_opcode_t);
void VUPKLSB(ppu_opcode_t);
void VUPKLSH(ppu_opcode_t);
void VXOR(ppu_opcode_t);
void TDI(ppu_opcode_t);
void TWI(ppu_opcode_t);
void MULLI(ppu_opcode_t);
void SUBFIC(ppu_opcode_t);
void CMPLI(ppu_opcode_t);
void CMPI(ppu_opcode_t);
void ADDIC(ppu_opcode_t);
void ADDI(ppu_opcode_t);
void ADDIS(ppu_opcode_t);
void BC(ppu_opcode_t);
void SC(ppu_opcode_t);
void B(ppu_opcode_t);
void MCRF(ppu_opcode_t);
void BCLR(ppu_opcode_t);
void CRNOR(ppu_opcode_t);
void CRANDC(ppu_opcode_t);
void ISYNC(ppu_opcode_t);
void CRXOR(ppu_opcode_t);
void CRNAND(ppu_opcode_t);
void CRAND(ppu_opcode_t);
void CREQV(ppu_opcode_t);
void CRORC(ppu_opcode_t);
void CROR(ppu_opcode_t);
void BCCTR(ppu_opcode_t);
void RLWIMI(ppu_opcode_t);
void RLWINM(ppu_opcode_t);
void RLWNM(ppu_opcode_t);
void ORI(ppu_opcode_t);
void ORIS(ppu_opcode_t);
void XORI(ppu_opcode_t);
void XORIS(ppu_opcode_t);
void ANDI(ppu_opcode_t);
void ANDIS(ppu_opcode_t);
void RLDICL(ppu_opcode_t);
void RLDICR(ppu_opcode_t);
void RLDIC(ppu_opcode_t);
void RLDIMI(ppu_opcode_t);
void RLDCL(ppu_opcode_t);
void RLDCR(ppu_opcode_t);
void CMP(ppu_opcode_t);
void TW(ppu_opcode_t);
void LVSL(ppu_opcode_t);
void LVEBX(ppu_opcode_t);
void SUBFC(ppu_opcode_t);
void ADDC(ppu_opcode_t);
void MULHDU(ppu_opcode_t);
void MULHWU(ppu_opcode_t);
void MFOCRF(ppu_opcode_t);
void LWARX(ppu_opcode_t);
void LDX(ppu_opcode_t);
void LWZX(ppu_opcode_t);
void SLW(ppu_opcode_t);
void CNTLZW(ppu_opcode_t);
void SLD(ppu_opcode_t);
void AND(ppu_opcode_t);
void CMPL(ppu_opcode_t);
void LVSR(ppu_opcode_t);
void LVEHX(ppu_opcode_t);
void SUBF(ppu_opcode_t);
void LDUX(ppu_opcode_t);
void DCBST(ppu_opcode_t);
void LWZUX(ppu_opcode_t);
void CNTLZD(ppu_opcode_t);
void ANDC(ppu_opcode_t);
void TD(ppu_opcode_t);
void LVEWX(ppu_opcode_t);
void MULHD(ppu_opcode_t);
void MULHW(ppu_opcode_t);
void LDARX(ppu_opcode_t);
void DCBF(ppu_opcode_t);
void LBZX(ppu_opcode_t);
void LVX(ppu_opcode_t);
void NEG(ppu_opcode_t);
void LBZUX(ppu_opcode_t);
void NOR(ppu_opcode_t);
void STVEBX(ppu_opcode_t);
void SUBFE(ppu_opcode_t);
void ADDE(ppu_opcode_t);
void MTOCRF(ppu_opcode_t);
void STDX(ppu_opcode_t);
void STWCX(ppu_opcode_t);
void STWX(ppu_opcode_t);
void STVEHX(ppu_opcode_t);
void STDUX(ppu_opcode_t);
void STWUX(ppu_opcode_t);
void STVEWX(ppu_opcode_t);
void SUBFZE(ppu_opcode_t);
void ADDZE(ppu_opcode_t);
void STDCX(ppu_opcode_t);
void STBX(ppu_opcode_t);
void STVX(ppu_opcode_t);
void SUBFME(ppu_opcode_t);
void MULLD(ppu_opcode_t);
void ADDME(ppu_opcode_t);
void MULLW(ppu_opcode_t);
void DCBTST(ppu_opcode_t);
void STBUX(ppu_opcode_t);
void ADD(ppu_opcode_t);
void DCBT(ppu_opcode_t);
void LHZX(ppu_opcode_t);
void EQV(ppu_opcode_t);
void ECIWX(ppu_opcode_t);
void LHZUX(ppu_opcode_t);
void XOR(ppu_opcode_t);
void MFSPR(ppu_opcode_t);
void LWAX(ppu_opcode_t);
void DST(ppu_opcode_t);
void LHAX(ppu_opcode_t);
void LVXL(ppu_opcode_t);
void MFTB(ppu_opcode_t);
void LWAUX(ppu_opcode_t);
void DSTST(ppu_opcode_t);
void LHAUX(ppu_opcode_t);
void STHX(ppu_opcode_t);
void ORC(ppu_opcode_t);
void ECOWX(ppu_opcode_t);
void STHUX(ppu_opcode_t);
void OR(ppu_opcode_t);
void DIVDU(ppu_opcode_t);
void DIVWU(ppu_opcode_t);
void MTSPR(ppu_opcode_t);
void DCBI(ppu_opcode_t);
void NAND(ppu_opcode_t);
void STVXL(ppu_opcode_t);
void DIVD(ppu_opcode_t);
void DIVW(ppu_opcode_t);
void LVLX(ppu_opcode_t);
void LDBRX(ppu_opcode_t);
void LSWX(ppu_opcode_t);
void LWBRX(ppu_opcode_t);
void LFSX(ppu_opcode_t);
void SRW(ppu_opcode_t);
void SRD(ppu_opcode_t);
void LVRX(ppu_opcode_t);
void LSWI(ppu_opcode_t);
void LFSUX(ppu_opcode_t);
void SYNC(ppu_opcode_t);
void LFDX(ppu_opcode_t);
void LFDUX(ppu_opcode_t);
void STVLX(ppu_opcode_t);
void STDBRX(ppu_opcode_t);
void STSWX(ppu_opcode_t);
void STWBRX(ppu_opcode_t);
void STFSX(ppu_opcode_t);
void STVRX(ppu_opcode_t);
void STFSUX(ppu_opcode_t);
void STSWI(ppu_opcode_t);
void STFDX(ppu_opcode_t);
void STFDUX(ppu_opcode_t);
void LVLXL(ppu_opcode_t);
void LHBRX(ppu_opcode_t);
void SRAW(ppu_opcode_t);
void SRAD(ppu_opcode_t);
void LVRXL(ppu_opcode_t);
void DSS(ppu_opcode_t);
void SRAWI(ppu_opcode_t);
void SRADI(ppu_opcode_t);
void EIEIO(ppu_opcode_t);
void STVLXL(ppu_opcode_t);
void STHBRX(ppu_opcode_t);
void EXTSH(ppu_opcode_t);
void STVRXL(ppu_opcode_t);
void EXTSB(ppu_opcode_t);
void STFIWX(ppu_opcode_t);
void EXTSW(ppu_opcode_t);
void ICBI(ppu_opcode_t);
void DCBZ(ppu_opcode_t);
void LWZ(ppu_opcode_t);
void LWZU(ppu_opcode_t);
void LBZ(ppu_opcode_t);
void LBZU(ppu_opcode_t);
void STW(ppu_opcode_t);
void STWU(ppu_opcode_t);
void STB(ppu_opcode_t);
void STBU(ppu_opcode_t);
void LHZ(ppu_opcode_t);
void LHZU(ppu_opcode_t);
void LHA(ppu_opcode_t);
void LHAU(ppu_opcode_t);
void STH(ppu_opcode_t);
void STHU(ppu_opcode_t);
void LMW(ppu_opcode_t);
void STMW(ppu_opcode_t);
void LFS(ppu_opcode_t);
void LFSU(ppu_opcode_t);
void LFD(ppu_opcode_t);
void LFDU(ppu_opcode_t);
void STFS(ppu_opcode_t);
void STFSU(ppu_opcode_t);
void STFD(ppu_opcode_t);
void STFDU(ppu_opcode_t);
void LD(ppu_opcode_t);
void LDU(ppu_opcode_t);
void LWA(ppu_opcode_t);
void STD(ppu_opcode_t);
void STDU(ppu_opcode_t);
void FDIVS(ppu_opcode_t);
void FSUBS(ppu_opcode_t);
void FADDS(ppu_opcode_t);
void FSQRTS(ppu_opcode_t);
void FRES(ppu_opcode_t);
void FMULS(ppu_opcode_t);
void FMADDS(ppu_opcode_t);
void FMSUBS(ppu_opcode_t);
void FNMSUBS(ppu_opcode_t);
void FNMADDS(ppu_opcode_t);
void MTFSB1(ppu_opcode_t);
void MCRFS(ppu_opcode_t);
void MTFSB0(ppu_opcode_t);
void MTFSFI(ppu_opcode_t);
void MFFS(ppu_opcode_t);
void MTFSF(ppu_opcode_t);
void FCMPU(ppu_opcode_t);
void FRSP(ppu_opcode_t);
void FCTIW(ppu_opcode_t);
void FCTIWZ(ppu_opcode_t);
void FDIV(ppu_opcode_t);
void FSUB(ppu_opcode_t);
void FADD(ppu_opcode_t);
void FSQRT(ppu_opcode_t);
void FSEL(ppu_opcode_t);
void FMUL(ppu_opcode_t);
void FRSQRTE(ppu_opcode_t);
void FMSUB(ppu_opcode_t);
void FMADD(ppu_opcode_t);
void FNMSUB(ppu_opcode_t);
void FNMADD(ppu_opcode_t);
void FCMPO(ppu_opcode_t);
void FNEG(ppu_opcode_t);
void FMR(ppu_opcode_t);
void FNABS(ppu_opcode_t);
void FABS(ppu_opcode_t);
void FCTID(ppu_opcode_t);
void FCTIDZ(ppu_opcode_t);
void FCFID(ppu_opcode_t);
};
+8 -7
View File
@@ -7,6 +7,7 @@ extern std::string ppu_get_syscall_name(u64 code)
{
case 1: return "sys_process_getpid";
case 2: return "sys_process_wait_for_child";
case 3: return "sys_process_exit";
case 4: return "sys_process_get_status";
case 5: return "sys_process_detach_child";
case 12: return "sys_process_get_number_of_object";
@@ -15,10 +16,10 @@ extern std::string ppu_get_syscall_name(u64 code)
case 18: return "sys_process_getppid";
case 19: return "sys_process_kill";
case 21: return "_sys_process_spawn";
case 22: return "_sys_process_exit";
case 22: return "sys_process_exit";
case 23: return "sys_process_wait_for_child2";
case 25: return "sys_process_get_sdk_version";
case 26: return "_sys_process_exit2";
case 26: return "_sys_process_exit";
case 28: return "_sys_process_get_number_of_object";
case 29: return "sys_process_get_id";
case 30: return "_sys_process_get_paramsfo";
@@ -413,16 +414,16 @@ extern std::string ppu_get_syscall_name(u64 code)
case 708: return "sys_net_bnet_recvmsg";
case 709: return "sys_net_bnet_sendmsg";
case 710: return "sys_net_bnet_sendto";
case 711: return "sys_net_bnet_setsockopt";
case 711: return "sys_net_bnet_setsockop";
case 712: return "sys_net_bnet_shutdown";
case 713: return "sys_net_bnet_socket";
case 714: return "sys_net_bnet_close";
case 715: return "sys_net_bnet_poll";
case 716: return "sys_net_bnet_select";
case 717: return "_sys_net_open_dump";
case 718: return "_sys_net_read_dump";
case 719: return "_sys_net_close_dump";
case 720: return "_sys_net_write_dump";
case 717: return "sys_net_open_dump";
case 718: return "sys_net_read_dump";
case 719: return "sys_net_close_dump";
case 720: return "sys_net_write_dump";
case 721: return "sys_net_abort";
case 722: return "sys_net_infoctl";
case 723: return "sys_net_control";
-5
View File
@@ -14,11 +14,6 @@ inline void ppu_cr_set(ppu_thread& ppu, u32 field, bool le, bool gt, bool eq, bo
ppu.cr[field * 4 + 1] = gt;
ppu.cr[field * 4 + 2] = eq;
ppu.cr[field * 4 + 3] = so;
if (UNLIKELY(g_cfg.core.ppu_debug))
{
*(u32*)(vm::g_stat_addr + ppu.cia) |= *(u32*)(u8*)(ppu.cr + field * 4);
}
}
// Write comparison results to CR field
+27 -87
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Utilities/VirtualMemory.h"
#include "Utilities/bin_patch.h"
#include "Crypto/sha1.h"
@@ -124,8 +124,7 @@ struct ppu_linkage_info
{
struct info
{
ppu_static_function* static_func = nullptr;
ppu_static_variable* static_var = nullptr;
bool hle = false;
u32 export_addr = 0;
std::set<u32> imports;
std::set<u32> frefss;
@@ -249,7 +248,7 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
&ppu_module_manager::sceNpTus,
&ppu_module_manager::sceNpUtil,
&ppu_module_manager::sys_io,
&ppu_module_manager::sys_net,
&ppu_module_manager::libnet,
&ppu_module_manager::sysPrxForUser,
&ppu_module_manager::sys_libc,
&ppu_module_manager::sys_lv2dbg,
@@ -316,9 +315,8 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
{
auto& flink = linkage.functions[function.first];
flink.static_func = &function.second;
flink.hle = true;
flink.export_addr = ppu_function_manager::addr + 8 * function.second.index;
function.second.export_addr = &flink.export_addr;
}
}
@@ -329,7 +327,7 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
// Allocate HLE variable
if (variable.second.size >= 4096 || variable.second.align >= 4096)
{
variable.second.addr = vm::alloc(variable.second.size, vm::main, std::max<u32>(variable.second.align, 4096));
variable.second.var->set(vm::alloc(variable.second.size, vm::main, std::max<u32>(variable.second.align, 4096)));
}
else
{
@@ -345,15 +343,10 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
alloc_addr = next;
}
variable.second.addr = alloc_addr;
variable.second.var->set(alloc_addr);
alloc_addr += variable.second.size;
}
if (variable.second.var)
{
variable.second.var->set(variable.second.addr);
}
LOG_TRACE(LOADER, "Allocated HLE variable %s.%s at 0x%x", module->name, variable.second.name, variable.second.var->addr());
// Initialize HLE variable
@@ -362,14 +355,10 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
variable.second.init();
}
if ((variable.second.flags & MFF_HIDDEN) == 0)
{
auto& vlink = linkage.variables[variable.first];
vlink.static_var = &variable.second;
vlink.export_addr = variable.second.addr;
variable.second.export_addr = &vlink.export_addr;
}
auto& vlink = linkage.variables[variable.first];
vlink.hle = true;
vlink.export_addr = variable.second.var->addr();
}
}
}
@@ -521,12 +510,7 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
// Function linkage info
auto& flink = mlink.functions[fnid];
if (flink.static_func && flink.export_addr == ppu_function_manager::addr + 8 * flink.static_func->index)
{
flink.export_addr = 0;
}
if (flink.export_addr)
if (flink.export_addr && !flink.hle)
{
LOG_ERROR(LOADER, "Already linked function '%s' in module '%s'", ppu_get_function_name(module_name, fnid), module_name);
}
@@ -560,6 +544,7 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
{
// Set exported function
flink.export_addr = faddr;
flink.hle = false;
// Fix imports
for (const u32 addr : flink.imports)
@@ -589,12 +574,7 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
// Variable linkage info
auto& vlink = mlink.variables[vnid];
if (vlink.static_var && vlink.export_addr == vlink.static_var->addr)
{
vlink.export_addr = 0;
}
if (vlink.export_addr)
if (vlink.export_addr && !vlink.hle)
{
LOG_ERROR(LOADER, "Already linked variable '%s' in module '%s'", ppu_get_variable_name(module_name, vnid), module_name);
}
@@ -602,6 +582,7 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
{
// Set exported variable
vlink.export_addr = vaddr;
vlink.hle = false;
// Fix imports
for (const auto vref : vlink.imports)
@@ -751,7 +732,6 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
ppu_segment _seg;
_seg.addr = addr;
_seg.size = mem_size;
_seg.filesz = file_size;
_seg.type = p_type;
_seg.flags = prog.p_flags;
prx->segs.emplace_back(_seg);
@@ -786,7 +766,6 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
_sec.size = size;
_sec.type = s.sh_type;
_sec.flags = s.sh_flags & 7;
_sec.filesz = 0;
prx->secs.emplace_back(_sec);
break;
}
@@ -906,7 +885,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
struct ppu_prx_library_info
{
be_t<u16> attributes;
u8 version[2];
be_t<u16> version;
char name[28];
be_t<u32> toc;
be_t<u32> exports_start;
@@ -919,11 +898,6 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
const auto& lib_info = vm::cptr<ppu_prx_library_info>(vm::cast(prx->segs[0].addr + elf.progs[0].p_paddr - elf.progs[0].p_offset, HERE));
const auto& lib_name = std::string(lib_info->name);
std::memcpy(prx->module_info_name, lib_info->name, sizeof(prx->module_info_name));
prx->module_info_version[0] = lib_info->version[0];
prx->module_info_version[1] = lib_info->version[1];
prx->module_info_attributes = lib_info->attributes;
LOG_WARNING(LOADER, "Library %s (rtoc=0x%x):", lib_name, lib_info->toc);
prx->specials = ppu_load_exports(link, lib_info->exports_start, lib_info->exports_end);
@@ -965,23 +939,6 @@ void ppu_unload_prx(const lv2_prx& prx)
pinfo->imports.erase(imp.first);
}
//for (auto& exp : prx.exports)
//{
// auto pinfo = static_cast<ppu_linkage_info::module::info*>(exp.second);
// if (pinfo->static_func)
// {
// pinfo->export_addr = ppu_function_manager::addr + 8 * pinfo->static_func->index;
// }
// else if (pinfo->static_var)
// {
// pinfo->export_addr = pinfo->static_var->addr;
// }
// else
// {
// pinfo->export_addr = 0;
// }
//}
for (auto& seg : prx.segs)
{
vm::dealloc(seg.addr, vm::main);
@@ -1022,7 +979,6 @@ void ppu_load_exec(const ppu_exec_object& elf)
const u32 size = _seg.size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
const u32 type = _seg.type = prog.p_type;
const u32 flag = _seg.flags = prog.p_flags;
_seg.filesz = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
// Hash big-endian values
sha1_update(&sha, (uchar*)&prog.p_type, sizeof(prog.p_type));
@@ -1063,7 +1019,6 @@ void ppu_load_exec(const ppu_exec_object& elf)
const u32 size = _sec.size = vm::cast(s.sh_size);
const u32 type = _sec.type = s.sh_type;
const u32 flag = _sec.flags = s.sh_flags & 7;
_sec.filesz = 0;
if (s.sh_type == 1 && addr && size)
{
@@ -1206,9 +1161,9 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Get LLE module list
std::set<std::string> load_libs;
if (g_cfg.core.lib_loading == lib_loading_type::manual)
if (g_cfg.core.lib_loading == lib_loading_type::manual || g_cfg.core.lib_loading == lib_loading_type::both)
{
// Load required set of modules (lib_loading_type::both processed in sys_prx.cpp)
// Load required set of modules
load_libs = g_cfg.core.load_libraries.get_set();
}
else if (g_cfg.core.lib_loading == lib_loading_type::liblv2only)
@@ -1388,7 +1343,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Set path (TODO)
_main->name = "";
_main->path = vfs::get(Emu.argv[0]);
_main->path = vfs::get(Emu.GetPath());
// Analyse executable (TODO)
_main->analyse(0, static_cast<u32>(elf.header.e_entry));
@@ -1400,42 +1355,27 @@ void ppu_load_exec(const ppu_exec_object& elf)
g_ps3_sdk_version = sdk_version;
// Initialize process arguments
auto args = vm::ptr<u64>::make(vm::alloc(SIZE_32(u64) * (::size32(Emu.argv) + ::size32(Emu.envp) + 2), vm::main));
auto argv = args;
std::initializer_list<std::string> args = { Emu.GetPath()/*, "-emu"s*/ };
for (const auto& arg : Emu.argv)
auto argv = vm::ptr<u64>::make(vm::alloc(SIZE_32(u64) * ::size32(args), vm::main));
auto envp = vm::ptr<u64>::make(vm::alloc(::align(SIZE_32(u64), 0x10), vm::main));
*envp = 0;
for (const auto& arg : args)
{
const u32 arg_size = ::align(::size32(arg) + 1, 0x10);
const u32 arg_addr = vm::alloc(arg_size, vm::main);
std::memcpy(vm::base(arg_addr), arg.data(), arg_size);
*args++ = arg_addr;
*argv++ = arg_addr;
}
*args++ = 0;
auto envp = args;
for (const auto& arg : Emu.envp)
{
const u32 arg_size = ::align(::size32(arg) + 1, 0x10);
const u32 arg_addr = vm::alloc(arg_size, vm::main);
std::memcpy(vm::base(arg_addr), arg.data(), arg_size);
*args++ = arg_addr;
}
argv -= ::size32(args);
// Initialize main thread
auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize);
// Write initial data (exitspawn)
if (Emu.data.size())
{
std::memcpy(vm::base(ppu->stack_addr + ppu->stack_size - ::size32(Emu.data)), Emu.data.data(), Emu.data.size());
ppu->gpr[1] -= Emu.data.size();
}
ppu->cmd_push({ppu_cmd::initialize, 0});
// TODO: adjust for liblv2 loading option
@@ -1477,7 +1417,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Set command line arguments, run entry function
ppu->cmd_list
({
{ ppu_cmd::set_args, 8 }, u64{Emu.argv.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
{ ppu_cmd::set_args, 8 }, u64{args.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
{ ppu_cmd::set_gpr, 11 }, u64{elf.header.e_entry},
{ ppu_cmd::set_gpr, 12 }, u64{malloc_pagesize},
{ ppu_cmd::lle_call, entry },
+7 -50
View File
@@ -3,7 +3,6 @@
#include "PPUFunction.h"
#include "PPUCallback.h"
#include "ErrorCodes.h"
#include <typeinfo>
// Helper function
constexpr const char* ppu_select_name(const char* name, u32 id)
@@ -27,7 +26,7 @@ constexpr u32 ppu_generate_id(u32 id)
}
// Flags set with REG_FUNC
enum ppu_static_module_flags : u32
enum ppu_static_function_flags : u32
{
MFF_FORCED_HLE = (1 << 0), // Always call HLE function
MFF_PERFECT = (1 << 1), // Indicates complete implementation and LLE interchangeability
@@ -40,15 +39,6 @@ struct ppu_static_function
const char* name;
u32 index; // Index for ppu_function_manager
u32 flags;
const char* type;
std::vector<const char*> args; // Arg names
const u32* export_addr;
ppu_static_function& flag(ppu_static_module_flags value)
{
flags |= value;
return *this;
}
};
// HLE variable information
@@ -59,16 +49,6 @@ struct ppu_static_variable
void(*init)(); // Variable initialization function
u32 size;
u32 align;
const char* type;
u32 flags;
u32 addr;
const u32* export_addr;
ppu_static_variable& flag(ppu_static_module_flags value)
{
flags |= value;
return *this;
}
};
// HLE module information
@@ -111,17 +91,10 @@ class ppu_module_manager final
static ppu_static_variable& access_static_variable(const char* module, u32 vnid);
// Global variable for each registered function
template <typename T, T Func>
struct registered
{
static ppu_static_function* info;
};
public:
static const ppu_static_module* get_module(const std::string& name);
template <typename T, T Func>
template<typename T, T Func>
static auto& register_static_function(const char* module, const char* name, ppu_function_t func, u32 fnid)
{
auto& info = access_static_function(module, fnid);
@@ -129,20 +102,11 @@ public:
info.name = name;
info.index = ppu_function_manager::register_function<T, Func>(func);
info.flags = 0;
info.type = typeid(T).name();
registered<T, Func>::info = &info;
return info;
}
template <typename T, T Func>
static auto& find_static_function()
{
return *registered<T, Func>::info;
}
template <typename T, T* Var>
template<typename T, T* Var>
static auto& register_static_variable(const char* module, const char* name, u32 vnid)
{
static_assert(std::is_same<u32, std::decay_t<typename T::addr_type>>::value, "Static variable registration: vm::gvar<T> expected");
@@ -154,9 +118,6 @@ public:
info.init = [] {};
info.size = SIZE_32(typename T::type);
info.align = ALIGN_32(typename T::type);
info.type = typeid(T).name();
info.flags = 0;
info.addr = 0;
return info;
}
@@ -260,24 +221,20 @@ public:
static const ppu_static_module sceNpTus;
static const ppu_static_module sceNpUtil;
static const ppu_static_module sys_io;
static const ppu_static_module sys_net;
static const ppu_static_module libnet;
static const ppu_static_module sysPrxForUser;
static const ppu_static_module sys_libc;
static const ppu_static_module sys_lv2dbg;
};
template<typename T, T Func>
ppu_static_function* ppu_module_manager::registered<T, Func>::info = nullptr;
// Call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
template<typename T, T Func, typename... Args, typename RT = std::result_of_t<T(Args...)>>
inline RT ppu_execute_function_or_callback(ppu_thread& ppu, Args&&... args)
inline RT ppu_execute_function_or_callback(const char* name, ppu_thread& ppu, Args&&... args)
{
vm::ps3::ptr<RT(Args...)> func = vm::cast(*ppu_module_manager::find_static_function<T, Func>().export_addr);
return func(ppu, std::forward<Args>(args)...);
return Func(std::forward<Args>(args)...);
}
#define CALL_FUNC(ppu, func, ...) ppu_execute_function_or_callback<decltype(&func), &func>(ppu, __VA_ARGS__)
#define CALL_FUNC(ppu, func, ...) ppu_execute_function_or_callback<decltype(&func), &func>(#func, ppu, __VA_ARGS__)
#define REG_FNID(module, nid, func) ppu_module_manager::register_static_function<decltype(&func), &func>(#module, ppu_select_name(#func, nid), BIND_FUNC(func, ppu.cia = (u32)ppu.lr & ~3), ppu_generate_id(nid))
+11 -49
View File
@@ -280,16 +280,15 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
if (!stack_addr)
{
// Allocate stack + gap between stacks
auto new_stack_base = vm::alloc(stack_size + 4096, vm::stack);
if (!new_stack_base)
const_cast<u32&>(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096;
if (!stack_addr)
{
fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size);
}
const_cast<u32&>(stack_addr) = new_stack_base + 4096;
// Make the gap inaccessible
vm::page_protect(new_stack_base, 4096, 0, 0, vm::page_readable + vm::page_writable);
vm::page_protect(stack_addr - 4096, 4096, 0, 0, vm::page_readable + vm::page_writable);
gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200;
@@ -329,43 +328,6 @@ extern void ppu_remove_breakpoint(u32 addr)
}
}
extern bool ppu_patch(u32 addr, u32 value)
{
// TODO: check executable flag
if (vm::check_addr(addr, sizeof(u32)))
{
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm && Emu.GetStatus() != system_state::ready)
{
// TODO
return false;
}
if (!vm::check_addr(addr, sizeof(u32), vm::page_writable))
{
utils::memory_protect(vm::g_base_addr + addr, sizeof(u32), utils::protection::rw);
}
vm::write32(addr, value);
const u32 _break = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_break));
const u32 fallback = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_fallback));
if (ppu_ref(addr) != _break && ppu_ref(addr) != fallback)
{
ppu_ref(addr) = ppu_cache(addr);
}
if (!vm::check_addr(addr, sizeof(u32), vm::page_writable))
{
utils::memory_protect(vm::g_base_addr + addr, sizeof(u32), utils::protection::ro);
}
return true;
}
return false;
}
std::string ppu_thread::get_name() const
{
return fmt::format("PPU[0x%x] Thread (%s)", id, m_name);
@@ -1115,8 +1077,8 @@ extern void ppu_initialize(const ppu_module& info)
const auto fstart = fpos;
// Copy module information (TODO: optimize)
ppu_module part;
part.copy_part(info);
ppu_module part = info;
part.funcs.clear();
part.funcs.reserve(16000);
// Unique suffix for each module part
@@ -1201,9 +1163,9 @@ extern void ppu_initialize(const ppu_module& info)
sha1_update(&ctx, vm::ps3::_ptr<const u8>(func.addr), func.size);
}
if (info.name == "liblv2.sprx" || info.name == "libsysmodule.sprx" || info.name == "libnet.sprx")
if (info.name == "liblv2.sprx")
{
const be_t<u64> forced_upd = 3;
const be_t<u64> forced_upd = 1;
sha1_update(&ctx, reinterpret_cast<const u8*>(&forced_upd), sizeof(forced_upd));
}
@@ -1276,10 +1238,10 @@ extern void ppu_initialize(const ppu_module& info)
return;
}
// Jit can be null if the loop doesn't ever enter.
if (jit && jit_mod.vars.empty())
{
if (jit_mod.vars.empty())
{
jit->fin();
// Get and install function addresses
for (const auto& func : info.funcs)
{
-14
View File
@@ -238,20 +238,6 @@ struct ppu_gpr_cast_impl<vm::_ref_base<T, AT>, void>
}
};
template <>
struct ppu_gpr_cast_impl<vm::null_t, void>
{
static inline u64 to(const vm::null_t& value)
{
return 0;
}
static inline vm::null_t from(const u64 reg)
{
return vm::null;
}
};
template<typename To = u64, typename From>
inline To ppu_gpr_cast(const From& value)
{

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