1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00
* Fix windows build.  I made sure to do everything with a win32 prefix to not effect linux build.

* Make the window resizable instead of fixed in the corner.

* Ignore moc files and things in the debug/release folder.  I might also ignore rpcs3qt.vcxproj and its filters as they're autogenerated by importing the qt project file.  But, this helps clean out clutter for now.

* Add cmake.  This doesn't interact with the rest of rpcs3 nor the main cmake file.  That's the next thing I'm doing. I'll probably need to modify them so it'll take me time to figure out. But, this will build rpcs3qt on linux and build as is with using qt.

* The build works. I'd like to thank my friends, Google and Stackoverflow.

Setted up by importing rpcs3Qt project using Qt's visual studio plugin.

* Cleanup.  Remove all the stuff in the rpcs3qt folder as its incorporated elsewhere. Remove the rpcs3qt project file as its now built into the solution and cmake doesn't care about pro files.

* Update readme to reflect getting Qt.

* Remove wxwidgets as submodule and add zlib instead. Wxwidgets was our old way of having zlib. I also added build dependencies to rpcs3qt so you should no longer get link errors on the first clean rebuild.

* Add rpcs3_version, few GUI tweaks

* Set defaultSize to 70% of screen size

* Add the view menu (#3)

* Added the view menu with the corresponding elements. Now, the debugger/log are hidden by default. The view menu has a checkbox which you click to show/hide the dock widgets.

* Make log visible by default

* Improve UI by making it into a checkbox that's easier to use.

* fix qt build for vs2017 (seems to work fine in 2015 with plugin but needs testing by other users)

* updated readme for qt

* update appveyor for qt
- cleaned formatting for the post build command

* fix build (#6)

* fix build legit this time i promise

* [Ready] Gamepadsettings (#4)

* WIP Gamepadsettings
pushbutton Eventhandling missing

* GamepadSettings should work except for cfg Init
Some KeyInputs are missing

* Update padsettingsdialog.h

* Update padsettingsdialog.cpp (#5)

* Update padsettingsdialog.cpp

removed silly tabs

* Update padsettingsdialog.cpp

* GetKeyCode simplified

* rename pad settings to keyboard settings o.O

* rename keyboard setting to input settings

* Remvoed the QT_UI defines.

* Readded new line at end of file. Replaced define in padsettings with constant.

* GUI fixes (Settings)

* Stub the logger UI. Nothing special besides a simple stub.

* Unstub the log. I haven't tested TTY but it should work.

Only thing to do, but this is in general, is add persistent settings.

* Minor refactoring to simplify code.

* Fix image loading. I'm 90% sure it works because it loads the path as expected and that's the same format I used in my gamelist implementation for the images.

* Made game lists much more functional than it was.

* mainwindow

* gamelist

* Please forgive me for I have lambdaed.

Added the ability to toggle showing columns via a context menu.

* Fix GameList further

* sort by name on init fixed

* Created the baseline refactoring. I'm going to start working on the callbacks now.  May need to implement other classes in the process. Fun stuff, I know.

* adds InstallPkg (tested) and InstallPup (should work but makes unknown shenanigans) implementation
adds RefreshGameList
obliterates 10sec Refresh

* messages

* Rpcs3 gs frame (#16)

* Messing with project settings try to get trails of cold steel to boot.bluh

Definitely one change is needed in linker settings for RPCS3 to not crash immediately.

Can't even see how horribly botched my implementation of GSFrame is because we aren't booting lol. Something is gone awry with elf.

* remove random ! not that it matters much right now

* minor additions

* "Working" with debug mode though you have to ignore an assert reached from Qt. Qt is upset that the rsx thread is calling stuff on the UI thread despite not owning it.  However, I can't do a thing to change that atm. (The fix would be to do what the TODO says in System.cpp-- making gsframe and stuff get initialized via system call)

Crashes due to needing pad callback to be done.

* With this build in debug mode, Trails of Cold steel will get FPS. (caveat. You have to ignore when Qt throws a debug assert lol)

* Fix release mode.  Fix the Qt debug assert by using ancient occault rituals.  I want to be able to remove the blocking connects but it won't work right now without it.  It isn't perfect but it's good enough for now IMO.

* Add enters to the end of files.

* Removing target and setting source of events to be the application instead of the main window. The main window isn't the game window, and I don't really know what widget will be targetted for the game event.  Works, though, it's admittedly probably not optimal by ANY means.

* Fix comment.

* Fix libpng wit zlib.

* Move Qt GUI into RPCS3Qt. (#17)

Restore wx GUI.

* fix install-progressdialogs randomly not showing

* install-progressdialog cosmetics

* add stylesheet file loading

* apply request

* Add stylesheet to git ignore.

* XInput..

* Joystick...

* Rpcs3 qt small fixes (#20)

* Small fixes.  Have emulator stop when x button is pressed on game window.  Have emulator/application stop when the main window is closed.

* If I forget another new line ending for a file.............................................

* Add CgDisasm (#21)

* fix install-progressdialogs randomly not showing

* install-progressdialog cosmetics

* add stylesheet file loading

* apply request

* add CgDisasm
add code to disable contextmenu options
fix gamelist issue

* missing proj changes

* Add ability to open stylesheets from menu.

* Mega searcher (#23)

* add MemoryStringSearcher
set minimum Sizes for mainwindow and CgDisasm

* minor fixes

* Since the system.cpp callbacks for emulator state were unused, I removed them.  Then, I replaced them with callbacks for the Gui.

* added stylesheet options
setfocus on settings fixed
newline added

* added signals and slots for EmuRun and EmuStop

* update ui

update ui now works
added callback onReady
added EnableMenues
added ps3 commands

* added restart logic to menu

* newline

* event header removed

* Added graphic settings class. (#26)

* Added graphic settings class. First thing is to have the dock widgets and window size/location be stateful.  Minor bug with debugger frame changing size on hide/show on default setup on second load. But, otherwise, fine. Also, the GUI doesn't update to accomodate the statefulness of the widgets.  But, that'll come in time as I update this class.

* Add view debugger, logger, gamelist to settings and synchronize them.

* Separate initializing actions from connects

* Add invisible fullscreen cursor and double click event.

* Add the UI log settings.

* Add MemoryViewer (#30)

* Add Memoryviewer
Image Button crashes/not fully implemented
focus on some button annoying

minor changes for question dialogs

* GuiSettings Refactoring (#31)

* Add settings for columns shown and which one is saved

* I accidentally refactored the settings class.  Added ability to reset to default GUI.  Added statefulness to column widths.

* add gui tab

* Fix logging at startup.

* Preset settings.I think I ironed out MOST of the glitches. Will work on the rest of it soon. Should be a lot simpler as I won't have to use the so-called meta settings. Also, renamed all settings methods to CapitalCase.

* Removed dock widget controls.

* Added style sheets. Removed the option from the menu.

* Rewrite to use folder design. Much simpler! Yay! Simpler. Better, right?

* It's remarkable how tricky this is.

* Added convenience button to open up the settings folder in explorer

* Add newlines at end of file

* simplified logic. Fixed a bug.. hopefully not more bugs

* Fix the undocumented feature

* Make the dialog big enough to have entire text on title shown. If talkashie changes the font to size 1203482 I don't care lol

* Make warning messagebox instead of changing the title of the dialog.

* marking...

* Hcorion suggested changes.

* [WIP] autopause (#32)

* autopause added
needs fixing
headers do not show text

* fix compile stuff

* Add MsgDialog + edge widgets (#33)

* Add MsgDialog
needs magic

* add "Debugger" Buttons to menubar

* Adapt ds4 changes. I'm not sure if they work as I don't have a compatible controller.  But, at the same time, it's kind of silly all I had to do was remove stdguiafx to get compilation.

* [Ready] Add KernelExplorer (#36)

* KernelExplorer added

* Fix build.  Connect mainwindow to show explorer.

* qstr formatting added
hid header, fixed button size

* Taskbar Progress for install PUP/PKG (#37)

* Add Taskbar Progress for both PKG and PUP installer

* fix missing ifdefs for windows

* add mainwindow icon + thumbnail toolbar

* add game specific icons to the GSFrame

* fix icon crash

* fix appIcon's aspect ratio in SetAppIconFromPath

* Fix black borders in RGB32 icons

* rename thumbar related buttons

* EmuSettings (#35)

* Core tab done minus doing the library list.

* Graphics tab.

* Audio tab

* Input tab

* Added the other tabs

* LLE part one-- load existing libraries sorted. (I'd finish it but I'm going to look at a PR by mega)

* add search and add other libraries that aren't checked.

* Finish adding lle selecting things.

* marking my territory (#38)

fixed settingsdialog glitch and width
added groupbox to gui buttons
removed parents from layouts

* add debuggerframe + RSXDebugger (#34)

* Add Debuggerframe

* add RSXDebugger

* add RSXDebugger fo real

* RSXDebugger improved
minor adjustments

* add utf8 conversions like neko told me to
hopefully i did not utf8-ise too many things xD

* fix some variables

* maybe fix image buffers in RSXDebugger

* fixed image view (pretty sure)

* fixed image buffer (hopefully)

*  QT Opengl frame (#41)

* fix RSX Debugger headers (#40)

* fix some debugger layout issues
fix RSX Debugger headers + some comments

* add kd-11's SPU options
fix D3D12 showing on non-compatible systems
tidy up coretab

* improve D3D12 behaviour in graphicstab:
adapter selection and D3D12 render won't show on non-compatible systems
add monospace font to cgDisasm

* enable update only on visibility

* Rpcs3 qt llvm build (#42)

* LLVM pushed so mega can test

* probably is what is needed with Release LLVM

* should probably have RPCS3-Qt be using release-llvm

* include zlib the same way.

* don't talk to me about how I made this happen.

* I applied the magical treatment to debug mode too.  Though, it's entirely probably that doing it once in LLVM-release mode made this entirely redundant

* hack

* progress bar for LLVM spawns but doesn't close yet.

* fix msgDialog (#43)

fix oskDialog

* Minor bug fixzz

* fix osk and msgdialog for real (#44)

* fix msgDialog
fix oskDialog

* fix OskDialog part 2
fix MsgDialog part 2

* This bug is evil, and it should be ashamed of itself.

* Refactor YAML.  Commented out gui options that aren't added to config yet (add em back later when we merge that in)

* Fix pad stuff.

* add SaveDataUtility (#45)

* add SaveDataUtility

* fix slots

* fix slots again
fix lists not showing stuff
fix dialogs not showing
add colClicked
refactor stuff and polish some layouts

* add SaveDataDialog.h and SaveDataDialog.cpp

* tidy up mainwindow

* add callback

* fix RegisterEditor (#47)

* fix RegisterEditor

* fix other dialogs' immortality (gasp...vampires)

* remove debug leftovers

* fix InstructionEditor (#46)

* fix InstructionEditor

* fix typo

* Fix MouseClickEvents in RSXDebugger (#50)

* Fix MouseClickEvents in RSXDebugger
Fix focus on MemoryViewer and RSXDebugger
Adjust PadButtonWidth

* fix another comment

* fix debuggerframe events (#49)

* Fix pad settings bro (#48)

* Fix pad settings bro

* fix comment

* Icons and Menu-Additions (#39)

* Add Icons and iconlogic to cornerWidget and actions

* add cornerWidget toggle
fix dockwidget action state on start
remove DoSettings

* fix game removal bug
remove tableitem focus rectangle
therefore add TableItemDelegate.h

* remove grid and focus rectangle from autopausedialog

* add fullscreen checkbox to misctab
minor padsettings layout improvements

* Add show category submenu to view menu
Add gamelist filter accordingly
fix minor bug where play icon was displayed despite pause label
add boolean b_fullscreen to mainwindow for later use in GSFrame

* fix headers in autopausesettings
fix remove bug in autopausesettings
add delete keypressevent in autopausesettings
fix missing tr() and minor refactoring in gamelist

* add default Icons for play/pause/stop/restart

* Fix fullscreen start.  Some stuff was wrong with settings, just trust me.

* remove fullscreen leftovers and fix merge

* SPU stuff. (There was also a weird thing with config.h in GLGSFrame.h with an include that I removed to fix build)

* please neko's lambda fetishes (#53)

* please neko's lambda fetish in mainwindow

* please neko's lambda fetish in gamelistframe

* please neko's lambda fetish in logframe

* fix neko's lambda fetish in debuggerframe

* pleasefixdofetishsomething in Autopausesettingsdialog

* fix sth sth lambda in cg disasm

* lambda stuff in instructioneditor

* lambda kernelexplorer

* lambda-ise memoryviewer

* lambda rsxdebugger

* lambda savedatautil
this could be done even more, but the functions are not implemented

* Rpcs3 qt fixes -- shadow taskbar bug (#52)

* SShadow's bug of taskbar progress staying fixed on cancelling pkg install.

* other taskbar

* i'm still a baka

* Fix a warning

* qtQt refactoring (#54)

* fix neko's snake fetish

* File names should match headers. Are these the names I want?  Not necessarily.  But, this is much less confusing.

* i thought I committed everything with stage all.........................

* remove unused utilities

* The most important commit of them all.

* Disable legacy opengl buffers when not using opengl.

* fix code review comment

* Quick crash patch. Neko removed autopause. SO, I remove it too from emusettings/misc tab

* Merge lovely things from master (#55)

* Configuration simplified

* untrivial parts of the merge

* no need for these options anymore

* Minor change to fix column widths at startup (not sure why it doesn't work already, but adding the true makes it work so......... whatever)

* here ya go

* FIx hitting okay in settings causing graphics to messup (#57)

* fixes + msgdialog taskbarprogress (#56)

* fix ok button in taskbar
add taskicon progressbar for msgdialog
add tablewidgetitem to rsxdebugger
fix comments in save_data_utility.cpp

* fix d3d adapter default

* fix taskicon progressbar not being destroyed properly

* add last_path to filedialogs

* fix msgdialog crash on ok (#58)

* fix thread stopping in debbugerFrame (#59)

* Move Emu.init to be first.  This will fix the qt stuff seeming to ignore the virtual filesystem in the config. (VFS to be made soon maybe) (#60)

* Fix full screen opening on double RIGHT click.

* fix other instances of double click ...

* Fix locaiton of gui config. (#61)

* fix d3d bug (#62)

* fix d3d bug

* small utf8 addition

* Fix cmake for qt (#64)

* Initial CMake fix

* Fix compilation with GCC

* Get rid of awful hack

* Update cotire with qt support

* Maybe fix travis

* Emergency Hack Relief Program Activated

* Fix travis build (#65)

* make about dialog great again (#67)

and add previous additions

* Fix library sort / smart gamelist context menu (#63)

* fix library sort

* add Title to custom game config dialog

* disable options on gamelist context menu

* use namespace for category Strings

* introduce sstr

* fix some tr nonsense

* Rpcs3qt Appveyor (#68)

Fix appyveyor build!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

* possible fix for gamelist icons (#69)

add warning for appicon

* Fix clang build (#66)

Hcorion, the build savior.

* Rpcs3 qt resources (#70)

* Resource files attempt 1

* Autorcc should probably be on?

* forgot the most important file lol

* Forgot an instance of the icon in the code...

* Patch fix for clang build.

* vulkan/d3d12 combobox merge (#71)

* add vulkan adapterbox and merge with d3d12 box

* fix adapter text on other renderer

* gather render strings

* attempt fix on gamelist row height

* adjust adapter behaviour to new guideline

* Compiler of Peace.

* High critical hit rate.

* Mugi eating strawberries is savage.

* Apply KD-11 Hotfix (#73)

* Most of Ani Adjusts (#72)

* Most of the adjustments are made here.

* fix gamelist rowheight

* fix msg dialog layout and disable_cancel

* cleanup

* fix disable cancle again

* fix debuggerframe buttons and doubleclick

* Add a fun little bonus feature :) (#74)

* category filters simplyfied (#75)

* Cleaning up cmake a bit.

* fixezzzzzz (#76)

* upgrade Info Boxes

* upgrade file explorer

* refactor GetSettings and SetSettings

* second refactoring

* cleanup

* travis is a grammar nazi

* second travis shenanigans

* third travis weirdo thingy

* travis 4 mega fun

* travis 5 default to def

* finish refactoring for settings
fix gamelist headers

* hotfix msgdialog and infobox (#77)

* msgdialog fix 1

* fix zombie infobox

* Rpcs3 Qt Welcome Page (#78)

* Add a welcome dialog.

* Add enter to end of file

* i'm an idiot

* last mistake i hope

* sponsored via --> funded by

* RPCS3 does not condone piracy.

* Mega Adjusts

* Ani Adjustments and a few refactorings

* Yay

* Add Gamelist Icon Sizes (#79)

* Reverting Mega's suggestion.  If people can use alt-f4 to get around this dialog, they can probably use an emulator too.

* Fix firmware file choice dialog in QT GUI (#80)

* ani adjusts 2 + minor icon size simplifications (#81)

FPS Additions

* Update Travis to Qt 5.9 (#82)
This commit is contained in:
Robbie 2017-06-04 09:48:33 -05:00 committed by Ivan
parent 195f24507b
commit 6cfb184b1e
150 changed files with 13761 additions and 3071 deletions

4
.gitignore vendored
View File

@ -86,3 +86,7 @@ CMakeCache.txt
# cotire
rpcs3/cotire/*
rpcs3/rpcs3_*_cotire.cmake
# Qt
moc_*.cpp
qrc_resources.cpp

9
.gitmodules vendored
View File

@ -1,7 +1,3 @@
[submodule "wxWidgets"]
path = wxWidgets
url = https://github.com/wxWidgets/wxWidgets
ignore = dirty
[submodule "rpcs3-ffmpeg"]
path = 3rdparty/ffmpeg
url = https://github.com/hrydgard/ppsspp-ffmpeg
@ -41,7 +37,10 @@
[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
branch = master

View File

@ -38,6 +38,11 @@ before_install:
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
sudo add-apt-repository ppa:beineri/opt-qt59-trusty -y;
sudo apt-get update;
sudo apt-get install qt59base -y;
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
@ -52,6 +57,7 @@ before_install:
before_script:
- git submodule update --init rsx_program_decompiler asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi
- source /opt/qt59/bin/qt59-env.sh
- mkdir build
- cd build
- cmake ..
@ -83,7 +89,8 @@ addons:
- libstdc++-5-dev
- lib32stdc++6
- zlib1g-dev
- libwxgtk3.0-dev
# We need to install qt 5.8 manually because the version trusty provides is too old.
#- qtbase5-dev
- libudev-dev
coverity_scan:
project:

2
3rdparty/libpng vendored

@ -1 +1 @@
Subproject commit ea77a6fd4983e6c2ab4ef1dee7c819188c2f4f3e
Subproject commit 1dcba4d6eb1bad9500be877cbd1b0442fa92cfa6

1
3rdparty/zlib vendored Submodule

@ -0,0 +1 @@
Subproject commit cacf7f1d4e3d44d871b605da3b647f07d718623f

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.12)
# uncomment next line if you want to build with GDB stub
# add_definitions(-DWITH_GDB_DEBUGGER)
set(CMAKE_CXX_STANDARD 14)
set(ASMJIT_STATIC TRUE)
if (NOT CMAKE_BUILD_TYPE)

View File

@ -25,8 +25,11 @@ __Windows__
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
* [Cmake 3.1.0+](http://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)
* [Visual Studio Qt Plugin] (https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
__Linux__
* Qt 5.8+. You can use the same link from earlier (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 libwxgtk3.0-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git`
* Arch: `sudo pacman -S glew openal wxgtk cmake llvm`
@ -40,10 +43,16 @@ Mac OSX is not supported at this moment because it doesn't meet system requireme
### Building
- __Windows__: </br>
1) To initialize the repository don't forget to execute `git submodule update --init` to pull the submodules. </br>
2) Open the *.SLN* file. </br>
3) Build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*. </br>
4) Press *BUILD* > *Build Solution* or *Rebuild Solution*. </br>
To initialize the repository don't forget to execute `git submodule update --init` to pull the submodules. </br>
**_Configuring Qt_** </br>
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):* </br>
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.8\msvc2015_64\` *OR* </br> open the SLN, wait for projects to load, in explorer open `rpcs3qt/rpcs3qt.vcxproj.user` and set `<QTDIR>QtInstallFolder/5.8/msvc2015_64</QTDIR>`
*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>
2) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added. </br>
**_Building the projects_** </br>
1) Build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*. </br>
2) Press *BUILD* > *Build Solution* or *Rebuild Solution*. </br>
- __Linux & Mac OSX__: </br>
1) `git clone https://github.com/RPCS3/rpcs3.git` </br>

View File

@ -12,8 +12,7 @@ configuration:
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 rsx_program_decompiler 3rdparty/cereal 3rdparty/hidapi
- 7z x wxWidgets.7z -aos -oC:\rpcs3\wxWidgets > null
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp rsx_program_decompiler 3rdparty/cereal 3rdparty/zlib 3rdparty/hidapi
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
@ -23,13 +22,12 @@ build_script:
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
install:
- if not exist wxWidgets.7z appveyor DownloadFile "https://dl.dropboxusercontent.com/s/c1by0uulee6g8th/wxWidgets.7z?dl=0" -FileName wxWidgets.7z
- 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=0B8A6NaxhQAGRa21fbDQteTN1dGs" -FileName vulkan.7z
- if not exist zlib.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B6v_qtb9hkicQ2hHa2dRbF83cE0" -FileName zlib.7z
- set WXWIN=C:\rpcs3\wxWidgets
- 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.8\msvc2015_64
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;C:\wxWidgets;%PATH%
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%QTDIR%;%PATH%
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
artifacts:
@ -38,7 +36,6 @@ artifacts:
type: zip
cache:
- wxWidgets.7z -> appveyor.yml
- llvmlibs.7z -> appveyor.yml
- vulkan.7z -> appveyor.yml
- zlib.7z -> appveyor.yml

BIN
bin/Qt5Core.dll Normal file

Binary file not shown.

BIN
bin/Qt5Gui.dll Normal file

Binary file not shown.

BIN
bin/Qt5Widgets.dll Normal file

Binary file not shown.

BIN
bin/Qt5WinExtras.dll Normal file

Binary file not shown.

BIN
bin/imageformats/qicns.dll Normal file

Binary file not shown.

BIN
bin/imageformats/qico.dll Normal file

Binary file not shown.

BIN
bin/platforms/qwindows.dll Normal file

Binary file not shown.

View File

@ -100,72 +100,6 @@
<ProjectReference Include="..\rpcs3\XAudio.vcxproj">
<Project>{78cb2f39-b809-4a06-8329-8c0a19119d3d}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_adv.vcxproj">
<Project>{24c45343-fd20-5c92-81c1-35a2ae841e79}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_aui.vcxproj">
<Project>{a16d3832-0f42-57ce-8f48-50e06649ade8}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_base.vcxproj">
<Project>{3fcc50c2-81e9-5db2-b8d8-2129427568b1}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_core.vcxproj">
<Project>{6744dad8-9c70-574a-bff2-9f8dddb24a75}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_gl.vcxproj">
<Project>{da8b15ef-6750-5928-bc0e-c748213cf9b2}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_html.vcxproj">
<Project>{33cc42f9-7756-5587-863c-8d4461b7c5dd}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_media.vcxproj">
<Project>{8bd8f8d9-4275-5b42-a8f4-f1db2970a550}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_net.vcxproj">
<Project>{69f2ede4-7d21-5738-9bc0-f66f61c9ae00}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_propgrid.vcxproj">
<Project>{97fdab45-9c58-5bc5-a2f4-ee42739ebc63}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_qa.vcxproj">
<Project>{e21129e0-7c08-5936-9d8c-0d60b5319ba7}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_ribbon.vcxproj">
<Project>{87b42a9c-3f5c-53d7-9017-2b1cae39457d}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_richtext.vcxproj">
<Project>{7fb0902d-8579-5dce-b883-daf66a885005}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_stc.vcxproj">
<Project>{23e1c437-a951-5943-8639-a17f3cf2e606}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxexpat.vcxproj">
<Project>{a1a8355b-0988-528e-9cc2-b971d6266669}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxjpeg.vcxproj">
<Project>{6053cc38-cdee-584c-8bc8-4b000d800fc7}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxpng.vcxproj">
<Project>{8acc122a-ca6a-5aa6-9c97-9cdd2e533db0}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxregex.vcxproj">
<Project>{56a4b526-bb81-5d01-aaa9-16d23bbb169d}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxscintilla.vcxproj">
<Project>{74827ebd-93dc-5110-ba95-3f2ab029b6b0}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxtiff.vcxproj">
<Project>{75596ce6-5ae7-55c9-b890-c07b0a657a83}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_wxzlib.vcxproj">
<Project>{8b867186-a0b5-5479-b824-e176edd27c40}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_xml.vcxproj">
<Project>{3e6dca27-5fa3-53ec-bbd6-2d42294b7ae6}</Project>
</ProjectReference>
<ProjectReference Include="..\wxWidgets\build\msw\wx_xrc.vcxproj">
<Project>{09f2f96a-1cc6-5e43-af1d-956ec2a4888d}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

507
rpcs3.sln
View File

@ -1,163 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxproj", "{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}"
ProjectSection(ProjectDependencies) = postProject
{AC40FF01-426E-4838-A317-66354CEFAE88} = {AC40FF01-426E-4838-A317-66354CEFAE88}
{56A4B526-BB81-5D01-AAA9-16D23BBB169D} = {56A4B526-BB81-5D01-AAA9-16D23BBB169D}
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {C4A10229-4712-4BD2-B63E-50D93C67A038}
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0} = {8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}
{7FB0902D-8579-5DCE-B883-DAF66A885005} = {7FB0902D-8579-5DCE-B883-DAF66A885005}
{A16D3832-0F42-57CE-8F48-50E06649ADE8} = {A16D3832-0F42-57CE-8F48-50E06649ADE8}
{23E1C437-A951-5943-8639-A17F3CF2E606} = {23E1C437-A951-5943-8639-A17F3CF2E606}
{6053CC38-CDEE-584C-8BC8-4B000D800FC7} = {6053CC38-CDEE-584C-8BC8-4B000D800FC7}
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63} = {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}
{A1A8355B-0988-528E-9CC2-B971D6266669} = {A1A8355B-0988-528E-9CC2-B971D6266669}
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D} = {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
{97E17077-A21F-45EF-9C3A-73A0BC092D7E} = {97E17077-A21F-45EF-9C3A-73A0BC092D7E}
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F} = {7D73447B-3D2D-4DFE-BF62-57E644C1D09F}
{8B867186-A0B5-5479-B824-E176EDD27C40} = {8B867186-A0B5-5479-B824-E176EDD27C40}
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D} = {87B42A9C-3F5C-53D7-9017-2B1CAE39457D}
{8BC303AB-25BE-4276-8E57-73F171B2D672} = {8BC303AB-25BE-4276-8E57-73F171B2D672}
{74827EBD-93DC-5110-BA95-3F2AB029B6B0} = {74827EBD-93DC-5110-BA95-3F2AB029B6B0}
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550} = {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}
{E21129E0-7C08-5936-9D8C-0D60B5319BA7} = {E21129E0-7C08-5936-9D8C-0D60B5319BA7}
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00} = {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}
{75596CE6-5AE7-55C9-B890-C07B0A657A83} = {75596CE6-5AE7-55C9-B890-C07B0A657A83}
{DA8B15EF-6750-5928-BC0E-C748213CF9B2} = {DA8B15EF-6750-5928-BC0E-C748213CF9B2}
{33CC42F9-7756-5587-863C-8D4461B7C5DD} = {33CC42F9-7756-5587-863C-8D4461B7C5DD}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wxWidgets", "wxWidgets", "{5812E712-6213-4372-B095-9EB9BAA1F2DF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adv", "wxWidgets\build\msw\wx_adv.vcxproj", "{24C45343-FD20-5C92-81C1-35A2AE841E79}"
ProjectSection(ProjectDependencies) = postProject
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aui", "wxWidgets\build\msw\wx_aui.vcxproj", "{A16D3832-0F42-57CE-8F48-50E06649ADE8}"
ProjectSection(ProjectDependencies) = postProject
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
{33CC42F9-7756-5587-863C-8D4461B7C5DD} = {33CC42F9-7756-5587-863C-8D4461B7C5DD}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "wxWidgets\build\msw\wx_base.vcxproj", "{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
{56A4B526-BB81-5D01-AAA9-16D23BBB169D} = {56A4B526-BB81-5D01-AAA9-16D23BBB169D}
{A1A8355B-0988-528E-9CC2-B971D6266669} = {A1A8355B-0988-528E-9CC2-B971D6266669}
{8B867186-A0B5-5479-B824-E176EDD27C40} = {8B867186-A0B5-5479-B824-E176EDD27C40}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "wxWidgets\build\msw\wx_core.vcxproj", "{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "propgrid", "wxWidgets\build\msw\wx_propgrid.vcxproj", "{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}"
ProjectSection(ProjectDependencies) = postProject
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gl", "wxWidgets\build\msw\wx_gl.vcxproj", "{DA8B15EF-6750-5928-BC0E-C748213CF9B2}"
ProjectSection(ProjectDependencies) = postProject
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "html", "wxWidgets\build\msw\wx_html.vcxproj", "{33CC42F9-7756-5587-863C-8D4461B7C5DD}"
ProjectSection(ProjectDependencies) = postProject
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "media", "wxWidgets\build\msw\wx_media.vcxproj", "{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}"
ProjectSection(ProjectDependencies) = postProject
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "wxWidgets\build\msw\wx_net.vcxproj", "{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}"
ProjectSection(ProjectDependencies) = postProject
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qa", "wxWidgets\build\msw\wx_qa.vcxproj", "{E21129E0-7C08-5936-9D8C-0D60B5319BA7}"
ProjectSection(ProjectDependencies) = postProject
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "richtext", "wxWidgets\build\msw\wx_richtext.vcxproj", "{7FB0902D-8579-5DCE-B883-DAF66A885005}"
ProjectSection(ProjectDependencies) = postProject
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxexpat", "wxWidgets\build\msw\wx_wxexpat.vcxproj", "{A1A8355B-0988-528E-9CC2-B971D6266669}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxjpeg", "wxWidgets\build\msw\wx_wxjpeg.vcxproj", "{6053CC38-CDEE-584C-8BC8-4B000D800FC7}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxpng", "wxWidgets\build\msw\wx_wxpng.vcxproj", "{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxregex", "wxWidgets\build\msw\wx_wxregex.vcxproj", "{56A4B526-BB81-5D01-AAA9-16D23BBB169D}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxtiff", "wxWidgets\build\msw\wx_wxtiff.vcxproj", "{75596CE6-5AE7-55C9-B890-C07B0A657A83}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxzlib", "wxWidgets\build\msw\wx_wxzlib.vcxproj", "{8B867186-A0B5-5479-B824-E176EDD27C40}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "wxWidgets\build\msw\wx_xml.vcxproj", "{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "wxWidgets\build\msw\wx_xrc.vcxproj", "{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ribbon", "wxWidgets\build\msw\wx_ribbon.vcxproj", "{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}"
ProjectSection(ProjectDependencies) = postProject
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stc", "wxWidgets\build\msw\wx_stc.vcxproj", "{23E1C437-A951-5943-8639-A17F3CF2E606}"
ProjectSection(ProjectDependencies) = postProject
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxscintilla", "wxWidgets\build\msw\wx_wxscintilla.vcxproj", "{74827EBD-93DC-5110-BA95-3F2AB029B6B0}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "asmjit", "asmjit", "{E2A982F2-4B1A-48B1-8D77-A17A589C58D7}"
@ -166,19 +10,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emucore", "rpcs3\emucore.vc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm_build", "llvm_build\llvm_build.vcxproj", "{8BC303AB-25BE-4276-8E57-73F171B2D672}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_custom_build", "wxWidgets\build\msw\wx_custom_build.vcxproj", "{01F4CE10-2CFB-41A8-B41F-E54337868A1D}"
ProjectSection(ProjectDependencies) = postProject
{00D36322-6188-4A66-B514-3B3F183E998D} = {00D36322-6188-4A66-B514-3B3F183E998D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_setup_h", "rpcs3\copy_setup_h.vcxproj", "{00D36322-6188-4A66-B514-3B3F183E998D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12GSRender", "rpcs3\D3D12GSRender.vcxproj", "{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3-tests", "rpcs3-tests\rpcs3-tests.vcxproj", "{AB222E8A-00CA-4ACF-A87E-5251C16C0587}"
ProjectSection(ProjectDependencies) = postProject
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {01F4CE10-2CFB-41A8-B41F-E54337868A1D}
{00D36322-6188-4A66-B514-3B3F183E998D} = {00D36322-6188-4A66-B514-3B3F183E998D}
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078} = {FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}
{8BC303AB-25BE-4276-8E57-73F171B2D672} = {8BC303AB-25BE-4276-8E57-73F171B2D672}
EndProjectSection
@ -216,15 +51,32 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VKGSRender", "rpcs3\VKGSRen
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webview", "wxWidgets\build\msw\wx_webview.vcxproj", "{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "yaml-cpp", "yaml-cpp", "{DDF904CA-2771-441A-8629-5DF2EB922A79}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__BUILD_BEFORE", "__BUILD_BEFORE", "{B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-cpp", "Utilities\yaml-cpp.vcxproj", "{FDC361C5-7734-493B-8CFB-037308B35122}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hidapi", "hidapi", "{3FDE34DE-0D62-47DE-8570-65F93D2E1B83}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3qt", "rpcs3\rpcs3qt.vcxproj", "{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}"
ProjectSection(ProjectDependencies) = postProject
{AC40FF01-426E-4838-A317-66354CEFAE88} = {AC40FF01-426E-4838-A317-66354CEFAE88}
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {A107C21C-418A-4697-BB10-20C3AA60E2E4}
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {C4A10229-4712-4BD2-B63E-50D93C67A038}
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {78CB2F39-B809-4A06-8329-8C0A19119D3D}
{3384223A-6D97-4799-9862-359F85312892} = {3384223A-6D97-4799-9862-359F85312892}
{30A05C4D-F5FD-421C-A864-17A64BDEAA75} = {30A05C4D-F5FD-421C-A864-17A64BDEAA75}
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
{97E17077-A21F-45EF-9C3A-73A0BC092D7E} = {97E17077-A21F-45EF-9C3A-73A0BC092D7E}
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F} = {7D73447B-3D2D-4DFE-BF62-57E644C1D09F}
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078} = {FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}
{58B40697-B15E-429E-B325-D52C28AEBCBF} = {58B40697-B15E-429E-B325-D52C28AEBCBF}
{FDC361C5-7734-493B-8CFB-037308B35122} = {FDC361C5-7734-493B-8CFB-037308B35122}
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hidapi", "hidapi", "{FA1E6C16-CA63-45F8-8D52-E21DF396BE36}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidapi", "3rdparty\hidapi\windows\hidapi.vcxproj", "{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
EndProject
@ -237,236 +89,6 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Debug - LLVM|x64.Build.0 = Debug - LLVM|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Debug - MemLeak|x64.ActiveCfg = Debug - MemLeak|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Debug - MemLeak|x64.Build.0 = Debug - MemLeak|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Debug|x64.ActiveCfg = Debug|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Debug|x64.Build.0 = Debug|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release - LLVM|x64.ActiveCfg = Release - LLVM|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release - LLVM|x64.Build.0 = Release - LLVM|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release|x64.ActiveCfg = Release|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release|x64.Build.0 = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug - LLVM|x64.Build.0 = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug - MemLeak|x64.Build.0 = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|x64.ActiveCfg = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|x64.Build.0 = Debug|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release - LLVM|x64.ActiveCfg = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release - LLVM|x64.Build.0 = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|x64.ActiveCfg = Release|x64
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|x64.Build.0 = Release|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug - LLVM|x64.Build.0 = Debug|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug - MemLeak|x64.Build.0 = Debug|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|x64.ActiveCfg = Debug|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|x64.Build.0 = Debug|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release - LLVM|x64.ActiveCfg = Release|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release - LLVM|x64.Build.0 = Release|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|x64.ActiveCfg = Release|x64
{A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug - LLVM|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug - MemLeak|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release - LLVM|x64.ActiveCfg = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release - LLVM|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug - LLVM|x64.Build.0 = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug - MemLeak|x64.Build.0 = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.ActiveCfg = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.Build.0 = Debug|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release - LLVM|x64.ActiveCfg = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release - LLVM|x64.Build.0 = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.ActiveCfg = Release|x64
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.Build.0 = Release|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug - LLVM|x64.Build.0 = Debug|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug - MemLeak|x64.Build.0 = Debug|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug|x64.ActiveCfg = Debug|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug|x64.Build.0 = Debug|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release - LLVM|x64.ActiveCfg = Release|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release - LLVM|x64.Build.0 = Release|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release|x64.ActiveCfg = Release|x64
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release|x64.Build.0 = Release|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Debug - LLVM|x64.Build.0 = Debug|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Debug - MemLeak|x64.Build.0 = Debug|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Debug|x64.ActiveCfg = Debug|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Debug|x64.Build.0 = Debug|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Release - LLVM|x64.ActiveCfg = Release|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Release - LLVM|x64.Build.0 = Release|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Release|x64.ActiveCfg = Release|x64
{DA8B15EF-6750-5928-BC0E-C748213CF9B2}.Release|x64.Build.0 = Release|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug - LLVM|x64.Build.0 = Debug|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug - MemLeak|x64.Build.0 = Debug|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug|x64.ActiveCfg = Debug|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug|x64.Build.0 = Debug|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release - LLVM|x64.ActiveCfg = Release|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release - LLVM|x64.Build.0 = Release|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release|x64.ActiveCfg = Release|x64
{33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release|x64.Build.0 = Release|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug - LLVM|x64.Build.0 = Debug|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug - MemLeak|x64.Build.0 = Debug|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug|x64.ActiveCfg = Debug|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug|x64.Build.0 = Debug|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release - LLVM|x64.ActiveCfg = Release|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release - LLVM|x64.Build.0 = Release|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release|x64.ActiveCfg = Release|x64
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release|x64.Build.0 = Release|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug - LLVM|x64.Build.0 = Debug|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug - MemLeak|x64.Build.0 = Debug|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|x64.ActiveCfg = Debug|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|x64.Build.0 = Debug|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release - LLVM|x64.ActiveCfg = Release|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release - LLVM|x64.Build.0 = Release|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|x64.ActiveCfg = Release|x64
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|x64.Build.0 = Release|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Debug - LLVM|x64.Build.0 = Debug|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Debug - MemLeak|x64.Build.0 = Debug|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Debug|x64.ActiveCfg = Debug|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Debug|x64.Build.0 = Debug|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Release - LLVM|x64.ActiveCfg = Release|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Release - LLVM|x64.Build.0 = Release|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Release|x64.ActiveCfg = Release|x64
{E21129E0-7C08-5936-9D8C-0D60B5319BA7}.Release|x64.Build.0 = Release|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug - LLVM|x64.Build.0 = Debug|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug - MemLeak|x64.Build.0 = Debug|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug|x64.ActiveCfg = Debug|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug|x64.Build.0 = Debug|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Release - LLVM|x64.ActiveCfg = Release|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Release - LLVM|x64.Build.0 = Release|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Release|x64.ActiveCfg = Release|x64
{7FB0902D-8579-5DCE-B883-DAF66A885005}.Release|x64.Build.0 = Release|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Debug - LLVM|x64.Build.0 = Debug|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Debug - MemLeak|x64.Build.0 = Debug|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Debug|x64.ActiveCfg = Debug|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Debug|x64.Build.0 = Debug|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Release - LLVM|x64.ActiveCfg = Release|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Release - LLVM|x64.Build.0 = Release|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Release|x64.ActiveCfg = Release|x64
{A1A8355B-0988-528E-9CC2-B971D6266669}.Release|x64.Build.0 = Release|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Debug - LLVM|x64.Build.0 = Debug|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Debug - MemLeak|x64.Build.0 = Debug|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Debug|x64.ActiveCfg = Debug|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Debug|x64.Build.0 = Debug|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Release - LLVM|x64.ActiveCfg = Release|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Release - LLVM|x64.Build.0 = Release|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Release|x64.ActiveCfg = Release|x64
{6053CC38-CDEE-584C-8BC8-4B000D800FC7}.Release|x64.Build.0 = Release|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Debug - LLVM|x64.Build.0 = Debug|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Debug - MemLeak|x64.Build.0 = Debug|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Debug|x64.ActiveCfg = Debug|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Debug|x64.Build.0 = Debug|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Release - LLVM|x64.ActiveCfg = Release|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Release - LLVM|x64.Build.0 = Release|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Release|x64.ActiveCfg = Release|x64
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0}.Release|x64.Build.0 = Release|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Debug - LLVM|x64.Build.0 = Debug|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Debug - MemLeak|x64.Build.0 = Debug|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Debug|x64.ActiveCfg = Debug|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Debug|x64.Build.0 = Debug|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Release - LLVM|x64.ActiveCfg = Release|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Release - LLVM|x64.Build.0 = Release|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Release|x64.ActiveCfg = Release|x64
{56A4B526-BB81-5D01-AAA9-16D23BBB169D}.Release|x64.Build.0 = Release|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Debug - LLVM|x64.Build.0 = Debug|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Debug - MemLeak|x64.Build.0 = Debug|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Debug|x64.ActiveCfg = Debug|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Debug|x64.Build.0 = Debug|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Release - LLVM|x64.ActiveCfg = Release|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Release - LLVM|x64.Build.0 = Release|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Release|x64.ActiveCfg = Release|x64
{75596CE6-5AE7-55C9-B890-C07B0A657A83}.Release|x64.Build.0 = Release|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Debug - LLVM|x64.Build.0 = Debug|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Debug - MemLeak|x64.Build.0 = Debug|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Debug|x64.ActiveCfg = Debug|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Debug|x64.Build.0 = Debug|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Release - LLVM|x64.ActiveCfg = Release|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Release - LLVM|x64.Build.0 = Release|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Release|x64.ActiveCfg = Release|x64
{8B867186-A0B5-5479-B824-E176EDD27C40}.Release|x64.Build.0 = Release|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug - LLVM|x64.Build.0 = Debug|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug - MemLeak|x64.Build.0 = Debug|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|x64.ActiveCfg = Debug|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|x64.Build.0 = Debug|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release - LLVM|x64.ActiveCfg = Release|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release - LLVM|x64.Build.0 = Release|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|x64.ActiveCfg = Release|x64
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|x64.Build.0 = Release|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug - LLVM|x64.Build.0 = Debug|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug - MemLeak|x64.Build.0 = Debug|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug|x64.ActiveCfg = Debug|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug|x64.Build.0 = Debug|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release - LLVM|x64.ActiveCfg = Release|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release - LLVM|x64.Build.0 = Release|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release|x64.ActiveCfg = Release|x64
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release|x64.Build.0 = Release|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Debug - LLVM|x64.Build.0 = Debug|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Debug - MemLeak|x64.Build.0 = Debug|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Debug|x64.ActiveCfg = Debug|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Debug|x64.Build.0 = Debug|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Release - LLVM|x64.ActiveCfg = Release|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Release - LLVM|x64.Build.0 = Release|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Release|x64.ActiveCfg = Release|x64
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}.Release|x64.Build.0 = Release|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Debug - LLVM|x64.Build.0 = Debug|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Debug - MemLeak|x64.Build.0 = Debug|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Debug|x64.ActiveCfg = Debug|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Debug|x64.Build.0 = Debug|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Release - LLVM|x64.ActiveCfg = Release|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Release - LLVM|x64.Build.0 = Release|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Release|x64.ActiveCfg = Release|x64
{23E1C437-A951-5943-8639-A17F3CF2E606}.Release|x64.Build.0 = Release|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Debug - LLVM|x64.Build.0 = Debug|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Debug - MemLeak|x64.Build.0 = Debug|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Debug|x64.ActiveCfg = Debug|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Debug|x64.Build.0 = Debug|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release - LLVM|x64.ActiveCfg = Release|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release - LLVM|x64.Build.0 = Release|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release|x64.ActiveCfg = Release|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release|x64.Build.0 = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - LLVM|x64.Build.0 = Debug - LLVM|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - MemLeak|x64.ActiveCfg = Debug - MemLeak|x64
@ -492,26 +114,6 @@ Global
{8BC303AB-25BE-4276-8E57-73F171B2D672}.Debug|x64.ActiveCfg = Debug|x64
{8BC303AB-25BE-4276-8E57-73F171B2D672}.Release - LLVM|x64.ActiveCfg = Release|x64
{8BC303AB-25BE-4276-8E57-73F171B2D672}.Release|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug - LLVM|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug - MemLeak|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release - LLVM|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release - LLVM|x64.Build.0 = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.Build.0 = Release|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Debug - LLVM|x64.Build.0 = Debug|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Debug - MemLeak|x64.Build.0 = Debug|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Debug|x64.ActiveCfg = Debug|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Debug|x64.Build.0 = Debug|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Release - LLVM|x64.ActiveCfg = Release|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Release - LLVM|x64.Build.0 = Release|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Release|x64.ActiveCfg = Release|x64
{00D36322-6188-4A66-B514-3B3F183E998D}.Release|x64.Build.0 = Release|x64
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}.Debug - LLVM|x64.Build.0 = Debug - LLVM|x64
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}.Debug - MemLeak|x64.ActiveCfg = Debug - MemLeak|x64
@ -587,16 +189,16 @@ Global
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release - LLVM|x64.Build.0 = Release Library|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.ActiveCfg = Release Library|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.Build.0 = Release Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - LLVM|x64.ActiveCfg = Debug Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - LLVM|x64.Build.0 = Debug Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - MemLeak|x64.ActiveCfg = Debug Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - MemLeak|x64.Build.0 = Debug Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|x64.ActiveCfg = Debug Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|x64.Build.0 = Debug Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release - LLVM|x64.ActiveCfg = Release Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release - LLVM|x64.Build.0 = Release Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|x64.ActiveCfg = Release Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|x64.Build.0 = Release Library|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - LLVM|x64.Build.0 = Debug|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - MemLeak|x64.Build.0 = Debug|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|x64.ActiveCfg = Debug|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|x64.Build.0 = Debug|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release - LLVM|x64.ActiveCfg = Release|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release - LLVM|x64.Build.0 = Release|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|x64.ActiveCfg = Release|x64
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|x64.Build.0 = Release|x64
{58B40697-B15E-429E-B325-D52C28AEBCBF}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{58B40697-B15E-429E-B325-D52C28AEBCBF}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{58B40697-B15E-429E-B325-D52C28AEBCBF}.Debug|x64.ActiveCfg = Debug|x64
@ -617,16 +219,6 @@ Global
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}.Release - LLVM|x64.Build.0 = Release - LLVM|x64
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}.Release|x64.ActiveCfg = Release|x64
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}.Release|x64.Build.0 = Release|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug - LLVM|x64.Build.0 = Debug|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug - MemLeak|x64.Build.0 = Debug|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug|x64.ActiveCfg = Debug|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug|x64.Build.0 = Debug|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release - LLVM|x64.ActiveCfg = Release|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release - LLVM|x64.Build.0 = Release|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release|x64.ActiveCfg = Release|x64
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release|x64.Build.0 = Release|x64
{FDC361C5-7734-493B-8CFB-037308B35122}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{FDC361C5-7734-493B-8CFB-037308B35122}.Debug - LLVM|x64.Build.0 = Debug|x64
{FDC361C5-7734-493B-8CFB-037308B35122}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
@ -637,6 +229,16 @@ Global
{FDC361C5-7734-493B-8CFB-037308B35122}.Release - LLVM|x64.Build.0 = Release|x64
{FDC361C5-7734-493B-8CFB-037308B35122}.Release|x64.ActiveCfg = Release|x64
{FDC361C5-7734-493B-8CFB-037308B35122}.Release|x64.Build.0 = Release|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Debug - LLVM|x64.Build.0 = Debug - LLVM|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Debug - MemLeak|x64.Build.0 = Debug|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Debug|x64.ActiveCfg = Debug|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Debug|x64.Build.0 = Debug|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Release - LLVM|x64.ActiveCfg = Release - LLVM|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Release - LLVM|x64.Build.0 = Release - LLVM|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Release|x64.ActiveCfg = Release|x64
{D0EC0F82-3BED-3CE4-8DEC-3BCF71B08B69}.Release|x64.Build.0 = Release|x64
{A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug - LLVM|x64.Build.0 = Debug|x64
{A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
@ -652,33 +254,9 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{A16D3832-0F42-57CE-8F48-50E06649ADE8} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{DA8B15EF-6750-5928-BC0E-C748213CF9B2} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{33CC42F9-7756-5587-863C-8D4461B7C5DD} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{E21129E0-7C08-5936-9D8C-0D60B5319BA7} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{7FB0902D-8579-5DCE-B883-DAF66A885005} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{A1A8355B-0988-528E-9CC2-B971D6266669} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{6053CC38-CDEE-584C-8BC8-4B000D800FC7} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{8ACC122A-CA6A-5AA6-9C97-9CDD2E533DB0} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{56A4B526-BB81-5D01-AAA9-16D23BBB169D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{75596CE6-5AE7-55C9-B890-C07B0A657A83} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{8B867186-A0B5-5479-B824-E176EDD27C40} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{23E1C437-A951-5943-8639-A17F3CF2E606} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{74827EBD-93DC-5110-BA95-3F2AB029B6B0} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{AC40FF01-426E-4838-A317-66354CEFAE88} = {E2A982F2-4B1A-48B1-8D77-A17A589C58D7}
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{8BC303AB-25BE-4276-8E57-73F171B2D672} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{00D36322-6188-4A66-B514-3B3F183E998D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{3384223A-6D97-4799-9862-359F85312892} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
@ -689,8 +267,7 @@ Global
{58B40697-B15E-429E-B325-D52C28AEBCBF} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{A8E8442A-078A-5FC5-B495-8D71BA77EE6E} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{FDC361C5-7734-493B-8CFB-037308B35122} = {DDF904CA-2771-441A-8629-5DF2EB922A79}
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {3FDE34DE-0D62-47DE-8570-65F93D2E1B83}
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {FA1E6C16-CA63-45F8-8D52-E21DF396BE36}
EndGlobalSection
EndGlobal

View File

@ -1,170 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "rpcs3.h"
#include "BasicKeyboardHandler.h"
void BasicKeyboardHandler::Init(const u32 max_connect)
{
for (u32 i = 0; i<max_connect; i++)
{
m_keyboards.emplace_back(Keyboard());
}
LoadSettings();
memset(&m_info, 0, sizeof(KbInfo));
m_info.max_connect = max_connect;
m_info.now_connect = std::min<size_t>(m_keyboards.size(), max_connect);
m_info.info = 0; // Ownership of keyboard data: 0=Application, 1=System
m_info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards)
}
BasicKeyboardHandler::BasicKeyboardHandler()
{
wxGetApp().Bind(wxEVT_KEY_DOWN, &BasicKeyboardHandler::KeyDown, this);
wxGetApp().Bind(wxEVT_KEY_UP, &BasicKeyboardHandler::KeyUp, this);
}
void BasicKeyboardHandler::KeyDown(wxKeyEvent& event)
{
Key(event.GetKeyCode(), 1);
event.Skip();
}
void BasicKeyboardHandler::KeyUp(wxKeyEvent& event)
{
Key(event.GetKeyCode(), 0);
event.Skip();
}
void BasicKeyboardHandler::LoadSettings()
{
// Meta Keys
m_keyboards[0].m_buttons.emplace_back(WXK_CONTROL, CELL_KB_MKEY_L_CTRL);
m_keyboards[0].m_buttons.emplace_back(WXK_SHIFT, CELL_KB_MKEY_L_SHIFT);
m_keyboards[0].m_buttons.emplace_back(WXK_ALT, CELL_KB_MKEY_L_ALT);
m_keyboards[0].m_buttons.emplace_back(WXK_WINDOWS_LEFT, CELL_KB_MKEY_L_WIN);
m_keyboards[0].m_buttons.emplace_back(WXK_COMMAND, CELL_KB_MKEY_L_WIN);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KB_MKEY_R_CTRL);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KB_MKEY_R_SHIFT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KB_MKEY_R_ALT);
m_keyboards[0].m_buttons.emplace_back(WXK_WINDOWS_RIGHT, CELL_KB_MKEY_R_WIN);
// CELL_KB_RAWDAT
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_NO_EVENT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_ROLLOVER);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_POSTFAIL);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_UNDEF);
m_keyboards[0].m_buttons.emplace_back(WXK_ESCAPE, CELL_KEYC_ESCAPE);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_106_KANJI);
m_keyboards[0].m_buttons.emplace_back(WXK_CAPITAL, CELL_KEYC_CAPS_LOCK);
m_keyboards[0].m_buttons.emplace_back(WXK_F1, CELL_KEYC_F1);
m_keyboards[0].m_buttons.emplace_back(WXK_F2, CELL_KEYC_F2);
m_keyboards[0].m_buttons.emplace_back(WXK_F3, CELL_KEYC_F3);
m_keyboards[0].m_buttons.emplace_back(WXK_F4, CELL_KEYC_F4);
m_keyboards[0].m_buttons.emplace_back(WXK_F5, CELL_KEYC_F5);
m_keyboards[0].m_buttons.emplace_back(WXK_F6, CELL_KEYC_F6);
m_keyboards[0].m_buttons.emplace_back(WXK_F7, CELL_KEYC_F7);
m_keyboards[0].m_buttons.emplace_back(WXK_F8, CELL_KEYC_F8);
m_keyboards[0].m_buttons.emplace_back(WXK_F9, CELL_KEYC_F9);
m_keyboards[0].m_buttons.emplace_back(WXK_F10, CELL_KEYC_F10);
m_keyboards[0].m_buttons.emplace_back(WXK_F11, CELL_KEYC_F11);
m_keyboards[0].m_buttons.emplace_back(WXK_F12, CELL_KEYC_F12);
m_keyboards[0].m_buttons.emplace_back(WXK_PRINT, CELL_KEYC_PRINTSCREEN);
m_keyboards[0].m_buttons.emplace_back(WXK_SCROLL, CELL_KEYC_SCROLL_LOCK);
m_keyboards[0].m_buttons.emplace_back(WXK_PAUSE, CELL_KEYC_PAUSE);
m_keyboards[0].m_buttons.emplace_back(WXK_INSERT, CELL_KEYC_INSERT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_HOME);
m_keyboards[0].m_buttons.emplace_back(WXK_PAGEUP, CELL_KEYC_PAGE_UP);
m_keyboards[0].m_buttons.emplace_back(WXK_DELETE, CELL_KEYC_DELETE);
m_keyboards[0].m_buttons.emplace_back(WXK_END, CELL_KEYC_END);
m_keyboards[0].m_buttons.emplace_back(WXK_PAGEDOWN, CELL_KEYC_PAGE_DOWN);
m_keyboards[0].m_buttons.emplace_back(WXK_RIGHT, CELL_KEYC_RIGHT_ARROW);
m_keyboards[0].m_buttons.emplace_back(WXK_LEFT, CELL_KEYC_LEFT_ARROW);
m_keyboards[0].m_buttons.emplace_back(WXK_DOWN, CELL_KEYC_DOWN_ARROW);
m_keyboards[0].m_buttons.emplace_back(WXK_UP, CELL_KEYC_UP_ARROW);
//m_keyboards[0].m_buttons.emplace_back(WXK_NUMLOCK, CELL_KEYC_NUM_LOCK);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_APPLICATION);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_KANA);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_HENKAN);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_MUHENKAN);
// CELL_KB_KEYPAD
m_keyboards[0].m_buttons.emplace_back(WXK_NUMLOCK, CELL_KEYC_KPAD_NUMLOCK);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD_DIVIDE, CELL_KEYC_KPAD_SLASH);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD_MULTIPLY, CELL_KEYC_KPAD_ASTERISK);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD_SUBTRACT, CELL_KEYC_KPAD_MINUS);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD_ADD, CELL_KEYC_KPAD_PLUS);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD_ENTER, CELL_KEYC_KPAD_ENTER);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD1, CELL_KEYC_KPAD_1);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD2, CELL_KEYC_KPAD_2);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD3, CELL_KEYC_KPAD_3);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD4, CELL_KEYC_KPAD_4);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD5, CELL_KEYC_KPAD_5);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD6, CELL_KEYC_KPAD_6);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD7, CELL_KEYC_KPAD_7);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD8, CELL_KEYC_KPAD_8);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD9, CELL_KEYC_KPAD_9);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD0, CELL_KEYC_KPAD_0);
m_keyboards[0].m_buttons.emplace_back(WXK_NUMPAD_DELETE, CELL_KEYC_KPAD_PERIOD);
// ASCII Printable characters
m_keyboards[0].m_buttons.emplace_back('A', CELL_KEYC_A);
m_keyboards[0].m_buttons.emplace_back('B', CELL_KEYC_B);
m_keyboards[0].m_buttons.emplace_back('C', CELL_KEYC_C);
m_keyboards[0].m_buttons.emplace_back('D', CELL_KEYC_D);
m_keyboards[0].m_buttons.emplace_back('E', CELL_KEYC_E);
m_keyboards[0].m_buttons.emplace_back('F', CELL_KEYC_F);
m_keyboards[0].m_buttons.emplace_back('G', CELL_KEYC_G);
m_keyboards[0].m_buttons.emplace_back('H', CELL_KEYC_H);
m_keyboards[0].m_buttons.emplace_back('I', CELL_KEYC_I);
m_keyboards[0].m_buttons.emplace_back('J', CELL_KEYC_J);
m_keyboards[0].m_buttons.emplace_back('K', CELL_KEYC_K);
m_keyboards[0].m_buttons.emplace_back('L', CELL_KEYC_L);
m_keyboards[0].m_buttons.emplace_back('M', CELL_KEYC_M);
m_keyboards[0].m_buttons.emplace_back('N', CELL_KEYC_N);
m_keyboards[0].m_buttons.emplace_back('O', CELL_KEYC_O);
m_keyboards[0].m_buttons.emplace_back('P', CELL_KEYC_P);
m_keyboards[0].m_buttons.emplace_back('Q', CELL_KEYC_Q);
m_keyboards[0].m_buttons.emplace_back('R', CELL_KEYC_R);
m_keyboards[0].m_buttons.emplace_back('S', CELL_KEYC_S);
m_keyboards[0].m_buttons.emplace_back('T', CELL_KEYC_T);
m_keyboards[0].m_buttons.emplace_back('U', CELL_KEYC_U);
m_keyboards[0].m_buttons.emplace_back('V', CELL_KEYC_V);
m_keyboards[0].m_buttons.emplace_back('W', CELL_KEYC_W);
m_keyboards[0].m_buttons.emplace_back('X', CELL_KEYC_X);
m_keyboards[0].m_buttons.emplace_back('Y', CELL_KEYC_Y);
m_keyboards[0].m_buttons.emplace_back('Z', CELL_KEYC_Z);
m_keyboards[0].m_buttons.emplace_back('1', CELL_KEYC_1);
m_keyboards[0].m_buttons.emplace_back('2', CELL_KEYC_2);
m_keyboards[0].m_buttons.emplace_back('3', CELL_KEYC_3);
m_keyboards[0].m_buttons.emplace_back('4', CELL_KEYC_4);
m_keyboards[0].m_buttons.emplace_back('5', CELL_KEYC_5);
m_keyboards[0].m_buttons.emplace_back('6', CELL_KEYC_6);
m_keyboards[0].m_buttons.emplace_back('7', CELL_KEYC_7);
m_keyboards[0].m_buttons.emplace_back('8', CELL_KEYC_8);
m_keyboards[0].m_buttons.emplace_back('9', CELL_KEYC_9);
m_keyboards[0].m_buttons.emplace_back('0', CELL_KEYC_0);
m_keyboards[0].m_buttons.emplace_back(WXK_RETURN, CELL_KEYC_ENTER);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_ESC);
m_keyboards[0].m_buttons.emplace_back(WXK_TAB, CELL_KEYC_TAB);
m_keyboards[0].m_buttons.emplace_back(WXK_SPACE, CELL_KEYC_SPACE);
m_keyboards[0].m_buttons.emplace_back(WXK_SUBTRACT, CELL_KEYC_MINUS);
m_keyboards[0].m_buttons.emplace_back('=', CELL_KEYC_EQUAL_101);
m_keyboards[0].m_buttons.emplace_back('^', CELL_KEYC_ACCENT_CIRCONFLEX_106);
//m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_LEFT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back('@', CELL_KEYC_ATMARK_106);
//m_keyboards[0].m_buttons.emplace_back(')', CELL_KEYC_RIGHT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_LEFT_BRACKET_106);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_BACKSLASH_101);
m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_RIGHT_BRACKET_106);
m_keyboards[0].m_buttons.emplace_back(';', CELL_KEYC_SEMICOLON);
m_keyboards[0].m_buttons.emplace_back('"', CELL_KEYC_QUOTATION_101);
m_keyboards[0].m_buttons.emplace_back(':', CELL_KEYC_COLON_106);
m_keyboards[0].m_buttons.emplace_back(',', CELL_KEYC_COMMA);
m_keyboards[0].m_buttons.emplace_back('.', CELL_KEYC_PERIOD);
m_keyboards[0].m_buttons.emplace_back('/', CELL_KEYC_SLASH);
m_keyboards[0].m_buttons.emplace_back('\\', CELL_KEYC_BACKSLASH_106);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_YEN_106);
}

View File

@ -1,15 +0,0 @@
#pragma once
#include "Emu/Io/KeyboardHandler.h"
class BasicKeyboardHandler final : public KeyboardHandlerBase, public wxWindow
{
public:
virtual void Init(const u32 max_connect) override;
BasicKeyboardHandler();
void KeyDown(wxKeyEvent& event);
void KeyUp(wxKeyEvent& event);
void LoadSettings();
};

View File

@ -1,57 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "rpcs3.h"
#include "BasicMouseHandler.h"
void BasicMouseHandler::Init(const u32 max_connect)
{
m_mice.emplace_back(Mouse());
memset(&m_info, 0, sizeof(MouseInfo));
m_info.max_connect = max_connect;
m_info.now_connect = std::min(m_mice.size(), (size_t)max_connect);
m_info.info = 0; // Ownership of mouse data: 0=Application, 1=System
m_info.status[0] = CELL_MOUSE_STATUS_CONNECTED; // (TODO: Support for more mice)
for (u32 i = 1; i<max_connect; i++) m_info.status[i] = CELL_MOUSE_STATUS_DISCONNECTED;
m_info.vendor_id[0] = 0x1234;
m_info.product_id[0] = 0x1234;
}
BasicMouseHandler::BasicMouseHandler()
{
wxGetApp().Bind(wxEVT_LEFT_DOWN, &BasicMouseHandler::MouseButtonDown, this);
wxGetApp().Bind(wxEVT_RIGHT_DOWN, &BasicMouseHandler::MouseButtonDown, this);
wxGetApp().Bind(wxEVT_MIDDLE_DOWN, &BasicMouseHandler::MouseButtonDown, this);
wxGetApp().Bind(wxEVT_LEFT_UP, &BasicMouseHandler::MouseButtonUp, this);
wxGetApp().Bind(wxEVT_RIGHT_UP, &BasicMouseHandler::MouseButtonUp, this);
wxGetApp().Bind(wxEVT_MIDDLE_UP, &BasicMouseHandler::MouseButtonUp, this);
wxGetApp().Bind(wxEVT_MOUSEWHEEL, &BasicMouseHandler::MouseScroll, this);
wxGetApp().Bind(wxEVT_MOTION, &BasicMouseHandler::MouseMove, this);
}
void BasicMouseHandler::MouseButtonDown(wxMouseEvent& event)
{
if (event.LeftDown()) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_1, 1);
else if (event.RightDown()) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_2, 1);
else if (event.MiddleDown()) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_3, 1);
event.Skip();
}
void BasicMouseHandler::MouseButtonUp(wxMouseEvent& event)
{
if (event.LeftUp()) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_1, 0);
else if (event.RightUp()) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_2, 0);
else if (event.MiddleUp()) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_3, 0);
event.Skip();
}
void BasicMouseHandler::MouseScroll(wxMouseEvent& event)
{
MouseHandlerBase::Scroll(event.GetWheelRotation());
event.Skip();
}
void BasicMouseHandler::MouseMove(wxMouseEvent& event)
{
MouseHandlerBase::Move(event.m_x, event.m_y);
event.Skip();
}

View File

@ -1,16 +0,0 @@
#pragma once
#include "Emu/Io/MouseHandler.h"
class BasicMouseHandler final : public MouseHandlerBase, public wxWindow
{
public:
virtual void Init(const u32 max_connect) override;
BasicMouseHandler();
void MouseButtonDown(wxMouseEvent& event);
void MouseButtonUp(wxMouseEvent& event);
void MouseScroll(wxMouseEvent& event);
void MouseMove(wxMouseEvent& event);
};

View File

@ -2,10 +2,31 @@ cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(RES_FILES "")
# Qt section
find_package(Qt5 REQUIRED 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()
set(RPCS3_QT_LIBS Qt5::Widgets)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
endif()
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON)
if (Qt5_POSITION_INDEPENDENT_CODE)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(UNIX)
# Cotire needs this set for some reason
SET(CMAKE_CXX_COMPILE_OPTIONS_PIE -fPIC)
endif()
endif()
include(cotire)
project(rpcs3)
# Generate git-version.h at build time.
add_custom_target(GitVersion ALL
DEPENDS something_that_never_exists)
@ -17,6 +38,7 @@ add_custom_command(OUTPUT something_that_never_exists
include(ConfigureCompiler)
if(WIN32)
add_definitions(-DUNICODE)
add_definitions(-D_WIN32_WINNT=0x0601)
@ -29,7 +51,6 @@ if(WIN32)
endif()
if(NOT MSVC)
add_definitions(-DwxGUI)
if($ENV{CI})
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1") # fix for travis gcc OoM crash. Might be fixed with the move to containers.
endif()
@ -72,8 +93,6 @@ if(NOT WIN32)
add_definitions(-DGLX_GLXEXT_PROTOTYPES)
endif()
set(wxWidgets_USE_STATIC ON)
find_package(wxWidgets COMPONENTS core base net aui gl xml REQUIRED)
if(NOT MSVC)
if(APPLE)
find_path(GLEW_INCLUDE_DIR GL/glew.h
@ -94,7 +113,6 @@ find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
find_package(LLVM 4.0 CONFIG)
include("${wxWidgets_USE_FILE}")
if(APPLE)
set(PLATFORM_ARCH "macosx/x86_64")
@ -126,7 +144,6 @@ endif()
include_directories(
${GLEW_INCLUDE_DIR}
${wxWidgets_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}
${LLVM_INCLUDE_DIRS}
@ -183,6 +200,7 @@ link_directories(
"${RPCS3_SRC_DIR}/../Vulkan"
)
if(NOT USE_SYSTEM_FFMPEG)
if(MSVC OR NOT WIN32)
link_directories("${RPCS3_SRC_DIR}/../3rdparty/ffmpeg/${PLATFORM_ARCH}/lib")
@ -214,8 +232,20 @@ if(NOT WIN32)
endforeach(TMP_PATH)
endif()
add_executable(rpcs3 ${RPCS3_SRC} ${RES_FILES})
# The Gui folder contains wxWidgets stuff, which we no longer want.
foreach (TMP_PATH ${RPCS3_SRC})
set (EXCLUDE_DIR "/Gui/")
string (FIND ${TMP_PATH} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND)
if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1)
list (REMOVE_ITEM RPCS3_SRC ${TMP_PATH})
endif ()
endforeach(TMP_PATH)
if (WIN32)
add_executable(rpcs3 WIN32 ${RPCS3_SRC} ${RES_FILES} resources.qrc)
else()
add_executable(rpcs3 ${RPCS3_SRC} ${RES_FILES} resources.qrc)
endif()
if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib")
@ -223,16 +253,18 @@ if(MSVC)
endif()
if(WIN32)
target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib VKstatic.1 glslang OSDependent OGLCompiler SPIRV HLSL setupapi.lib hidapi-hid)
target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib VKstatic.1 glslang OSDependent OGLCompiler SPIRV HLSL setupapi.lib hidapi-hid Shlwapi.lib)
if(NOT MSVC)
target_link_libraries(rpcs3 ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} opengl32.lib glu32.lib libpthread)
else()
target_link_libraries(rpcs3 dxgi.lib d2d1.lib dwrite.lib)
endif()
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
else()
target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES} hidapi-hidraw udev)
target_link_libraries(rpcs3 -ldl -latomic ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES} hidapi-hidraw udev)
target_link_libraries(rpcs3 -ldl -latomic -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
if (USE_SYSTEM_FFMPEG)
link_libraries(${FFMPEG_LIBRARY_DIR})
target_link_libraries(rpcs3 libavformat.so libavcodec.so libavutil.so libswresample.so libswscale.so)
@ -253,3 +285,6 @@ target_link_libraries(rpcs3 rsx_decompiler shader_code)
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
cotire(rpcs3)
target_link_libraries(rpcs3 ${RPCS3_QT_LIBS})

View File

@ -6,7 +6,6 @@
#include "Emu/VFS.h"
#include <algorithm>
// TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions?
#include <zlib.h>
inline u8 Read8(const fs::file& f)

View File

@ -43,21 +43,6 @@ extern std::shared_ptr<struct lv2_prx> ppu_load_prx(const ppu_prx_object&, const
fs::file g_tty;
template <>
void fmt_class_string<keyboard_handler>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](keyboard_handler value)
{
switch (value)
{
case keyboard_handler::null: return "Null";
case keyboard_handler::basic: return "Basic";
}
return unknown;
});
}
template <>
void fmt_class_string<mouse_handler>::format(std::string& out, u64 arg)
{
@ -116,26 +101,6 @@ void fmt_class_string<video_renderer>::format(std::string& out, u64 arg)
});
}
template <>
void fmt_class_string<audio_renderer>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](audio_renderer value)
{
switch (value)
{
case audio_renderer::null: return "Null";
#ifdef _WIN32
case audio_renderer::xaudio: return "XAudio2";
#elif __linux__
case audio_renderer::alsa: return "ALSA";
#endif
case audio_renderer::openal: return "OpenAL";
}
return unknown;
});
}
template <>
void fmt_class_string<video_resolution>::format(std::string& out, u64 arg)
{
@ -173,12 +138,40 @@ void fmt_class_string<video_aspect>::format(std::string& out, u64 arg)
});
}
namespace rpcs3
template <>
void fmt_class_string<keyboard_handler>::format(std::string& out, u64 arg)
{
event<void>& on_run() { static event<void> on_run; return on_run; }
event<void>& on_stop() { static event<void> on_stop; return on_stop; }
event<void>& on_pause() { static event<void> on_pause; return on_pause; }
event<void>& on_resume() { static event<void> on_resume; return on_resume; }
format_enum(out, arg, [](keyboard_handler value)
{
switch (value)
{
case keyboard_handler::null: return "Null";
case keyboard_handler::basic: return "Basic";
}
return unknown;
});
}
template <>
void fmt_class_string<audio_renderer>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](audio_renderer value)
{
switch (value)
{
case audio_renderer::null: return "Null";
#ifdef _WIN32
case audio_renderer::xaudio: return "XAudio2";
#elif __linux__
case audio_renderer::alsa: return "ALSA";
#endif
case audio_renderer::openal: return "OpenAL";
}
return unknown;
});
}
void Emulator::Init()
@ -425,6 +418,8 @@ void Emulator::Load()
// PS3 executable
g_system = system_type::ps3;
m_state = system_state::ready;
GetCallbacks().on_ready();
vm::ps3::init();
if (m_elf_path.empty())
@ -442,6 +437,7 @@ void Emulator::Load()
// PPU PRX (experimental)
g_system = system_type::ps3;
m_state = system_state::ready;
GetCallbacks().on_ready();
vm::ps3::init();
ppu_load_prx(ppu_prx, "");
}
@ -450,6 +446,7 @@ void Emulator::Load()
// SPU executable (experimental)
g_system = system_type::ps3;
m_state = system_state::ready;
GetCallbacks().on_ready();
vm::ps3::init();
spu_load_exec(spu_exec);
}
@ -458,6 +455,7 @@ void Emulator::Load()
// ARMv7 executable
g_system = system_type::psv;
m_state = system_state::ready;
GetCallbacks().on_ready();
vm::psv::init();
if (m_elf_path.empty())
@ -486,6 +484,7 @@ void Emulator::Load()
else if (IsPaused())
{
m_state = system_state::ready;
GetCallbacks().on_ready();
}
}
catch (const std::exception& e)
@ -511,7 +510,8 @@ void Emulator::Run()
return;
}
rpcs3::on_run()();
GetCallbacks().on_run();
m_pause_start_time = 0;
m_pause_amend_time = 0;
@ -538,7 +538,7 @@ bool Emulator::Pause()
return m_state.compare_and_swap_test(system_state::ready, system_state::paused);
}
rpcs3::on_pause()();
GetCallbacks().on_pause();
// Update pause start time
if (m_pause_start_time.exchange(start))
@ -602,7 +602,7 @@ void Emulator::Resume()
on_select(0, *mfc);
}
rpcs3::on_resume()();
GetCallbacks().on_resume();
}
void Emulator::Stop()
@ -614,7 +614,7 @@ void Emulator::Stop()
LOG_NOTICE(GENERAL, "Stopping emulator...");
rpcs3::on_stop()();
GetCallbacks().on_stop();
#ifdef WITH_GDB_DEBUGGER
//fxm for some reason doesn't call on_stop

View File

@ -146,6 +146,11 @@ struct EmuCallbacks
{
std::function<void(std::function<void()>)> call_after;
std::function<void()> process_events;
std::function<void()> on_run;
std::function<void()> on_pause;
std::function<void()> on_resume;
std::function<void()> on_stop;
std::function<void()> on_ready;
std::function<void()> exit;
std::function<std::shared_ptr<class KeyboardHandlerBase>()> get_kb_handler;
std::function<std::shared_ptr<class MouseHandlerBase>()> get_mouse_handler;
@ -370,8 +375,10 @@ struct cfg_root : cfg::node
{
node_misc(cfg::node* _this) : cfg::node(_this, "Miscellaneous") {}
cfg::_bool autostart{this, "Always start after boot", true};
cfg::_bool autostart{this, "Automatically start games after boot", true};
cfg::_bool autoexit{this, "Exit RPCS3 when process finishes"};
cfg::_bool start_fullscreen{ this, "Start games in fullscreen mode" };
cfg::_bool show_fps_in_title{ this, "Show FPS counter in window title", true};
cfg::_int<1, 65535> gdb_server_port{this, "Port", 2345};
} misc{this};

BIN
rpcs3/Icons/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
rpcs3/Icons/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
rpcs3/Icons/restart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
rpcs3/Icons/stop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,61 +0,0 @@
#pragma once
#include "Utilities/Config.h"
#include "Emu/Io/PadHandler.h"
struct KeyboardPadConfig final : cfg::node
{
const std::string cfg_name = fs::get_config_dir() + "/config_kbpad.yml";
cfg::int32 left_stick_left{this, "Left Analog Stick Left", static_cast<int>('A')};
cfg::int32 left_stick_down{this, "Left Analog Stick Down", static_cast<int>('S')};
cfg::int32 left_stick_right{this, "Left Analog Stick Right", static_cast<int>('D')};
cfg::int32 left_stick_up{this, "Left Analog Stick Up", static_cast<int>('W')};
cfg::int32 right_stick_left{this, "Right Analog Stick Left", 313};
cfg::int32 right_stick_down{this, "Right Analog Stick Down", 367};
cfg::int32 right_stick_right{this, "Right Analog Stick Right", 312};
cfg::int32 right_stick_up{this, "Right Analog Stick Up", 366};
cfg::int32 start{this, "Start", 13};
cfg::int32 select{this, "Select", 32};
cfg::int32 square{this, "Square", static_cast<int>('Z')};
cfg::int32 cross{this, "Cross", static_cast<int>('X')};
cfg::int32 circle{this, "Circle", static_cast<int>('C')};
cfg::int32 triangle{this, "Triangle", static_cast<int>('V')};
cfg::int32 left{this, "Left", 314};
cfg::int32 down{this, "Down", 317};
cfg::int32 right{this, "Right", 316};
cfg::int32 up{this, "Up", 315};
cfg::int32 r1{this, "R1", static_cast<int>('E')};
cfg::int32 r2{this, "R2", static_cast<int>('T')};
cfg::int32 r3{this, "R3", static_cast<int>('G')};
cfg::int32 l1{this, "L1", static_cast<int>('Q')};
cfg::int32 l2{this, "L2", static_cast<int>('R')};
cfg::int32 l3{this, "L3", static_cast<int>('F')};
bool load()
{
if (fs::file cfg_file{ cfg_name, fs::read })
{
return from_string(cfg_file.to_string());
}
return false;
}
void save()
{
fs::file(cfg_name, fs::rewrite).write(to_string());
}
};
class KeyboardPadHandler final : public PadHandlerBase, public wxWindow
{
public:
virtual void Init(const u32 max_connect) override;
KeyboardPadHandler();
void KeyDown(wxKeyEvent& event);
void KeyUp(wxKeyEvent& event);
void LoadSettings();
};

View File

@ -0,0 +1,183 @@
#include "basic_keyboard_handler.h"
#include <QKeyEvent>
void basic_keyboard_handler::Init(const u32 max_connect)
{
for (u32 i = 0; i<max_connect; i++)
{
m_keyboards.emplace_back(Keyboard());
}
LoadSettings();
memset(&m_info, 0, sizeof(KbInfo));
m_info.max_connect = max_connect;
m_info.now_connect = std::min<size_t>(m_keyboards.size(), max_connect);
m_info.info = 0; // Ownership of keyboard data: 0=Application, 1=System
m_info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards)
}
basic_keyboard_handler::basic_keyboard_handler(QObject* target, QObject* parent) : QObject(parent), m_target(target)
{
// Adds event filter to the target to filter keyevents.
target->installEventFilter(this);
}
bool basic_keyboard_handler::eventFilter(QObject* target, QEvent* ev)
{
// Commenting target since I don't know how to target game window yet.
//if (target == m_target)
{
if (ev->type() == QEvent::KeyPress)
{
keyPressEvent(static_cast<QKeyEvent*>(ev));
}
else if (ev->type() == QEvent::KeyRelease)
{
keyReleaseEvent(static_cast<QKeyEvent*>(ev));
}
}
return false;
}
void basic_keyboard_handler::keyPressEvent(QKeyEvent* keyEvent)
{
Key(keyEvent->key(), 1);
}
void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent)
{
Key(keyEvent->key(), 0);
}
void basic_keyboard_handler::LoadSettings()
{
// Meta Keys
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Control, CELL_KB_MKEY_L_CTRL);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Shift, CELL_KB_MKEY_L_SHIFT);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Alt, CELL_KB_MKEY_L_ALT);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Super_L, CELL_KB_MKEY_L_WIN);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KB_MKEY_R_CTRL);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KB_MKEY_R_SHIFT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KB_MKEY_R_ALT);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Super_R, CELL_KB_MKEY_R_WIN);
// CELL_KB_RAWDAT
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_NO_EVENT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_ROLLOVER);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_POSTFAIL);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_UNDEF);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Escape, CELL_KEYC_ESCAPE);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_106_KANJI);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_CapsLock, CELL_KEYC_CAPS_LOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F1, CELL_KEYC_F1);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F2, CELL_KEYC_F2);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F3, CELL_KEYC_F3);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F4, CELL_KEYC_F4);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F5, CELL_KEYC_F5);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F6, CELL_KEYC_F6);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F7, CELL_KEYC_F7);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F8, CELL_KEYC_F8);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F9, CELL_KEYC_F9);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F10, CELL_KEYC_F10);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F11, CELL_KEYC_F11);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F12, CELL_KEYC_F12);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Print, CELL_KEYC_PRINTSCREEN);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_ScrollLock, CELL_KEYC_SCROLL_LOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Pause, CELL_KEYC_PAUSE);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Insert, CELL_KEYC_INSERT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_HOME);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_PageUp, CELL_KEYC_PAGE_UP);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Delete, CELL_KEYC_DELETE);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_End, CELL_KEYC_END);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_PageDown, CELL_KEYC_PAGE_DOWN);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Right, CELL_KEYC_RIGHT_ARROW);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Left, CELL_KEYC_LEFT_ARROW);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Down, CELL_KEYC_DOWN_ARROW);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Up, CELL_KEYC_UP_ARROW);
//m_keyboards[0].m_buttons.emplace_back(WXK_NUMLOCK, CELL_KEYC_NUM_LOCK);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_APPLICATION);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_KANA);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_HENKAN);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_MUHENKAN);
// CELL_KB_KEYPAD
m_keyboards[0].m_buttons.emplace_back(Qt::Key_NumLock, CELL_KEYC_KPAD_NUMLOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_division, CELL_KEYC_KPAD_SLASH);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_multiply, CELL_KEYC_KPAD_ASTERISK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Minus, CELL_KEYC_KPAD_MINUS);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Plus, CELL_KEYC_KPAD_PLUS);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Enter, CELL_KEYC_KPAD_ENTER);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_1, CELL_KEYC_KPAD_1);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_2, CELL_KEYC_KPAD_2);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_3, CELL_KEYC_KPAD_3);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_4, CELL_KEYC_KPAD_4);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_5, CELL_KEYC_KPAD_5);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_6, CELL_KEYC_KPAD_6);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_7, CELL_KEYC_KPAD_7);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_8, CELL_KEYC_KPAD_8);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_9, CELL_KEYC_KPAD_9);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_0, CELL_KEYC_KPAD_0);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Delete, CELL_KEYC_KPAD_PERIOD);
// ASCII Printable characters
m_keyboards[0].m_buttons.emplace_back('A', CELL_KEYC_A);
m_keyboards[0].m_buttons.emplace_back('B', CELL_KEYC_B);
m_keyboards[0].m_buttons.emplace_back('C', CELL_KEYC_C);
m_keyboards[0].m_buttons.emplace_back('D', CELL_KEYC_D);
m_keyboards[0].m_buttons.emplace_back('E', CELL_KEYC_E);
m_keyboards[0].m_buttons.emplace_back('F', CELL_KEYC_F);
m_keyboards[0].m_buttons.emplace_back('G', CELL_KEYC_G);
m_keyboards[0].m_buttons.emplace_back('H', CELL_KEYC_H);
m_keyboards[0].m_buttons.emplace_back('I', CELL_KEYC_I);
m_keyboards[0].m_buttons.emplace_back('J', CELL_KEYC_J);
m_keyboards[0].m_buttons.emplace_back('K', CELL_KEYC_K);
m_keyboards[0].m_buttons.emplace_back('L', CELL_KEYC_L);
m_keyboards[0].m_buttons.emplace_back('M', CELL_KEYC_M);
m_keyboards[0].m_buttons.emplace_back('N', CELL_KEYC_N);
m_keyboards[0].m_buttons.emplace_back('O', CELL_KEYC_O);
m_keyboards[0].m_buttons.emplace_back('P', CELL_KEYC_P);
m_keyboards[0].m_buttons.emplace_back('Q', CELL_KEYC_Q);
m_keyboards[0].m_buttons.emplace_back('R', CELL_KEYC_R);
m_keyboards[0].m_buttons.emplace_back('S', CELL_KEYC_S);
m_keyboards[0].m_buttons.emplace_back('T', CELL_KEYC_T);
m_keyboards[0].m_buttons.emplace_back('U', CELL_KEYC_U);
m_keyboards[0].m_buttons.emplace_back('V', CELL_KEYC_V);
m_keyboards[0].m_buttons.emplace_back('W', CELL_KEYC_W);
m_keyboards[0].m_buttons.emplace_back('X', CELL_KEYC_X);
m_keyboards[0].m_buttons.emplace_back('Y', CELL_KEYC_Y);
m_keyboards[0].m_buttons.emplace_back('Z', CELL_KEYC_Z);
m_keyboards[0].m_buttons.emplace_back('1', CELL_KEYC_1);
m_keyboards[0].m_buttons.emplace_back('2', CELL_KEYC_2);
m_keyboards[0].m_buttons.emplace_back('3', CELL_KEYC_3);
m_keyboards[0].m_buttons.emplace_back('4', CELL_KEYC_4);
m_keyboards[0].m_buttons.emplace_back('5', CELL_KEYC_5);
m_keyboards[0].m_buttons.emplace_back('6', CELL_KEYC_6);
m_keyboards[0].m_buttons.emplace_back('7', CELL_KEYC_7);
m_keyboards[0].m_buttons.emplace_back('8', CELL_KEYC_8);
m_keyboards[0].m_buttons.emplace_back('9', CELL_KEYC_9);
m_keyboards[0].m_buttons.emplace_back('0', CELL_KEYC_0);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Return, CELL_KEYC_ENTER);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_ESC);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Tab, CELL_KEYC_TAB);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Space, CELL_KEYC_SPACE);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Minus, CELL_KEYC_MINUS);
m_keyboards[0].m_buttons.emplace_back('=', CELL_KEYC_EQUAL_101);
m_keyboards[0].m_buttons.emplace_back('^', CELL_KEYC_ACCENT_CIRCONFLEX_106);
//m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_LEFT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back('@', CELL_KEYC_ATMARK_106);
//m_keyboards[0].m_buttons.emplace_back(')', CELL_KEYC_RIGHT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_LEFT_BRACKET_106);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_BACKSLASH_101);
m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_RIGHT_BRACKET_106);
m_keyboards[0].m_buttons.emplace_back(';', CELL_KEYC_SEMICOLON);
m_keyboards[0].m_buttons.emplace_back('"', CELL_KEYC_QUOTATION_101);
m_keyboards[0].m_buttons.emplace_back(':', CELL_KEYC_COLON_106);
m_keyboards[0].m_buttons.emplace_back(',', CELL_KEYC_COMMA);
m_keyboards[0].m_buttons.emplace_back('.', CELL_KEYC_PERIOD);
m_keyboards[0].m_buttons.emplace_back('/', CELL_KEYC_SLASH);
m_keyboards[0].m_buttons.emplace_back('\\', CELL_KEYC_BACKSLASH_106);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_YEN_106);
}

View File

@ -0,0 +1,26 @@
#ifndef BASIC_KEYBOARD_HANDLER_H
#define BASIC_KEYBOARD_HANDLER_H
#include "stdafx.h"
#include "Emu/Io/KeyboardHandler.h"
#include <QObject>
#include <QKeyEvent>
class basic_keyboard_handler final : public QObject, public KeyboardHandlerBase
{
Q_OBJECT
public:
virtual void Init(const u32 max_connect) override;
explicit basic_keyboard_handler(QObject* target = nullptr, QObject* parent = nullptr);
bool eventFilter(QObject* obj, QEvent* ev);
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void LoadSettings();
private:
QObject* m_target;
};
#endif

View File

@ -0,0 +1,68 @@
#include "basic_mouse_handler.h"
void basic_mouse_handler::Init(const u32 max_connect)
{
m_mice.emplace_back(Mouse());
memset(&m_info, 0, sizeof(MouseInfo));
m_info.max_connect = max_connect;
m_info.now_connect = std::min(m_mice.size(), (size_t)max_connect);
m_info.info = 0; // Ownership of mouse data: 0=Application, 1=System
m_info.status[0] = CELL_MOUSE_STATUS_CONNECTED; // (TODO: Support for more mice)
for (u32 i = 1; i<max_connect; i++) m_info.status[i] = CELL_MOUSE_STATUS_DISCONNECTED;
m_info.vendor_id[0] = 0x1234;
m_info.product_id[0] = 0x1234;
}
basic_mouse_handler::basic_mouse_handler(QObject* target, QObject* parent) : QObject(parent), m_target(target)
{
target->installEventFilter(this);
}
bool basic_mouse_handler::eventFilter(QObject* obj, QEvent* ev)
{
// Commenting target since I don't know how to target game window yet.
//if (m_target == obj)
{
switch (ev->type())
{
case QEvent::MouseButtonPress:
MouseButtonDown(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonRelease:
MouseButtonUp(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseMove:
MouseMove(static_cast<QMouseEvent*>(ev));
break;
case QEvent::Wheel:
MouseScroll(static_cast<QWheelEvent*>(ev));
break;
}
}
return false;
}
void basic_mouse_handler::MouseButtonDown(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_1, 1);
else if (event->button() == Qt::RightButton) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_2, 1);
else if (event->button() == Qt::MiddleButton) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_3, 1);
}
void basic_mouse_handler::MouseButtonUp(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_1, 0);
else if (event->button() == Qt::RightButton) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_2, 0);
else if (event->button() == Qt::MiddleButton) MouseHandlerBase::Button(CELL_MOUSE_BUTTON_3, 0);
}
void basic_mouse_handler::MouseScroll(QWheelEvent* event)
{
// Woo lads, Qt handles multidimensional scrolls. Just gonna grab the x for now. Not sure if this works. TODO: Test
MouseHandlerBase::Scroll(event->angleDelta().x());
}
void basic_mouse_handler::MouseMove(QMouseEvent* event)
{
MouseHandlerBase::Move(event->x(), event->y());
}

View File

@ -0,0 +1,28 @@
#ifndef BASIC_MOUSE_HANDLER_H
#define BASIC_MOUSE_HANDLER_H
#include "stdafx.h"
#include "Emu/Io/MouseHandler.h"
#include <QMouseEvent>
#include <QWheelEvent>
class basic_mouse_handler final : public QObject, public MouseHandlerBase
{
Q_OBJECT
public:
virtual void Init(const u32 max_connect) override;
basic_mouse_handler(QObject* target, QObject* parent);
void MouseButtonDown(QMouseEvent* event);
void MouseButtonUp(QMouseEvent* event);
void MouseScroll(QWheelEvent* event);
void MouseMove(QMouseEvent* event);
bool eventFilter(QObject* obj, QEvent* ev);
private:
QObject* m_target;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/System.h"
#include "DS4PadHandler.h"
#include "ds4_pad_handler.h"
#include <thread>
#include <cmath>
@ -123,12 +122,12 @@ namespace
}
}
DS4PadHandler::~DS4PadHandler()
ds4_pad_handler::~ds4_pad_handler()
{
Close();
}
void DS4PadHandler::Init(const u32 max_connect)
void ds4_pad_handler::Init(const u32 max_connect)
{
std::memset(&m_info, 0, sizeof m_info);
m_info.max_connect = max_connect;
@ -182,11 +181,11 @@ void DS4PadHandler::Init(const u32 max_connect)
pad.m_vibrateMotors.emplace_back(false, 0);
}
ds4Thread = std::make_shared<DS4Thread>();
ds4Thread = std::make_shared<ds4_thread>();
ds4Thread->on_init(ds4Thread);
}
PadInfo& DS4PadHandler::GetInfo()
PadInfo& ds4_pad_handler::GetInfo()
{
if (ds4Thread)
{
@ -221,7 +220,7 @@ PadInfo& DS4PadHandler::GetInfo()
return m_info;
}
std::vector<Pad>& DS4PadHandler::GetPads()
std::vector<Pad>& ds4_pad_handler::GetPads()
{
if (ds4Thread)
ProcessData();
@ -229,7 +228,7 @@ std::vector<Pad>& DS4PadHandler::GetPads()
return m_pads;
}
void DS4PadHandler::Close()
void ds4_pad_handler::Close()
{
if (ds4Thread)
ds4Thread.reset();
@ -237,7 +236,7 @@ void DS4PadHandler::Close()
m_pads.clear();
}
void DS4PadHandler::ProcessData()
void ds4_pad_handler::ProcessData()
{
if (!ds4Thread)
@ -395,7 +394,7 @@ void DS4PadHandler::ProcessData()
pad.m_buttons[12 + i - 4].m_value = pressed ? 255 : 0;
}
// these values come already calibrated from our DS4Thread,
// these values come already calibrated from our ds4Thread,
// all we need to do is convert to ds3 range
// accel
@ -426,7 +425,7 @@ void DS4PadHandler::ProcessData()
}
}
void DS4PadHandler::SetRumble(const u32 pad, u8 largeMotor, bool smallMotor)
void ds4_pad_handler::SetRumble(const u32 pad, u8 largeMotor, bool smallMotor)
{
if (pad > m_pads.size())
return;
@ -440,7 +439,7 @@ void DS4PadHandler::SetRumble(const u32 pad, u8 largeMotor, bool smallMotor)
ds4Thread->SetRumbleData(pad, largeMotor, smallMotor ? 255 : 0);
}
void DS4Thread::SetRumbleData(u32 port, u8 largeVibrate, u8 smallVibrate)
void ds4_thread::SetRumbleData(u32 port, u8 largeVibrate, u8 smallVibrate)
{
semaphore_lock lock(mutex);
@ -460,7 +459,7 @@ void DS4Thread::SetRumbleData(u32 port, u8 largeVibrate, u8 smallVibrate)
}
}
std::array<bool, MAX_GAMEPADS> DS4Thread::GetConnectedControllers()
std::array<bool, MAX_GAMEPADS> ds4_thread::GetConnectedControllers()
{
std::array<bool, MAX_GAMEPADS> rtnData{};
int i = 0;
@ -473,7 +472,7 @@ std::array<bool, MAX_GAMEPADS> DS4Thread::GetConnectedControllers()
return rtnData;
}
std::array<std::array<u8, 64>, MAX_GAMEPADS> DS4Thread::GetControllerData()
std::array<std::array<u8, 64>, MAX_GAMEPADS> ds4_thread::GetControllerData()
{
std::array<std::array<u8, 64>, MAX_GAMEPADS> rtnData;
@ -486,7 +485,7 @@ std::array<std::array<u8, 64>, MAX_GAMEPADS> DS4Thread::GetControllerData()
return rtnData;
}
bool DS4Thread::GetCalibrationData(DS4Device* ds4Dev)
bool ds4_thread::GetCalibrationData(DS4Device* ds4Dev)
{
std::array<u8, 64> buf;
if (ds4Dev->btCon)
@ -574,7 +573,7 @@ bool DS4Thread::GetCalibrationData(DS4Device* ds4Dev)
return true;
}
void DS4Thread::CheckAddDevice(hid_device* hidDevice, hid_device_info* hidDevInfo)
void ds4_thread::CheckAddDevice(hid_device* hidDevice, hid_device_info* hidDevInfo)
{
std::string serial = "";
DS4Device ds4Dev;
@ -607,7 +606,7 @@ void DS4Thread::CheckAddDevice(hid_device* hidDevice, hid_device_info* hidDevInf
controllers.emplace(serial, ds4Dev);
}
void DS4Thread::on_init(const std::shared_ptr<void>& _this)
void ds4_thread::on_init(const std::shared_ptr<void>& _this)
{
const int res = hid_init();
if (res != 0)
@ -639,7 +638,7 @@ void DS4Thread::on_init(const std::shared_ptr<void>& _this)
named_thread::on_init(_this);
}
DS4Thread::~DS4Thread()
ds4_thread::~ds4_thread()
{
for (auto & controller : controllers)
{
@ -649,7 +648,7 @@ DS4Thread::~DS4Thread()
hid_exit();
}
void DS4Thread::SendVibrateData(const DS4Device& device)
void ds4_thread::SendVibrateData(const DS4Device& device)
{
std::array<u8, 78> outputBuf{0};
// write rumble state
@ -689,7 +688,7 @@ void DS4Thread::SendVibrateData(const DS4Device& device)
}
}
void DS4Thread::on_task()
void ds4_thread::on_task()
{
while (!Emu.IsStopped())
{

View File

@ -8,7 +8,8 @@
const u32 MAX_GAMEPADS = 7;
class DS4Thread final : public named_thread
class ds4_thread final : public named_thread
{
private:
enum DS4CalibIndex
@ -70,9 +71,11 @@ public:
void SetRumbleData(u32 port, u8 largeVibrate, u8 smallVibrate);
DS4Thread() = default;
~DS4Thread();
ds4_thread() = default;
~ds4_thread();
private:
bool GetCalibrationData(DS4Device* ds4Device);
@ -93,11 +96,13 @@ private:
}
};
class DS4PadHandler final : public PadHandlerBase
class ds4_pad_handler final : public PadHandlerBase
{
public:
DS4PadHandler() {}
~DS4PadHandler();
ds4_pad_handler() {}
~ds4_pad_handler();
void Init(const u32 max_connect) override;
void Close();
@ -112,5 +117,6 @@ private:
// holds internal controller state change
std::array<bool, MAX_GAMEPADS> last_connection_status = {};
std::shared_ptr<DS4Thread> ds4Thread;
std::shared_ptr<ds4_thread> ds4Thread;
};

View File

@ -61,7 +61,7 @@
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>..\llvm\include;..\llvm_build\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\3rdparty\zlib;..\llvm\include;..\llvm_build\include;</AdditionalIncludeDirectories>
</ClCompile>
<PreBuildEvent>
<Command>%windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd"</Command>

View File

@ -1,12 +1,10 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "rpcs3.h"
#include "KeyboardPadHandler.h"
#include "keyboard_pad_handler.h"
KeyboardPadConfig g_kbpad_config;
keyboard_pad_config g_kbpad_config;
void KeyboardPadHandler::Init(const u32 max_connect)
void keyboard_pad_handler::Init(const u32 max_connect)
{
memset(&m_info, 0, sizeof(PadInfo));
m_info.max_connect = max_connect;
@ -14,25 +12,39 @@ void KeyboardPadHandler::Init(const u32 max_connect)
m_info.now_connect = std::min(m_pads.size(), (size_t)max_connect);
}
KeyboardPadHandler::KeyboardPadHandler()
keyboard_pad_handler::keyboard_pad_handler(QObject* target, QObject* parent) : QObject(parent), m_target(target)
{
wxGetApp().Bind(wxEVT_KEY_DOWN, &KeyboardPadHandler::KeyDown, this);
wxGetApp().Bind(wxEVT_KEY_UP, &KeyboardPadHandler::KeyUp, this);
target->installEventFilter(this);
}
void KeyboardPadHandler::KeyDown(wxKeyEvent& event)
bool keyboard_pad_handler::eventFilter(QObject* target, QEvent* ev)
{
Key(event.GetKeyCode(), 1);
event.Skip();
// Commenting target since I don't know how to target game window yet.
//if (target == m_target)
{
if (ev->type() == QEvent::KeyPress)
{
keyPressEvent(static_cast<QKeyEvent*>(ev));
}
else if (ev->type() == QEvent::KeyRelease)
{
keyReleaseEvent(static_cast<QKeyEvent*>(ev));
}
}
return false;
}
void KeyboardPadHandler::KeyUp(wxKeyEvent& event)
void keyboard_pad_handler::keyPressEvent(QKeyEvent* event)
{
Key(event.GetKeyCode(), 0);
event.Skip();
Key(event->key(), 1);
}
void KeyboardPadHandler::LoadSettings()
void keyboard_pad_handler::keyReleaseEvent(QKeyEvent* event)
{
Key(event->key(), 0);
}
void keyboard_pad_handler::LoadSettings()
{
g_kbpad_config.load();

View File

@ -0,0 +1,70 @@
#pragma once
#include "Utilities/Config.h"
#include "Emu/Io/PadHandler.h"
#include "stdafx.h"
#include "Emu/System.h"
#include <QKeyEvent>
#include <QObject>
struct keyboard_pad_config final : cfg::node
{
const std::string cfg_name = fs::get_config_dir() + "/config_kbpad_qt.yml";
cfg::int32 left_stick_left{ this, "Left Analog Stick Left", Qt::Key_A };
cfg::int32 left_stick_down{ this, "Left Analog Stick Down", Qt::Key_S };
cfg::int32 left_stick_right{ this, "Left Analog Stick Right", Qt::Key_D };
cfg::int32 left_stick_up{ this, "Left Analog Stick Up", Qt::Key_W };
cfg::int32 right_stick_left{ this, "Right Analog Stick Left", Qt::Key_Home };
cfg::int32 right_stick_down{ this, "Right Analog Stick Down", Qt::Key_PageDown };
cfg::int32 right_stick_right{ this, "Right Analog Stick Right", Qt::Key_End };
cfg::int32 right_stick_up{ this, "Right Analog Stick Up", Qt::Key_PageUp };
cfg::int32 start{ this, "Start", Qt::Key_Return };
cfg::int32 select{ this, "Select", Qt::Key_Space };
cfg::int32 square{ this, "Square", Qt::Key_Z };
cfg::int32 cross{ this, "Cross", Qt::Key_X };
cfg::int32 circle{ this, "Circle", Qt::Key_C };
cfg::int32 triangle{ this, "Triangle", Qt::Key_V };
cfg::int32 left{ this, "Left", Qt::Key_Left };
cfg::int32 down{ this, "Down", Qt::Key_Down };
cfg::int32 right{ this, "Right", Qt::Key_Right };
cfg::int32 up{ this, "Up", Qt::Key_Up };
cfg::int32 r1{ this, "R1", Qt::Key_E };
cfg::int32 r2{ this, "R2", Qt::Key_T };
cfg::int32 r3{ this, "R3", Qt::Key_G };
cfg::int32 l1{ this, "L1", Qt::Key_Q };
cfg::int32 l2{ this, "L2", Qt::Key_R };
cfg::int32 l3{ this, "L3", Qt::Key_F };
bool load()
{
if (fs::file cfg_file{ cfg_name, fs::read })
{
return from_string(cfg_file.to_string());
}
return false;
}
void save()
{
fs::file(cfg_name, fs::rewrite).write(to_string());
}
};
class keyboard_pad_handler final : public QObject, public PadHandlerBase
{
public:
virtual void Init(const u32 max_connect) override;
keyboard_pad_handler(QObject* target, QObject* parent);
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void LoadSettings();
bool eventFilter(QObject* obj, QEvent* ev);
private:
QObject* m_target;
};

14
rpcs3/main.cpp Normal file
View File

@ -0,0 +1,14 @@
// Qt5.2+ frontend implementation for rpcs3. Known to work on Windows, Linux, Mac
// by Sacha Refshauge
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include "rpcs3_app.h"
int main(int argc, char** argv)
{
rpcs3_app app(argc, argv);
app.Init();
return app.exec();
}

View File

@ -1,9 +1,8 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#ifdef _WIN32
#include "MMJoystickHandler.h"
#include "mm_joystick_handler.h"
MMJoystickConfig g_mmjoystick_config;
mm_joystick_config g_mmjoystick_config;
namespace {
const DWORD THREAD_SLEEP = 10;
@ -17,16 +16,16 @@ namespace {
}
MMJoystickHandler::MMJoystickHandler() : active(false), thread(nullptr)
mm_joystick_handler::mm_joystick_handler() : active(false), thread(nullptr)
{
}
MMJoystickHandler::~MMJoystickHandler()
mm_joystick_handler::~mm_joystick_handler()
{
Close();
}
void MMJoystickHandler::Init(const u32 max_connect)
void mm_joystick_handler::Init(const u32 max_connect)
{
supportedJoysticks = joyGetNumDevs();
if (supportedJoysticks > 0)
@ -86,7 +85,7 @@ void MMJoystickHandler::Init(const u32 max_connect)
pad.m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, 0, 0);
active = true;
thread = CreateThread(NULL, 0, &MMJoystickHandler::ThreadProcProxy, this, 0, NULL);
thread = CreateThread(NULL, 0, &mm_joystick_handler::ThreadProcProxy, this, 0, NULL);
}
}
@ -96,7 +95,7 @@ void MMJoystickHandler::Init(const u32 max_connect)
}
}
void MMJoystickHandler::Close()
void mm_joystick_handler::Close()
{
if (active)
{
@ -112,7 +111,7 @@ void MMJoystickHandler::Close()
m_pads.clear();
}
DWORD MMJoystickHandler::ThreadProcedure()
DWORD mm_joystick_handler::ThreadProcedure()
{
// holds internal controller state change
std::array<bool, CELL_PAD_MAX_PORT_NUM> last_connection_status = {};
@ -169,9 +168,9 @@ DWORD MMJoystickHandler::ThreadProcedure()
return 0;
}
DWORD WINAPI MMJoystickHandler::ThreadProcProxy(LPVOID parameter)
DWORD WINAPI mm_joystick_handler::ThreadProcProxy(LPVOID parameter)
{
return reinterpret_cast<MMJoystickHandler *>(parameter)->ThreadProcedure();
return reinterpret_cast<mm_joystick_handler *>(parameter)->ThreadProcedure();
}
#endif

View File

@ -1,10 +1,12 @@
#pragma once
#ifndef MM_JOYSTICK_HANDLER_H
#define MM_JOYSTICK_HANDLER_H
#include "Emu/Io/PadHandler.h"
#include <Windows.h>
#include <mmsystem.h>
#include "Utilities/Config.h"
struct MMJoystickConfig final : cfg::node
struct mm_joystick_config final : cfg::node
{
const std::string cfg_name = fs::get_config_dir() + "/config_mmjoystick.yml";
@ -49,11 +51,11 @@ struct MMJoystickConfig final : cfg::node
}
};
class MMJoystickHandler final : public PadHandlerBase
class mm_joystick_handler final : public PadHandlerBase
{
public:
MMJoystickHandler();
~MMJoystickHandler();
mm_joystick_handler();
~mm_joystick_handler();
void Init(const u32 max_connect) override;
void Close();
@ -69,3 +71,5 @@ private:
JOYINFOEX js_info;
JOYCAPS js_caps;
};
#endif

9
rpcs3/resources.qrc Normal file
View File

@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/">
<file>Icons/pause.png</file>
<file>Icons/play.png</file>
<file>Icons/restart.png</file>
<file>Icons/stop.png</file>
<file>rpcs3.ico</file>
</qresource>
</RCC>

View File

@ -1,285 +0,0 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "rpcs3.h"
#include "Utilities/Config.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Gui/ConLogFrame.h"
#include "Emu/GameInfo.h"
#include "Emu/Io/Null/NullKeyboardHandler.h"
#include "BasicKeyboardHandler.h"
#include "Emu/Io/Null/NullMouseHandler.h"
#include "BasicMouseHandler.h"
#include "Emu/Io/Null/NullPadHandler.h"
#include "KeyboardPadHandler.h"
#include "DS4PadHandler.h"
#ifdef _MSC_VER
#include "XInputPadHandler.h"
#endif
#ifdef _WIN32
#include "MMJoystickHandler.h"
#endif
#include "Emu/RSX/Null/NullGSRender.h"
#include "Emu/RSX/GL/GLGSRender.h"
#include "Gui/MsgDialog.h"
#include "Gui/SaveDataDialog.h"
#include "Gui/GLGSFrame.h"
#include "Emu/RSX/Null/NullGSRender.h"
#include "Emu/RSX/GL/GLGSRender.h"
#include "Emu/Audio/Null/NullAudioThread.h"
#include "Emu/Audio/AL/OpenALThread.h"
#ifdef _MSC_VER
#include "Emu/RSX/D3D12/D3D12GSRender.h"
#endif
#ifdef _WIN32
#include "Emu/RSX/VK/VKGSRender.h"
#include "Emu/Audio/XAudio2/XAudio2Thread.h"
#include <wx/msw/wrapwin.h>
#endif
#ifdef __linux__
#include "Emu/Audio/ALSA/ALSAThread.h"
#endif
#ifdef __unix__
#include <X11/Xlib.h>
#endif
// GUI config
YAML::Node g_gui_cfg;
// GUI config file
static fs::file s_gui_cfg;
void save_gui_cfg()
{
YAML::Emitter out;
out.SetSeqFormat(YAML::Flow);
out << g_gui_cfg;
// Save to file
s_gui_cfg.seek(0);
s_gui_cfg.trunc(0);
s_gui_cfg.write(out.c_str(), out.size());
}
IMPLEMENT_APP(Rpcs3App)
Rpcs3App* TheApp;
bool Rpcs3App::OnInit()
{
static const wxCmdLineEntryDesc desc[]
{
{ wxCMD_LINE_SWITCH, "h", "help", "Command line options:\nh (help): Help and commands\nt (test): For directly executing a (S)ELF", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_SWITCH, "t", "test", "Run in test mode on (S)ELF", wxCMD_LINE_VAL_NONE },
{ wxCMD_LINE_PARAM, NULL, NULL, "(S)ELF", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_NONE }
};
parser.SetDesc(desc);
parser.SetCmdLine(argc, argv);
if (parser.Parse())
{
// help was given, terminating
this->Exit();
}
s_gui_cfg.open(fs::get_config_dir() + "/config_gui.yml", fs::read + fs::write + fs::create);
g_gui_cfg = YAML::Load(s_gui_cfg.to_string());
EmuCallbacks callbacks;
callbacks.call_after = [](std::function<void()> func)
{
wxGetApp().CallAfter(std::move(func));
};
callbacks.process_events = [this]()
{
m_MainFrame->Update();
wxGetApp().ProcessPendingEvents();
};
callbacks.exit = [this]()
{
wxGetApp().Exit();
};
callbacks.get_kb_handler = []() -> std::shared_ptr<KeyboardHandlerBase>
{
switch (keyboard_handler type = g_cfg.io.keyboard)
{
case keyboard_handler::null: return std::make_shared<NullKeyboardHandler>();
case keyboard_handler::basic: return std::make_shared<BasicKeyboardHandler>();
default: fmt::throw_exception("Invalid keyboard handler: %s", type);
}
};
callbacks.get_mouse_handler = []() -> std::shared_ptr<MouseHandlerBase>
{
switch (mouse_handler type = g_cfg.io.mouse)
{
case mouse_handler::null: return std::make_shared<NullMouseHandler>();
case mouse_handler::basic: return std::make_shared<BasicMouseHandler>();
default: fmt::throw_exception("Invalid mouse handler: %s", type);
}
};
callbacks.get_pad_handler = []() -> std::shared_ptr<PadHandlerBase>
{
switch (pad_handler type = g_cfg.io.pad)
{
case pad_handler::null: return std::make_shared<NullPadHandler>();
case pad_handler::keyboard: return std::make_shared<KeyboardPadHandler>();
case pad_handler::ds4: return std::make_shared<DS4PadHandler>();
#ifdef _MSC_VER
case pad_handler::xinput: return std::make_shared<XInputPadHandler>();
#endif
#ifdef _WIN32
case pad_handler::mm: return std::make_shared<MMJoystickHandler>();
#endif
default: fmt::throw_exception("Invalid pad handler: %s", type);
}
};
callbacks.get_gs_frame = []() -> std::unique_ptr<GSFrameBase>
{
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution);
switch (video_renderer type = g_cfg.video.renderer)
{
case video_renderer::null: return std::make_unique<GSFrame>("Null", size.first, size.second);
case video_renderer::opengl: return std::make_unique<GLGSFrame>(size.first, size.second);
#ifdef _WIN32
case video_renderer::vulkan: return std::make_unique<GSFrame>("Vulkan", size.first, size.second);
#endif
#ifdef _MSC_VER
case video_renderer::dx12: return std::make_unique<GSFrame>("DirectX 12", size.first, size.second);
#endif
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
}
};
callbacks.get_gs_render = []() -> std::shared_ptr<GSRender>
{
switch (video_renderer type = g_cfg.video.renderer)
{
case video_renderer::null: return std::make_shared<NullGSRender>();
case video_renderer::opengl: return std::make_shared<GLGSRender>();
#ifdef _WIN32
case video_renderer::vulkan: return std::make_shared<VKGSRender>();
#endif
#ifdef _MSC_VER
case video_renderer::dx12: return std::make_shared<D3D12GSRender>();
#endif
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
}
};
callbacks.get_audio = []() -> std::shared_ptr<AudioThread>
{
switch (audio_renderer type = g_cfg.audio.renderer)
{
case audio_renderer::null: return std::make_shared<NullAudioThread>();
#ifdef _WIN32
case audio_renderer::xaudio: return std::make_shared<XAudio2Thread>();
#elif __linux__
case audio_renderer::alsa: return std::make_shared<ALSAThread>();
#endif
case audio_renderer::openal: return std::make_shared<OpenALThread>();
default: fmt::throw_exception("Invalid audio renderer: %s" HERE, type);
}
};
callbacks.get_msg_dialog = []() -> std::shared_ptr<MsgDialogBase>
{
return std::make_shared<MsgDialogFrame>();
};
callbacks.get_save_dialog = []() -> std::unique_ptr<SaveDialogBase>
{
return std::make_unique<SaveDialogFrame>();
};
Emu.SetCallbacks(std::move(callbacks));
TheApp = this;
SetAppName("RPCS3");
wxInitAllImageHandlers();
Emu.Init();
m_MainFrame = new MainFrame();
SetTopWindow(m_MainFrame);
m_MainFrame->Show();
m_MainFrame->DoSettings(true);
OnArguments(parser);
return true;
}
void Rpcs3App::OnArguments(const wxCmdLineParser& parser)
{
// Usage:
// rpcs3-*.exe Initializes RPCS3
// rpcs3-*.exe [(S)ELF] Initializes RPCS3, then loads and runs the specified (S)ELF file.
if (parser.FoundSwitch("t"))
{
if (parser.GetParamCount() != 1)
{
wxLogDebug("A (S)ELF file needs to be given in test mode, exiting.");
this->Exit();
}
// TODO: clean implementation
g_cfg.misc.autostart.from_string("true");
g_cfg.misc.autoexit.from_string("true");
}
if (parser.GetParamCount() > 0)
{
Emu.SetPath(fmt::ToUTF8(parser.GetParam(0)));
Emu.Load();
Emu.Run();
}
}
void Rpcs3App::Exit()
{
Emu.Stop();
wxApp::Exit();
}
Rpcs3App::Rpcs3App()
{
#ifdef _WIN32
timeBeginPeriod(1);
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
WSAStartup(wVersionRequested, &wsaData);
std::atexit([]
{
timeEndPeriod(1);
WSACleanup();
});
#endif
#if defined(__unix__) && !defined(__APPLE__)
XInitThreads();
#endif
}

View File

@ -1,24 +0,0 @@
#pragma once
#include "Gui/MainFrame.h"
#include <wx/app.h>
#include <wx/cmdline.h>
class Rpcs3App : public wxApp
{
private:
wxCmdLineParser parser;
public:
MainFrame* m_MainFrame;
virtual bool OnInit(); // RPCS3's entry point
virtual void OnArguments(const wxCmdLineParser& parser); // Handle arguments: Rpcs3App::argc, Rpcs3App::argv
virtual void Exit();
Rpcs3App();
};
DECLARE_APP(Rpcs3App)
extern Rpcs3App* TheApp;

View File

@ -3,24 +3,34 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)bin\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3bC:\Qt\5.8\msvc2015_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
<QTDIR>C:\Qt\5.8\msvc2015_64</QTDIR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)bin\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3bC:\Qt\5.8\msvc2015_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
<QTDIR>C:\Qt\5.8\msvc2015_64</QTDIR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)bin\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3bC:\Qt\5.8\msvc2015_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
<QTDIR>C:\Qt\5.8\msvc2015_64</QTDIR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)bin\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>1&gt; stdout.log 2&gt; stderr.log</LocalDebuggerCommandArguments>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3bC:\Qt\5.8\msvc2015_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
<QTDIR>C:\Qt\5.8\msvc2015_64</QTDIR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)bin\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>1&gt; stdout.log 2&gt; stderr.log</LocalDebuggerCommandArguments>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3bC:\Qt\5.8\msvc2015_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
<QTDIR>C:\Qt\5.8\msvc2015_64</QTDIR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)bin\</LocalDebuggerWorkingDirectory>

268
rpcs3/rpcs3_app.cpp Normal file
View File

@ -0,0 +1,268 @@
#include "rpcs3_app.h"
#include "rpcs3qt/welcome_dialog.h"
#include "rpcs3qt/gui_settings.h"
#include "Emu/System.h"
#include "rpcs3qt/gs_frame.h"
#include "rpcs3qt/gl_gs_frame.h"
#include "Emu/Cell/Modules/cellSaveData.h"
#include "rpcs3qt/save_data_dialog.h"
#include "rpcs3qt/msg_dialog_frame.h"
#include "Emu/Cell/Modules/cellMsgDialog.h"
#include "Emu/Io/Null/NullKeyboardHandler.h"
#include "basic_keyboard_handler.h"
#include "Emu/Io/Null/NullMouseHandler.h"
#include "basic_mouse_handler.h"
#include "Emu/Io/Null/NullPadHandler.h"
#include "keyboard_pad_handler.h"
#include "ds4_pad_handler.h"
#ifdef _MSC_VER
#include "xinput_pad_handler.h"
#endif
#ifdef _WIN32
#include "mm_joystick_handler.h"
#endif
#include "Emu/RSX/Null/NullGSRender.h"
#include "Emu/RSX/GL/GLGSRender.h"
#include "Emu/Audio/Null/NullAudioThread.h"
#include "Emu/Audio/AL/OpenALThread.h"
#ifdef _MSC_VER
#include "Emu/RSX/D3D12/D3D12GSRender.h"
#endif
#ifdef _WIN32
#include "Emu/RSX/VK/VKGSRender.h"
#include "Emu/Audio/XAudio2/XAudio2Thread.h"
#endif
#ifdef __linux__
#include "Emu/Audio/ALSA/ALSAThread.h"
#endif
// For now, a trivial constructor/destructor. May add command line usage later.
rpcs3_app::rpcs3_app(int& argc, char** argv) : QApplication(argc, argv)
{
}
void rpcs3_app::Init()
{
Emu.Init();
// Create the main window
RPCS3MainWin = new main_window(nullptr);
// Reset the pads -- see the method for why this is currently needed.
ResetPads();
// Create callbacks from the emulator, which reference the handlers.
InitializeCallbacks();
// Create connects to propagate events throughout Gui.
InitializeConnects();
setApplicationName("RPCS3");
RPCS3MainWin->show();
// Create the thumbnail toolbar after the main_window is created
RPCS3MainWin->CreateThumbnailToolbar();
// Slightly inneficient to make a gui_settings instance right here.
// But, I don't really feel like adding this as a dependency injection into RPCS3MainWin.
if (gui_settings().GetValue(GUI::ib_show_welcome).toBool())
{
welcome_dialog* welcome = new welcome_dialog();
welcome->exec();
}
}
/** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here.
*/
void rpcs3_app::InitializeCallbacks()
{
EmuCallbacks callbacks;
callbacks.exit = [this]()
{
quit();
};
callbacks.call_after = [=](std::function<void()> func)
{
emit RequestCallAfter(std::move(func));
};
callbacks.process_events = [this]()
{
RPCS3MainWin->update();
processEvents();
};
callbacks.get_kb_handler = [=]() -> std::shared_ptr<KeyboardHandlerBase>
{
switch (keyboard_handler type = g_cfg.io.keyboard)
{
case keyboard_handler::null: return std::make_shared<NullKeyboardHandler>();
case keyboard_handler::basic: return m_basicKeyboardHandler;
default: fmt::throw_exception("Invalid keyboard handler: %s", type);
}
};
callbacks.get_mouse_handler = [=]() -> std::shared_ptr<MouseHandlerBase>
{
switch (mouse_handler type = g_cfg.io.mouse)
{
case mouse_handler::null: return std::make_shared<NullMouseHandler>();
case mouse_handler::basic: return m_basicMouseHandler;
default: fmt::throw_exception("Invalid mouse handler: %s", type);
}
};
callbacks.get_pad_handler = [this]() -> std::shared_ptr<PadHandlerBase>
{
switch (pad_handler type = g_cfg.io.pad)
{
case pad_handler::null: return std::make_shared<NullPadHandler>();
case pad_handler::keyboard: return m_keyboardPadHandler;
case pad_handler::ds4: return std::make_shared<ds4_pad_handler>();
#ifdef _MSC_VER
case pad_handler::xinput: return std::make_shared<xinput_pad_handler>();
#endif
#ifdef _WIN32
case pad_handler::mm: return std::make_shared<mm_joystick_handler>();
#endif
default: fmt::throw_exception("Invalid pad handler: %s", type);
}
};
callbacks.get_gs_frame = [this]() -> std::unique_ptr<GSFrameBase>
{
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution);
switch (video_renderer type = g_cfg.video.renderer)
{
case video_renderer::null: return std::make_unique<gs_frame>("Null", size.first, size.second, RPCS3MainWin->GetAppIcon());
case video_renderer::opengl: return std::make_unique<gl_gs_frame>(size.first, size.second, RPCS3MainWin->GetAppIcon());
#ifdef _WIN32
case video_renderer::vulkan: return std::make_unique<gs_frame>("Vulkan", size.first, size.second, RPCS3MainWin->GetAppIcon());
#endif
#ifdef _MSC_VER
case video_renderer::dx12: return std::make_unique<gs_frame>("DirectX 12", size.first, size.second, RPCS3MainWin->GetAppIcon());
#endif
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
}
};
callbacks.get_gs_render = []() -> std::shared_ptr<GSRender>
{
switch (video_renderer type = g_cfg.video.renderer)
{
case video_renderer::null: return std::make_shared<NullGSRender>();
case video_renderer::opengl: return std::make_shared<GLGSRender>();
#ifdef _WIN32
case video_renderer::vulkan: return std::make_shared<VKGSRender>();
#endif
#ifdef _MSC_VER
case video_renderer::dx12: return std::make_shared<D3D12GSRender>();
#endif
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
}
};
callbacks.get_audio = []() -> std::shared_ptr<AudioThread>
{
switch (audio_renderer type = g_cfg.audio.renderer)
{
case audio_renderer::null: return std::make_shared<NullAudioThread>();
#ifdef _WIN32
case audio_renderer::xaudio: return std::make_shared<XAudio2Thread>();
#elif __linux__
case audio_renderer::alsa: return std::make_shared<ALSAThread>();
#endif
case audio_renderer::openal: return std::make_shared<OpenALThread>();
default: fmt::throw_exception("Invalid audio renderer: %s" HERE, type);
}
};
callbacks.get_msg_dialog = [=]() -> std::shared_ptr<MsgDialogBase>
{
return std::make_shared<msg_dialog_frame>(RPCS3MainWin->windowHandle());
};
callbacks.get_save_dialog = [=]() -> std::unique_ptr<SaveDialogBase>
{
return std::make_unique<save_data_dialog>();
};
callbacks.on_run = [=]() { emit OnEmulatorRun(); };
callbacks.on_pause = [=]() {emit OnEmulatorPause(); };
callbacks.on_resume = [=]() {emit OnEmulatorResume(); };
callbacks.on_stop = [=]() {emit OnEmulatorStop(); };
callbacks.on_ready = [=]() {emit OnEmulatorReady(); };
Emu.SetCallbacks(std::move(callbacks));
}
/*
* Initialize connects here. These are used to connect things between UI elements that require the intervention of rpcs3_app.
*/
void rpcs3_app::InitializeConnects()
{
connect(RPCS3MainWin, &main_window::RequestGlobalStylesheetChange, this, &rpcs3_app::OnChangeStyleSheetRequest);
qRegisterMetaType <std::function<void()>>("std::function<void()>");
connect(this, &rpcs3_app::RequestCallAfter, this, &rpcs3_app::HandleCallAfter);
connect(this, &rpcs3_app::OnEmulatorRun, RPCS3MainWin, &main_window::OnEmuRun);
connect(this, &rpcs3_app::OnEmulatorStop, this, &rpcs3_app::ResetPads);
connect(this, &rpcs3_app::OnEmulatorStop, RPCS3MainWin, &main_window::OnEmuStop);
connect(this, &rpcs3_app::OnEmulatorPause, RPCS3MainWin, &main_window::OnEmuPause);
connect(this, &rpcs3_app::OnEmulatorResume, RPCS3MainWin, &main_window::OnEmuResume);
connect(this, &rpcs3_app::OnEmulatorReady, RPCS3MainWin, &main_window::OnEmuReady);
}
/*
* Handle a request to change the stylesheet. May consider adding reporting of errors in future.
* Empty string means default.
*/
void rpcs3_app::OnChangeStyleSheetRequest(const QString& sheetFilePath)
{
QFile file(sheetFilePath);
if (sheetFilePath == "")
{
setStyleSheet("");
}
else if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
setStyleSheet(file.readAll());
file.close();
}
}
/**
* Using connects avoids timers being unable to be used in a non-qt thread. So, even if this looks stupid to just call func, it's succinct.
*/
void rpcs3_app::HandleCallAfter(const std::function<void()>& func)
{
func();
}
/**
* We need to make this in the main thread to receive events from the main thread.
* This leads to the tricky situation. Creating it while booting leads to deadlock with a blocking connection.
* So, I need to make them before, but when?
* I opted to reset them when the Emu stops and on first init. Potentially a race condition on restart? Never encountered issues.
* The other tricky issue is that I don't want Init to be called twice on the same object. Reseting the pointer on emu stop should handle this as well!
*/
void rpcs3_app::ResetPads()
{
m_basicKeyboardHandler.reset(new basic_keyboard_handler(this, this));
m_basicMouseHandler.reset(new basic_mouse_handler(this, this));
m_keyboardPadHandler.reset(new keyboard_pad_handler(this, this));
}

56
rpcs3/rpcs3_app.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef RPCS3_APP_H
#define RPCS3_APP_H
#include "stdafx.h"
#include "keyboard_pad_handler.h"
#include "basic_keyboard_handler.h"
#include "basic_mouse_handler.h"
#include "Utilities/Config.h"
#include "Emu/RSX/GSRender.h"
#include "Emu/Io/KeyboardHandler.h"
#include "Emu/Io/PadHandler.h"
#include "Emu/Io/MouseHandler.h"
#include "Emu/Audio/AudioThread.h"
#include "rpcs3qt/msg_dialog_frame.h"
#include "rpcs3qt/main_window.h"
#include <QApplication>
/** RPCS3 Application Class
* The point of this class is to do application initialization and to hold onto the main window. The main thing I intend this class to do, for now, is to initialize callbacks and the main_window.
*/
class rpcs3_app : public QApplication
{
Q_OBJECT
public:
rpcs3_app(int& argc, char** argv);
/** Call this method before calling app.exec
*/
void Init();
signals:
void OnEmulatorRun();
void OnEmulatorPause();
void OnEmulatorResume();
void OnEmulatorStop();
void OnEmulatorReady();
void RequestCallAfter(const std::function<void()>& func);
private slots:
void OnChangeStyleSheetRequest(const QString& path);
void HandleCallAfter(const std::function<void()>& func);
void ResetPads();
private:
void InitializeCallbacks();
void InitializeConnects();
// See ResetPads() for why these shared pointers exist.
std::shared_ptr<keyboard_pad_handler> m_keyboardPadHandler;
std::shared_ptr<basic_keyboard_handler> m_basicKeyboardHandler;
std::shared_ptr<basic_mouse_handler> m_basicMouseHandler;
main_window* RPCS3MainWin;
};
#endif

1527
rpcs3/rpcs3qt.vcxproj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,648 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Generated Files">
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
<Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
<Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
</Filter>
<Filter Include="Gui">
<UniqueIdentifier>{c7e705d0-5c35-4008-8a5f-690b35623ab9}</UniqueIdentifier>
</Filter>
<Filter Include="Generated Files\Debug">
<UniqueIdentifier>{f3356193-d7b3-4328-b5e2-7ab9e8ef9f3d}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Generated Files\Release">
<UniqueIdentifier>{46da41cb-0929-4bca-bf2c-30599aa91923}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="rpcs3">
<UniqueIdentifier>{364dd441-10bc-446b-b6aa-4d7b338f30fe}</UniqueIdentifier>
</Filter>
<Filter Include="Io">
<UniqueIdentifier>{cc5a491c-6f1b-491a-8e4a-96743645fd3e}</UniqueIdentifier>
</Filter>
<Filter Include="Io\Basic">
<UniqueIdentifier>{750a54d9-a15b-4d9a-9938-a15e00ba62f8}</UniqueIdentifier>
</Filter>
<Filter Include="Io\XInput">
<UniqueIdentifier>{8f3a932a-5c23-4f8c-a29b-003c59840ef8}</UniqueIdentifier>
</Filter>
<Filter Include="Io\DS4">
<UniqueIdentifier>{04f53189-8145-4a58-8fe0-3b1abebe11e9}</UniqueIdentifier>
</Filter>
<Filter Include="Io\MMJoystick">
<UniqueIdentifier>{0f9f8411-9536-42d8-8f46-5537fb4aae6f}</UniqueIdentifier>
</Filter>
<Filter Include="Generated Files\Release - LLVM">
<UniqueIdentifier>{9dcc13d5-0080-4338-baad-070a544b63b6}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Generated Files\Debug - LLVM">
<UniqueIdentifier>{ed43eb83-3470-4fec-9340-91385acd5d19}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
<Extensions>qrc;*</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="\Gui\*.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>rpcs3</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_audio_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_audio_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_audio_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_audio_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\audio_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\auto_pause_settings_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_auto_pause_settings_dialog.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_auto_pause_settings_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_auto_pause_settings_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_auto_pause_settings_dialog.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_cg_disasm_window.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_cg_disasm_window.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_cg_disasm_window.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_cg_disasm_window.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\cg_disasm_window.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_core_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_core_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_core_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_core_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\core_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_debugger_frame.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_debugger_frame.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_debugger_frame.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_debugger_frame.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\debugger_frame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_emu_settings.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_emu_settings.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_emu_settings.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_emu_settings.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\emu_settings.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_game_list_frame.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_game_list_frame.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_game_list_frame.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_game_list_frame.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\game_list_frame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\gl_gs_frame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_graphics_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_graphics_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_graphics_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_graphics_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\graphics_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gs_frame.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_gs_frame.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_gs_frame.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gs_frame.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\gs_frame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gui_settings.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_gui_settings.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_gui_settings.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gui_settings.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\gui_settings.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gui_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_gui_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_gui_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gui_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\gui_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_input_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_input_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_input_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_input_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\input_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_kernel_explorer.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_kernel_explorer.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_kernel_explorer.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_kernel_explorer.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\kernel_explorer.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_log_frame.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_log_frame.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_log_frame.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_log_frame.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\log_frame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_main_window.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_main_window.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_main_window.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_main_window.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\main_window.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_memory_string_searcher.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_memory_string_searcher.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_memory_string_searcher.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_memory_string_searcher.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\memory_string_searcher.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_misc_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_misc_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_misc_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_misc_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\misc_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_networking_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_networking_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_networking_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_networking_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\networking_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_pad_settings_dialog.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_pad_settings_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_pad_settings_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_pad_settings_dialog.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\pad_settings_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_rsx_debugger.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_rsx_debugger.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_rsx_debugger.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_rsx_debugger.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\rsx_debugger.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\save_data_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\save_data_utility.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_save_data_utility.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_save_data_utility.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_save_data_utility.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_save_data_utility.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_settings_dialog.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_settings_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_settings_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_settings_dialog.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\settings_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\system_tab.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_system_tab.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_system_tab.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_system_tab.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_system_tab.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="basic_keyboard_handler.cpp">
<Filter>Io\Basic</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_basic_keyboard_handler.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_basic_keyboard_handler.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_basic_keyboard_handler.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_basic_keyboard_handler.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_basic_mouse_handler.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_basic_mouse_handler.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_basic_mouse_handler.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_basic_mouse_handler.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="basic_mouse_handler.cpp">
<Filter>Io\Basic</Filter>
</ClCompile>
<ClCompile Include="keyboard_pad_handler.cpp">
<Filter>Io\Basic</Filter>
</ClCompile>
<ClCompile Include="ds4_pad_handler.cpp">
<Filter>Io\DS4</Filter>
</ClCompile>
<ClCompile Include="mm_joystick_handler.cpp">
<Filter>Io\MMJoystick</Filter>
</ClCompile>
<ClCompile Include="xinput_pad_handler.cpp">
<Filter>Io\XInput</Filter>
</ClCompile>
<ClCompile Include="rpcs3_app.cpp">
<Filter>rpcs3</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_rpcs3_app.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcs3_app.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_rpcs3_app.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_rpcs3_app.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\instruction_editor_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\memory_viewer_panel.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\msg_dialog_frame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_msg_dialog_frame.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_msg_dialog_frame.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_msg_dialog_frame.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_msg_dialog_frame.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\register_editor_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\qrc_resources.cpp">
<Filter>Generated Files</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\welcome_dialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_welcome_dialog.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_welcome_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_welcome_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_welcome_dialog.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="\Gui\*.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h" />
<ClInclude Include="rpcs3qt\gl_gs_frame.h">
<Filter>Gui</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\save_data_dialog.h">
<Filter>Gui</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\table_item_delegate.h">
<Filter>Gui</Filter>
</ClInclude>
<ClInclude Include="keyboard_pad_handler.h">
<Filter>Io\Basic</Filter>
</ClInclude>
<ClInclude Include="ds4_pad_handler.h">
<Filter>Io\DS4</Filter>
</ClInclude>
<ClInclude Include="mm_joystick_handler.h">
<Filter>Io\MMJoystick</Filter>
</ClInclude>
<ClInclude Include="xinput_pad_handler.h">
<Filter>Io\XInput</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\instruction_editor_dialog.h">
<Filter>Gui</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\memory_viewer_panel.h">
<Filter>Gui</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\register_editor_dialog.h">
<Filter>Gui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
<Filter>Generated Files</Filter>
</CustomBuild>
<CustomBuild Include="release\moc_predefs.h.cbt">
<Filter>Generated Files</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\audio_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\auto_pause_settings_dialog.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\cg_disasm_window.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\core_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\debugger_frame.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\emu_settings.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\game_list_frame.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\graphics_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\gs_frame.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\gui_settings.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\gui_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\input_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\kernel_explorer.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\log_frame.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\main_window.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\memory_string_searcher.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\misc_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\networking_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\pad_settings_dialog.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\rsx_debugger.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\save_data_utility.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\settings_dialog.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\system_tab.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="basic_keyboard_handler.h">
<Filter>Io\Basic</Filter>
</CustomBuild>
<CustomBuild Include="basic_mouse_handler.h">
<Filter>Io\Basic</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3_app.h">
<Filter>rpcs3</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\msg_dialog_frame.h">
<Filter>Gui</Filter>
</CustomBuild>
<CustomBuild Include="resources.qrc">
<Filter>Resource Files</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\welcome_dialog.h">
<Filter>Gui</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -1,3 +0,0 @@
# P is project dir, B is build dir
P = $$PWD/..
B = $$shadowed($$PWD)

View File

@ -1,49 +0,0 @@
#ifdef QT_UI
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QTableWidget>
#include "AutoPauseSettingsDialog.h"
AutoPauseSettingsDialog::AutoPauseSettingsDialog(QWidget *parent) : QDialog(parent)
{
QLabel *desc = new QLabel(tr("To use auto pause: enter the ID(s) of a function or a system call.\nRestart of the game is required to apply. You can enable/disable this in the settings."));
QTableWidget *pauseList = new QTableWidget;
pauseList->setColumnCount(2);
pauseList->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Call ID")));
pauseList->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Type")));
QPushButton *clearButton = new QPushButton(tr("Clear"));
QPushButton *reloadButton = new QPushButton(tr("Reload"));
QPushButton *saveButton = new QPushButton(tr("Save"));
connect(saveButton, &QAbstractButton::clicked, this, &QDialog::accept);
QPushButton *cancelButton = new QPushButton(tr("Cancel"));
cancelButton->setDefault(true);
connect(cancelButton, &QAbstractButton::clicked, this, &QWidget::close);
QHBoxLayout *buttonsLayout = new QHBoxLayout;
buttonsLayout->addWidget(clearButton);
buttonsLayout->addWidget(reloadButton);
buttonsLayout->addStretch();
buttonsLayout->addWidget(saveButton);
buttonsLayout->addWidget(cancelButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(desc);
mainLayout->addWidget(pauseList);
mainLayout->addLayout(buttonsLayout);
setLayout(mainLayout);
setMinimumSize(QSize(400, 360));
setWindowTitle(tr("Auto Pause Manager"));
}
#endif // QT_UI

View File

@ -1,14 +0,0 @@
#ifndef AUTOPAUSESETTINGSDIALOG_H
#define AUTOPAUSESETTINGSDIALOG_H
#include <QDialog>
class AutoPauseSettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit AutoPauseSettingsDialog(QWidget *parent = 0);
};
#endif // AUTOPAUSESETTINGSDIALOG_H

View File

@ -1,38 +1,33 @@
#ifdef QT_UI
#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "audiotab.h"
#include "audio_tab.h"
AudioTab::AudioTab(QWidget *parent) : QWidget(parent)
audio_tab::audio_tab(std::shared_ptr<emu_settings> xemu_settings, QWidget *parent) : QWidget(parent)
{
// Audio Out
QGroupBox *audioOut = new QGroupBox(tr("Audio Out"));
QComboBox *audioOutBox = new QComboBox;
audioOutBox->addItem(tr("Null"));
#ifdef _WIN32
audioOutBox->addItem(tr("XAudio2"));
#endif // _WIN32
audioOutBox->addItem(tr("OpenAL"));
QComboBox *audioOutBox = xemu_settings->CreateEnhancedComboBox(emu_settings::AudioRenderer, this);
QVBoxLayout *audioOutVbox = new QVBoxLayout;
audioOutVbox->addWidget(audioOutBox);
audioOut->setLayout(audioOutVbox);
// Checkboxes
QCheckBox *audioDump = new QCheckBox(tr("Dump to file"));
QCheckBox *conv = new QCheckBox(tr("Convert to 16 bit"));
QCheckBox *audioDump = xemu_settings->CreateEnhancedCheckBox(emu_settings::DumpToFile, this);
QCheckBox *conv = xemu_settings->CreateEnhancedCheckBox(emu_settings::ConvertTo16Bit, this);
QCheckBox *downmix = xemu_settings->CreateEnhancedCheckBox(emu_settings::DownmixStereo, this);
// Main layout
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(audioOut);
vbox->addWidget(audioDump);
vbox->addWidget(conv);
vbox->addWidget(downmix);
vbox->addStretch();
QHBoxLayout *hbox = new QHBoxLayout;
@ -40,5 +35,3 @@ AudioTab::AudioTab(QWidget *parent) : QWidget(parent)
hbox->addStretch();
setLayout(hbox);
}
#endif // QT_UI

22
rpcs3/rpcs3qt/audio_tab.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef AUDIOTAB_H
#define AUDIOTAB_H
#include "emu_settings.h"
#include <QWidget>
#include <memory>
class audio_tab : public QWidget
{
Q_OBJECT
public:
explicit audio_tab(std::shared_ptr<emu_settings> xemu_settings, QWidget *parent = 0);
signals:
public slots:
};
#endif // AUDIOTAB_H

View File

@ -1,18 +0,0 @@
#ifndef AUDIOTAB_H
#define AUDIOTAB_H
#include <QWidget>
class AudioTab : public QWidget
{
Q_OBJECT
public:
explicit AudioTab(QWidget *parent = 0);
signals:
public slots:
};
#endif // AUDIOTAB_H

View File

@ -0,0 +1,268 @@
#include "auto_pause_settings_dialog.h"
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
auto_pause_settings_dialog::auto_pause_settings_dialog(QWidget *parent) : QDialog(parent)
{
QLabel *description = new QLabel(tr("To use auto pause: enter the ID(s) of a function or a system call.\nRestart of the game is required to apply. You can enable/disable this in the settings."), this);
pauseList = new QTableWidget(this);
pauseList->setColumnCount(2);
pauseList->setHorizontalHeaderLabels(QStringList() << tr("Call ID") << tr("Type"));
//pauseList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
pauseList->setSelectionBehavior(QAbstractItemView::SelectRows);
pauseList->setContextMenuPolicy(Qt::CustomContextMenu);
pauseList->setItemDelegate(new table_item_delegate(this));
pauseList->setShowGrid(false);
QPushButton *clearButton = new QPushButton(tr("Clear"), this);
QPushButton *reloadButton = new QPushButton(tr("Reload"), this);
QPushButton *saveButton = new QPushButton(tr("Save"), this);
QPushButton *cancelButton = new QPushButton(tr("Cancel"), this);
cancelButton->setDefault(true);
QHBoxLayout *buttonsLayout = new QHBoxLayout();
buttonsLayout->addWidget(clearButton);
buttonsLayout->addWidget(reloadButton);
buttonsLayout->addStretch();
buttonsLayout->addWidget(saveButton);
buttonsLayout->addWidget(cancelButton);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(description);
mainLayout->addWidget(pauseList);
mainLayout->addLayout(buttonsLayout);
setLayout(mainLayout);
setMinimumSize(QSize(400, 360));
setWindowTitle(tr("Auto Pause Manager"));
//Events
connect(pauseList, &QTableWidget::customContextMenuRequested, this, &auto_pause_settings_dialog::ShowContextMenu);
connect(clearButton, &QAbstractButton::clicked, [=](){ m_entries.clear(); UpdateList(); });
connect(reloadButton, &QAbstractButton::clicked, [=](){ LoadEntries(); UpdateList(); });
connect(saveButton, &QAbstractButton::clicked, [=](){
SaveEntries();
LOG_SUCCESS(HLE, "Auto Pause: File pause.bin was updated.");
});
connect(cancelButton, &QAbstractButton::clicked, this, &QWidget::close);
Emu.Stop();
LoadEntries();
UpdateList();
setFixedSize(sizeHint());
}
//Copied some from AutoPause.
void auto_pause_settings_dialog::LoadEntries(void)
{
m_entries.clear();
m_entries.reserve(16);
fs::file list(fs::get_config_dir() + "pause.bin");
if (list)
{
//System calls ID and Function calls ID are all u32 iirc.
u32 num;
size_t fmax = list.size();
size_t fcur = 0;
list.seek(0);
while (fcur <= fmax - sizeof(u32))
{
list.read(&num, sizeof(u32));
fcur += sizeof(u32);
if (num == 0xFFFFFFFF) break;
m_entries.emplace_back(num);
}
}
}
//Copied some from AutoPause.
//Tip: This one doesn't check for the file is being read or not.
//This would always use a 0xFFFFFFFF as end of the pause.bin
void auto_pause_settings_dialog::SaveEntries(void)
{
fs::file list(fs::get_config_dir() + "pause.bin", fs::rewrite);
//System calls ID and Function calls ID are all u32 iirc.
u32 num = 0;
list.seek(0);
for (size_t i = 0; i < m_entries.size(); ++i)
{
if (num == 0xFFFFFFFF) continue;
num = m_entries[i];
list.write(&num, sizeof(u32));
}
num = 0xFFFFFFFF;
list.write(&num, sizeof(u32));
}
void auto_pause_settings_dialog::UpdateList(void)
{
pauseList->clearContents();
pauseList->setRowCount(m_entries.size());
for (size_t i = 0; i < m_entries.size(); ++i)
{
QTableWidgetItem* callItem = new QTableWidgetItem;
QTableWidgetItem* typeItem = new QTableWidgetItem;
callItem->setFlags(callItem->flags() & ~Qt::ItemIsEditable);
typeItem->setFlags(typeItem->flags() & ~Qt::ItemIsEditable);
if (m_entries[i] != 0xFFFFFFFF)
{
callItem->setData(Qt::DisplayRole, qstr(fmt::format("%08x", m_entries[i])));
}
else
{
callItem->setData(Qt::DisplayRole, tr("Unset"));
}
if (m_entries[i] < 1024)
{
typeItem->setData(Qt::DisplayRole, tr("System Call"));
}
else
{
typeItem->setData(Qt::DisplayRole, tr("Function Call"));
}
pauseList->setItem(i, 0, callItem);
pauseList->setItem(i, 1, typeItem);
}
}
void auto_pause_settings_dialog::ShowContextMenu(const QPoint &pos)
{
int row = pauseList->indexAt(pos).row();
QPoint globalPos = pauseList->mapToGlobal(pos);
QMenu myMenu;
// Make Actions
QAction* add = myMenu.addAction(tr("&Add"));
QAction* remove = myMenu.addAction(tr("&Remove"));
myMenu.addSeparator();
QAction* config = myMenu.addAction(tr("&Config"));
if (row == -1)
{
remove->setEnabled(false);
config->setEnabled(false);
}
auto OnEntryConfig = [=](int row, bool newEntry)
{
AutoPauseConfigDialog *config = new AutoPauseConfigDialog(this, this, newEntry, &m_entries[row]);
config->setModal(true);
config->exec();
UpdateList();
};
connect(add, &QAction::triggered, [=]() {
m_entries.emplace_back(0xFFFFFFFF);
UpdateList();
u32 idx = m_entries.size() - 1;
pauseList->selectRow(idx);
OnEntryConfig(idx, true);
});
connect(remove, &QAction::triggered, this, &auto_pause_settings_dialog::OnRemove);
connect(config, &QAction::triggered, [=]() {OnEntryConfig(row, false); });
myMenu.exec(globalPos);
}
void auto_pause_settings_dialog::OnRemove()
{
QModelIndexList selection = pauseList->selectionModel()->selectedRows();
qSort(selection.begin(), selection.end()); // crash on unordered
for (int i = selection.count() - 1; i >= 0; i--)
{
m_entries.erase(m_entries.begin() + selection.at(i).row());
}
UpdateList();
}
void auto_pause_settings_dialog::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Delete)
{
OnRemove();
}
}
AutoPauseConfigDialog::AutoPauseConfigDialog(QWidget* parent, auto_pause_settings_dialog* apsd, bool newEntry, u32 *entry)
: QDialog(parent), m_presult(entry), b_newEntry(newEntry), apsd_parent(apsd)
{
m_entry = *m_presult;
setMinimumSize(QSize(300, -1));
QPushButton* button_ok = new QPushButton(tr("&Ok"), this);
QPushButton* button_cancel = new QPushButton(tr("&Cancel"), this);
button_ok->setFixedWidth(50);
button_cancel->setFixedWidth(50);
QLabel* description = new QLabel(tr("Specify ID of System Call or Function Call below. You need to use a Hexadecimal ID."), this);
description->setWordWrap(true);
m_current_converted = new QLabel(tr("Currently it gets an id of \"Unset\"."), this);
m_current_converted->setWordWrap(true);
m_id = new QLineEdit(this);
m_id->setText(qstr(fmt::format("%08x", m_entry)));
m_id->setPlaceholderText("ffffffff");
m_id->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
m_id->setMaxLength(8);
m_id->setFixedWidth(65);
setWindowTitle("Auto Pause Setting: " + m_id->text());
connect(button_cancel, &QAbstractButton::clicked, this, &AutoPauseConfigDialog::OnCancel);
connect(button_ok, &QAbstractButton::clicked, this, &AutoPauseConfigDialog::OnOk);
connect(m_id, &QLineEdit::textChanged, this, &AutoPauseConfigDialog::OnUpdateValue);
QHBoxLayout* configHBox = new QHBoxLayout();
configHBox->addWidget(m_id);
configHBox->addWidget(button_ok);
configHBox->addWidget(button_cancel);
configHBox->setAlignment(Qt::AlignCenter);
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(description);
mainLayout->addLayout(configHBox);
mainLayout->addWidget(m_current_converted);
setLayout(mainLayout);
setFixedSize(QSize(300, sizeHint().height()));
OnUpdateValue();
}
void AutoPauseConfigDialog::OnOk()
{
bool ok;
ullong value = m_id->text().toULongLong(&ok, 16);
m_entry = value;
*m_presult = m_entry;
accept();
}
void AutoPauseConfigDialog::OnCancel()
{
if (b_newEntry)
{
apsd_parent->OnRemove();
}
close();
}
void AutoPauseConfigDialog::OnUpdateValue()
{
bool ok;
ullong value = m_id->text().toULongLong(&ok, 16);
const bool is_ok = ok && value <= UINT32_MAX;
m_current_converted->setText(qstr(fmt::format("Current value: %08x (%s)", u32(value), is_ok ? "OK" : "conversion failed")));
}

View File

@ -0,0 +1,70 @@
#ifndef AUTOPAUSESETTINGSDIALOG_H
#define AUTOPAUSESETTINGSDIALOG_H
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "table_item_delegate.h"
#include <QDialog>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QPushButton>
#include <QAbstractButton>
#include <QLabel>
#include <QString>
#include <QTableWidget>
#include <QHeaderView>
#include <QMouseEvent>
#include <QMenu>
#include <QLineEdit>
#include <QFontDatabase>
class auto_pause_settings_dialog : public QDialog
{
Q_OBJECT
enum
{
id_add,
id_remove,
id_config,
};
std::vector<u32> m_entries;
public:
explicit auto_pause_settings_dialog(QWidget* parent);
QTableWidget *pauseList;
void UpdateList(void);
void LoadEntries(void);
void SaveEntries(void);
public slots :
void OnRemove();
private slots :
void ShowContextMenu(const QPoint &pos);
void keyPressEvent(QKeyEvent *event);
};
class AutoPauseConfigDialog : public QDialog
{
Q_OBJECT
u32 m_entry;
u32* m_presult;
bool b_newEntry;
QLineEdit* m_id;
QLabel* m_current_converted;
auto_pause_settings_dialog* apsd_parent;
public:
explicit AutoPauseConfigDialog(QWidget* parent, auto_pause_settings_dialog* apsd, bool newEntry, u32* entry);
private slots :
void OnOk();
void OnCancel();
void OnUpdateValue();
};
#endif // AUTOPAUSESETTINGSDIALOG_H

View File

@ -0,0 +1,80 @@
#include "stdafx.h"
#include "cg_disasm_window.h"
#include "Emu/System.h"
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QFileDialog>
#include <QDialog>
#include <QVBoxLayout>
#include <QDockWidget>
#include <QCoreApplication>
#include <QFontDatabase>
#include "Emu/RSX/CgBinaryProgram.h"
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
cg_disasm_window::cg_disasm_window(QWidget* parent): QTabWidget()
{
setWindowTitle(tr("Cg Disasm"));
setAttribute(Qt::WA_DeleteOnClose);
setMinimumSize(200, 150); // seems fine on win 10
resize(QSize(620, 395));
tab_disasm = new QWidget(this);
tab_glsl = new QWidget(this);
addTab(tab_disasm, "ASM");
addTab(tab_glsl, "GLSL");
QVBoxLayout* layout_disasm = new QVBoxLayout();
m_disasm_text = new QTextEdit();
m_disasm_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_disasm_text->setReadOnly(true);
m_disasm_text->setWordWrapMode(QTextOption::NoWrap);
m_disasm_text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
layout_disasm->addWidget(m_disasm_text);
tab_disasm->setLayout(layout_disasm);
QVBoxLayout* layout_glsl = new QVBoxLayout();
m_glsl_text = new QTextEdit();
m_glsl_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_glsl_text->setReadOnly(true);
m_glsl_text->setWordWrapMode(QTextOption::NoWrap);
m_glsl_text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
layout_glsl->addWidget(m_glsl_text);
tab_glsl->setLayout(layout_glsl);
m_disasm_text->setContextMenuPolicy(Qt::CustomContextMenu);
m_glsl_text->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_disasm_text, &QWidget::customContextMenuRequested, this, &cg_disasm_window::ShowContextMenu);
connect(m_glsl_text, &QWidget::customContextMenuRequested, this, &cg_disasm_window::ShowContextMenu);
}
void cg_disasm_window::ShowContextMenu(const QPoint &pos) // this is a slot
{
QMenu myMenu;
QPoint globalPos = mapToGlobal(pos);
QAction* clear = new QAction(tr("&Clear"));
QAction* open = new QAction(tr("Open &Cg binary program"));
myMenu.addAction(open);
myMenu.addSeparator();
myMenu.addAction(clear);
auto l_clear = [=]() {m_disasm_text->clear(); m_glsl_text->clear();};
connect(clear, &QAction::triggered, l_clear);
connect(open, &QAction::triggered, [=] {
QString filePath = QFileDialog::getOpenFileName(this, tr("Select Cg program object"), m_path_last, tr("Cg program objects (*.fpo;*.vpo);;"));
if (filePath == NULL) return;
m_path_last = QFileInfo(filePath).path();
CgBinaryDisasm disasm(sstr(filePath));
disasm.BuildShaderBody();
m_disasm_text->setText(qstr(disasm.GetArbShader()));
m_glsl_text->setText(qstr(disasm.GetGlslShader()));
});
myMenu.exec(globalPos);
}

View File

@ -0,0 +1,26 @@
#ifndef CGDISASMWINDOW_H
#define CGDISASMWINDOW_H
#include <QTextEdit>
#include <QMainWindow>
class cg_disasm_window : public QTabWidget
{
Q_OBJECT
private slots:
void ShowContextMenu(const QPoint &pos);
private:
QString m_path_last;
QTextEdit* m_disasm_text;
QTextEdit* m_glsl_text;
QWidget* tab_disasm;
QWidget* tab_glsl;
QAction *openCgBinaryProgram;
public:
explicit cg_disasm_window(QWidget *parent);
};
#endif // CGDISASMWINDOW_H

259
rpcs3/rpcs3qt/core_tab.cpp Normal file
View File

@ -0,0 +1,259 @@
#include "core_tab.h"
#include "stdafx.h"
#include "Emu/System.h"
#include "Crypto/unself.h"
#include "rpcs3qt/emu_settings.h"
#include <QCheckBox>
#include <QGroupBox>
#include <QRadioButton>
#include <QButtonGroup>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <unordered_set>
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
core_tab::core_tab(std::shared_ptr<emu_settings> settings, QWidget *parent) : QWidget(parent), xemu_settings(settings)
{
// PPU Decoder
QGroupBox *ppuDecoder = new QGroupBox(tr("PPU Decoder"));
QVBoxLayout *ppuVbox = new QVBoxLayout;
{ // PPU Stuff : I could make a lambda/special getter in emu_settings, but it's only used three times like this, and two times they're done slighly differently (one setting is disabled).
std::string selectedPPU = settings->GetSetting(emu_settings::PPUDecoder);
for (QString settingType : settings->GetSettingOptions(emu_settings::PPUDecoder))
{
std::string curr = sstr(settingType);
QRadioButton* butt = new QRadioButton(tr(curr.c_str()), this);
butt->setCheckable(true);
ppuVbox->addWidget(butt);
if (curr == selectedPPU)
{
butt->setChecked(true);
}
connect(butt, &QAbstractButton::pressed, [=]() {settings->SetSetting(emu_settings::PPUDecoder, curr); });
}
}
ppuDecoder->setLayout(ppuVbox);
// SPU Decoder
QGroupBox *spuDecoder = new QGroupBox(tr("SPU Decoder"));
QVBoxLayout *spuVbox = new QVBoxLayout;
{ // Spu stuff
std::string selectedSPU = settings->GetSetting(emu_settings::SPUDecoder);
for (QString settingType : settings->GetSettingOptions(emu_settings::SPUDecoder))
{
std::string curr = sstr(settingType);
QRadioButton* butt = new QRadioButton(tr(curr.c_str()), this);
if (curr == "Recompiler (LLVM)")
{
butt->setEnabled(false);
}
butt->setCheckable(true);
spuVbox->addWidget(butt);
if (curr == selectedSPU)
{
butt->setChecked(true);
}
connect(butt, &QAbstractButton::pressed, [=]() {settings->SetSetting(emu_settings::SPUDecoder, curr); });
}
}
spuDecoder->setLayout(spuVbox);
// Checkboxes
QCheckBox *hookStFunc = settings->CreateEnhancedCheckBox(emu_settings::HookStaticFuncs, this);
QCheckBox *bindSPUThreads = settings->CreateEnhancedCheckBox(emu_settings::BindSPUThreads, this);
QCheckBox *lowerSPUThrPrio = settings->CreateEnhancedCheckBox(emu_settings::LowerSPUThreadPrio, this);
// Load libraries
QGroupBox *lle = new QGroupBox(tr("Load libraries"));
QButtonGroup *libModeBG = new QButtonGroup(this);
QVBoxLayout *lleVbox = new QVBoxLayout;
{// Handle lib loading options
std::string selectedLib = settings->GetSetting(emu_settings::LibLoadOptions);
for (QString settingType : settings->GetSettingOptions(emu_settings::LibLoadOptions))
{
std::string curr = sstr(settingType);
QRadioButton* butt = new QRadioButton(tr(curr.c_str()), lle);
butt->setCheckable(true);
libModeBG->addButton(butt);
lleVbox->addWidget(butt);
if (curr == selectedLib)
{
butt->setChecked(true);
}
connect(butt, &QAbstractButton::pressed, [=]() {settings->SetSetting(emu_settings::LibLoadOptions, curr); });
}
}
lleList = new QListWidget;
lleList->setSelectionMode(QAbstractItemView::MultiSelection);
searchBox = new QLineEdit;
// Sort string vector alphabetically
static const auto sort_string_vector = [](std::vector<std::string>& vec)
{
std::sort(vec.begin(), vec.end(), [](const std::string &str1, const std::string &str2) { return str1 < str2; });
};
std::vector<std::string> loadedLibs = xemu_settings->GetLoadedLibraries();
sort_string_vector(loadedLibs);
for (auto lib : loadedLibs)
{
QListWidgetItem* item = new QListWidgetItem(qstr(lib), lleList);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag
item->setCheckState(Qt::Checked); // AND initialize check state
lleList->addItem(item);
}
const std::string& lle_dir = Emu.GetLibDir(); // TODO
std::unordered_set<std::string> set(loadedLibs.begin(), loadedLibs.end());
std::vector<std::string> lle_module_list_unselected;
for (const auto& prxf : fs::dir(lle_dir))
{
// List found unselected modules
if (prxf.is_directory || (prxf.name.substr(std::max<size_t>(size_t(3), prxf.name.length()) - 3)) != "prx")
continue;
if (verify_npdrm_self_headers(fs::file(lle_dir + prxf.name)) && !set.count(prxf.name))
{
lle_module_list_unselected.push_back(prxf.name);
}
}
sort_string_vector(lle_module_list_unselected);
for (auto lib : lle_module_list_unselected)
{
QListWidgetItem* item = new QListWidgetItem(qstr(lib), lleList);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag
item->setCheckState(Qt::Unchecked); // AND initialize check state
lleList->addItem(item);
}
// lleVbox
lleVbox->addSpacing(5);
lleVbox->addWidget(lleList);
lleVbox->addWidget(searchBox);
lle->setLayout(lleVbox);
// Main layout
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(ppuDecoder);
vbox->addWidget(spuDecoder);
vbox->addWidget(hookStFunc);
vbox->addWidget(bindSPUThreads);
vbox->addWidget(lowerSPUThrPrio);
vbox->addStretch();
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vbox);
hbox->addWidget(lle);
setLayout(hbox);
auto l_OnLibButtonClicked = [=](int ind)
{
if (ind == -3 || ind == -4)
{
shouldSaveLibs = true;
searchBox->setEnabled(true);
lleList->setEnabled(true);
}
else
{
shouldSaveLibs = false;
searchBox->setEnabled(false);
lleList->setEnabled(false);
}
};
auto l_OnSearchBoxTextChanged = [=](QString text)
{
QString searchTerm = text.toLower();
QList<QListWidgetItem*> checked_Libs;
QList<QListWidgetItem*> unchecked_Libs;
// create sublists. we need clones to preserve checkstates
for (int i = 0; i < lleList->count(); ++i)
{
if (lleList->item(i)->checkState() == Qt::Checked)
{
checked_Libs.append(lleList->item(i)->clone());
}
else
{
unchecked_Libs.append(lleList->item(i)->clone());
}
}
// sort sublists
auto qLessThan = [](QListWidgetItem *i1, QListWidgetItem *i2) { return i1->text() < i2->text(); };
qSort(checked_Libs.begin(), checked_Libs.end(), qLessThan);
qSort(unchecked_Libs.begin(), unchecked_Libs.end(), qLessThan);
// refill library list
lleList->clear();
for (auto lib : checked_Libs)
{
lleList->addItem(lib);
}
for (auto lib : unchecked_Libs)
{
lleList->addItem(lib);
}
// only show items filtered for search text
for (int i = 0; i < lleList->count(); i++)
{
if (lleList->item(i)->text().contains(searchTerm))
{
lleList->setRowHidden(i, false);
}
else
{
lleList->setRowHidden(i, true);
}
}
};
// Events
connect(libModeBG, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), l_OnLibButtonClicked);
connect(searchBox, &QLineEdit::textChanged, l_OnSearchBoxTextChanged);
int buttid = libModeBG->checkedId();
if (buttid != -1)
{
l_OnLibButtonClicked(buttid);
}
}
void core_tab::SaveSelectedLibraries()
{
if (shouldSaveLibs)
{
std::set<std::string> selectedlle;
for (int i =0; i<lleList->count(); ++i)
{
auto item = lleList->item(i);
if (item->checkState() != Qt::CheckState::Unchecked)
{
std::string lib = sstr(item->text());
selectedlle.emplace(lib);
}
}
std::vector<std::string> selected_ls = std::vector<std::string>(selectedlle.begin(), selectedlle.end());
xemu_settings->SaveSelectedLibraries(selected_ls);
}
}

29
rpcs3/rpcs3qt/core_tab.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef CORETAB_H
#define CORETAB_H
#include "emu_settings.h"
#include <QLineEdit>
#include <QListWidget>
#include <QWidget>
#include <memory>
class core_tab : public QWidget
{
Q_OBJECT
public:
explicit core_tab(std::shared_ptr<emu_settings> xSettings, QWidget *parent = 0);
public slots:
void SaveSelectedLibraries();
private:
bool shouldSaveLibs = false;
QListWidget *lleList;
QLineEdit *searchBox;
std::shared_ptr<emu_settings> xemu_settings;
};
#endif // CORETAB_H

View File

@ -1,83 +0,0 @@
#ifdef QT_UI
#include <QCheckBox>
#include <QGroupBox>
#include <QRadioButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QDebug>
#include "coretab.h"
CoreTab::CoreTab(QWidget *parent) : QWidget(parent)
{
// PPU Decoder
QGroupBox *ppuDecoder = new QGroupBox(tr("PPU Decoder"));
QRadioButton *ppuRadio1 = new QRadioButton(tr("Interpreter (precise)"));
QRadioButton *ppuRadio2 = new QRadioButton(tr("Interpreter (fast)"));
QRadioButton *ppuRadio3 = new QRadioButton(tr("Recompiler (LLVM)"));
QVBoxLayout *ppuVbox = new QVBoxLayout;
ppuVbox->addWidget(ppuRadio1);
ppuVbox->addWidget(ppuRadio2);
ppuVbox->addWidget(ppuRadio3);
ppuDecoder->setLayout(ppuVbox);
// SPU Decoder
QGroupBox *spuDecoder = new QGroupBox(tr("SPU Decoder"));
QRadioButton *spuRadio1 = new QRadioButton(tr("Interpreter (precise)"));
QRadioButton *spuRadio2 = new QRadioButton(tr("Interpreter (fast)"));
QRadioButton *spuRadio3 = new QRadioButton(tr("Recompiler (ASMJIT)"));
QRadioButton *spuRadio4 = new QRadioButton(tr("Recompiler (LLVM)"));
spuRadio4->setEnabled(false); // TODO
QVBoxLayout *spuVbox = new QVBoxLayout;
spuVbox->addWidget(spuRadio1);
spuVbox->addWidget(spuRadio2);
spuVbox->addWidget(spuRadio3);
spuVbox->addWidget(spuRadio4);
spuDecoder->setLayout(spuVbox);
// Checkboxes
QCheckBox *hookStFunc = new QCheckBox(tr("Hook static functions"));
QCheckBox *loadLiblv2 = new QCheckBox(tr("Load liblv2.sprx only"));
// Load libraries
QGroupBox *lle = new QGroupBox(tr("Load libraries"));
lleList = new QListWidget;
searchBox = new QLineEdit;
connect(searchBox, &QLineEdit::textChanged, this, &CoreTab::OnSearchBoxTextChanged);
QVBoxLayout *lleVbox = new QVBoxLayout;
lleVbox->addWidget(lleList);
lleVbox->addWidget(searchBox);
lle->setLayout(lleVbox);
// Main layout
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(ppuDecoder);
vbox->addWidget(spuDecoder);
vbox->addWidget(hookStFunc);
vbox->addWidget(loadLiblv2);
vbox->addStretch();
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vbox);
hbox->addWidget(lle);
setLayout(hbox);
}
void CoreTab::OnSearchBoxTextChanged()
{
if (searchBox->text().isEmpty())
qDebug() << "Empty!";
lleList->clear();
QString searchTerm = searchBox->text().toLower();
}
#endif // QT_UI

View File

@ -1,23 +0,0 @@
#ifndef CORETAB_H
#define CORETAB_H
#include <QLineEdit>
#include <QListWidget>
#include <QWidget>
class CoreTab : public QWidget
{
Q_OBJECT
public:
explicit CoreTab(QWidget *parent = 0);
private slots:
void OnSearchBoxTextChanged();
private:
QListWidget *lleList;
QLineEdit *searchBox;
};
#endif // CORETAB_H

View File

@ -0,0 +1,568 @@
#include "debugger_frame.h"
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
debugger_frame::debugger_frame(QWidget *parent) : QDockWidget(tr("Debugger"), parent)
{
pSize = 10;
update = new QTimer(this);
connect(update, &QTimer::timeout, this, &debugger_frame::UpdateUI);
EnableUpdateTimer(true);
body = new QWidget(this);
mono = QFontDatabase::systemFont(QFontDatabase::FixedFont);
mono.setPointSize(pSize);
QFontMetrics* fontMetrics = new QFontMetrics(mono);
QVBoxLayout* vbox_p_main = new QVBoxLayout();
QHBoxLayout* hbox_b_main = new QHBoxLayout();
m_list = new debugger_list(this);
m_choice_units = new QComboBox(this);
m_choice_units->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_choice_units->setMaxVisibleItems(30);
m_choice_units->setMaximumWidth(500);
m_go_to_addr = new QPushButton(tr("Go To Address"), this);
m_go_to_pc = new QPushButton(tr("Go To PC"), this);
m_btn_step = new QPushButton(tr("Step"), this);
m_btn_run = new QPushButton(tr("Run"), this);
m_btn_pause = new QPushButton(tr("Pause"), this);
EnableButtons(Emu.IsRunning() || Emu.IsPaused());
hbox_b_main->addWidget(m_go_to_addr);
hbox_b_main->addWidget(m_go_to_pc);
hbox_b_main->addWidget(m_btn_step);
hbox_b_main->addWidget(m_btn_run);
hbox_b_main->addWidget(m_btn_pause);
hbox_b_main->addWidget(m_choice_units);
hbox_b_main->addStretch();
//Registers
m_regs = new QTextEdit(this);
m_regs->setLineWrapMode(QTextEdit::NoWrap);
m_regs->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
m_list->setFont(mono);
m_regs->setFont(mono);
QHBoxLayout* hbox_w_list = new QHBoxLayout();
hbox_w_list->addWidget(m_list);
hbox_w_list->addWidget(m_regs);
vbox_p_main->addLayout(hbox_b_main);
vbox_p_main->addLayout(hbox_w_list);
body->setLayout(vbox_p_main);
setWidget(body);
m_list->setWindowTitle(tr("ASM"));
for (uint i = 0; i < m_list->m_item_count; ++i)
{
m_list->insertItem(i, new QListWidgetItem(""));
}
m_list->setSizeAdjustPolicy(QListWidget::AdjustToContents);
connect(m_go_to_addr, &QAbstractButton::clicked, this, &debugger_frame::Show_Val);
connect(m_go_to_pc, &QAbstractButton::clicked, this, &debugger_frame::Show_PC);
connect(m_btn_step, &QAbstractButton::clicked, this, &debugger_frame::DoStep);
connect(m_btn_run, &QAbstractButton::clicked, [=](){
const auto cpu = this->cpu.lock();
if (cpu && cpu->state.test_and_reset(cpu_flag::dbg_pause))
if (!test(cpu->state, cpu_flag::dbg_pause + cpu_flag::dbg_global_pause))
cpu->notify();
UpdateUI();
});
connect(m_btn_pause, &QAbstractButton::clicked, [=](){
if (const auto cpu = this->cpu.lock()) cpu->state += cpu_flag::dbg_pause;
UpdateUI();
});
connect(m_choice_units, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, &debugger_frame::UpdateUI);
connect(m_choice_units, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &debugger_frame::OnSelectUnit);
connect(this, &QDockWidget::visibilityChanged, this, &debugger_frame::EnableUpdateTimer);
m_list->ShowAddr(CentrePc(m_list->m_pc));
UpdateUnitList();
}
void debugger_frame::closeEvent(QCloseEvent *event)
{
QDockWidget::closeEvent(event);
emit DebugFrameClosed();
}
//static const int show_lines = 30;
#include <map>
std::map<u32, bool> g_breakpoints;
extern void ppu_breakpoint(u32 addr);
u32 debugger_frame::GetPc() const
{
const auto cpu = this->cpu.lock();
if (!cpu)
{
return 0;
}
switch (g_system)
{
case system_type::ps3: return cpu->id_type() == 1 ? static_cast<ppu_thread*>(cpu.get())->cia : static_cast<SPUThread*>(cpu.get())->pc;
case system_type::psv: return static_cast<ARMv7Thread*>(cpu.get())->PC;
}
return 0xabadcafe;
}
u32 debugger_frame::CentrePc(u32 pc) const
{
return pc/* - ((m_item_count / 2) * 4)*/;
}
void debugger_frame::UpdateUI()
{
UpdateUnitList();
const auto cpu = this->cpu.lock();
if (!cpu)
{
if (m_last_pc != -1 || m_last_stat)
{
m_last_pc = -1;
m_last_stat = 0;
DoUpdate();
m_btn_run->setEnabled(false);
m_btn_step->setEnabled(false);
m_btn_pause->setEnabled(false);
}
}
else
{
const auto cia = GetPc();
const auto state = cpu->state.load();
if (m_last_pc != cia || m_last_stat != static_cast<u32>(state))
{
m_last_pc = cia;
m_last_stat = static_cast<u32>(state);
DoUpdate();
if (test(state & cpu_flag::dbg_pause))
{
m_btn_run->setEnabled(true);
m_btn_step->setEnabled(true);
m_btn_pause->setEnabled(false);
}
else
{
m_btn_run->setEnabled(false);
m_btn_step->setEnabled(false);
m_btn_pause->setEnabled(true);
}
}
}
if (Emu.IsStopped())
{
g_breakpoints.clear();
}
}
void debugger_frame::UpdateUnitList()
{
const u64 threads_created = cpu_thread::g_threads_created;
const u64 threads_deleted = cpu_thread::g_threads_deleted;
if (threads_created != m_threads_created || threads_deleted != m_threads_deleted)
{
m_threads_created = threads_created;
m_threads_deleted = threads_deleted;
}
else
{
// Nothing to do
return;
}
m_choice_units->clear();
const auto on_select = [&](u32, cpu_thread& cpu)
{
QVariant var_cpu = qVariantFromValue((void *)&cpu);
m_choice_units->addItem(qstr(cpu.get_name()), var_cpu);
};
idm::select<ppu_thread>(on_select);
idm::select<ARMv7Thread>(on_select);
idm::select<RawSPUThread>(on_select);
idm::select<SPUThread>(on_select);
m_choice_units->update();
}
void debugger_frame::OnSelectUnit()
{
if (m_choice_units->count() < 1) return;
m_disasm.reset();
const auto on_select = [&](u32, cpu_thread& cpu)
{
cpu_thread* data = (cpu_thread *)m_choice_units->currentData().value<void *>();
return data == &cpu;
};
if (auto ppu = idm::select<ppu_thread>(on_select))
{
m_disasm = std::make_unique<PPUDisAsm>(CPUDisAsm_InterpreterMode);
cpu = ppu.ptr;
}
else if (auto spu1 = idm::select<SPUThread>(on_select))
{
m_disasm = std::make_unique<SPUDisAsm>(CPUDisAsm_InterpreterMode);
cpu = spu1.ptr;
}
else if (auto rspu = idm::select<RawSPUThread>(on_select))
{
m_disasm = std::make_unique<SPUDisAsm>(CPUDisAsm_InterpreterMode);
cpu = rspu.ptr;
}
else if (auto arm = idm::select<ARMv7Thread>(on_select))
{
m_disasm = std::make_unique<ARMv7DisAsm>(CPUDisAsm_InterpreterMode);
cpu = arm.ptr;
}
DoUpdate();
}
//void debugger_frame::resizeEvent(QResizeEvent* event)
//{
// if (0)
// {
// if (!m_list->rowCount())
// {
// m_list->InsertItem(m_list->rowCount(), "");
// }
//
// int size = 0;
// m_list->clear();
// int item = 0;
// while (size < m_list->GetSize().GetHeight())
// {
// item = m_list->rowCount();
// m_list->InsertItem(item, "");
// QRect rect;
// m_list->GetItemRect(item, rect);
//
// size = rect.GetBottom();
// }
//
// if (item)
// {
// m_list->removeRow(--item);
// }
//
// m_item_count = item;
// ShowAddr(m_pc);
// }
//}
void debugger_frame::DoUpdate()
{
Show_PC();
WriteRegs();
}
void debugger_frame::WriteRegs()
{
const auto cpu = this->cpu.lock();
if (!cpu)
{
m_regs->clear();
return;
}
m_regs->clear();
m_regs->setText(qstr(cpu->dump()));
}
void debugger_frame::OnUpdate()
{
//WriteRegs();
}
void debugger_frame::Show_Val()
{
QDialog* diag = new QDialog(this);
diag->setWindowTitle(tr("Set value"));
diag->setModal(true);
QPushButton* button_ok = new QPushButton(tr("Ok"));
QPushButton* button_cancel = new QPushButton(tr("Cancel"));
QVBoxLayout* vbox_panel(new QVBoxLayout());
QHBoxLayout* hbox_text_panel(new QHBoxLayout());
QHBoxLayout* hbox_button_panel(new QHBoxLayout());
QLineEdit* p_pc(new QLineEdit(diag));
p_pc->setFont(mono);
p_pc->setMaxLength(8);
p_pc->setFixedWidth(75);
QLabel* addr(new QLabel(diag));
addr->setFont(mono);
hbox_text_panel->addWidget(addr);
hbox_text_panel->addWidget(p_pc);
hbox_button_panel->addWidget(button_ok);
hbox_button_panel->addWidget(button_cancel);
vbox_panel->addLayout(hbox_text_panel);
vbox_panel->addSpacing(8);
vbox_panel->addLayout(hbox_button_panel);
diag->setLayout(vbox_panel);
const auto cpu = this->cpu.lock();
if (cpu)
{
unsigned long pc = cpu ? GetPc() : 0x0;
bool ok;
addr->setText("Address: " + QString("%1").arg(pc, 8, 16, QChar('0'))); // set address input line to 8 digits
p_pc->setPlaceholderText(QString("%1").arg(pc, 8, 16, QChar('0')));
}
else
{
p_pc->setPlaceholderText("00000000");
addr->setText("Address: 00000000");
}
auto l_changeLabel = [=]()
{
if (p_pc->text().isEmpty())
{
addr->setText("Address: " + p_pc->placeholderText());
}
else
{
bool ok;
ulong ul_addr = p_pc->text().toULong(&ok, 16);
addr->setText("Address: " + QString("%1").arg(ul_addr, 8, 16, QChar('0'))); // set address input line to 8 digits
}
};
connect(p_pc, &QLineEdit::textChanged, l_changeLabel);
connect(button_ok, &QAbstractButton::clicked, diag, &QDialog::accept);
connect(button_cancel, &QAbstractButton::clicked, diag, &QDialog::reject);;
if (diag->exec() == QDialog::Accepted)
{
unsigned long pc = cpu ? GetPc() : 0x0;
if (p_pc->text().isEmpty())
{
addr->setText(p_pc->placeholderText());
}
else
{
bool ok;
pc = p_pc->text().toULong(&ok, 16);
addr->setText(p_pc->text());
}
m_list->ShowAddr(CentrePc(pc));
}
}
void debugger_frame::Show_PC()
{
if (const auto cpu = this->cpu.lock()) m_list->ShowAddr(CentrePc(GetPc()));
}
void debugger_frame::DoStep()
{
if (const auto cpu = this->cpu.lock())
{
if (test(cpu_flag::dbg_pause, cpu->state.fetch_op([](bs_t<cpu_flag>& state)
{
state += cpu_flag::dbg_step;
state -= cpu_flag::dbg_pause;
})))
{
cpu->notify();
}
}
UpdateUI();
}
void debugger_frame::EnableUpdateTimer(bool enable)
{
enable ? update->start(50) : update->stop();
}
void debugger_frame::EnableButtons(bool enable)
{
m_go_to_addr->setEnabled(enable);
m_go_to_pc->setEnabled(enable);
m_btn_step->setEnabled(enable);
m_btn_run->setEnabled(enable);
m_btn_pause->setEnabled(enable);
}
debugger_list::debugger_list(debugger_frame* parent) : QListWidget(parent)
{
m_pc = 0;
m_item_count = 30;
m_debugFrame = parent;
};
void debugger_list::ShowAddr(u32 addr)
{
m_pc = addr;
const auto cpu = m_debugFrame->cpu.lock();
if (!cpu)
{
for (uint i = 0; i<m_item_count; ++i, m_pc += 4)
{
item(i)->setText(qstr(fmt::format("[%08x] illegal address", m_pc)));
}
}
else
{
const u32 cpu_offset = g_system == system_type::ps3 && cpu->id_type() != 1 ? static_cast<SPUThread&>(*cpu).offset : 0;
m_debugFrame->m_disasm->offset = (u8*)vm::base(cpu_offset);
for (uint i = 0, count = 4; i<m_item_count; ++i, m_pc += count)
{
if (!vm::check_addr(cpu_offset + m_pc, 4))
{
item(i)->setText((IsBreakPoint(m_pc) ? ">>> " : " ") + qstr(fmt::format("[%08x] illegal address", m_pc)));
count = 4;
continue;
}
count = m_debugFrame->m_disasm->disasm(m_debugFrame->m_disasm->dump_pc = m_pc);
item(i)->setText((IsBreakPoint(m_pc) ? ">>> " : " ") + qstr(m_debugFrame->m_disasm->last_opcode));
QColor colour;
if (test(cpu->state & cpu_state_pause) && m_pc == m_debugFrame->GetPc())
{
colour = QColor(Qt::green);
}
else
{
colour = QColor(IsBreakPoint(m_pc) ? Qt::yellow : Qt::white);
}
item(i)->setBackgroundColor(colour);
}
}
setLineWidth(-1);
}
bool debugger_list::IsBreakPoint(u32 pc)
{
return g_breakpoints.count(pc) != 0;
}
void debugger_list::AddBreakPoint(u32 pc)
{
g_breakpoints.emplace(pc, false);
ppu_breakpoint(pc);
}
void debugger_list::RemoveBreakPoint(u32 pc)
{
g_breakpoints.erase(pc);
ppu_breakpoint(pc);
}
void debugger_list::keyPressEvent(QKeyEvent* event)
{
if (!isActiveWindow())
{
return;
}
const auto cpu = m_debugFrame->cpu.lock();
long i = currentRow();
if (i < 0 || !cpu)
{
return;
}
const u32 start_pc = m_pc - m_item_count * 4;
const u32 pc = start_pc + i * 4;
if (event->key() == Qt::Key_Space && QApplication::keyboardModifiers() & Qt::ControlModifier)
{
m_debugFrame->DoStep();
return;
}
else
{
switch (event->key())
{
case Qt::Key_PageUp: ShowAddr(m_pc - (m_item_count * 2) * 4); return;
case Qt::Key_PageDown: ShowAddr(m_pc); return;
case Qt::Key_Up: ShowAddr(m_pc - (m_item_count + 1) * 4); return;
case Qt::Key_Down: ShowAddr(m_pc - (m_item_count - 1) * 4); return;
case Qt::Key_E:
{
instruction_editor_dialog* dlg = new instruction_editor_dialog(this, pc, cpu, m_debugFrame->m_disasm.get());
dlg->show();
m_debugFrame->DoUpdate();
return;
}
case Qt::Key_R:
{
register_editor_dialog* dlg = new register_editor_dialog(this, pc, cpu, m_debugFrame->m_disasm.get());
dlg->show();
m_debugFrame->DoUpdate();
return;
}
}
}
}
void debugger_list::mouseDoubleClickEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton && (Emu.IsRunning() || Emu.IsPaused()))
{
long i = currentRow();
if (i < 0) return;
const u32 start_pc = m_pc - m_item_count * 4;
const u32 pc = start_pc + i * 4;
//ConLog.Write("pc=0x%llx", pc);
if (IsBreakPoint(pc))
{
RemoveBreakPoint(pc);
}
else
{
AddBreakPoint(pc);
}
ShowAddr(start_pc);
}
}
void debugger_list::wheelEvent(QWheelEvent* event)
{
QPoint numSteps = event->angleDelta() / 8 / 15; // http://doc.qt.io/qt-5/qwheelevent.html#pixelDelta
const int value = numSteps.y();
ShowAddr(m_pc - (event->modifiers() == Qt::ControlModifier ? m_item_count * (value + 1) : m_item_count + value) * 4);
}

View File

@ -0,0 +1,119 @@
#ifndef DEBUGGERFRAME_H
#define DEBUGGERFRAME_H
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDisAsm.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/RawSPUThread.h"
#include "Emu/PSP2/ARMv7Thread.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/SPUDisAsm.h"
#include "Emu/PSP2/ARMv7DisAsm.h"
#include "Emu/Cell/PPUInterpreter.h"
#include "instruction_editor_dialog.h"
#include "register_editor_dialog.h"
#include <QApplication>
#include <QDockWidget>
#include <QListWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QComboBox>
#include <QKeyEvent>
#include <QWheelEvent>
#include <QInputDialog>
#include <QFontDatabase>
#include <QTimer>
#include <QTextEdit>
class debugger_list;
class debugger_frame : public QDockWidget
{
Q_OBJECT
QWidget* body;
debugger_list* m_list;
int pSize;
QFont mono;
QTextEdit* m_regs;
QPushButton* m_go_to_addr;
QPushButton* m_go_to_pc;
QPushButton* m_btn_step;
QPushButton* m_btn_run;
QPushButton* m_btn_pause;
QComboBox* m_choice_units;
u64 m_threads_created = 0;
u64 m_threads_deleted = 0;
u32 m_last_pc = -1;
u32 m_last_stat = 0;
QTimer* update;
public:
std::unique_ptr<CPUDisAsm> m_disasm;
std::weak_ptr<cpu_thread> cpu;
public:
explicit debugger_frame(QWidget *parent = 0);
void UpdateUI();
void UpdateUnitList();
u32 GetPc() const;
u32 CentrePc(u32 pc) const;
//void resizeEvent(QResizeEvent* event);
void DoUpdate();
void WriteRegs();
void EnableButtons(bool enable);
void OnUpdate();
protected:
/** Override inherited method from Qt to allow signalling when close happened.*/
void closeEvent(QCloseEvent* event);
signals:
void DebugFrameClosed();
public slots:
void DoStep();
private slots:
void OnSelectUnit();
void Show_Val();
void Show_PC();
void EnableUpdateTimer(bool state);
};
class debugger_list : public QListWidget
{
Q_OBJECT
debugger_frame* m_debugFrame;
public:
u32 m_pc;
u32 m_item_count;
public:
debugger_list(debugger_frame* parent);
void ShowAddr(u32 addr);
private:
bool IsBreakPoint(u32 pc);
void AddBreakPoint(u32 pc);
void RemoveBreakPoint(u32 pc);
protected:
void keyPressEvent(QKeyEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent* event);
};
#endif // DEBUGGERFRAME_H

View File

@ -1,10 +0,0 @@
#ifdef QT_UI
#include "debuggerframe.h"
DebuggerFrame::DebuggerFrame(QWidget *parent) : QDockWidget(tr("Debugger"), parent)
{
}
#endif // QT_UI

View File

@ -1,14 +0,0 @@
#ifndef DEBUGGERFRAME_H
#define DEBUGGERFRAME_H
#include <QDockWidget>
class DebuggerFrame : public QDockWidget
{
Q_OBJECT
public:
explicit DebuggerFrame(QWidget *parent = 0);
};
#endif // DEBUGGERFRAME_H

View File

@ -0,0 +1,214 @@
#include "emu_settings.h"
#include "stdafx.h"
#include "Emu/System.h"
#include "Utilities/Config.h"
extern std::string g_cfg_defaults; //! Default settings grabbed from Utilities/Config.h
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
inline std::string sstr(const QVariant& _in) { return sstr(_in.toString()); }
// Emit sorted YAML
namespace
{
static NEVER_INLINE void emitData(YAML::Emitter& out, const YAML::Node& node)
{
// TODO
out << node;
}
// Incrementally load YAML
static NEVER_INLINE void operator +=(YAML::Node& left, const YAML::Node& node)
{
if (node && !node.IsNull())
{
if (node.IsMap())
{
for (const auto& pair : node)
{
if (pair.first.IsScalar())
{
auto&& lhs = left[pair.first.Scalar()];
lhs += pair.second;
}
else
{
// Exotic case (TODO: probably doesn't work)
auto&& lhs = left[YAML::Clone(pair.first)];
lhs += pair.second;
}
}
}
else if (node.IsScalar() || node.IsSequence())
{
// Scalars and sequences are replaced completely, but this may change in future.
// This logic may be overwritten by custom demands of every specific cfg:: node.
left = node;
}
}
}
}
// Helper methods to interact with YAML and the config settings.
namespace cfg_adapter
{
static cfg::_base& get_cfg(cfg::_base& root, const std::string& name)
{
if (root.get_type() == cfg::type::node)
{
for (const auto& pair : static_cast<cfg::node&>(root).get_nodes())
{
if (pair.first == name)
{
return *pair.second;
}
}
}
fmt::throw_exception("Node not found: %s", name);
}
static cfg::_base& get_cfg(cfg::_base& root, cfg_location::const_iterator begin, cfg_location::const_iterator end)
{
return begin == end ? root : get_cfg(get_cfg(root, *begin), begin + 1, end);
}
static YAML::Node get_node(const YAML::Node& node, cfg_location::const_iterator begin, cfg_location::const_iterator end)
{
return begin == end ? node : get_node(node[*begin], begin + 1, end); // TODO
}
/** Syntactic sugar to get a setting at a given config location. */
static YAML::Node get_node(const YAML::Node& node, cfg_location loc)
{
return get_node(node, loc.cbegin(), loc.cend());
}
};
/** Returns possible options for values for some particular setting.*/
static QStringList getOptions(cfg_location location)
{
QStringList values;
auto begin = location.cbegin();
auto end = location.cend();
for (const auto& v : cfg_adapter::get_cfg(g_cfg, begin, end).to_list())
{
values.append(qstr(v));
}
return values;
}
emu_settings::emu_settings(const std::string& path) : QObject()
{
currentSettings = YAML::Load(g_cfg_defaults);
// Create config path if necessary
fs::create_path(fs::get_config_dir() + path);
// Incrementally load config.yml
config = fs::file(fs::get_config_dir() + path + "/config.yml", fs::read + fs::write + fs::create);
if (config.size() == 0 && !path.empty()) // First time
{
config = fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::write + fs::create);
currentSettings += YAML::Load(config.to_string());
}
else
{
currentSettings += YAML::Load(config.to_string());
}
}
emu_settings::~emu_settings()
{
}
void emu_settings::SaveSettings()
{
YAML::Emitter out;
emitData(out, currentSettings);
// Save config
config.seek(0);
config.trunc(0);
config.write(out.c_str(), out.size());
}
QComboBox* emu_settings::CreateEnhancedComboBox(SettingsType type, QWidget* parent)
{
QComboBox* box = new QComboBox(parent);
for (QString setting : GetSettingOptions(type))
{
box->addItem(tr(setting.toStdString().c_str()), QVariant(setting));
}
QString selected = qstr(GetSetting(type));
int index = box->findData(selected);
if (index == -1)
{
LOG_WARNING(GENERAL, "Current setting not found while creating combobox");
}
else
{
box->setCurrentIndex(index);
}
connect(box, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int index) {
SetSetting(type, sstr(box->itemData(index)));
});
return box;
}
QCheckBox* emu_settings::CreateEnhancedCheckBox(SettingsType type, QWidget* parent)
{
cfg_location loc = SettingsLoc[type];
std::string name = loc[loc.size()-1];
QCheckBox* settingsButton = new QCheckBox(tr(name.c_str()), parent);
std::string currSet = GetSetting(type);
if (currSet == "true")
{
settingsButton->setChecked(true);
}
else if (currSet != "false")
{
LOG_WARNING(GENERAL, "Passed in an invalid setting for creating enhanced checkbox");
}
connect(settingsButton, &QCheckBox::stateChanged, [=](int val) {
std::string str = val != 0 ? "true" : "false";
SetSetting(type, str);
});
return settingsButton;
}
std::vector<std::string> emu_settings::GetLoadedLibraries()
{
return currentSettings["Core"]["Load libraries"].as<std::vector<std::string>, std::initializer_list<std::string>>({});
}
void emu_settings::SaveSelectedLibraries(const std::vector<std::string>& libs)
{
currentSettings["Core"]["Load libraries"] = libs;
}
QStringList emu_settings::GetSettingOptions(SettingsType type) const
{
return getOptions(const_cast<cfg_location&&>(SettingsLoc[type]));
}
std::string emu_settings::GetSetting(SettingsType type) const
{
return cfg_adapter::get_node(currentSettings, SettingsLoc[type]).Scalar();
}
void emu_settings::SetSetting(SettingsType type, const std::string& val)
{
cfg_adapter::get_node(currentSettings, SettingsLoc[type])= val;
}

View File

@ -0,0 +1,248 @@
#ifndef EMU_SETTINGS_H
#define EMU_SETTINGS_H
#include "Utilities/File.h"
#include "Utilities/Log.h"
#include "yaml-cpp/yaml.h"
#include <QCheckBox>
#include <QStringList>
#include <QMap>
#include <QObject>
#include <QComboBox>
#ifdef _MSC_VER
#include <Windows.h>
#undef GetHwnd
#include <d3d12.h>
#include <wrl/client.h>
#include <dxgi1_4.h>
#endif
#ifdef _WIN32
#include "Emu/RSX/VK/VKHelpers.h"
#endif
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
struct Render_Creator
{
bool supportsD3D12 = false;
bool supportsVulkan = false;
QStringList D3D12Adapters;
QStringList vulkanAdapters;
QString render_Vulkan = QObject::tr("Vulkan");
QString render_D3D12 = QObject::tr("D3D12");
QString render_OpenGL = QObject::tr("OpenGL");
Render_Creator()
{
// check for dx12 adapters
#ifdef _MSC_VER
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory;
supportsD3D12 = SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory)));
if (supportsD3D12)
{
supportsD3D12 = false;
IDXGIAdapter1* pAdapter = nullptr;
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != dxgi_factory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex)
{
HMODULE D3D12Module = verify("d3d12.dll", LoadLibrary(L"d3d12.dll"));
PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(D3D12Module, "D3D12CreateDevice");
if (SUCCEEDED(wrapD3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
{
//A device with D3D12 support found. Init data
supportsD3D12 = true;
DXGI_ADAPTER_DESC desc;
pAdapter->GetDesc(&desc);
D3D12Adapters.append(QString::fromWCharArray(desc.Description));
}
}
}
#endif
// check for vulkan adapters
#ifdef _WIN32
vk::context device_enum_context;
u32 instance_handle = device_enum_context.createInstance("RPCS3", true);
if (instance_handle > 0)
{
device_enum_context.makeCurrentInstance(instance_handle);
std::vector<vk::physical_device>& gpus = device_enum_context.enumerateDevices();
if (gpus.size() > 0)
{
//A device with vulkan support found. Init data
supportsVulkan = true;
for (auto& gpu : gpus)
{
vulkanAdapters.append(qstr(gpu.name()));
}
}
}
#endif
}
};
// Node location
using cfg_location = std::vector<const char*>;
class emu_settings : public QObject
{
/** A settings class for Emulator specific settings. This class is a refactored version of the wx version. It is much nicer
*
*/
Q_OBJECT
public:
enum SettingsType {
// Core
PPUDecoder,
SPUDecoder,
LibLoadOptions,
HookStaticFuncs,
BindSPUThreads,
LowerSPUThreadPrio,
// Graphics
Renderer,
Resolution,
AspectRatio,
FrameLimit,
LogShaderPrograms,
WriteDepthBuffer,
WriteColorBuffers,
ReadColorBuffers,
ReadDepthBuffer,
VSync,
DebugOutput,
DebugOverlay,
LegacyBuffers,
GPUTextureScaling,
D3D12Adapter,
VulkanAdapter,
// Audio
AudioRenderer,
DumpToFile,
ConvertTo16Bit,
DownmixStereo,
// Input / Output
PadHandler,
KeyboardHandler,
MouseHandler,
Camera,
CameraType,
// Misc
ExitRPCS3OnFinish,
StartOnBoot,
StartGameFullscreen,
ShowFPSInTitle,
ShowWelcomeScreen,
// Network
ConnectionStatus,
// Language
Language,
EnableHostRoot,
};
/** Creates a settings object which reads in the config.yml file at rpcs3/bin/%path%/config.yml
* Settings are only written when SaveSettings is called.
*/
emu_settings(const std::string& path);
~emu_settings();
/** Returns a combo box of that setting type that is bound to the parent. */
QComboBox* CreateEnhancedComboBox(SettingsType type, QWidget* parent = nullptr);
/** Returns a check button that is connected to the target settings type, bound to the life of parent*/
QCheckBox* CreateEnhancedCheckBox(SettingsType target, QWidget* parent = nullptr);
std::vector<std::string> GetLoadedLibraries();
void SaveSelectedLibraries(const std::vector<std::string>& libs);
/** Returns the valid options for a given setting.*/
QStringList GetSettingOptions(SettingsType type) const;
/** Returns the value of the setting type.*/
std::string GetSetting(SettingsType type) const;
/** Sets the setting type to a given value.*/
void SetSetting(SettingsType type, const std::string& val);
public slots:
/** Writes the unsaved settings to file. Used in settings dialog on accept.*/
void SaveSettings();
private:
/** A helper map that keeps track of where a given setting type is located*/
const QMap<SettingsType, cfg_location> SettingsLoc = {
// Core Tab
{ PPUDecoder, { "Core", "PPU Decoder"}},
{ SPUDecoder, { "Core", "SPU Decoder"}},
{ LibLoadOptions, { "Core", "Lib Loader"}},
{ HookStaticFuncs, { "Core", "Hook static functions"}},
{ BindSPUThreads, { "Core", "Bind SPU threads to secondary cores"}},
{ LowerSPUThreadPrio, { "Core", "Lower SPU thread priority"}},
// Graphics Tab
{ Renderer, { "Video", "Renderer"}},
{ Resolution, { "Video", "Resolution"}},
{ AspectRatio, { "Video", "Aspect ratio"}},
{ FrameLimit, { "Video", "Frame limit"}},
{ LogShaderPrograms,{ "Video", "Log shader programs"}},
{ WriteDepthBuffer, { "Video", "Write Depth Buffer"}},
{ WriteColorBuffers,{ "Video", "Write Color Buffers"}},
{ ReadColorBuffers, { "Video", "Read Color Buffers"}},
{ ReadDepthBuffer, { "Video", "Read Depth Buffer"}},
{ VSync, { "Video", "VSync"}},
{ DebugOutput, { "Video", "Debug output"}},
{ DebugOverlay, { "Video", "Debug overlay"}},
{ LegacyBuffers, { "Video", "Use Legacy OpenGL Buffers (Debug)"}},
{ GPUTextureScaling,{ "Video", "Use GPU texture scaling"}},
{ D3D12Adapter, { "Video", "D3D12", "Adapter"}},
{ VulkanAdapter, { "Video", "Vulkan", "Adapter"}},
// Audio
{ AudioRenderer, { "Audio", "Renderer"}},
{ DumpToFile, { "Audio", "Dump to file"}},
{ ConvertTo16Bit, { "Audio", "Convert to 16 bit"}},
{ DownmixStereo, { "Audio", "Downmix to Stereo"}},
// Input / Output
{ PadHandler, { "Input/Output", "Pad"}},
{ KeyboardHandler, { "Input/Output", "Keyboard"}},
{ MouseHandler, { "Input/Output", "Mouse"}},
{ Camera, { "Input/Output", "Camera"}},
{ CameraType, { "Input/Output", "Camera type"}},
// Misc
{ExitRPCS3OnFinish, { "Miscellaneous", "Exit RPCS3 when process finishes" }},
{StartOnBoot, { "Miscellaneous", "Automatically start games after boot" }},
{StartGameFullscreen, { "Miscellaneous", "Start games in fullscreen mode"}},
{ShowFPSInTitle, { "Miscellaneous", "Show FPS counter in window title"}},
{ShowWelcomeScreen, { "Miscellaneous", "Show Welcome Screen"}},
// Networking
{ConnectionStatus, { "Net", "Connection status"}},
// System
{Language, { "System", "Language"}},
{EnableHostRoot, { "VFS", "Enable /host_root/"}},
};
YAML::Node currentSettings; // The current settings as a YAML node.
fs::file config; //! File to read/write the config settings.
};
#endif

View File

@ -0,0 +1,641 @@
#include "game_list_frame.h"
#include "settings_dialog.h"
#include "table_item_delegate.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Loader/PSF.h"
#include "Utilities/types.h"
#include <algorithm>
#include <memory>
#include <QDesktopServices>
#include <QDir>
#include <QHeaderView>
#include <QListView>
#include <QMenuBar>
#include <QMessageBox>
#include <QProcess>
#include <QTimer>
static const std::string m_class_name = "GameViewer";
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
// Auxiliary classes
class sortGameData
{
int sortColumn;
bool sortAscending;
public:
sortGameData(u32 column, bool ascending) : sortColumn(column), sortAscending(ascending) {}
bool operator()(const GameInfo& game1, const GameInfo& game2) const
{
// Note that the column index has to match the appropriate GameInfo member
switch (sortColumn - 1) // skip *icon* column
{
case 0: return sortAscending ? (game1.name < game2.name) : (game1.name > game2.name);
case 1: return sortAscending ? (game1.serial < game2.serial) : (game1.serial > game2.serial);
case 2: return sortAscending ? (game1.fw < game2.fw) : (game1.fw > game2.fw);
case 3: return sortAscending ? (game1.app_ver < game2.app_ver) : (game1.app_ver > game2.app_ver);
case 4: return sortAscending ? (game1.category < game2.category) : (game1.category > game2.category);
case 5: return sortAscending ? (game1.root < game2.root) : (game1.root > game2.root);
default: return false;
}
}
};
game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, Render_Creator r_Creator, QWidget *parent)
: QDockWidget(tr("Game List"), parent), xgui_settings(settings), m_Render_Creator(r_Creator)
{
m_Icon_Size = GUI::gl_icon_size.at(m_gui_settings->GetValue(GUI::gl_iconSize).toString());
m_columns = columns_arr(m_Icon_Size);
gameList = new QTableWidget(this);
gameList->setShowGrid(false);
gameList->setItemDelegate(new table_item_delegate(this));
gameList->setSelectionBehavior(QAbstractItemView::SelectRows);
gameList->setSelectionMode(QAbstractItemView::SingleSelection);
gameList->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
gameList->verticalHeader()->setMinimumSectionSize(m_Icon_Size.height());
gameList->verticalHeader()->setMaximumSectionSize(m_Icon_Size.height());
gameList->verticalHeader()->setVisible(false);
gameList->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
gameList->setContextMenuPolicy(Qt::CustomContextMenu);
gameList->setColumnCount(7);
gameList->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Icon")));
gameList->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Name")));
gameList->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Serial")));
gameList->setHorizontalHeaderItem(3, new QTableWidgetItem(tr("FW")));
gameList->setHorizontalHeaderItem(4, new QTableWidgetItem(tr("App version")));
gameList->setHorizontalHeaderItem(5, new QTableWidgetItem(tr("Category")));
gameList->setHorizontalHeaderItem(6, new QTableWidgetItem(tr("Path")));
setWidget(gameList);
// Actions
showIconColAct = new QAction(tr("Show Icons"), this);
showNameColAct = new QAction(tr("Show Names"), this);
showSerialColAct = new QAction(tr("Show Serials"), this);
showFWColAct = new QAction(tr("Show FWs"), this);
showAppVersionColAct = new QAction(tr("Show App Versions"), this);
showCategoryColAct = new QAction(tr("Show Categories"), this);
showPathColAct = new QAction(tr("Show Paths"), this);
columnActs = { showIconColAct, showNameColAct, showSerialColAct, showFWColAct, showAppVersionColAct, showCategoryColAct, showPathColAct };
// Events
connect(gameList, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
connect(gameList->horizontalHeader(), &QHeaderView::customContextMenuRequested, [=](const QPoint& pos) {
QMenu* configure = new QMenu(this);
configure->addActions({ showIconColAct, showNameColAct, showSerialColAct, showFWColAct, showAppVersionColAct, showCategoryColAct, showPathColAct });
configure->exec(mapToGlobal(pos));
});
connect(gameList, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked);
for (int col = 0; col < columnActs.count(); ++col)
{
columnActs[col]->setCheckable(true);
auto l_CallBack = [this, col](bool val) {
if (!val) // be sure to have at least one column left so you can call the context menu at all time
{
int c = 0;
for (int i = 0; i < columnActs.count(); ++i)
{
if (xgui_settings->GetGamelistColVisibility(i)) { if (++c > 1) { break; } }
}
if (c < 2)
{
columnActs[col]->setChecked(true); // re-enable the checkbox if we don't change the actual state
return;
}
}
gameList->setColumnHidden(col, !val); // Negate because it's a set col hidden and we have menu say show.
xgui_settings->SetGamelistColVisibility(col, val);
};
connect(columnActs[col], &QAction::triggered, l_CallBack);
}
// Init
Refresh(); // Data MUST be loaded so that first settings load will reset columns to correct width w/r to data.
LoadSettings();
}
void game_list_frame::LoadSettings()
{
QByteArray state = xgui_settings->GetValue(GUI::gl_state).toByteArray();
for (int col = 0; col < columnActs.count(); ++col)
{
bool vis = xgui_settings->GetGamelistColVisibility(col);
columnActs[col]->setChecked(vis);
gameList->setColumnHidden(col, !vis);
}
m_sortAscending = xgui_settings->GetValue(GUI::gl_sortAsc).toBool();
m_sortColumn = xgui_settings->GetValue(GUI::gl_sortCol).toInt();
m_categoryFilters = xgui_settings->GetGameListCategoryFilters();
if (state.isEmpty())
{ // If no settings exist, go to default.
gameList->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
gameList->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
gameList->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
}
else
{
gameList->horizontalHeader()->restoreState(state);
}
Refresh();
}
game_list_frame::~game_list_frame()
{
SaveSettings();
}
void game_list_frame::OnColClicked(int col)
{
if (col == m_sortColumn)
{
m_sortAscending ^= true;
}
else
{
m_sortAscending = true;
}
m_sortColumn = col;
xgui_settings->SetValue(GUI::gl_sortAsc, m_sortAscending);
xgui_settings->SetValue(GUI::gl_sortCol, col);
// Sort entries, update columns and refresh the panel
Refresh();
}
void game_list_frame::LoadGames()
{
m_games.clear();
for (const auto& entry : fs::dir(Emu.GetGameDir()))
{
if (entry.is_directory)
{
m_games.push_back(entry.name);
}
}
}
void game_list_frame::LoadPSF()
{
m_game_data.clear();
const std::string& game_path = Emu.GetGameDir();
for (u32 i = 0; i < m_games.size(); ++i)
{
const std::string& dir = game_path + m_games[i];
const std::string& sfb = dir + "/PS3_DISC.SFB";
const std::string& sfo = dir + (fs::is_file(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO");
const fs::file sfo_file(sfo);
if (!sfo_file)
{
continue;
}
const auto& psf = psf::load_object(sfo_file);
GameInfo game;
game.root = m_games[i];
game.serial = psf::get_string(psf, "TITLE_ID", "");
game.name = psf::get_string(psf, "TITLE", "unknown");
game.app_ver = psf::get_string(psf, "APP_VER", "unknown");
game.category = psf::get_string(psf, "CATEGORY", "unknown");
game.fw = psf::get_string(psf, "PS3_SYSTEM_VER", "unknown");
game.parental_lvl = psf::get_integer(psf, "PARENTAL_LEVEL");
game.resolution = psf::get_integer(psf, "RESOLUTION");
game.sound_format = psf::get_integer(psf, "SOUND_FORMAT");
if (game.category == "HG")
{
game.category = sstr(category::hdd_Game);
game.icon_path = dir + "/ICON0.PNG";
}
else if (game.category == "DG")
{
game.category = sstr(category::disc_Game);
game.icon_path = dir + "/PS3_GAME/ICON0.PNG";
}
else if (game.category == "HM")
{
game.category = sstr(category::home);
game.icon_path = dir + "/ICON0.PNG";
}
else if (game.category == "AV")
{
game.category = sstr(category::audio_Video);
game.icon_path = dir + "/ICON0.PNG";
}
else if (game.category == "GD")
{
game.category = sstr(category::game_Data);
game.icon_path = dir + "/ICON0.PNG";
}
else if (game.category == "unknown")
{
game.category = sstr(category::unknown);
}
m_game_data.push_back(game);
}
// Sort entries and update columns
std::sort(m_game_data.begin(), m_game_data.end(), sortGameData(m_sortColumn, m_sortAscending));
m_columns.Update(m_game_data);
}
void game_list_frame::ShowData()
{
m_columns.ShowData(gameList);
}
// Filter for Categories
void game_list_frame::FilterData()
{
for (int i = 0; i < gameList->rowCount(); ++i)
{
bool match = false;
for (auto filter : m_categoryFilters)
{
for (int j = 0; j < gameList->columnCount(); ++j)
{
if (gameList->horizontalHeaderItem(j)->text() == tr("Category") && gameList->item(i, j)->text().contains(filter))
{
match = true;
goto OutOfThis;
}
}
}
OutOfThis:
gameList->setRowHidden(i, !match);
}
}
void game_list_frame::Refresh()
{
int row = gameList->currentRow();
LoadGames();
LoadPSF();
ShowData();
FilterData();
gameList->selectRow(row);
}
void game_list_frame::ToggleCategoryFilter(QString category, bool show)
{
if (show) { m_categoryFilters.append(category); } else { m_categoryFilters.removeAll(category); }
Refresh();
}
void game_list_frame::SaveSettings()
{
for (int col = 0; col < columnActs.count(); ++col)
{
xgui_settings->SetGamelistColVisibility(col, columnActs[col]->isChecked());
}
xgui_settings->SetValue(GUI::gl_sortCol, m_sortColumn);
xgui_settings->SetValue(GUI::gl_sortAsc, m_sortAscending);
xgui_settings->SetValue(GUI::gl_state, gameList->horizontalHeader()->saveState());
}
static void open_dir(const std::string& spath)
{
fs::create_dir(spath);
QString path = qstr(spath);
QProcess* process = new QProcess();
#ifdef _WIN32
std::string command = "explorer";
std::replace(path.begin(), path.end(), '/', '\\');
process->start("explorer", QStringList() << path);
#elif __APPLE__
process->start("open", QStringList() << path);
#elif __linux__
process->start("xdg-open", QStringList() << path);
#endif
}
void game_list_frame::doubleClickedSlot(const QModelIndex& index)
{
int i = index.row();
QString category = qstr(m_game_data[i].category);
// Boot these categories
if (category == category::hdd_Game || category == category::disc_Game || category == category::audio_Video)
{
const std::string& path = Emu.GetGameDir() + m_game_data[i].root;
emit RequestIconPathSet(path);
Emu.Stop();
if (!Emu.BootGame(path))
{
LOG_ERROR(LOADER, "Failed to boot /dev_hdd0/game/%s", m_game_data[i].root);
}
}
else
{
open_dir(Emu.GetGameDir() + m_game_data[i].root);
}
}
void game_list_frame::ShowContextMenu(const QPoint &pos) // this is a slot
{
int row = gameList->indexAt(pos).row();
if (row == -1)
{
return; // invalid
}
// for most widgets
QPoint globalPos = gameList->mapToGlobal(pos);
// for QAbstractScrollArea and derived classes you would use:
// QPoint globalPos = myWidget->viewport()->mapToGlobal(pos);
QMenu myMenu;
// Make Actions
QAction* boot = myMenu.addAction(tr("&Boot"));
QFont f = boot->font();
f.setBold(true);
boot->setFont(f);
QAction* configure = myMenu.addAction(tr("&Configure"));
myMenu.addSeparator();
QAction* removeGame = myMenu.addAction(tr("&Remove"));
QAction* removeConfig = myMenu.addAction(tr("&Remove Custom Configuration"));
myMenu.addSeparator();
QAction* openGameFolder = myMenu.addAction(tr("&Open Install Folder"));
QAction* openConfig = myMenu.addAction(tr("&Open Config Folder"));
myMenu.addSeparator();
QAction* checkCompat = myMenu.addAction(tr("&Check Game Compatibility"));
connect(boot, &QAction::triggered, [=]() {Boot(row); });
connect(configure, &QAction::triggered, [=](){
settings_dialog(xgui_settings, m_Render_Creator, this, &m_game_data[row]).exec();
});
connect(removeGame, &QAction::triggered, [=](){
if (QMessageBox::question(this, tr("Confirm Delete"), tr("Permanently delete files?")) == QMessageBox::Yes)
fs::remove_all(Emu.GetGameDir() + m_game_data[row].root);
Refresh();
});
connect(removeConfig, &QAction::triggered, [=]() {RemoveCustomConfiguration(row); });
connect(openGameFolder, &QAction::triggered, [=]() {open_dir(Emu.GetGameDir() + m_game_data[row].root); });
connect(openConfig, &QAction::triggered, [=]() {open_dir(fs::get_config_dir() + "data/" + m_game_data[row].serial); });
connect(checkCompat, &QAction::triggered, [=]() {
QString serial = qstr(m_game_data[row].serial);
QString link = "https://rpcs3.net/compatibility?g=" + serial;
QDesktopServices::openUrl(QUrl(link));
});
//Disable options depending on software category
QString category = qstr(m_game_data[row].category);
if (category == category::disc_Game)
{
removeGame->setEnabled(false);
}
else if (category == category::audio_Video)
{
configure->setEnabled(false);
removeConfig->setEnabled(false);
openConfig->setEnabled(false);
checkCompat->setEnabled(false);
}
else if (category == category::home || category == category::game_Data)
{
boot->setEnabled(false), f.setBold(false), boot->setFont(f);
configure->setEnabled(false);
removeConfig->setEnabled(false);
openConfig->setEnabled(false);
checkCompat->setEnabled(false);
}
myMenu.exec(globalPos);
}
void game_list_frame::Boot(int row)
{
const std::string& path = Emu.GetGameDir() + m_game_data[row].root;
emit RequestIconPathSet(path);
Emu.Stop();
if (!Emu.BootGame(path))
{
QMessageBox::warning(this, tr("Warning!"), tr("Failed to boot ") + qstr(m_game_data[row].root));
LOG_ERROR(LOADER, "Failed to boot /dev_hdd0/game/%s", m_game_data[row].root);
}
}
void game_list_frame::RemoveCustomConfiguration(int row)
{
const std::string config_path = fs::get_config_dir() + "data/" + m_game_data[row].serial + "/config.yml";
if (fs::is_file(config_path))
{
if (QMessageBox::question(this, tr("Confirm Delete"), tr("Delete custom game configuration?")) == QMessageBox::Yes)
{
if (fs::remove_file(config_path))
{
LOG_SUCCESS(GENERAL, "Removed configuration file: %s", config_path);
}
else
{
QMessageBox::warning(this, tr("Warning!"), tr("Failed to delete configuration file!"));
LOG_FATAL(GENERAL, "Failed to delete configuration file: %s\nError: %s", config_path, fs::g_tls_error);
}
}
}
else
{
QMessageBox::warning(this, tr("Warning!"), tr("No custom configuration found!"));
LOG_ERROR(GENERAL, "Configuration file not found: %s", config_path);
}
}
void game_list_frame::ResizeIcons(QSize size)
{
m_columns.m_Icon_Size = size;
m_Icon_Size = size;
gameList->verticalHeader()->setMinimumSectionSize(m_Icon_Size.height());
gameList->verticalHeader()->setMaximumSectionSize(m_Icon_Size.height());
Refresh();
}
columns_arr::columns_arr(QSize icon_Size) : m_Icon_Size(icon_Size)
{
m_img_list = new QList<QImage*>();
m_columns.clear();
m_columns.emplace_back(0, 90, "Icon");
m_columns.emplace_back(1, 160, "Name");
m_columns.emplace_back(2, 85, "Serial");
m_columns.emplace_back(3, 55, "FW");
m_columns.emplace_back(4, 55, "App version");
m_columns.emplace_back(5, 75, "Category");
m_columns.emplace_back(6, 160, "Path");
m_col_icon = &m_columns[0];
m_col_name = &m_columns[1];
m_col_serial = &m_columns[2];
m_col_fw = &m_columns[3];
m_col_app_ver = &m_columns[4];
m_col_category = &m_columns[5];
m_col_path = &m_columns[6];
}
Column* columns_arr::GetColumnByPos(u32 pos)
{
std::vector<Column *> columns;
for (u32 pos = 0; pos<m_columns.size(); pos++)
{
for (u32 c = 0; c<m_columns.size(); ++c)
{
if (m_columns[c].pos != pos) continue;
columns.push_back(&m_columns[c]);
}
}
for (u32 c = 0; c<columns.size(); ++c)
{
if (!columns[c]->shown)
{
pos++;
continue;
}
if (columns[c]->pos != pos) continue;
return columns[c];
}
return NULL;
}
void columns_arr::Update(const std::vector<GameInfo>& game_data)
{
m_img_list->clear();
m_col_icon->data.clear();
m_col_name->data.clear();
m_col_serial->data.clear();
m_col_fw->data.clear();
m_col_app_ver->data.clear();
m_col_category->data.clear();
m_col_path->data.clear();
m_icon_indexes.clear();
if (m_columns.size() == 0) return;
for (const auto& game : game_data)
{
m_col_icon->data.push_back(game.icon_path);
m_col_name->data.push_back(game.name);
m_col_serial->data.push_back(game.serial);
m_col_fw->data.push_back(game.fw);
m_col_app_ver->data.push_back(game.app_ver);
m_col_category->data.push_back(game.category);
m_col_path->data.push_back(game.root);
}
int c = 0;
// load icons
for (const auto& path : m_col_icon->data)
{
QImage* img = new QImage(m_Icon_Size, QImage::Format_ARGB32);
if (!path.empty())
{
// Load image.
bool success = img->load(qstr(path));
if (success)
{
m_img_list->append(new QImage(img->scaled(m_Icon_Size, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation)));
}
else {
// IIRC a load failure means blank image which is fine to have as a placeholder.
QString abspath = QDir(qstr(path)).absolutePath();
LOG_ERROR(HLE, "Count not load image from path %s", sstr(abspath));
img->fill(QColor(0, 0, 0, 0));
m_img_list->append(img);
}
}
else
{
LOG_ERROR(HLE, "Count not load image from empty path");
img->fill(QColor(0, 0, 0, 0));
m_img_list->append(img);
}
m_icon_indexes.push_back(c);
c++;
}
}
void columns_arr::ShowData(QTableWidget* table)
{
// Hack to delete everything without removing the headers.
table->setRowCount(0);
// Expect number of columns to be the same as number of icons.
table->setRowCount(m_img_list->length());
// Add icons.
for (int r = 0; r < m_img_list->length(); ++r)
{
QTableWidgetItem* iconItem = new QTableWidgetItem;
iconItem->setFlags(iconItem->flags() & ~Qt::ItemIsEditable);
iconItem->setData(Qt::DecorationRole, QPixmap::fromImage(*m_img_list->at(m_icon_indexes[r])));
table->setItem(r, 0, iconItem);
}
// Add the other data.
for (int c = 1; c < table->columnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if (!col)
{
LOG_ERROR(HLE, "Columns loaded with error!");
return;
}
int numRows = col->data.size();
if (numRows != table->rowCount())
{
table->setRowCount(numRows);
LOG_WARNING(HLE, "Warning. Columns are of different size: number of icons %d number wanted: %d", m_img_list->length(), numRows);
}
for (int r = 0; r<col->data.size(); ++r)
{
QTableWidgetItem* curr = new QTableWidgetItem;
curr->setFlags(curr->flags() & ~Qt::ItemIsEditable);
QString text = qstr(col->data[r]);
curr->setText(text);
table->setItem(r, c, curr);
}
table->resizeRowsToContents();
table->resizeColumnToContents(0);
}
}
void game_list_frame::closeEvent(QCloseEvent *event)
{
QDockWidget::closeEvent(event);
emit game_list_frameClosed();
}

View File

@ -0,0 +1,139 @@
#ifndef GAMELISTFRAME_H
#define GAMELISTFRAME_H
#include "stdafx.h"
#include "Emu/GameInfo.h"
#include "gui_settings.h"
#include "emu_settings.h"
#include <QDockWidget>
#include <QList>
#include <QTableWidget>
struct Column
{
u32 pos;
u32 width;
bool shown;
std::vector<std::string> data;
const std::string name;
const u32 def_pos;
const u32 def_width;
Column(const u32 _def_pos, const u32 _def_width, const std::string& _name)
: def_pos(_def_pos)
, def_width(_def_width)
, pos(_def_pos)
, width(_def_width)
, shown(true)
, name(_name)
{
data.clear();
}
};
struct columns_arr
{
std::vector<Column> m_columns;
columns_arr(){};
columns_arr(QSize icon_Size);
Column* GetColumnByPos(u32 pos);
public:
Column* m_col_icon;
Column* m_col_name;
Column* m_col_serial;
Column* m_col_fw;
Column* m_col_app_ver;
Column* m_col_category;
Column* m_col_path;
QSize m_Icon_Size;
QList<QImage*>* m_img_list;
std::vector<int> m_icon_indexes;
void Update(const std::vector<GameInfo>& game_data);
void ShowData(QTableWidget* list);
};
namespace category
{
const QString hdd_Game = QObject::tr("HDD Game");
const QString disc_Game = QObject::tr("Disc Game");
const QString home = QObject::tr("Home");
const QString audio_Video = QObject::tr("Audio/Video");
const QString game_Data = QObject::tr("Game Data");
const QString unknown = QObject::tr("Unknown");
}
class game_list_frame : public QDockWidget {
Q_OBJECT
int m_sortColumn;
bool m_sortAscending;
std::vector<std::string> m_games;
std::vector<GameInfo> m_game_data;
gui_settings* m_gui_settings = new gui_settings(this);
QSize m_Icon_Size;
columns_arr m_columns;
QStringList m_categoryFilters;
Render_Creator m_Render_Creator;
public:
explicit game_list_frame(std::shared_ptr<gui_settings> settings, Render_Creator r_Creator, QWidget *parent = nullptr);
~game_list_frame();
void Refresh();
void ToggleCategoryFilter(QString category, bool show);
/** Loads from settings. Public so that main frame can easily reset these settings if needed. */
void LoadSettings();
/** Saves settings. Public so that main frame can save this when a caching of column widths is needed for settings backup */
void SaveSettings();
public slots:
/** Resize Gamelist Icons to size */
void ResizeIcons(QSize size);
private slots:
void Boot(int row);
void RemoveCustomConfiguration(int row);
void OnColClicked(int col);
signals:
void game_list_frameClosed();
void RequestIconPathSet(const std::string path);
protected:
/** Override inherited method from Qt to allow signalling when close happened.*/
void closeEvent(QCloseEvent* event);
private:
QTableWidget *gameList;
void ShowContextMenu(const QPoint &pos);
void doubleClickedSlot(const QModelIndex& index);
void LoadGames();
void LoadPSF();
void ShowData();
void FilterData();
// Actions regarding showing/hiding columns
QAction* showIconColAct;
QAction* showNameColAct;
QAction* showSerialColAct;
QAction* showFWColAct;
QAction* showAppVersionColAct;
QAction* showCategoryColAct;
QAction* showPathColAct;
QList<QAction*> columnActs;
std::shared_ptr<gui_settings> xgui_settings;
};
#endif // GAMELISTFRAME_H

View File

@ -1,20 +0,0 @@
#ifdef QT_UI
#include "gamelistframe.h"
GameListFrame::GameListFrame(QWidget *parent) : QDockWidget(tr("Game List"), parent)
{
gameList = new QTableWidget(this);
gameList->setColumnCount(7);
gameList->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Icon")));
gameList->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Name")));
gameList->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Serial")));
gameList->setHorizontalHeaderItem(3, new QTableWidgetItem(tr("FW")));
gameList->setHorizontalHeaderItem(4, new QTableWidgetItem(tr("Version")));
gameList->setHorizontalHeaderItem(5, new QTableWidgetItem(tr("Category")));
gameList->setHorizontalHeaderItem(6, new QTableWidgetItem(tr("Path")));
setWidget(gameList);
}
#endif // QT_UI

View File

@ -1,18 +0,0 @@
#ifndef GAMELISTFRAME_H
#define GAMELISTFRAME_H
#include <QDockWidget>
#include <QTableWidget>
class GameListFrame : public QDockWidget
{
Q_OBJECT
public:
explicit GameListFrame(QWidget *parent = 0);
private:
QTableWidget *gameList;
};
#endif // GAMELISTFRAME_H

View File

@ -0,0 +1,50 @@
#include "stdafx.h"
#include "gl_gs_frame.h"
#include "Emu/System.h"
#include <QOpenGLContext>
#include <QWindow>
gl_gs_frame::gl_gs_frame(int w, int h, QIcon appIcon)
: gs_frame("OpenGL", w, h, appIcon)
{
setSurfaceType(QSurface::OpenGLSurface);
m_format.setMajorVersion(4);
m_format.setMinorVersion(3);
m_format.setProfile(QSurfaceFormat::CoreProfile);
m_format.setDepthBufferSize(16);
m_format.setSwapBehavior(QSurfaceFormat::SwapBehavior::DoubleBuffer);
if (g_cfg.video.debug_output)
{
m_format.setOption(QSurfaceFormat::FormatOption::DebugContext);
}
setFormat(m_format);
}
void* gl_gs_frame::make_context()
{
auto context = new QOpenGLContext();
context->setFormat(m_format);
context->create();
return context;
}
void gl_gs_frame::set_current(draw_context_t ctx)
{
((QOpenGLContext*)ctx.get())->makeCurrent(this);
}
void gl_gs_frame::delete_context(void* ctx)
{
delete (QOpenGLContext*)ctx;
}
void gl_gs_frame::flip(draw_context_t context)
{
gs_frame::flip(context);
((QOpenGLContext*)context.get())->makeCurrent(this);
((QOpenGLContext*)context.get())->swapBuffers(this);
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "stdafx.h"
#include "gs_frame.h"
class gl_gs_frame : public gs_frame
{
private:
QSurfaceFormat m_format;
public:
gl_gs_frame(int w, int h, QIcon appIcon);
void* make_context() override;
void set_current(draw_context_t context) override;
void delete_context(void* context) override;
void flip(draw_context_t context) override;
};

View File

@ -1,60 +0,0 @@
#ifdef QT_UI
#include <QQuickWindow>
#include <QOpenGLContext>
#include <QCoreApplication>
#include "glviewer.h"
// This class hooks beforeRendering and allows us to draw a scene and reset GL state.
// In future, we will likely want to manually control the update rate.
void GLRenderer::paint()
{
// Do GL here
glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());
glDisable(GL_DEPTH_TEST);
// Draw blue to the window to show that we work
glClearColor(0.2, 0, 0.8, 1);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
// Put the GL state back to how it was in case it makes SceneGraph angry
((QQuickWindow*)sender())->resetOpenGLState();
}
GLViewer::GLViewer()
: m_renderer(0)
{
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
}
void GLViewer::handleWindowChanged(QQuickWindow *win)
{
if (win) {
connect(win, SIGNAL(beforeSynchronizing()), this, SLOT(sync()), Qt::DirectConnection);
connect(win, SIGNAL(sceneGraphInvalidated()), this, SLOT(cleanup()), Qt::DirectConnection);
// We will take over from here
win->setClearBeforeRendering(false);
}
}
void GLViewer::sync()
{
if (!m_renderer) {
m_renderer = new GLRenderer();
connect(window(), SIGNAL(beforeRendering()), m_renderer, SLOT(paint()), Qt::DirectConnection);
}
m_renderer->setViewportSize(window()->size() * window()->devicePixelRatio());
}
void GLViewer::cleanup()
{
if (m_renderer) {
delete m_renderer;
m_renderer = 0;
}
}
#endif

View File

@ -1,36 +0,0 @@
#pragma once
#include <QQuickItem>
class GLRenderer : public QObject
{
Q_OBJECT
public:
GLRenderer() { }
void setViewportSize(const QSize &size) { m_viewportSize = size; }
public slots:
void paint();
private:
QSize m_viewportSize;
};
class GLViewer : public QQuickItem
{
Q_OBJECT
public:
GLViewer();
~GLViewer() { cleanup(); }
public slots:
void sync();
void cleanup();
private slots:
void handleWindowChanged(QQuickWindow *win);
private:
GLRenderer *m_renderer;
};

View File

@ -0,0 +1,264 @@
#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "graphics_tab.h"
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
graphics_tab::graphics_tab(std::shared_ptr<emu_settings> xSettings, Render_Creator r_Creator, QWidget *parent) : QWidget(parent), xemu_settings(xSettings)
{
// Render
QGroupBox *render = new QGroupBox(tr("Render"));
QComboBox *renderBox = xemu_settings->CreateEnhancedComboBox(emu_settings::Renderer, this);
QVBoxLayout *renderVbox = new QVBoxLayout();
renderVbox->addWidget(renderBox);
render->setLayout(renderVbox);
// Resolution
QGroupBox *res = new QGroupBox(tr("Resolution"));
QComboBox* resBox = xemu_settings->CreateEnhancedComboBox(emu_settings::Resolution, this);
QVBoxLayout *resVbox = new QVBoxLayout();
resVbox->addWidget(resBox);
res->setLayout(resVbox);
// Graphics Adapter
QStringList D3D12Adapters = r_Creator.D3D12Adapters;
QStringList vulkanAdapters = r_Creator.vulkanAdapters;
bool supportsD3D12 = r_Creator.supportsD3D12;
bool supportsVulkan = r_Creator.supportsVulkan;
QString r_D3D12 = r_Creator.render_D3D12;
QString r_Vulkan = r_Creator.render_Vulkan;
QString r_OpenGL = r_Creator.render_OpenGL;
QString old_D3D12;
QString old_Vulkan;
QGroupBox *graphicsAdapter;
QComboBox *graphicsAdapterBox;
if (supportsD3D12)
{
old_D3D12 = qstr(xemu_settings->GetSetting(emu_settings::D3D12Adapter));
}
else
{
// Remove D3D12 option from render combobox
for (int i = 0; i < renderBox->count(); i++)
{
if (renderBox->itemText(i) == r_D3D12)
{
renderBox->removeItem(i);
break;
}
}
}
if (supportsVulkan)
{
old_Vulkan = qstr(xemu_settings->GetSetting(emu_settings::VulkanAdapter));
}
else
{
// Remove Vulkan option from render combobox
for (int i = 0; i < renderBox->count(); i++)
{
if (renderBox->itemText(i) == r_Vulkan)
{
renderBox->removeItem(i);
break;
}
}
}
if (supportsD3D12 || supportsVulkan)
{
graphicsAdapter = new QGroupBox(tr("Select Graphics Device"));
graphicsAdapterBox = new QComboBox(this);
QVBoxLayout *graphicsAdapterVbox = new QVBoxLayout();
graphicsAdapterVbox->addWidget(graphicsAdapterBox);
graphicsAdapter->setLayout(graphicsAdapterVbox);
QString oldRender = renderBox->itemText(renderBox->currentIndex());
auto switchGraphicsAdapter = [=](int index)
{
QString render = renderBox->itemText(index);
m_isD3D12 = render == r_D3D12;
m_isVulkan = render == r_Vulkan;
graphicsAdapter->setEnabled(m_isD3D12 || m_isVulkan);
// D3D Adapter
if (m_isD3D12)
{
// Fill combobox
graphicsAdapterBox->clear();
for (auto adapter : D3D12Adapters)
{
graphicsAdapterBox->addItem(adapter);
}
// Reset Adapter to old config
xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(old_D3D12));
int idx = graphicsAdapterBox->findText(old_D3D12);
if (idx == -1)
{
idx = 0;
LOG_WARNING(RSX, "Current %s adapter not available: resetting to default!", sstr(r_D3D12));
}
graphicsAdapterBox->setCurrentIndex(idx);
}
// Vulkan Adapter
else if (m_isVulkan)
{
// Fill combobox
graphicsAdapterBox->clear();
for (auto adapter : vulkanAdapters)
{
graphicsAdapterBox->addItem(adapter);
}
// Reset Adapter to old config
xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(old_Vulkan));
int idx = graphicsAdapterBox->findText(old_Vulkan);
if (idx == -1)
{
idx = 0;
LOG_WARNING(RSX, "Current %s adapter not available: resetting to default!", sstr(r_Vulkan));
}
graphicsAdapterBox->setCurrentIndex(idx);
}
// Other Adapter
else
{
// Reset Adapters to old config
if (supportsD3D12)
{
xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(old_D3D12));
}
if (supportsVulkan)
{
xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(old_Vulkan));
}
// Fill combobox with placeholder
graphicsAdapterBox->clear();
graphicsAdapterBox->addItem(tr("Not needed for %1 renderer").arg(render));
}
};
auto setAdapter = [=](QString text)
{
if (text.isEmpty()) return;
// don't set adapter if signal was created by switching render
QString newRender = renderBox->itemText(renderBox->currentIndex());
if (m_oldRender == newRender)
{
if (m_isD3D12 && D3D12Adapters.contains(text))
{
xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(text));
}
else if (m_isVulkan && vulkanAdapters.contains(text))
{
xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(text));
}
}
else
{
m_oldRender = newRender;
}
};
// Init
setAdapter(graphicsAdapterBox->currentText());
switchGraphicsAdapter(renderBox->currentIndex());
// Events
connect(graphicsAdapterBox, &QComboBox::currentTextChanged, setAdapter);
connect(renderBox, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), switchGraphicsAdapter);
}
// Aspect ratio
QGroupBox *aspect = new QGroupBox(tr("Aspect ratio"));
QComboBox *aspectBox = xemu_settings->CreateEnhancedComboBox(emu_settings::AspectRatio, this);
QVBoxLayout *aspectVbox = new QVBoxLayout();
aspectVbox->addWidget(aspectBox);
aspect->setLayout(aspectVbox);
// Frame limit
QGroupBox *frameLimit = new QGroupBox(tr("Frame limit"));
QComboBox *frameLimitBox = xemu_settings->CreateEnhancedComboBox(emu_settings::FrameLimit, this);
QVBoxLayout *frameLimitVbox = new QVBoxLayout();
frameLimitVbox->addWidget(frameLimitBox);
frameLimit->setLayout(frameLimitVbox);
// Checkboxes
QCheckBox *dumpColor = xemu_settings->CreateEnhancedCheckBox(emu_settings::WriteColorBuffers, this);
QCheckBox *readColor = xemu_settings->CreateEnhancedCheckBox(emu_settings::ReadColorBuffers, this);
QCheckBox *dumpDepth = xemu_settings->CreateEnhancedCheckBox(emu_settings::WriteDepthBuffer, this);
QCheckBox *readDepth = xemu_settings->CreateEnhancedCheckBox(emu_settings::ReadDepthBuffer, this);
QCheckBox *glLegacyBuffers = xemu_settings->CreateEnhancedCheckBox(emu_settings::LegacyBuffers, this);
QCheckBox *debugOutput = xemu_settings->CreateEnhancedCheckBox(emu_settings::DebugOutput, this);
QCheckBox *debugOverlay = xemu_settings->CreateEnhancedCheckBox(emu_settings::DebugOverlay, this);
QCheckBox *logProg = xemu_settings->CreateEnhancedCheckBox(emu_settings::LogShaderPrograms, this);
QCheckBox *vsync = xemu_settings->CreateEnhancedCheckBox(emu_settings::VSync, this);
QCheckBox *gpuTextureScaling = xemu_settings->CreateEnhancedCheckBox(emu_settings::GPUTextureScaling, this);
// Combobox Part
QHBoxLayout *hbox1 = new QHBoxLayout();
QVBoxLayout *vbox11 = new QVBoxLayout();
vbox11->addWidget(render);
vbox11->addWidget(res);
if (supportsD3D12 || supportsVulkan)
{
// be careful with layout changes due to render when adding new stuff
vbox11->addWidget(graphicsAdapter);
}
vbox11->addStretch();
QVBoxLayout *vbox12 = new QVBoxLayout();
vbox12->addWidget(aspect);
vbox12->addWidget(frameLimit);
vbox12->addStretch();
hbox1->addLayout(vbox11);
hbox1->addLayout(vbox12);
// Checkbox Part
QHBoxLayout *hbox2 = new QHBoxLayout();
QVBoxLayout *vbox21 = new QVBoxLayout();
vbox21->addWidget(dumpColor);
vbox21->addWidget(readColor);
vbox21->addWidget(dumpDepth);
vbox21->addWidget(readDepth);
vbox21->addWidget(glLegacyBuffers);
QVBoxLayout *vbox22 = new QVBoxLayout();
vbox22->addWidget(debugOutput);
vbox22->addWidget(debugOverlay);
vbox22->addWidget(logProg);
vbox22->addWidget(vsync);
vbox22->addWidget(gpuTextureScaling);
hbox2->addLayout(vbox21);
hbox2->addLayout(vbox22);
QVBoxLayout *vbox = new QVBoxLayout();
vbox->addLayout(hbox1);
vbox->addSpacing(10);
vbox->addLayout(hbox2);
vbox->addStretch();
setLayout(vbox);
auto fixGLLegacy = [=](const QString& text) {
glLegacyBuffers->setEnabled(text == r_OpenGL);
};
// Handle connects to disable specific checkboxes that depend on GUI state.
fixGLLegacy(renderBox->currentText()); // Init
connect(renderBox, &QComboBox::currentTextChanged, fixGLLegacy);
}

View File

@ -0,0 +1,26 @@
#ifndef GRAPHICSTAB_H
#define GRAPHICSTAB_H
#include "emu_settings.h"
#include <QWidget>
#include <memory>
class graphics_tab : public QWidget
{
Q_OBJECT
public:
explicit graphics_tab(std::shared_ptr<emu_settings> xemu_settings, Render_Creator r_Creator, QWidget *parent = 0);
signals:
private:
std::shared_ptr<emu_settings> xemu_settings;
QString m_oldRender = "";
bool m_isD3D12 = false;
bool m_isVulkan = false;
};
#endif // GRAPHICSTAB_H

View File

@ -1,147 +0,0 @@
#ifdef QT_UI
#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#ifdef _MSC_VER
#include <Windows.h>
#undef GetHwnd
#include <d3d12.h>
#include <wrl/client.h>
#include <dxgi1_4.h>
#endif
#include "graphicstab.h"
GraphicsTab::GraphicsTab(QWidget *parent) : QWidget(parent)
{
// Render
QGroupBox *render = new QGroupBox(tr("Render"));
QComboBox *renderBox = new QComboBox;
renderBox->addItem(tr("Null"));
renderBox->addItem(tr("Opengl"));
#ifdef _MSC_VER
renderBox->addItem(tr("D3D12"));
#endif // _MSC_VER
#ifdef _WIN32
renderBox->addItem(tr("Vulkan"));
#endif // _WIN32
QVBoxLayout *renderVbox = new QVBoxLayout;
renderVbox->addWidget(renderBox);
render->setLayout(renderVbox);
// Resolution
QGroupBox *res = new QGroupBox(tr("Resolution"));
QComboBox *resBox = new QComboBox;
resBox->addItem(tr("1920x1080"));
resBox->addItem(tr("1280x720"));
resBox->addItem(tr("720x480"));
resBox->addItem(tr("1600x1080"));
resBox->addItem(tr("1440x1080"));
resBox->addItem(tr("1280x1080"));
resBox->addItem(tr("960x1080"));
QVBoxLayout *resVbox = new QVBoxLayout;
resVbox->addWidget(resBox);
res->setLayout(resVbox);
// D3D Adapter
QGroupBox *d3dAdapter = new QGroupBox(tr("D3D Adapter"));
QComboBox *d3dAdapterBox = new QComboBox;
QVBoxLayout *d3dAdapterVbox = new QVBoxLayout;
d3dAdapterVbox->addWidget(d3dAdapterBox);
d3dAdapter->setLayout(d3dAdapterVbox);
// Aspect ratio
QGroupBox *aspect = new QGroupBox(tr("Aspect ratio"));
QComboBox *aspectBox = new QComboBox;
aspectBox->addItem(tr("4x3"));
aspectBox->addItem(tr("16x9"));
QVBoxLayout *aspectVbox = new QVBoxLayout;
aspectVbox->addWidget(aspectBox);
aspect->setLayout(aspectVbox);
// Frame limit
QGroupBox *frameLimit = new QGroupBox(tr("Frame limit"));
QComboBox *frameLimitBox = new QComboBox;
frameLimitBox->addItem(tr("Off"));
frameLimitBox->addItem(tr("50"));
frameLimitBox->addItem(tr("60"));
frameLimitBox->addItem(tr("30"));
frameLimitBox->addItem(tr("Auto"));
QVBoxLayout *frameLimitVbox = new QVBoxLayout;
frameLimitVbox->addWidget(frameLimitBox);
frameLimit->setLayout(frameLimitVbox);
// Checkboxes
QCheckBox *dumpColor = new QCheckBox(tr("Write Color Buffers"));
QCheckBox *readColor = new QCheckBox(tr("Read Color Buffers"));
QCheckBox *dumpDepth = new QCheckBox(tr("Write Depth Buffer"));
QCheckBox *readDepth = new QCheckBox(tr("Read Depth Buffer"));
QCheckBox *glLegacyBuffers = new QCheckBox(tr("Use Legacy OpenGL Buffers"));
QCheckBox *debugOutput = new QCheckBox(tr("Debug Output"));
QCheckBox *debugOverlay = new QCheckBox(tr("Debug Overlay"));
QCheckBox *logProg = new QCheckBox(tr("Log shader programs"));
QCheckBox *vsync = new QCheckBox(tr("VSync"));
// Main layout
QVBoxLayout *vbox1 = new QVBoxLayout;
vbox1->addWidget(render);
vbox1->addWidget(res);
vbox1->addWidget(d3dAdapter);
vbox1->addWidget(aspect);
vbox1->addWidget(frameLimit);
QVBoxLayout *vbox2 = new QVBoxLayout;
vbox2->addWidget(dumpColor);
vbox2->addWidget(readColor);
vbox2->addWidget(dumpDepth);
vbox2->addWidget(readDepth);
vbox2->addWidget(glLegacyBuffers);
vbox2->addWidget(debugOutput);
vbox2->addWidget(debugOverlay);
vbox2->addWidget(logProg);
vbox2->addWidget(vsync);
vbox2->addStretch();
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vbox1);
hbox->addLayout(vbox2);
setLayout(hbox);
#ifdef _MSC_VER
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory;
if (SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory))))
{
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
for (UINT id = 0; dxgi_factory->EnumAdapters(id, adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND; id++)
{
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
d3dAdapterBox->addItem(QString::fromWCharArray(desc.Description));
}
//pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "D3D12", "Adapter" }, cbox_gs_d3d_adapter));
}
else
#endif
{
d3dAdapter->setEnabled(false);
}
}
#endif // QT_UI

View File

@ -1,18 +0,0 @@
#ifndef GRAPHICSTAB_H
#define GRAPHICSTAB_H
#include <QWidget>
class GraphicsTab : public QWidget
{
Q_OBJECT
public:
explicit GraphicsTab(QWidget *parent = 0);
signals:
public slots:
};
#endif // GRAPHICSTAB_H

205
rpcs3/rpcs3qt/gs_frame.cpp Normal file
View File

@ -0,0 +1,205 @@
#include "gs_frame.h"
#include "Utilities/Config.h"
#include "Utilities/Timer.h"
#include "Emu/System.h"
#include <QKeyEvent>
#include <QTimer>
#include <QThread>
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
gs_frame::gs_frame(const QString& title, int w, int h, QIcon appIcon)
: QWindow()
{
m_windowTitle = title;
if (!appIcon.isNull())
{
setIcon(appIcon);
}
g_cfg.misc.show_fps_in_title ? m_show_fps = true : m_show_fps = false;
resize(w, h);
// Change cursor when in fullscreen.
connect(this, &QWindow::visibilityChanged, this, &gs_frame::HandleCursor);
}
void gs_frame::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
}
void gs_frame::keyPressEvent(QKeyEvent *keyEvent)
{
auto l_handleKeyEvent = [this ,keyEvent]()
{
switch (keyEvent->key())
{
case Qt::Key_Return: if (keyEvent->modifiers() == Qt::AltModifier) { OnFullScreen(); return; } break;
case Qt::Key_Escape: if (visibility() == FullScreen) { setVisibility(Windowed); return; } break;
}
};
Emu.CallAfter(l_handleKeyEvent);
}
void gs_frame::OnFullScreen()
{
auto l_setFullScreenVis = [=]()
{
if (visibility() == FullScreen)
{
setVisibility(Windowed);
}
else
{
setVisibility(FullScreen);
}
};
Emu.CallAfter(l_setFullScreenVis);
}
void gs_frame::close()
{
Emu.Stop();
Emu.CallAfter([=]() {QWindow::close(); });
}
bool gs_frame::shown()
{
return QWindow::isVisible();
}
void gs_frame::hide()
{
Emu.CallAfter([=]() {QWindow::hide(); });
}
void gs_frame::show()
{
Emu.CallAfter([=]() {
QWindow::show();
if (g_cfg.misc.start_fullscreen)
{
setVisibility(FullScreen);
}
});
}
void* gs_frame::handle() const
{
#ifdef __linux__
return (void *)this->winId();
#elif _WIN32
return (HWND) this->winId();
#endif
}
void* gs_frame::make_context()
{
return nullptr;
}
void gs_frame::set_current(draw_context_t ctx)
{
Q_UNUSED(ctx);
}
void gs_frame::delete_context(void* ctx)
{
Q_UNUSED(ctx);
}
int gs_frame::client_width()
{
return size().width();
}
int gs_frame::client_height()
{
return size().height();
}
void gs_frame::flip(draw_context_t)
{
QString title;
if (!m_windowTitle.isEmpty())
{
title += m_windowTitle;
}
if (!Emu.GetTitle().empty())
{
title += qstr(" | " + Emu.GetTitle());
}
if (!Emu.GetTitleID().empty())
{
title += qstr(" | [" + Emu.GetTitleID() + ']');
}
if (m_show_fps)
{
++m_frames;
static Timer fps_t;
if (fps_t.GetElapsedTimeInSec() >= 0.5)
{
QString fps_title = qstr(fmt::format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec()));
if (!title.isEmpty())
{
fps_title += " | " + title;
}
Emu.CallAfter([this, title = std::move(fps_title)]() {setTitle(title); });
m_frames = 0;
fps_t.Start();
}
}
else
{
if (this->title() != title)
{
Emu.CallAfter([this, title = std::move(title)]() {setTitle(title); });
}
}
}
void gs_frame::mouseDoubleClickEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
OnFullScreen();
}
}
void gs_frame::HandleCursor(QWindow::Visibility visibility)
{
if (visibility == QWindow::Visibility::FullScreen)
{
setCursor(Qt::BlankCursor);
}
else
{
setCursor(Qt::ArrowCursor);
}
}
/** Override qt hideEvent.
* For some reason beyond me, hitting X hides the game window instead of closes. To remedy this, I forcefully murder it for commiting this transgression.
* Closing the window has a side-effect of also stopping the emulator.
*/
void gs_frame::hideEvent(QHideEvent* ev)
{
Q_UNUSED(ev);
close();
}

48
rpcs3/rpcs3qt/gs_frame.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef GSFRAME_H
#define GSFRAME_H
#include "stdafx.h"
#include "Emu/RSX/GSRender.h"
#include <QWidget>
#include <QWindow>
class gs_frame : public QWindow, public GSFrameBase
{
Q_OBJECT
u64 m_frames = 0;
QString m_windowTitle;
bool m_show_fps;
public:
gs_frame(const QString& title, int w, int h, QIcon appIcon);
protected:
virtual void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *keyEvent);
void OnFullScreen();
void close() override;
bool shown() override;
void hide() override;
void show() override;
void mouseDoubleClickEvent(QMouseEvent* ev) override;
//void SetSize(int width, int height);
void* handle() const override;
void* make_context() override;
void set_current(draw_context_t context) override;
void delete_context(void* context) override;
void flip(draw_context_t context) override;
int client_width() override;
int client_height() override;
void hideEvent(QHideEvent* ev) override;
private slots:
void HandleCursor(QWindow::Visibility visibility);
};
#endif

View File

@ -0,0 +1,206 @@
#include "gui_settings.h"
#include "game_list_frame.h"
#include <QCoreApplication>
#include <QDir>
#include <QMessageBox>
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
gui_settings::gui_settings(QObject* parent) : QObject(parent), settings(ComputeSettingsDir() + tr("CurrentSettings") + ".ini", QSettings::Format::IniFormat, parent),
settingsDir(ComputeSettingsDir())
{
}
gui_settings::~gui_settings()
{
settings.sync();
}
QString gui_settings::ComputeSettingsDir()
{
QString path = QDir(QDir::currentPath()).relativeFilePath(QCoreApplication::applicationDirPath());
path += "/GuiConfigs/";
return path;
}
void gui_settings::ChangeToConfig(const QString& name)
{
if (name != tr("CurrentSettings"))
{ // don't try to change to yourself.
Reset(false);
QSettings other(settingsDir.absoluteFilePath(name + ".ini"), QSettings::IniFormat);
QStringList keys = other.allKeys();
for (QStringList::iterator i = keys.begin(); i != keys.end(); i++)
{
settings.setValue(*i, other.value(*i));
}
settings.sync();
}
}
void gui_settings::Reset(bool removeMeta)
{
if (removeMeta)
{
settings.clear();
}
else
{
settings.remove(GUI::logger);
settings.remove(GUI::main_window);
settings.remove(GUI::game_list);
}
}
QVariant gui_settings::GetValue(const GUI_SAVE& entry)
{
return settings.value(entry.key + "/" + entry.name, entry.def);
}
void gui_settings::SetValue(const GUI_SAVE& entry, const QVariant& value)
{
settings.beginGroup(entry.key);
settings.setValue(entry.name, value);
settings.endGroup();
}
QStringList gui_settings::GetGameListCategoryFilters()
{
QStringList filterList;
if (GetCategoryVisibility(category::hdd_Game)) filterList.append(category::hdd_Game);
if (GetCategoryVisibility(category::disc_Game)) filterList.append(category::disc_Game);
if (GetCategoryVisibility(category::home)) filterList.append(category::home);
if (GetCategoryVisibility(category::audio_Video)) filterList.append(category::audio_Video);
if (GetCategoryVisibility(category::game_Data)) filterList.append(category::game_Data);
if (GetCategoryVisibility(category::unknown)) filterList.append(category::unknown);
return filterList;
}
bool gui_settings::GetCategoryVisibility(QString cat)
{
GUI_SAVE value;
if (cat == category::hdd_Game) value = GUI::cat_hdd_game;
else if (cat == category::disc_Game) value = GUI::cat_disc_game;
else if (cat == category::home) value = GUI::cat_home;
else if (cat == category::audio_Video) value = GUI::cat_audio_video;
else if (cat == category::game_Data) value = GUI::cat_game_data;
else if (cat == category::unknown) value = GUI::cat_unknown;
else
{
value = GUI::cat_other;
LOG_WARNING(GENERAL, "Category %s is unknown. Entry %s was loaded", sstr(cat), sstr(value.name));
}
return GetValue(value).toBool();
}
void gui_settings::SetCategoryVisibility(const QString& cat, const bool& val)
{
GUI_SAVE value;
if (cat == category::hdd_Game) value = GUI::cat_hdd_game;
else if (cat == category::disc_Game) value = GUI::cat_disc_game;
else if (cat == category::home) value = GUI::cat_home;
else if (cat == category::audio_Video) value = GUI::cat_audio_video;
else if (cat == category::game_Data) value = GUI::cat_game_data;
else if (cat == category::unknown) value = GUI::cat_unknown;
else
{
value = GUI::cat_other;
LOG_WARNING(GENERAL, "Category %s is unknown. Entry %s has been set to %d", sstr(cat), sstr(value.name), val);
}
SetValue(value, val);
}
void gui_settings::ShowInfoBox(const GUI_SAVE& entry, const QString& title, const QString& text, QWidget* parent)
{
if (GetValue(entry).toBool())
{
QCheckBox* cb = new QCheckBox(tr("Don't show again"));
QMessageBox* mb = new QMessageBox(QMessageBox::Information, title, text, QMessageBox::Ok, parent);
mb->setCheckBox(cb);
mb->deleteLater();
mb->exec();
if (mb->checkBox()->isChecked())
{
SetValue(entry, false);
LOG_WARNING(GENERAL, "Entry %s was set to false", sstr(entry.name));
}
}
else LOG_WARNING(GENERAL, "Entry %s is false, Info Box not shown", sstr(entry.name));
}
void gui_settings::SetGamelistColVisibility(int col, bool val)
{
SetValue(GUI_SAVE(GUI::game_list, "Col" + QString::number(col) + "visible", true), val);
}
void gui_settings::SaveCurrentConfig(const QString& friendlyName)
{
SetValue(GUI::m_currentConfig, friendlyName);
BackupSettingsToTarget(friendlyName);
}
logs::level gui_settings::GetLogLevel()
{
return (logs::level) GetValue(GUI::l_level).toUInt();
}
bool gui_settings::GetGamelistColVisibility(int col)
{
return GetValue(GUI_SAVE(GUI::game_list, "Col" + QString::number(col) + "visible", true)).toBool();
}
QStringList gui_settings::GetConfigEntries()
{
QStringList nameFilter;
nameFilter << "*.ini";
QFileInfoList entries = settingsDir.entryInfoList(nameFilter, QDir::Files);
QStringList res;
for (QFileInfo entry : entries)
{
res.append(entry.baseName());
}
return res;
}
void gui_settings::BackupSettingsToTarget(const QString& friendlyName)
{
QSettings target(ComputeSettingsDir() + friendlyName + ".ini", QSettings::Format::IniFormat);
QStringList keys = settings.allKeys();
for (QStringList::iterator i = keys.begin(); i != keys.end(); i++)
{
if (!i->startsWith(GUI::meta))
{
target.setValue(*i, settings.value(*i));
}
}
target.sync();
}
QStringList gui_settings::GetStylesheetEntries()
{
QStringList nameFilter;
nameFilter << "*.qss";
QString path = settingsDir.absolutePath();
QFileInfoList entries = settingsDir.entryInfoList(nameFilter, QDir::Files);
QStringList res;
for (QFileInfo entry : entries)
{
res.append(entry.baseName());
}
return res;
}
QString gui_settings::GetCurrentStylesheetPath()
{
return settingsDir.absoluteFilePath(GetValue(GUI::m_currentStylesheet).toString() + ".qss");
}

View File

@ -0,0 +1,135 @@
#ifndef GUI_SETTINGS_H
#define GUI_SETTINGS_H
#include "Utilities/Log.h"
#include <QSettings>
#include <QDir>
#include <QVariant>
#include <QSize>
typedef struct GUI_SAVE
{
QString key;
QString name;
QVariant def;
GUI_SAVE() {
key = "";
name = "";
def = QVariant();
};
GUI_SAVE(const QString& k, const QString& n, const QVariant& d) {
key = k;
name = n;
def = d;
};
};
typedef std::map<const QString, const QSize> icon_size;
namespace GUI
{
const QString gl_icon_key_small = "small";
const QString gl_icon_key_medium = "medium";
const QString gl_icon_key_large = "large";
const icon_size gl_icon_size = {
{ gl_icon_key_small, QSize(80, 44) },
{ gl_icon_key_medium, QSize(160, 88) },
{ gl_icon_key_large, QSize(320, 176) }
};
const QString main_window = "main_window";
const QString game_list = "GameList";
const QString logger = "Logger";
const QString meta = "Meta";
const GUI_SAVE ib_pkg_success = GUI_SAVE( main_window, "infoBoxEnabledInstallPKG", true );
const GUI_SAVE ib_pup_success = GUI_SAVE( main_window, "infoBoxEnabledInstallPUP", true );
const GUI_SAVE ib_show_welcome = GUI_SAVE(main_window, "infoBoxEnabledWelcome", true);
const GUI_SAVE fd_install_pkg = GUI_SAVE( main_window, "lastExplorePathPKG", "" );
const GUI_SAVE fd_install_pup = GUI_SAVE( main_window, "lastExplorePathPUP", "" );
const GUI_SAVE fd_boot_elf = GUI_SAVE( main_window, "lastExplorePathELF", "" );
const GUI_SAVE fd_boot_game = GUI_SAVE( main_window, "lastExplorePathGAME", "" );
const GUI_SAVE fd_decrypt_sprx = GUI_SAVE( main_window, "lastExplorePathSPRX", "" );
const GUI_SAVE mw_debugger = GUI_SAVE( main_window, "debuggerVisible", false );
const GUI_SAVE mw_logger = GUI_SAVE( main_window, "loggerVisible", true );
const GUI_SAVE mw_gamelist = GUI_SAVE( main_window, "gamelistVisible", true );
const GUI_SAVE mw_controls = GUI_SAVE( main_window, "controlsVisible", true );
const GUI_SAVE mw_geometry = GUI_SAVE( main_window, "geometry", QByteArray() );
const GUI_SAVE mw_windowState = GUI_SAVE( main_window, "windowState", QByteArray() );
const GUI_SAVE cat_hdd_game = GUI_SAVE( game_list, "categoryVisibleHDDGame", true );
const GUI_SAVE cat_disc_game = GUI_SAVE( game_list, "categoryVisibleDiscGame", true );
const GUI_SAVE cat_home = GUI_SAVE( game_list, "categoryVisibleHome", true );
const GUI_SAVE cat_audio_video = GUI_SAVE( game_list, "categoryVisibleAudioVideo", true );
const GUI_SAVE cat_game_data = GUI_SAVE( game_list, "categoryVisibleGameData", true );
const GUI_SAVE cat_unknown = GUI_SAVE( game_list, "categoryVisibleUnknown", true );
const GUI_SAVE cat_other = GUI_SAVE( game_list, "categoryVisibleOther", true );
const GUI_SAVE gl_sortAsc = GUI_SAVE( game_list, "sortAsc", true );
const GUI_SAVE gl_sortCol = GUI_SAVE( game_list, "sortCol", 1 );
const GUI_SAVE gl_state = GUI_SAVE( game_list, "state", QByteArray() );
const GUI_SAVE gl_iconSize = GUI_SAVE( game_list, "iconSize", gl_icon_key_small);
const GUI_SAVE l_tty = GUI_SAVE( logger, "TTY", true );
const GUI_SAVE l_level = GUI_SAVE( logger, "level", (uint)(logs::level::success) );
const GUI_SAVE m_currentConfig = GUI_SAVE(meta, "currentConfig", QObject::tr("CurrentSettings"));
const GUI_SAVE m_currentStylesheet = GUI_SAVE(meta, "currentStylesheet", QObject::tr("default"));
}
/** Class for GUI settings..
*/
class gui_settings : public QObject
{
Q_OBJECT
public:
explicit gui_settings(QObject* parent = nullptr);
~gui_settings();
QString GetSettingsDir() {
return settingsDir.absolutePath();
}
/** Changes the settings file to the destination preset*/
void ChangeToConfig(const QString& destination);
bool GetCategoryVisibility(QString cat);
QVariant GetValue(const GUI_SAVE& entry);
void ShowInfoBox(const GUI_SAVE& entry, const QString& title, const QString& text, QWidget* parent = 0);
logs::level GetLogLevel();
bool GetGamelistColVisibility(int col);
QStringList GetConfigEntries();
QString GetCurrentStylesheetPath();
QStringList GetStylesheetEntries();
QStringList GetGameListCategoryFilters();
public slots:
void Reset(bool removeMeta = false);
/** Write value to entry */
void SetValue(const GUI_SAVE& entry, const QVariant& value);
/** Sets the visibility of the chosen category. */
void SetCategoryVisibility(const QString& cat, const bool& val);
void SetGamelistColVisibility(int col, bool val);
void SaveCurrentConfig(const QString& friendlyName);
private:
QString ComputeSettingsDir();
void BackupSettingsToTarget(const QString& destination);
QSettings settings;
QDir settingsDir;
};
#endif

208
rpcs3/rpcs3qt/gui_tab.cpp Normal file
View File

@ -0,0 +1,208 @@
#include "gui_tab.h"
#include <QFileDialog>
#include <QInputDialog>
#include <QAction>
#include <QDesktopServices>
#include <QCheckBox>
gui_tab::gui_tab(std::shared_ptr<gui_settings> xSettings, QWidget *parent) : QWidget(parent), xgui_settings(xSettings)
{
// Left Widgets
// configs
QGroupBox *gb_configs = new QGroupBox(tr("GUI Configs"), this);
QVBoxLayout *vbox_configs = new QVBoxLayout();
QHBoxLayout *hbox_configs = new QHBoxLayout();
combo_configs = new QComboBox(this);
QPushButton *pb_apply_config = new QPushButton(tr("Apply"), this);
// control buttons
QGroupBox *gb_controls = new QGroupBox(tr("GUI Controls"), this);
QVBoxLayout *vbox_controls = new QVBoxLayout();
QPushButton *pb_reset_default = new QPushButton(tr("Reset GUI to Default"), this);
QPushButton *pb_backup_config = new QPushButton(tr("Save Current Configuration"), this);
QPushButton *pb_open_folder = new QPushButton(tr("Open Config/Sheet Folder"), this);
QCheckBox *cb_show_welcome = new QCheckBox(tr("Show Welcome Screen"), this);
cb_show_welcome->setChecked(xSettings->GetValue(GUI::ib_show_welcome).toBool());
// Right Widgets
QGroupBox *gb_stylesheets = new QGroupBox(tr("Stylesheets"), this);
QVBoxLayout *vbox_stylesheets = new QVBoxLayout();
QHBoxLayout *hbox_stylesheets = new QHBoxLayout();
combo_stylesheets = new QComboBox(this);
QPushButton *pb_apply_stylesheet = new QPushButton(tr("Apply"), this);
// Left layout
QVBoxLayout *vbox_left = new QVBoxLayout();
hbox_configs->addWidget(pb_apply_config);
vbox_configs->addWidget(combo_configs);
vbox_configs->addLayout(hbox_configs);
gb_configs->setLayout(vbox_configs);
vbox_controls->addWidget(cb_show_welcome);
vbox_controls->addWidget(pb_reset_default);
vbox_controls->addWidget(pb_backup_config);
vbox_controls->addWidget(pb_open_folder);
gb_controls->setLayout(vbox_controls);
vbox_left->addWidget(gb_configs);
vbox_left->addWidget(gb_controls);
vbox_left->addStretch(1);
// Right layout
QVBoxLayout *vbox_right = new QVBoxLayout();
hbox_stylesheets->addWidget(pb_apply_stylesheet);
vbox_stylesheets->addWidget(combo_stylesheets);
vbox_stylesheets->addLayout(hbox_stylesheets);
gb_stylesheets->setLayout(vbox_stylesheets);
vbox_right->addWidget(gb_stylesheets);
vbox_right->addStretch(1);
// Main Layout
QHBoxLayout *hbox = new QHBoxLayout();
hbox->addLayout(vbox_left);
hbox->addLayout(vbox_right);
setLayout(hbox);
// Connections
connect(pb_reset_default, &QAbstractButton::clicked, this, &gui_tab::OnResetDefault);
connect(pb_backup_config, &QAbstractButton::clicked, this, &gui_tab::OnBackupCurrentConfig);
connect(pb_apply_config, &QAbstractButton::clicked, this, &gui_tab::OnApplyConfig);
connect(pb_apply_stylesheet, &QAbstractButton::clicked, this, &gui_tab::OnApplyStylesheet);
connect(pb_open_folder, &QAbstractButton::clicked, [=]() {QDesktopServices::openUrl(xgui_settings->GetSettingsDir()); });
connect(cb_show_welcome, &QCheckBox::clicked, [=](bool val) {xSettings->SetValue(GUI::ib_show_welcome, val); });
AddConfigs();
AddStylesheets();
}
void gui_tab::Accept()
{
// Only attempt to load a config if changes occurred.
if (m_startingConfig != xgui_settings->GetValue(GUI::m_currentConfig).toString())
{
OnApplyConfig();
}
if (m_startingStylesheet != xgui_settings->GetValue(GUI::m_currentStylesheet).toString())
{
OnApplyStylesheet();
}
}
void gui_tab::AddConfigs()
{
combo_configs->clear();
combo_configs->addItem(tr("default"));
for (QString entry : xgui_settings->GetConfigEntries())
{
if (entry != tr("default"))
{
combo_configs->addItem(entry);
}
}
QString currentSelection = tr("CurrentSettings");
m_startingConfig = currentSelection;
int index = combo_configs->findText(currentSelection);
if (index != -1)
{
combo_configs->setCurrentIndex(index);
}
else
{
LOG_WARNING(GENERAL, "Trying to set an invalid config index ", index);
}
}
void gui_tab::AddStylesheets()
{
combo_stylesheets->clear();
combo_stylesheets->addItem(tr("default"));
for (QString entry : xgui_settings->GetStylesheetEntries())
{
if (entry != tr("default"))
{
combo_stylesheets->addItem(entry);
}
}
QString currentSelection = xgui_settings->GetValue(GUI::m_currentStylesheet).toString();
m_startingStylesheet = currentSelection;
int index = combo_stylesheets->findText(currentSelection);
if (index != -1)
{
combo_stylesheets->setCurrentIndex(index);
}
else
{
LOG_WARNING(GENERAL, "Trying to set an invalid stylesheets index ", index);
}
}
void gui_tab::OnResetDefault()
{
if (QMessageBox::question(this, tr("Reset GUI to default?"), tr("This will include your stylesheet as well. Do you wish to proceed?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
{
xgui_settings->Reset(true);
xgui_settings->ChangeToConfig(tr("default"));
emit GuiStylesheetRequest(tr("default"));
emit GuiSettingsSyncRequest();
AddConfigs();
AddStylesheets();
}
}
void gui_tab::OnBackupCurrentConfig()
{
QInputDialog* dialog = new QInputDialog(this);
dialog->setWindowTitle(tr("Choose a unique name"));
dialog->setLabelText(tr("Configuration Name: "));
dialog->resize(500, 100);
while (dialog->exec() != QDialog::Rejected)
{
dialog->resize(500, 100);
QString friendlyName = dialog->textValue();
if (friendlyName == "")
{
QMessageBox::warning(this, tr("Error"), tr("Name cannot be empty"));
continue;
}
if (friendlyName.contains("."))
{
QMessageBox::warning(this, tr("Error"), tr("Must choose a name with no '.'"));
continue;
}
if (combo_configs->findText(friendlyName) != -1)
{
QMessageBox::warning(this, tr("Error"), tr("Please choose a non-existing name"));
continue;
}
emit GuiSettingsSaveRequest();
xgui_settings->SaveCurrentConfig(friendlyName);
combo_configs->addItem(friendlyName);
combo_configs->setCurrentIndex(combo_configs->findText(friendlyName));
break;
}
}
void gui_tab::OnApplyConfig()
{
QString name = combo_configs->currentText();
xgui_settings->SetValue(GUI::m_currentConfig, name);
xgui_settings->ChangeToConfig(name);
emit GuiSettingsSyncRequest();
}
void gui_tab::OnApplyStylesheet()
{
xgui_settings->SetValue(GUI::m_currentStylesheet, combo_stylesheets->currentText());
emit GuiStylesheetRequest(xgui_settings->GetCurrentStylesheetPath());
}

48
rpcs3/rpcs3qt/gui_tab.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef GUITAB_H
#define GUITAB_H
#include "gui_settings.h"
#include <QWidget>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QAbstractButton>
#include <QGroupBox>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <memory>
class gui_tab : public QWidget
{
Q_OBJECT
public:
explicit gui_tab(std::shared_ptr<gui_settings> guiSettings, QWidget *parent = 0);
public slots:
void Accept();
signals:
void GuiSettingsSyncRequest();
void GuiSettingsSaveRequest();
void GuiStylesheetRequest(const QString& path);
private slots:
void OnResetDefault();
void OnBackupCurrentConfig();
void OnApplyConfig();
void OnApplyStylesheet();
private:
void AddConfigs();
void AddStylesheets();
QComboBox *combo_configs;
QComboBox *combo_stylesheets;
QString m_startingStylesheet;
QString m_startingConfig;
std::shared_ptr<gui_settings> xgui_settings;
};
#endif // GUITAB_H

View File

@ -1,23 +1,16 @@
#ifdef QT_UI
#include <QComboBox>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "inputtab.h"
#include "input_tab.h"
InputTab::InputTab(QWidget *parent) : QWidget(parent)
input_tab::input_tab(std::shared_ptr<emu_settings> xemu_settings, QWidget *parent) : QWidget(parent)
{
// Pad Handler
QGroupBox *padHandler = new QGroupBox(tr("Pad Handler"));
QComboBox *padHandlerBox = new QComboBox;
padHandlerBox->addItem(tr("Null"));
padHandlerBox->addItem(tr("Keyboard"));
#ifdef _MSC_VER
padHandlerBox->addItem(tr("XInput"));
#endif // _MSC_VER
QComboBox *padHandlerBox = xemu_settings->CreateEnhancedComboBox(emu_settings::PadHandler, this);
QVBoxLayout *padHandlerVbox = new QVBoxLayout;
padHandlerVbox->addWidget(padHandlerBox);
@ -26,9 +19,7 @@ InputTab::InputTab(QWidget *parent) : QWidget(parent)
// Keyboard Handler
QGroupBox *keyboardHandler = new QGroupBox(tr("Keyboard Handler"));
QComboBox *keyboardHandlerBox = new QComboBox;
keyboardHandlerBox->addItem(tr("Null"));
keyboardHandlerBox->addItem(tr("Basic"));
QComboBox *keyboardHandlerBox = xemu_settings->CreateEnhancedComboBox(emu_settings::KeyboardHandler, this);
QVBoxLayout *keyboardHandlerVbox = new QVBoxLayout;
keyboardHandlerVbox->addWidget(keyboardHandlerBox);
@ -37,9 +28,7 @@ InputTab::InputTab(QWidget *parent) : QWidget(parent)
// Mouse Handler
QGroupBox *mouseHandler = new QGroupBox(tr("Mouse Handler"));
QComboBox *mouseHandlerBox = new QComboBox;
mouseHandlerBox->addItem(tr("Null"));
mouseHandlerBox->addItem(tr("Basic"));
QComboBox *mouseHandlerBox = xemu_settings->CreateEnhancedComboBox(emu_settings::MouseHandler, this);
QVBoxLayout *mouseHandlerVbox = new QVBoxLayout;
mouseHandlerVbox->addWidget(mouseHandlerBox);
@ -48,9 +37,7 @@ InputTab::InputTab(QWidget *parent) : QWidget(parent)
// Camera
QGroupBox *camera = new QGroupBox(tr("Camera"));
QComboBox *cameraBox = new QComboBox;
cameraBox->addItem(tr("Null"));
cameraBox->addItem(tr("Fake"));
QComboBox *cameraBox = xemu_settings->CreateEnhancedComboBox(emu_settings::Camera, this);
QVBoxLayout *cameraVbox = new QVBoxLayout;
cameraVbox->addWidget(cameraBox);
@ -59,11 +46,7 @@ InputTab::InputTab(QWidget *parent) : QWidget(parent)
// Camera type
QGroupBox *cameraType = new QGroupBox(tr("Camera type"));
QComboBox *cameraTypeBox = new QComboBox;
cameraTypeBox->addItem(tr("Unknown"));
cameraTypeBox->addItem(tr("EyeToy"));
cameraTypeBox->addItem(tr("PS Eye"));
cameraTypeBox->addItem(tr("UVC 1.1"));
QComboBox *cameraTypeBox = xemu_settings->CreateEnhancedComboBox(emu_settings::CameraType, this);
QVBoxLayout *cameraTypeVbox = new QVBoxLayout;
cameraTypeVbox->addWidget(cameraTypeBox);
@ -87,4 +70,3 @@ InputTab::InputTab(QWidget *parent) : QWidget(parent)
setLayout(hbox);
}
#endif // QT_UI

22
rpcs3/rpcs3qt/input_tab.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef INPUTTAB_H
#define INPUTTAB_H
#include "emu_settings.h"
#include <QWidget>
#include <memory>
class input_tab : public QWidget
{
Q_OBJECT
public:
explicit input_tab(std::shared_ptr<emu_settings> xemu_settings, QWidget *parent = 0);
signals:
public slots:
};
#endif // INPUTTAB_H

View File

@ -1,18 +0,0 @@
#ifndef INPUTTAB_H
#define INPUTTAB_H
#include <QWidget>
class InputTab : public QWidget
{
Q_OBJECT
public:
explicit InputTab(QWidget *parent = 0);
signals:
public slots:
};
#endif // INPUTTAB_H

View File

@ -0,0 +1,103 @@
#include "instruction_editor_dialog.h"
#include <QFontDatabase>
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
instruction_editor_dialog::instruction_editor_dialog(QWidget *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm)
: QDialog(parent)
, pc(_pc)
, cpu(_cpu)
, disasm(_disasm)
{
setWindowTitle(tr("Edit instruction"));
setAttribute(Qt::WA_DeleteOnClose);
setMinimumSize(300, sizeHint().height());
const auto cpu = _cpu.get();
cpu_offset = g_system == system_type::ps3 && cpu->id_type() != 1 ? static_cast<SPUThread&>(*cpu).offset : 0;
QString instruction = qstr(fmt::format("%08x", vm::ps3::read32(cpu_offset + pc).value()));
QVBoxLayout* vbox_panel(new QVBoxLayout());
QHBoxLayout* hbox_panel(new QHBoxLayout());
QVBoxLayout* vbox_left_panel(new QVBoxLayout());
QVBoxLayout* vbox_right_panel(new QVBoxLayout());
QHBoxLayout* hbox_b_panel(new QHBoxLayout());
QPushButton* button_ok(new QPushButton(tr("Ok")));
QPushButton* button_cancel(new QPushButton(tr("Cancel")));
button_ok->setFixedWidth(80);
button_cancel->setFixedWidth(80);
QLabel* t1_text = new QLabel(tr("Address: "), this);
QLabel* t2_text = new QLabel(tr("Instruction: "), this);
QLabel* t3_text = new QLabel(tr("Preview: "), this);
QLabel* t1_addr = new QLabel(qstr(fmt::format("%08x", pc)), this);
t2_instr = new QLineEdit(this);
t2_instr->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
t2_instr->setPlaceholderText(instruction);
t2_instr->setText(instruction);
t2_instr->setMaxLength(8);
t2_instr->setMaximumWidth(65);
t3_preview = new QLabel("", this);
// Layouts
vbox_left_panel->addWidget(t1_text);
vbox_left_panel->addWidget(t2_text);
vbox_left_panel->addWidget(t3_text);
vbox_right_panel->addWidget(t1_addr);
vbox_right_panel->addWidget(t2_instr);
vbox_right_panel->addWidget(t3_preview);
vbox_right_panel->setAlignment(Qt::AlignLeft);
hbox_b_panel->addWidget(button_ok);
hbox_b_panel->addWidget(button_cancel);
hbox_b_panel->setAlignment(Qt::AlignCenter);
// Main Layout
hbox_panel->addLayout(vbox_left_panel);
hbox_panel->addSpacing(10);
hbox_panel->addLayout(vbox_right_panel);
vbox_panel->addLayout(hbox_panel);
vbox_panel->addSpacing(10);
vbox_panel->addLayout(hbox_b_panel);
setLayout(vbox_panel);
setModal(true);
// Events
connect(button_ok, &QAbstractButton::pressed, [=]() {
bool ok;
ulong opcode = t2_instr->text().toULong(&ok, 16);
if (!ok)
QMessageBox::critical(this, tr("Error"), tr("This instruction could not be parsed.\nNo changes were made."));
else
vm::ps3::write32(cpu_offset + pc, (u32)opcode);
accept();
});
connect(button_cancel, &QAbstractButton::pressed, this, &instruction_editor_dialog::reject);
connect(t2_instr, &QLineEdit::textChanged, this, &instruction_editor_dialog::updatePreview);
updatePreview();
}
void instruction_editor_dialog::updatePreview()
{
bool ok;
ulong opcode = t2_instr->text().toULong(&ok, 16);
if (ok)
{
if (g_system == system_type::psv)
{
t3_preview->setText(tr("Preview for ARMv7Thread not implemented yet."));
}
else
{
t3_preview->setText(tr("Preview disabled."));
}
}
else
{
t3_preview->setText(tr("Could not parse instruction."));
}
}

View File

@ -0,0 +1,37 @@
#ifndef INSTRUCTIONEDITOR_H
#define INSTRUCTIONEDITOR_H
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDisAsm.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include <QDialog>
#include <QLineEdit>
#include <QLabel>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QPushButton>
class instruction_editor_dialog : public QDialog
{
u32 pc;
u32 cpu_offset;
CPUDisAsm* disasm;
QLineEdit* t2_instr;
QLabel* t3_preview;
public:
std::weak_ptr<cpu_thread> cpu;
public:
instruction_editor_dialog(QWidget *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm);
void updatePreview();
};
#endif // !INSTRUCTIONEDITOR_H

View File

@ -0,0 +1,314 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/RawSPUThread.h"
#include "Emu/Cell/lv2/sys_lwmutex.h"
#include "Emu/Cell/lv2/sys_lwcond.h"
#include "Emu/Cell/lv2/sys_mutex.h"
#include "Emu/Cell/lv2/sys_cond.h"
#include "Emu/Cell/lv2/sys_semaphore.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/lv2/sys_event_flag.h"
#include "Emu/Cell/lv2/sys_rwlock.h"
#include "Emu/Cell/lv2/sys_prx.h"
#include "Emu/Cell/lv2/sys_memory.h"
#include "Emu/Cell/lv2/sys_mmapper.h"
#include "Emu/Cell/lv2/sys_spu.h"
#include "Emu/Cell/lv2/sys_interrupt.h"
#include "Emu/Cell/lv2/sys_timer.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_fs.h"
#include "kernel_explorer.h"
kernel_explorer::kernel_explorer(QWidget* parent) : QDialog(parent)
{
setWindowTitle(tr("Kernel Explorer"));
setAttribute(Qt::WA_DeleteOnClose);
setMinimumSize(QSize(700, 450));
QPalette pal;
pal.setColor(QPalette::Background, QColor(240, 240, 240));
setPalette(pal); //This fix the ugly background color under Windows
QVBoxLayout* vbox_panel = new QVBoxLayout();
QHBoxLayout* hbox_buttons = new QHBoxLayout();
QPushButton* button_refresh = new QPushButton(tr("Refresh"), this);
hbox_buttons->addWidget(button_refresh);
hbox_buttons->addStretch();
m_tree = new QTreeWidget(this);
m_tree->setBaseSize(QSize(600, 300));
m_tree->setWindowTitle(tr("Kernel"));
m_tree->header()->close();
// Merge and display everything
vbox_panel->addSpacing(10);
vbox_panel->addLayout(hbox_buttons);
vbox_panel->addSpacing(10);
vbox_panel->addWidget(m_tree);
vbox_panel->addSpacing(10);
setLayout(vbox_panel);
// Events
connect(button_refresh, &QAbstractButton::clicked, this, &kernel_explorer::Update);
// Fill the wxTreeCtrl
Update();
};
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
void kernel_explorer::Update()
{
m_tree->clear();
const auto vm_block = vm::get(vm::user_space);
if (!vm_block)
{
return;
}
const u32 total_memory_usage = vm_block->used();
QTreeWidgetItem* root = new QTreeWidgetItem();
root->setText(0, qstr(fmt::format("Process, ID = 0x00000001, Total Memory Usage = 0x%x (%0.2f MB)", total_memory_usage, (float)total_memory_usage / (1024 * 1024))));
m_tree->addTopLevelItem(root);
union name64
{
u64 u64_data;
char string[8];
name64(u64 data)
: u64_data(data & 0x00ffffffffffffffull)
{
}
const char* operator+() const
{
return string;
}
};
// TODO: FileSystem
struct lv2_obj_rec
{
QTreeWidgetItem* node;
u32 count{ 0 };
lv2_obj_rec() = default;
lv2_obj_rec(QTreeWidgetItem* node)
: node(node)
{
}
};
auto l_addTreeChild = [=](QTreeWidgetItem *parent, QString text)
{
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
treeItem->setText(0, text);
parent->addChild(treeItem);
return treeItem;
};
std::vector<lv2_obj_rec> lv2_types(256);
lv2_types[SYS_MEM_OBJECT] = l_addTreeChild(root, "Memory");
lv2_types[SYS_MUTEX_OBJECT] = l_addTreeChild(root, "Mutexes");
lv2_types[SYS_COND_OBJECT] = l_addTreeChild(root, "Condition Variables");
lv2_types[SYS_RWLOCK_OBJECT] = l_addTreeChild(root, "Reader Writer Locks");
lv2_types[SYS_INTR_TAG_OBJECT] = l_addTreeChild(root, "Interrupt Tags");
lv2_types[SYS_INTR_SERVICE_HANDLE_OBJECT] = l_addTreeChild(root, "Interrupt Service Handles");
lv2_types[SYS_EVENT_QUEUE_OBJECT] = l_addTreeChild(root, "Event Queues");
lv2_types[SYS_EVENT_PORT_OBJECT] = l_addTreeChild(root, "Event Ports");
lv2_types[SYS_TRACE_OBJECT] = l_addTreeChild(root, "Traces");
lv2_types[SYS_SPUIMAGE_OBJECT] = l_addTreeChild(root, "SPU Images");
lv2_types[SYS_PRX_OBJECT] = l_addTreeChild(root, "Modules");
lv2_types[SYS_SPUPORT_OBJECT] = l_addTreeChild(root, "SPU Ports");
lv2_types[SYS_LWMUTEX_OBJECT] = l_addTreeChild(root, "Light Weight Mutexes");
lv2_types[SYS_TIMER_OBJECT] = l_addTreeChild(root, "Timers");
lv2_types[SYS_SEMAPHORE_OBJECT] = l_addTreeChild(root, "Semaphores");
lv2_types[SYS_LWCOND_OBJECT] = l_addTreeChild(root, "Light Weight Condition Variables");
lv2_types[SYS_EVENT_FLAG_OBJECT] = l_addTreeChild(root, "Event Flags");
idm::select<lv2_obj>([&](u32 id, lv2_obj& obj)
{
lv2_types[id >> 24].count++;
if (auto& node = lv2_types[id >> 24].node) switch (id >> 24)
{
case SYS_MEM_OBJECT:
{
auto& mem = static_cast<lv2_memory&>(obj);
l_addTreeChild(node, qstr(fmt::format("Memory: ID = 0x%08x", id)));
break;
}
case SYS_MUTEX_OBJECT:
{
auto& mutex = static_cast<lv2_mutex&>(obj);
l_addTreeChild(node, qstr(fmt::format("Mutex: ID = 0x%08x \"%s\",%s Owner = 0x%x, Locks = %u, Conds = %u, Wq = %zu", id, +name64(mutex.name),
mutex.recursive == SYS_SYNC_RECURSIVE ? " Recursive," : "", mutex.owner >> 1, +mutex.lock_count, +mutex.cond_count, mutex.sq.size())));
break;
}
case SYS_COND_OBJECT:
{
auto& cond = static_cast<lv2_cond&>(obj);
l_addTreeChild(node, qstr(fmt::format("Cond: ID = 0x%08x \"%s\", Waiters = %u", id, +name64(cond.name), +cond.waiters)));
break;
}
case SYS_RWLOCK_OBJECT:
{
auto& rw = static_cast<lv2_rwlock&>(obj);
const s64 val = rw.owner;
l_addTreeChild(node, qstr(fmt::format("RW Lock: ID = 0x%08x \"%s\", Owner = 0x%x(%d), Rq = %zu, Wq = %zu", id, +name64(rw.name),
std::max<s64>(0, val >> 1), -std::min<s64>(0, val >> 1), rw.rq.size(), rw.wq.size())));
break;
}
case SYS_INTR_TAG_OBJECT:
{
auto& tag = static_cast<lv2_int_tag&>(obj);
l_addTreeChild(node, qstr(fmt::format("Intr Tag: ID = 0x%08x", id)));
break;
}
case SYS_INTR_SERVICE_HANDLE_OBJECT:
{
auto& serv = static_cast<lv2_int_serv&>(obj);
l_addTreeChild(node, qstr(fmt::format("Intr Svc: ID = 0x%08x", id)));
break;
}
case SYS_EVENT_QUEUE_OBJECT:
{
auto& eq = static_cast<lv2_event_queue&>(obj);
l_addTreeChild(node, qstr(fmt::format("Event Queue: ID = 0x%08x \"%s\", %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", id, +name64(eq.name),
eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.key, eq.events.size(), eq.size, eq.sq.size())));
break;
}
case SYS_EVENT_PORT_OBJECT:
{
auto& ep = static_cast<lv2_event_port&>(obj);
l_addTreeChild(node, qstr(fmt::format("Event Port: ID = 0x%08x, Name = %#llx", id, ep.name)));
break;
}
case SYS_TRACE_OBJECT:
{
l_addTreeChild(node, qstr(fmt::format("Trace: ID = 0x%08x", id)));
break;
}
case SYS_SPUIMAGE_OBJECT:
{
l_addTreeChild(node, qstr(fmt::format("SPU Image: ID = 0x%08x", id)));
break;
}
case SYS_PRX_OBJECT:
{
auto& prx = static_cast<lv2_prx&>(obj);
l_addTreeChild(node, qstr(fmt::format("PRX: ID = 0x%08x '%s'", id, prx.name)));
break;
}
case SYS_SPUPORT_OBJECT:
{
l_addTreeChild(node, qstr(fmt::format("SPU Port: ID = 0x%08x", id)));
break;
}
case SYS_LWMUTEX_OBJECT:
{
auto& lwm = static_cast<lv2_lwmutex&>(obj);
l_addTreeChild(node, qstr(fmt::format("LWMutex: ID = 0x%08x \"%s\", Wq = %zu", id, +name64(lwm.name), lwm.sq.size())));
break;
}
case SYS_TIMER_OBJECT:
{
auto& timer = static_cast<lv2_timer&>(obj);
l_addTreeChild(node, qstr(fmt::format("Timer: ID = 0x%08x", id)));
break;
}
case SYS_SEMAPHORE_OBJECT:
{
auto& sema = static_cast<lv2_sema&>(obj);
l_addTreeChild(node, qstr(fmt::format("Semaphore: ID = 0x%08x \"%s\", Count = %d, Max Count = %d, Waiters = %#zu", id, +name64(sema.name),
sema.val.load(), sema.max, sema.sq.size())));
break;
}
case SYS_LWCOND_OBJECT:
{
auto& lwc = static_cast<lv2_cond&>(obj);
l_addTreeChild(node, qstr(fmt::format("LWCond: ID = 0x%08x \"%s\", Waiters = %zu", id, +name64(lwc.name), +lwc.waiters)));
break;
}
case SYS_EVENT_FLAG_OBJECT:
{
auto& ef = static_cast<lv2_event_flag&>(obj);
l_addTreeChild(node, qstr(fmt::format("Event Flag: ID = 0x%08x \"%s\", Type = 0x%x, Pattern = 0x%llx, Wq = %zu", id, +name64(ef.name),
ef.type, ef.pattern.load(), +ef.waiters)));
break;
}
default:
{
l_addTreeChild(node, qstr(fmt::format("Unknown object: ID = 0x%08x", id)));
}
}
});
lv2_types.emplace_back(l_addTreeChild(root, "Memory Containers"));
idm::select<lv2_memory_container>([&](u32 id, lv2_memory_container&)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("Memory Container: ID = 0x%08x", id)));
});
lv2_types.emplace_back(l_addTreeChild(root, "PPU Threads"));
idm::select<ppu_thread>([&](u32 id, ppu_thread& ppu)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("PPU Thread: ID = 0x%08x '%s'", id, ppu.get_name())));
});
lv2_types.emplace_back(l_addTreeChild(root, "SPU Threads"));
idm::select<SPUThread>([&](u32 id, SPUThread& spu)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread: ID = 0x%08x '%s'", id, spu.get_name())));
});
lv2_types.emplace_back(l_addTreeChild(root, "SPU Thread Groups"));
idm::select<lv2_spu_group>([&](u32 id, lv2_spu_group& tg)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread Group: ID = 0x%08x '%s'", id, tg.name)));
});
lv2_types.emplace_back(l_addTreeChild(root, "File Descriptors"));
idm::select<lv2_fs_object>([&](u32 id, lv2_fs_object& fo)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("FD: ID = 0x%08x '%s'", id, fo.name.data())));
});
for (auto&& entry : lv2_types)
{
if (entry.node && entry.count)
{
// Append object count
entry.node->setText(0, entry.node->text(0) + qstr(fmt::format(" (%zu)", entry.count)));
}
else if (entry.node)
{
// Delete node otherwise
delete entry.node;
}
}
// RawSPU Threads (TODO)
root->setExpanded(true);
}

View File

@ -0,0 +1,22 @@
#ifndef KERNELEXPLORER_H
#define KERNELEXPLORER_H
#include <QDialog>
#include <QVBoxLayout>
#include <QPushButton>
#include <QTreeWidget>
#include <QHeaderView>
class kernel_explorer : public QDialog
{
Q_OBJECT
QTreeWidget* m_tree;
public:
kernel_explorer(QWidget* parent);
private slots:
void Update();
};
#endif // KERNELEXPLORER_H

345
rpcs3/rpcs3qt/log_frame.cpp Normal file
View File

@ -0,0 +1,345 @@
#include "log_frame.h"
#include <stdafx.h>
#include "rpcs3_version.h"
#include <QMenu>
#include <QActionGroup>
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
struct gui_listener : logs::listener
{
atomic_t<logs::level> enabled{};
struct packet
{
atomic_t<packet*> next{};
logs::level sev{};
std::string msg;
~packet()
{
for (auto ptr = next.raw(); UNLIKELY(ptr);)
{
delete std::exchange(ptr, std::exchange(ptr->next.raw(), nullptr));
}
}
};
atomic_t<packet*> last; // Packet for writing another packet
atomic_t<packet*> read; // Packet for reading
gui_listener()
: logs::listener()
{
// Initialize packets
read = new packet;
last = new packet;
read->next = last.load();
last->msg = fmt::format("RPCS3 v%s\n", rpcs3::version.to_string());
// Self-registration
logs::listener::add(this);
}
~gui_listener()
{
delete read;
}
void log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& text)
{
Q_UNUSED(stamp);
if (msg.sev <= enabled)
{
const auto _new = new packet;
_new->sev = msg.sev;
if (prefix.size() > 0)
{
_new->msg += "{";
_new->msg += prefix;
_new->msg += "} ";
}
if (msg.ch->name)
{
_new->msg += msg.ch->name;
_new->msg += msg.sev == logs::level::todo ? " TODO: " : ": ";
}
else if (msg.sev == logs::level::todo)
{
_new->msg += "TODO: ";
}
_new->msg += text;
_new->msg += '\n';
last.exchange(_new)->next = _new;
}
}
void pop()
{
if (const auto head = read->next.exchange(nullptr))
{
delete read.exchange(head);
}
}
void clear()
{
while (read->next)
{
pop();
}
}
};
// GUI Listener instance
static gui_listener s_gui_listener;
log_frame::log_frame(std::shared_ptr<gui_settings> guiSettings, QWidget *parent) : QDockWidget(tr("Log"), parent), xgui_settings(guiSettings)
{
tabWidget = new QTabWidget;
log = new QTextEdit(tabWidget);
QPalette logPalette = log->palette();
logPalette.setColor(QPalette::Base, Qt::black);
log->setPalette(logPalette);
log->setReadOnly(true);
tty = new QTextEdit(tabWidget);
QPalette ttyPalette = log->palette();
ttyPalette.setColor(QPalette::Base, Qt::black);
ttyPalette.setColor(QPalette::Text, Qt::white);
tty->setPalette(ttyPalette);
tty->setReadOnly(true);
tabWidget->addTab(log, tr("Log"));
tabWidget->addTab(tty, tr("TTY"));
setWidget(tabWidget);
// Open or create TTY.log
tty_file.open(fs::get_config_dir() + "TTY.log", fs::read + fs::create);
CreateAndConnectActions();
log->setContextMenuPolicy(Qt::CustomContextMenu);
connect(log, &QWidget::customContextMenuRequested, [=](const QPoint& pos){
QMenu* menu = log->createStandardContextMenu();
menu->addAction(clearAct);
menu->addSeparator();
menu->addActions({ nothingAct, fatalAct, errorAct, todoAct, successAct, warningAct, noticeAct, traceAct });
menu->addSeparator();
menu->addAction(TTYAct);
menu->exec(mapToGlobal(pos));
});
// Check for updates every ~10 ms
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &log_frame::UpdateUI);
timer->start(10);
}
void log_frame::SetLogLevel(logs::level lev)
{
switch (lev)
{
case logs::level::always:
{
nothingAct->trigger();
break;
}
case logs::level::fatal:
{
fatalAct->trigger();
break;
}
case logs::level::error:
{
errorAct->trigger();
break;
}
case logs::level::todo:
{
todoAct->trigger();
break;
}
case logs::level::success:
{
successAct->trigger();
break;
}
case logs::level::warning:
{
warningAct->trigger();
break;
}
case logs::level::notice:
{
noticeAct->trigger();
break;
}
case logs::level::trace:
{
traceAct->trigger();
break;
}
default:
warningAct->trigger();
}
}
void log_frame::SetTTYLogging(bool val)
{
TTYAct->setChecked(val);
}
void log_frame::CreateAndConnectActions()
{
// I, for one, welcome our lambda overlord
// It's either this or a signal mapper
// Then, probably making a list of these actions so that it's easier to iterate to generate the mapper.
auto l_initAct = [this](QAction* act, logs::level logLevel)
{
act->setCheckable(true);
// This sets the log level properly when the action is triggered.
auto l_callback = [this, logLevel]() {
s_gui_listener.enabled = logLevel;
xgui_settings->SetValue(GUI::l_level, static_cast<uint>(logLevel));
};
connect(act, &QAction::triggered, l_callback);
};
clearAct = new QAction(tr("Clear"), this);
connect(clearAct, &QAction::triggered, log, &QTextEdit::clear);
// Action groups make these actions mutually exclusive.
logLevels = new QActionGroup(this);
nothingAct = new QAction(tr("Nothing"), logLevels);
fatalAct = new QAction(tr("Fatal"), logLevels);
errorAct = new QAction(tr("Error"), logLevels);
todoAct = new QAction(tr("Todo"), logLevels);
successAct = new QAction(tr("Success"), logLevels);
warningAct = new QAction(tr("Warning"), logLevels);
noticeAct = new QAction(tr("Notice"), logLevels);
traceAct = new QAction(tr("Trace"), logLevels);
TTYAct = new QAction(tr("TTY"), this);
TTYAct->setCheckable(true);
connect(TTYAct, &QAction::triggered, xgui_settings.get(), [=](bool checked){
xgui_settings->SetValue(GUI::l_tty, checked);
});
l_initAct(nothingAct, logs::level::always);
l_initAct(fatalAct, logs::level::fatal);
l_initAct(errorAct, logs::level::error);
l_initAct(todoAct, logs::level::todo);
l_initAct(successAct, logs::level::success);
l_initAct(warningAct, logs::level::warning);
l_initAct(noticeAct, logs::level::notice);
l_initAct(traceAct, logs::level::trace);
LoadSettings();
}
void log_frame::LoadSettings()
{
SetLogLevel(xgui_settings->GetLogLevel());
SetTTYLogging(xgui_settings->GetValue(GUI::l_tty).toBool());
}
void log_frame::UpdateUI()
{
std::vector<char> buf(4096);
// Get UTF-8 string from file
auto get_utf8 = [&](const fs::file& file, u64 size) -> QString
{
size = file.read(buf.data(), size);
for (u64 i = 0; i < size; i++)
{
// Get UTF-8 sequence length (no real validation performed)
const u64 tail =
(buf[i] & 0xF0) == 0xF0 ? 3 :
(buf[i] & 0xE0) == 0xE0 ? 2 :
(buf[i] & 0xC0) == 0xC0 ? 1 : 0;
if (i + tail >= size)
{ // Copying is expensive-- O(i)-- but I suspect this corruption will be exceptionally unlikely.
file.seek(i - size, fs::seek_cur);
std::vector<char> sub(&buf[0], &buf[i]);
return QString(sub.data());
}
}
return QString(buf.data());
};
const auto start = steady_clock::now();
// Check TTY logs
while (const u64 size = std::min<u64>(buf.size(), tty_file.size() - tty_file.pos()))
{
QString text = get_utf8(tty_file, size);
// Hackily used the state of the check.. be better if I actually stored this value.
if (TTYAct->isChecked())
{
text.chop(1); // remove newline since Qt automatically adds a newline.
tty->append(text);
}
// Limit processing time
if (steady_clock::now() >= start + 4ms || text.isEmpty()) break;
}
// Check main logs
while (const auto packet = s_gui_listener.read->next.load())
{
// Confirm log level
if (packet->sev <= s_gui_listener.enabled)
{
// Get text color
QColor color;
QString text;
switch (packet->sev)
{
case logs::level::always: color = QColor(0x00, 0xFF, 0xFF); break; // Cyan
case logs::level::fatal: text = "F "; color = QColor(0xFF, 0x00, 0xFF); break; // Fuchsia
case logs::level::error: text = "E "; color = QColor(0xFF, 0x00, 0x00); break; // Red
case logs::level::todo: text = "U "; color = QColor(0xFF, 0x60, 0x00); break; // Orange
case logs::level::success: text = "S "; color = QColor(0x00, 0xFF, 0x00); break; // Green
case logs::level::warning: text = "W "; color = QColor(0xFF, 0xFF, 0x00); break; // Yellow
case logs::level::notice: text = "! "; color = QColor(0xFF, 0xFF, 0xFF); break; // White
case logs::level::trace: text = "T "; color = QColor(0x80, 0x80, 0x80); break; // Gray
default: continue;
}
// Print UTF-8 text.
text += qstr(packet->msg);
log->setTextColor(color);
// remove the new line because Qt's append adds a new line already.
text.chop(1);
log->append(text);
}
// Drop packet
s_gui_listener.pop();
// Limit processing time
if (steady_clock::now() >= start + 7ms) break;
}
}
void log_frame::closeEvent(QCloseEvent *event)
{
QDockWidget::closeEvent(event);
emit log_frameClosed();
}

62
rpcs3/rpcs3qt/log_frame.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef LOGFRAME_H
#define LOGFRAME_H
#include "Utilities/File.h"
#include "Utilities/Log.h"
#include "gui_settings.h"
#include <memory>
#include <QDockWidget>
#include <QTabWidget>
#include <QTextEdit>
#include <QActionGroup>
#include <QTimer>
class log_frame : public QDockWidget
{
Q_OBJECT
public:
explicit log_frame(std::shared_ptr<gui_settings> guiSettings, QWidget *parent = nullptr);
/** Loads from settings. Public so that main_window can call this easily. */
void LoadSettings();
signals:
void log_frameClosed();
protected:
/** Override inherited method from Qt to allow signalling when close happened.*/
void closeEvent(QCloseEvent* event);
private slots:
void UpdateUI();
private:
void SetLogLevel(logs::level lev);
void SetTTYLogging(bool val);
void CreateAndConnectActions();
QTabWidget *tabWidget;
QTextEdit *log;
QTextEdit *tty;
fs::file tty_file;
QAction* clearAct;
QActionGroup* logLevels;
QAction* nothingAct;
QAction* fatalAct;
QAction* errorAct;
QAction* todoAct;
QAction* successAct;
QAction* warningAct;
QAction* noticeAct;
QAction* traceAct;
QAction* TTYAct;
std::shared_ptr<gui_settings> xgui_settings;
};
#endif // LOGFRAME_H

View File

@ -1,38 +0,0 @@
#ifdef QT_UI
#include "logframe.h"
LogFrame::LogFrame(QWidget *parent) : QDockWidget(tr("Log"), parent)
{
tabWidget = new QTabWidget;
log = new QTextEdit(tabWidget);
QPalette logPalette = log->palette();
logPalette.setColor(QPalette::Base, Qt::black);
log->setPalette(logPalette);
log->setReadOnly(true);
tty = new QTextEdit(tabWidget);
QPalette ttyPalette = log->palette();
ttyPalette.setColor(QPalette::Base, Qt::black);
ttyPalette.setColor(QPalette::Text, Qt::white);
tty->setPalette(ttyPalette);
tty->setReadOnly(true);
tabWidget->addTab(log, tr("Log"));
tabWidget->addTab(tty, tr("TTY"));
setWidget(tabWidget);
// Check for updates every ~10 ms
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &LogFrame::Update);
timer->start(10);
}
void LogFrame::Update()
{
}
#endif // QT_UI

View File

@ -1,25 +0,0 @@
#ifndef LOGFRAME_H
#define LOGFRAME_H
#include <QDockWidget>
#include <QTabWidget>
#include <QTextEdit>
#include <QTimer>
class LogFrame : public QDockWidget
{
Q_OBJECT
public:
explicit LogFrame(QWidget *parent = 0);
private slots:
void Update();
private:
QTabWidget *tabWidget;
QTextEdit *log;
QTextEdit *tty;
};
#endif // LOGFRAME_H

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